extends Node const SERVER_PORT = 8080 const SERVER_IP = "127.0.0.1" var handle : String var id : int = 1 var players : Dictionary = {} signal client_added(handle : String, id : int) signal all_ready() var player_readiness : Dictionary[int, bool] = {} var waiting : bool = false func become_host() -> void: print("Starting host!") var server_peer = ENetMultiplayerPeer.new() server_peer.create_server(SERVER_PORT) players[handle] = 1 player_readiness[1] = false multiplayer.multiplayer_peer = server_peer id = multiplayer.get_unique_id() print("%s %d t" % [handle, multiplayer.get_unique_id()]) multiplayer.peer_connected.connect(_add_player_to_game) multiplayer.peer_disconnected.connect(_remove_player_from_game) func join_game(new_handle : String, ip : String = "") -> Error: print("Player 2 joining.") if ip == "": ip = SERVER_IP var client_peer = ENetMultiplayerPeer.new() var error = client_peer.create_client(ip, SERVER_PORT) multiplayer.multiplayer_peer = client_peer handle = new_handle id = multiplayer.get_unique_id() players[handle] = id player_readiness[id] = false if !error: print("%s %d" % [handle, multiplayer.get_unique_id()]) await get_tree().create_timer(0.5).timeout get_handle_from_peer(1) return !error func is_server() -> bool: return multiplayer && multiplayer.is_server() func is_host() -> bool: return id == 1 func _process(delta: float) -> void: if waiting: var ready : bool = true for pr in player_readiness.values(): if !pr: ready = false break if ready: all_ready.emit() waiting = false for pr in player_readiness.keys(): player_readiness[pr] = false func _add_player_to_game(id : int) -> void: print("Player %s joined the game!" % id) await get_tree().create_timer(0.5).timeout get_handle_from_peer(id) func _remove_player_from_game(id : int) -> void: print("Player %s left the game!" % id) func get_handle_from_peer(peer_id) -> void: rpc_id(peer_id, "report_handle_to_peer", id) @rpc("call_local", "any_peer", "reliable") func set_player_ready(peer_id : int) -> void: player_readiness[peer_id] = true @rpc("any_peer", "call_remote") func receive_peer_handle(peer_id, peer_handle) -> void: print("Player %s identified as %s!" % [peer_id, peer_handle]) players[peer_handle] = peer_id player_readiness[peer_id] = false client_added.emit(peer_handle, peer_id) @rpc("any_peer", "call_remote") func report_handle_to_peer(peer_id : int) -> void: rpc_id(peer_id, "receive_peer_handle", multiplayer.get_unique_id(), handle) func get_local_ip() -> String: var ip_address = "" # Get all local addresses as an Array var addresses: PackedStringArray = IP.get_local_addresses() for address in addresses: # Check if it is an IPv4 address and not a loopback or link-local address if "." in address and not address.begins_with("127.") and not address.begins_with("169.254."): # Filter for common private IP ranges (192.168.x.x, 10.x.x.x, 172.16-31.x.x) if address.begins_with("192.168.") or address.begins_with("10.") or (address.begins_with("172.") and int(address.split(".")[1]) >= 16 and int(address.split(".")[1]) <= 31): ip_address = address break # Exit the loop once a valid local IP is found return ip_address