136 lines
3.4 KiB
GDScript
136 lines
3.4 KiB
GDScript
@tool
|
|
extends EditorPlugin
|
|
|
|
var server: TCPServer
|
|
var port := 6009
|
|
var peers : Array[StreamPeerTCP] = []
|
|
|
|
enum COMMAND {OPEN_SCENE}
|
|
|
|
func node_to_tree(node, root=false):
|
|
var n = {}
|
|
n["name"] = node.name
|
|
n["type"] = node.get_class()
|
|
n["index"] = node.get_index()
|
|
n["path"] = "/" + node.get_path().get_concatenated_names()
|
|
var c = []
|
|
for i in node.get_children():
|
|
c.append(node_to_tree(i))
|
|
if len(c) > 0:
|
|
n["children"] = c
|
|
return n
|
|
|
|
func node_to_props(node):
|
|
var n = {}
|
|
n["name"] = node.name
|
|
n["type"] = node.get_class()
|
|
n["path"] = "/" + node.get_path().get_concatenated_names()
|
|
n["props"] = []
|
|
var props = node.get_property_list()
|
|
var i = 0
|
|
# NOTE: I cannot begin to fathom the reasons for why this shit is done
|
|
# the way that it is, but this is bordering on an exercise
|
|
# in pure futility at this stage.
|
|
while i < len(props):
|
|
var p = props[i]
|
|
if p["usage"] & 128 == 128:
|
|
var cat = {}
|
|
cat["name"] = p["name"]
|
|
cat["props"] = []
|
|
|
|
if i == len(props) - 1:
|
|
break
|
|
|
|
i += 1
|
|
|
|
while i < len(props):
|
|
p = props[i]
|
|
if p["usage"] & 128 == 128:
|
|
break
|
|
if p["usage"] & 4 == 4:
|
|
var c = {}
|
|
c["name"] = p["name"]
|
|
c["value"] = node.get(p["name"])
|
|
cat["props"].append(c)
|
|
i += 1
|
|
|
|
n["props"].append(cat)
|
|
else:
|
|
print(p["name"], " ", p["usage"])
|
|
break
|
|
n["props"].reverse()
|
|
return n
|
|
|
|
func parse_command(str: String, peer: StreamPeerTCP):
|
|
var cmd = JSON.parse_string(str)
|
|
print(cmd)
|
|
match cmd["command"]:
|
|
"open-scene":
|
|
print("Opening")
|
|
EditorInterface.open_scene_from_path(cmd["scene"])
|
|
|
|
"select-node":
|
|
var n = get_node(NodePath(cmd["path"]))
|
|
EditorInterface.edit_node(n)
|
|
|
|
"get-scene-tree":
|
|
var result = node_to_props(EditorInterface.get_selection().get_selected_nodes()[0])
|
|
result = JSON.stringify({"for-cmd": "get-selected-node", "value": result})
|
|
peer.put_data(result.to_utf8_buffer())
|
|
|
|
# TODO: this is terrible
|
|
await get_tree().create_timer(0.05).timeout
|
|
|
|
result = node_to_tree(EditorInterface.get_edited_scene_root(), true)
|
|
result = JSON.stringify({"for-cmd": "get-scene-tree", "value": result})
|
|
peer.put_data(result.to_utf8_buffer())
|
|
|
|
"set-node-name":
|
|
var n = get_node(NodePath(cmd["path"]))
|
|
var new_name = cmd["new-name"]
|
|
print("setting ", n, "'s name as ", new_name)
|
|
n.name = new_name
|
|
|
|
"update-property":
|
|
var n = get_node(NodePath(cmd["path"]))
|
|
var prop = cmd["name"]
|
|
var val = cmd ["new-value"]
|
|
|
|
n.set(prop, val)
|
|
|
|
_:
|
|
print("Not a valid command: ", cmd["command"])
|
|
|
|
if cmd["command"] != "get-scene-tree":
|
|
await parse_command(JSON.stringify({"command": "get-scene-tree"}), peer)
|
|
|
|
func _enter_tree() -> void:
|
|
server = TCPServer.new()
|
|
server.listen(port)
|
|
print("Remote control server listening on port ", port)
|
|
|
|
|
|
func _process(delta: float) -> void:
|
|
if server.is_connection_available():
|
|
var peer = server.take_connection()
|
|
peer.set_no_delay(true)
|
|
peers.append(peer)
|
|
print("Took connection")
|
|
|
|
for peer in peers:
|
|
if peer.get_status() == 2 and peer.poll() == Error.OK:
|
|
if peer.get_available_bytes() > 0:
|
|
print("-----")
|
|
print(peer.get_status())
|
|
var packet = peer.get_utf8_string(peer.get_available_bytes())
|
|
parse_command(packet, peer)
|
|
print("-----")
|
|
else:
|
|
if peer.get_status() != 0:
|
|
peer.disconnect_from_host()
|
|
peers.erase(peer)
|
|
print("Peer removed.")
|
|
|
|
func _exit_tree() -> void:
|
|
server.stop()
|
|
print("Remote control server stopped.")
|