extends Node signal player_registered(peer_id: int, player_info: Dictionary) signal network_error(message: String) const DEFAULT_PORT: int = 10567 const MAX_PEERS: int = 20 var players := {} var is_dedicated: bool = false var _peer: ENetMultiplayerPeer var _local_player_info := {"name": ""} var _title_scene := preload("res://scenes/title.tscn") var _main_scene := preload("res://scenes/main.tscn") var _player_scene := preload("res://scenes/player.tscn") func _ready() -> void: multiplayer.peer_connected.connect(_on_multiplayer_peer_connected) multiplayer.peer_disconnected.connect(_on_multiplayer_peer_disconnected) multiplayer.connected_to_server.connect(_on_multiplayer_connected_to_server) multiplayer.connection_failed.connect(_on_multiplayer_connection_failed) multiplayer.server_disconnected.connect(_on_multiplayer_server_disconnected) func _process(_delta: float) -> void: Debugger.text("_local_player_info", _local_player_info) Debugger.text("players", players) func set_local_player_info(username: String) -> void: _local_player_info["name"] = username func host_game(dedicated: bool = false) -> void: print("Hosting...") is_dedicated = dedicated _peer = ENetMultiplayerPeer.new() var error := _peer.create_server(DEFAULT_PORT, MAX_PEERS) if error: match error: ERR_ALREADY_IN_USE: var message := "Already in use" printerr(message) network_error.emit(message) ERR_CANT_CREATE: var message := "Cannot create server" printerr(message) network_error.emit(message) return multiplayer.set_multiplayer_peer(_peer) _load_main() if not dedicated: players[1] = _local_player_info print("Registered player ", 1, " ", _local_player_info) _add_player(multiplayer.get_unique_id(), _local_player_info) func join_game(address: String) -> void: print("Joining " + address + "...") _peer = ENetMultiplayerPeer.new() var error := _peer.create_client(address, DEFAULT_PORT) if error: match error: ERR_ALREADY_IN_USE: var message := "Already in use" printerr(message) network_error.emit(message) ERR_CANT_CREATE: var message := "Cannot create client" printerr(message) network_error.emit(message) return multiplayer.set_multiplayer_peer(_peer) _load_main() func is_active() -> bool: return ( multiplayer.multiplayer_peer.get_connection_status() == MultiplayerPeer.CONNECTION_CONNECTED ) func is_dedicated_server() -> bool: return OS.has_feature("dedicated_server") or DisplayServer.get_name() == "headless" func player_name(peer_id: int) -> String: if peer_id in players: return str(peer_id) + " (" + players[peer_id]["name"] + ")" return str(peer_id) func _switch_scene(to: PackedScene, from: Node) -> void: if from: from.queue_free() var new_scene := to.instantiate() get_tree().get_root().add_child(new_scene) print("Scene loaded") func _load_main() -> void: print("Loading Main...") _switch_scene(_main_scene, $/root/Title) func _add_player(peer_id: int, player_info: Dictionary) -> void: if not multiplayer.is_server(): return print("Adding player ", player_name(peer_id)) var player := _player_scene.instantiate() as Player player.name = str(peer_id) Referencer.main.player_holder.add_child(player, true) player.set_info(player_info) func _remove_player(peer_id: int) -> void: if not multiplayer.is_server(): return print("Removing player ", player_name(peer_id)) var player := Referencer.main.player_holder.get_node_or_null(str(peer_id)) if player: player.queue_free() @rpc("any_peer", "reliable") func _register_player(player_info: Dictionary) -> void: var peer_id := multiplayer.get_remote_sender_id() print("Registering player ", peer_id, " ", player_info) if peer_id == 1 and !player_info["name"]: print("Skipping registering the host") return players[peer_id] = player_info player_registered.emit(peer_id, player_info) func _on_multiplayer_peer_connected(peer_id: int) -> void: print("Peer connected ", peer_id) _register_player.rpc_id(peer_id, _local_player_info) _add_player(peer_id, _local_player_info) func _on_multiplayer_peer_disconnected(peer_id: int) -> void: print("Peer disconnected ", player_name(peer_id)) _remove_player(peer_id) players.erase(peer_id) func _on_multiplayer_connected_to_server() -> void: var peer_id := multiplayer.get_unique_id() print("Connected to server as ", peer_id) players[peer_id] = _local_player_info print("Registered player ", peer_id, " ", _local_player_info) func _on_multiplayer_connection_failed() -> void: multiplayer.set_multiplayer_peer(null) var message := "Connection failed" printerr(message) network_error.emit(message) func _on_multiplayer_server_disconnected() -> void: var message := "Server disconnected" printerr(message) players.clear() _switch_scene(_title_scene, $/root/Main) network_error.emit(message)