mirror of
https://github.com/thegatesbrowser/thegates.git
synced 2025-08-23 17:17:31 -04:00
add license, move folders
This commit is contained in:
parent
185cc74060
commit
271c4a46a1
132 changed files with 21 additions and 0 deletions
31
app/scripts/sandbox/command_sync.gd
Normal file
31
app/scripts/sandbox/command_sync.gd
Normal file
|
@ -0,0 +1,31 @@
|
|||
extends CommandSync
|
||||
|
||||
@export var gate_events: GateEvents
|
||||
@export var command_events: CommandEvents
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
gate_events.gate_entered.connect(bind)
|
||||
execute_function = _execute_function
|
||||
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
receive_commands()
|
||||
|
||||
|
||||
func _execute_function(command: Command) -> Variant:
|
||||
Debug.logclr("Recieved command: " + command.name + ". Args: " + str(command.args), Color.SANDY_BROWN)
|
||||
match command.name:
|
||||
"send_filehandle":
|
||||
if command.args.size() != 1: Debug.logerr("Arg count should be 1"); return ""
|
||||
command_events.send_filehandle_emit(command.args[0])
|
||||
"set_mouse_mode":
|
||||
if command.args.size() != 1: Debug.logerr("Arg count should be 1"); return ""
|
||||
command_events.set_mouse_mode_emit(command.args[0])
|
||||
"open_gate":
|
||||
if command.args.size() != 1: Debug.logerr("Arg count should be 1"); return ""
|
||||
var url = Url.join(gate_events.current_gate_url, command.args[0])
|
||||
gate_events.open_gate_emit(url)
|
||||
_:
|
||||
Debug.logerr("Command %s not implemented" % [command.name])
|
||||
return ""
|
45
app/scripts/sandbox/input_sync.gd
Normal file
45
app/scripts/sandbox/input_sync.gd
Normal file
|
@ -0,0 +1,45 @@
|
|||
extends Node
|
||||
|
||||
@export var gate_events: GateEvents
|
||||
@export var ui_events: UiEvents
|
||||
@export var render_result: RenderResult
|
||||
|
||||
var scale_width: float
|
||||
var scale_height: float
|
||||
|
||||
var input_sync: InputSync
|
||||
var should_send := false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
gate_events.gate_entered.connect(start_server)
|
||||
ui_events.ui_mode_changed.connect(on_ui_mode_changed)
|
||||
|
||||
scale_width = float(render_result.width) / ui_events.current_ui_size.x
|
||||
scale_height = float(render_result.height) / ui_events.current_ui_size.y
|
||||
Debug.logclr("Mouse position scale: %.2fx%.2f" % [scale_width, scale_height], Color.DIM_GRAY)
|
||||
|
||||
|
||||
func start_server() -> void:
|
||||
input_sync = InputSync.new()
|
||||
input_sync.bind()
|
||||
|
||||
|
||||
func on_ui_mode_changed(mode: UiEvents.UiMode) -> void:
|
||||
should_send = mode == UiEvents.UiMode.FULL_SCREEN
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if input_sync == null or not should_send: return
|
||||
|
||||
if event is InputEventMouse:
|
||||
event.position = get_scaled_mouse_pos(event.position)
|
||||
event.global_position = get_scaled_mouse_pos(event.global_position)
|
||||
|
||||
input_sync.send_input_event(event)
|
||||
|
||||
|
||||
func get_scaled_mouse_pos(position : Vector2) -> Vector2:
|
||||
position.x *= scale_width
|
||||
position.y *= scale_height
|
||||
return position
|
89
app/scripts/sandbox/render_result.gd
Normal file
89
app/scripts/sandbox/render_result.gd
Normal file
|
@ -0,0 +1,89 @@
|
|||
extends TextureRect
|
||||
class_name RenderResult
|
||||
|
||||
@export var gate_events: GateEvents
|
||||
@export var command_events: CommandEvents
|
||||
@export var splash_screen: Texture2D
|
||||
|
||||
var rd: RenderingDevice
|
||||
var ext_texure: ExternalTexture
|
||||
var texture_rid: RID
|
||||
|
||||
@onready var width: int = get_viewport().size.x
|
||||
@onready var height: int = get_viewport().size.y
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
gate_events.gate_info_loaded.connect(initialize)
|
||||
gate_events.gate_entered.connect(create_external_texture)
|
||||
command_events.send_filehandle.connect(send_filehandle)
|
||||
|
||||
# Change size
|
||||
var image = resize_and_convert(splash_screen.get_image(), Image.FORMAT_RGB8)
|
||||
self.texture = ImageTexture.create_from_image(image)
|
||||
|
||||
|
||||
func initialize(gate: Gate, is_cached: bool) -> void:
|
||||
rd = RenderingServer.get_rendering_device()
|
||||
|
||||
if not is_cached: # Show thumbnail image
|
||||
self.texture = create_gate_image(gate)
|
||||
|
||||
texture_rid = RenderingServer.texture_get_rd_texture(self.texture.get_rid())
|
||||
if not texture_rid.is_valid(): Debug.logerr("Cannot create ImageTexture")
|
||||
|
||||
|
||||
func create_gate_image(gate: Gate) -> ImageTexture:
|
||||
var tex = FileTools.load_external_tex(gate.image)
|
||||
|
||||
var image: Image
|
||||
if tex != null: image = resize_and_convert(tex.get_image(), Image.FORMAT_RGB8)
|
||||
else: image = Image.create(width, height, false, Image.FORMAT_RGB8)
|
||||
|
||||
return ImageTexture.create_from_image(image)
|
||||
|
||||
|
||||
func create_external_texture() -> void:
|
||||
var t_format: RDTextureFormat = RDTextureFormat.new()
|
||||
t_format.format = RenderingDevice.DATA_FORMAT_R8G8B8A8_UNORM
|
||||
t_format.usage_bits = RenderingDevice.TEXTURE_USAGE_CAN_COPY_FROM_BIT | \
|
||||
RenderingDevice.TEXTURE_USAGE_CAN_UPDATE_BIT
|
||||
t_format.width = width
|
||||
t_format.height = height
|
||||
t_format.depth = 1
|
||||
var t_view: RDTextureView = RDTextureView.new()
|
||||
|
||||
# For some reason when switching scene something is not freed
|
||||
# So need to wait to free that up
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
|
||||
ext_texure = ExternalTexture.new()
|
||||
var image = resize_and_convert(splash_screen.get_image(), Image.FORMAT_RGBA8)
|
||||
var err = ext_texure.create(t_format, t_view, [image.get_data()])
|
||||
if err: Debug.logerr("Cannot create external texture")
|
||||
else: Debug.logclr("External texture created", Color.AQUAMARINE)
|
||||
|
||||
|
||||
func resize_and_convert(image: Image, format: Image.Format) -> Image:
|
||||
image.resize(width, height)
|
||||
image.convert(format)
|
||||
image.clear_mipmaps()
|
||||
return image
|
||||
|
||||
|
||||
func send_filehandle(filehandle_path: String) -> void:
|
||||
Debug.logr("Sending filehandle...")
|
||||
var sent = false
|
||||
while not sent:
|
||||
sent = ext_texure.send_filehandle(filehandle_path)
|
||||
await get_tree().create_timer(0.1).timeout
|
||||
Debug.logr("filehandle was sent")
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if ext_texure == null or not ext_texure.get_rid().is_valid(): return
|
||||
if not texture_rid.is_valid(): return
|
||||
|
||||
ext_texure.copy_to(texture_rid)
|
80
app/scripts/sandbox/sandbox_env.gd
Normal file
80
app/scripts/sandbox/sandbox_env.gd
Normal file
|
@ -0,0 +1,80 @@
|
|||
extends Resource
|
||||
class_name SandboxEnv
|
||||
|
||||
@export var zip: String
|
||||
@export var the_gates_folder: String
|
||||
@export var the_gates_folder_abs: String
|
||||
@export var snbx_exe_name: String
|
||||
@export var start_sh: String
|
||||
@export var subprocesses_sh: String
|
||||
|
||||
const ENV_FOLDER := "/tmp/sandbox_env"
|
||||
|
||||
var zip_path: String :
|
||||
get = get_zip_path
|
||||
|
||||
var start: String :
|
||||
get = get_start_sh
|
||||
|
||||
var subprocesses: String :
|
||||
get = get_subprocesses_sh
|
||||
|
||||
|
||||
var main_pack: String
|
||||
|
||||
|
||||
func get_zip_path() -> String:
|
||||
var executable_dir = OS.get_executable_path().get_base_dir() + "/"
|
||||
return executable_dir + zip
|
||||
|
||||
|
||||
func get_start_sh() -> String:
|
||||
return ProjectSettings.globalize_path(ENV_FOLDER + "/" + start_sh)
|
||||
|
||||
|
||||
func get_subprocesses_sh() -> String:
|
||||
return ProjectSettings.globalize_path(ENV_FOLDER + "/" + subprocesses_sh)
|
||||
|
||||
|
||||
func zip_exists() -> bool:
|
||||
return FileAccess.file_exists(zip_path)
|
||||
|
||||
|
||||
func create_env(snbx_executable: String, gate: Gate) -> void:
|
||||
Debug.logclr("create_env %s" % [ENV_FOLDER], Color.DIM_GRAY)
|
||||
UnZip.unzip(zip_path, ENV_FOLDER, true)
|
||||
|
||||
var folder = ENV_FOLDER + "/" + the_gates_folder
|
||||
var executable = folder + "/" + snbx_exe_name
|
||||
DirAccess.copy_absolute(snbx_executable, executable)
|
||||
|
||||
main_pack = executable.get_basename() + "." + gate.resource_pack.get_extension()
|
||||
DirAccess.copy_absolute(gate.resource_pack, main_pack)
|
||||
main_pack = the_gates_folder_abs + "/" + main_pack.get_file()
|
||||
|
||||
if not gate.shared_libs_dir.is_empty() and DirAccess.dir_exists_absolute(gate.shared_libs_dir):
|
||||
for file in DirAccess.get_files_at(gate.shared_libs_dir):
|
||||
var lib = gate.shared_libs_dir + "/" + file
|
||||
var lib_in_folder = folder + "/" + file
|
||||
DirAccess.copy_absolute(lib, lib_in_folder)
|
||||
Debug.logclr(lib_in_folder, Color.DIM_GRAY)
|
||||
|
||||
|
||||
func get_subprocesses(ppid: int) -> Array[int]:
|
||||
var pids: Array[int] = []
|
||||
var output = []
|
||||
|
||||
OS.execute(subprocesses, [str(ppid)], output)
|
||||
if output.is_empty(): return pids
|
||||
|
||||
var s_pids = output[0].split('\n')
|
||||
for s_pid in s_pids:
|
||||
if s_pid.is_empty(): continue
|
||||
var pid = s_pid.to_int()
|
||||
pids.append(pid)
|
||||
|
||||
return pids
|
||||
|
||||
|
||||
func clean() -> void:
|
||||
OS.execute("rm", ["-rf", ProjectSettings.globalize_path(ENV_FOLDER)])
|
33
app/scripts/sandbox/sandbox_executable.gd
Normal file
33
app/scripts/sandbox/sandbox_executable.gd
Normal file
|
@ -0,0 +1,33 @@
|
|||
extends Resource
|
||||
class_name SandboxExecutable
|
||||
|
||||
@export var linux: String
|
||||
@export var linux_debug: String
|
||||
|
||||
@export var windows: String
|
||||
@export var windows_debug: String
|
||||
|
||||
var path: String :
|
||||
get = get_executable_path
|
||||
|
||||
|
||||
func get_executable_path() -> String:
|
||||
var executable_dir = OS.get_executable_path().get_base_dir() + "/"
|
||||
return executable_dir + get_filename()
|
||||
|
||||
|
||||
func get_filename() -> String:
|
||||
var is_debug = Platform.is_debug()
|
||||
|
||||
match Platform.get_platform():
|
||||
Platform.WINDOWS:
|
||||
return windows_debug if is_debug else windows
|
||||
Platform.LINUX_BSD:
|
||||
return linux_debug if is_debug else linux
|
||||
_:
|
||||
assert(false, "Platform is not supported")
|
||||
return ""
|
||||
|
||||
|
||||
func exists() -> bool:
|
||||
return FileAccess.file_exists(path)
|
93
app/scripts/sandbox/sandbox_manager.gd
Normal file
93
app/scripts/sandbox/sandbox_manager.gd
Normal file
|
@ -0,0 +1,93 @@
|
|||
extends Node
|
||||
class_name SandboxManager
|
||||
|
||||
@export var gate_events: GateEvents
|
||||
@export var render_result: RenderResult
|
||||
@export var snbx_executable: SandboxExecutable
|
||||
@export var snbx_env: SandboxEnv
|
||||
|
||||
var sandbox_pid: int
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
gate_events.gate_loaded.connect(start_sandbox)
|
||||
|
||||
|
||||
func start_sandbox(gate: Gate) -> void:
|
||||
match Platform.get_platform():
|
||||
Platform.WINDOWS:
|
||||
start_sandbox_windows(gate)
|
||||
Platform.LINUX_BSD:
|
||||
start_sandbox_linux(gate)
|
||||
_:
|
||||
assert(false, "Platform is not supported")
|
||||
|
||||
|
||||
func start_sandbox_linux(gate: Gate) -> void:
|
||||
if not snbx_executable.exists():
|
||||
Debug.logerr("Sandbox executable not found at " + snbx_executable.path); return
|
||||
if not snbx_env.zip_exists():
|
||||
Debug.logerr("Sandbox environment not found at " + snbx_env.zip_path); return
|
||||
|
||||
snbx_env.create_env(snbx_executable.path, gate)
|
||||
|
||||
var args = [
|
||||
snbx_env.start.get_base_dir(), # cd to dir
|
||||
"--main-pack", snbx_env.main_pack,
|
||||
"--resolution", "%dx%d" % [render_result.width, render_result.height],
|
||||
"--verbose"
|
||||
]
|
||||
Debug.logclr(snbx_env.start + " " + " ".join(args), Color.DARK_VIOLET)
|
||||
sandbox_pid = OS.create_process(snbx_env.start, args)
|
||||
|
||||
gate_events.gate_entered_emit()
|
||||
|
||||
|
||||
func start_sandbox_windows(gate: Gate) -> void:
|
||||
if not snbx_executable.exists():
|
||||
Debug.logerr("Sandbox executable not found at " + snbx_executable.path); return
|
||||
|
||||
var pack_file = ProjectSettings.globalize_path(gate.resource_pack)
|
||||
var shared_libs = ProjectSettings.globalize_path(gate.shared_libs_dir)
|
||||
var args = [
|
||||
"--main-pack", pack_file,
|
||||
"--gdext-libs-dir", shared_libs,
|
||||
"--resolution", "%dx%d" % [render_result.width, render_result.height]
|
||||
]
|
||||
Debug.logclr(snbx_executable.path + " " + " ".join(args), Color.DARK_VIOLET)
|
||||
sandbox_pid = OS.create_process(snbx_executable.path, args)
|
||||
|
||||
gate_events.gate_entered_emit()
|
||||
|
||||
|
||||
func kill_sandbox() -> void:
|
||||
match Platform.get_platform():
|
||||
Platform.WINDOWS:
|
||||
kill_sandbox_windows()
|
||||
Platform.LINUX_BSD:
|
||||
kill_sandbox_linux()
|
||||
_:
|
||||
assert(false, "Platform is not supported")
|
||||
|
||||
|
||||
func kill_sandbox_linux() -> void:
|
||||
if sandbox_pid == 0: return
|
||||
|
||||
var pids = snbx_env.get_subprocesses(sandbox_pid)
|
||||
pids.append(sandbox_pid)
|
||||
|
||||
for pid in pids:
|
||||
OS.kill(pid)
|
||||
Debug.logclr("Process killed " + str(pid), Color.DIM_GRAY)
|
||||
|
||||
snbx_env.clean()
|
||||
|
||||
|
||||
func kill_sandbox_windows() -> void:
|
||||
if OS.is_process_running(sandbox_pid):
|
||||
OS.kill(sandbox_pid)
|
||||
Debug.logclr("Process killed " + str(sandbox_pid), Color.DIM_GRAY)
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
kill_sandbox()
|
38
app/scripts/sandbox/unzip.gd
Normal file
38
app/scripts/sandbox/unzip.gd
Normal file
|
@ -0,0 +1,38 @@
|
|||
extends Node
|
||||
class_name UnZip
|
||||
|
||||
|
||||
static func unzip(zip_path: String, to_folder: String, contains_symlink: bool = false) -> void:
|
||||
var reader = ZIPReader.new()
|
||||
var err = reader.open(zip_path)
|
||||
if err != OK: Debug.logerr("Cannot open file %s to unzip" % [zip_path]); return
|
||||
|
||||
for path in reader.get_files():
|
||||
if path.get_file().is_empty(): # is directory
|
||||
DirAccess.make_dir_recursive_absolute(to_folder + "/" + path)
|
||||
# Debug.logclr("makedir %s" % [to_folder + "/" + path], Color.DIM_GRAY)
|
||||
else:
|
||||
create_file(reader, path, to_folder, contains_symlink)
|
||||
|
||||
|
||||
static func create_file(reader: ZIPReader, path: String, folder: String, contains_symlink: bool) -> void:
|
||||
var data = reader.read_file(path)
|
||||
var symlink = ""
|
||||
|
||||
if contains_symlink:
|
||||
symlink = data.get_string_from_utf8()
|
||||
if symlink.split("\n").size() != 1:
|
||||
symlink = ""
|
||||
|
||||
if contains_symlink and symlink.is_absolute_path():
|
||||
var link_to = ProjectSettings.globalize_path(folder + "/" + path.get_basename())
|
||||
OS.execute("ln", ["-s", symlink, link_to])
|
||||
# Debug.logclr("ln -s %s %s" % [symlink, link_to], Color.DIM_GRAY)
|
||||
else:
|
||||
var file_path = folder + "/" + path
|
||||
var file = FileAccess.open(file_path, FileAccess.WRITE)
|
||||
file.store_buffer(data)
|
||||
file.close()
|
||||
if file_path.get_extension() == "sh":
|
||||
OS.execute("chmod", ["+x", ProjectSettings.globalize_path(file_path)])
|
||||
# Debug.logclr("touch %s" % [folder + "/" + path], Color.DIM_GRAY)
|
Loading…
Add table
Add a link
Reference in a new issue