godot-remote-control/addons/godot_remote_control/plugin.gd

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.")