From 1bdfb112b659a6e4447ae8ed02c452bf12d8700a Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Tue, 17 Dec 2024 16:01:19 -0500 Subject: Add position tracking via IPC --- Archipelago/client.gd | 1 + Archipelago/load.gd | 6 +++ Archipelago/player.gd | 29 +++++++++++++++ Archipelago/settings_screen.gd | 1 + Archipelago/tracker.gd | 84 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 121 insertions(+) create mode 100644 Archipelago/tracker.gd diff --git a/Archipelago/client.gd b/Archipelago/client.gd index 85cfd05..384c907 100644 --- a/Archipelago/client.gd +++ b/Archipelago/client.gd @@ -9,6 +9,7 @@ var SCRIPT_notifier var SCRIPT_panel var SCRIPT_pilgrimage_terminator var SCRIPT_textclient +var SCRIPT_tracker var SCRIPT_uuid var ap_server = "" diff --git a/Archipelago/load.gd b/Archipelago/load.gd index 651fc39..ba350f6 100644 --- a/Archipelago/load.gd +++ b/Archipelago/load.gd @@ -692,6 +692,12 @@ func _load(): multiplayer_node.ghost_mode = true add_child(multiplayer_node) + # Create the autotracker node. + var autotracker_script = apclient.SCRIPT_tracker + var autotracker = autotracker_script.new() + autotracker.set_name("AP_Tracker") + self.add_child(autotracker) + # Hook up Geronimo handler. $player.connect("player_jumped", apclient, "geronimo") diff --git a/Archipelago/player.gd b/Archipelago/player.gd index 52d743a..6638329 100644 --- a/Archipelago/player.gd +++ b/Archipelago/player.gd @@ -2,12 +2,16 @@ extends "res://scripts/player.gd" var _oldpos = Vector3(0, -200, 0) +var _oldpos_fine = Vector3(0, -200, 0) func _ready(): _oldpos = translation _oldpos.y = 0 + _oldpos_fine = translation + _oldpos_fine.y = 0 + var apclient = global.get_node("Archipelago") if apclient.track_player: var tracking_timer = Timer.new() @@ -17,8 +21,19 @@ func _ready(): tracking_timer.connect("timeout", self, "_tick_tracking") tracking_timer.start() + var tracking_timer_fine = Timer.new() + tracking_timer_fine.name = "TrackingTimerFine" + tracking_timer_fine.wait_time = 0.5 + add_child(tracking_timer_fine) + tracking_timer_fine.connect("timeout", self, "_tick_tracking_fine") + tracking_timer_fine.start() + func _tick_tracking(): + var tracker = get_tree().get_root().get_node("Spatial/AP_Tracker") + if tracker.has_connection(): + return + var newpos = translation newpos.y = 0 @@ -29,6 +44,20 @@ func _tick_tracking(): apclient.setValue("PlayerPos", {"x": int(_oldpos.x), "z": int(_oldpos.z)}) +func _tick_tracking_fine(): + var tracker = get_tree().get_root().get_node("Spatial/AP_Tracker") + if !tracker.has_connection(): + return + + var newpos = translation + newpos.y = 0 + + if newpos != _oldpos_fine && newpos.distance_to(_oldpos_fine) > 0.5: + _oldpos_fine = newpos + + tracker.update_position(int(_oldpos_fine.x), int(_oldpos_fine.z)) + + func _solving(): ._solving() diff --git a/Archipelago/settings_screen.gd b/Archipelago/settings_screen.gd index 2ed8594..d3c654c 100644 --- a/Archipelago/settings_screen.gd +++ b/Archipelago/settings_screen.gd @@ -33,6 +33,7 @@ func _ready(): var pilg_term = load("user://maps/Archipelago/pilgrimage_terminator.gd") apclient_instance.SCRIPT_pilgrimage_terminator = pilg_term apclient_instance.SCRIPT_textclient = load("user://maps/Archipelago/textclient.gd") + apclient_instance.SCRIPT_tracker = load("user://maps/Archipelago/tracker.gd") apclient_instance.SCRIPT_uuid = load("user://maps/Archipelago/vendor/uuid.gd") var apdata = ResourceLoader.load("user://maps/Archipelago/gamedata.gd") diff --git a/Archipelago/tracker.gd b/Archipelago/tracker.gd new file mode 100644 index 0000000..798721d --- /dev/null +++ b/Archipelago/tracker.gd @@ -0,0 +1,84 @@ +extends Node + +var autotracker_port = 41253 + +var _server = WebSocketServer.new() +var _peers = [] + + +func _ready(): + _server.bind_ip = "127.0.0.1" + _server.connect("client_connected", self, "_connection_established") + _server.connect("client_disconnected", self, "_connection_dropped") + _server.connect("data_received", self, "_data_received") + _server.listen(autotracker_port) + + +func _process(_delta): + _server.poll() + + +func _connection_established(id, _protocol): + _peers.append(id) + + var apclient = global.get_node("Archipelago") + + var msg = {"cmd": "Connect", "slot": {"server": apclient.ap_server, "player": apclient.ap_user}} + + var peer = _server.get_peer(id) + peer.set_write_mode(WebSocketPeer.WRITE_MODE_TEXT) + peer.put_packet(JSON.print(msg).to_utf8()) + + +func _connection_dropped(id, _was_clean_close): + _peers.erase(id) + + +func _data_received(id): + var peer = _server.get_peer(id) + peer.set_write_mode(WebSocketPeer.WRITE_MODE_TEXT) + + var packet_text = peer.get_packet().get_string_from_utf8() + global._print("Got data from tracker: " + packet_text) + var msg = JSON.parse(packet_text) + if msg.error != OK: + global._print("Error parsing packet from Tracker: " + msg.error_string) + return + + var apclient = global.get_node("Archipelago") + + if msg["cmd"] == "Sync": + var resp = {} + + if apclient.track_player: + var player = get_tree().get_root().get_node("Spatial/player") + resp = { + "cmd": "UpdatePosition", + "position": {"x": int(player._oldpos_fine.x), "z": int(player._oldpos_fine.z)} + } + + peer.put_packet(JSON.print(resp).to_utf8()) + + +func _broadcast(msg): + var to_remove = [] + var serialized = JSON.print(msg).to_utf8() + + for peer_id in _peers: + if _server.has_peer(peer_id): + var peer = _server.get_peer(peer_id) + peer.set_write_mode(WebSocketPeer.WRITE_MODE_TEXT) + peer.put_packet(serialized) + else: + to_remove.append(peer_id) + + for peer_id in to_remove: + _peers.erase(peer_id) + + +func has_connection(): + return _peers.size() > 0 + + +func update_position(x, z): + _broadcast({"cmd": "UpdatePosition", "position": {"x": x, "z": z}}) -- cgit 1.4.1