diff options
Diffstat (limited to 'Game/Network.gd')
-rw-r--r-- | Game/Network.gd | 154 |
1 files changed, 38 insertions, 116 deletions
diff --git a/Game/Network.gd b/Game/Network.gd index 48558ce..5f8be5c 100644 --- a/Game/Network.gd +++ b/Game/Network.gd @@ -19,140 +19,66 @@ func host_game(port): peer.create_server(int(port)) multiplayer.multiplayer_peer = peer - players[1] = Client.player + + Client.player.id = multiplayer.get_unique_id() + %Players.add_child(Client.player) func join_game(ip, port): var peer = ENetMultiplayerPeer.new() peer.create_client(ip, int(port)) multiplayer.multiplayer_peer = peer + + Client.player.id = multiplayer.get_unique_id() func _on_connected_to_server(): - print("connected to server") + print(multiplayer.get_unique_id(), ": connected to server") func _on_peer_connected(id): - print("peer connected: ", id) - add_to_players.rpc(to_rpc_object(Client.player)) + print(multiplayer.get_unique_id(), ": peer connected: ", id) + + if id == 1: # tell host to add player + add_to_players.rpc_id(1, inst_to_dict(Client.player)) + Client._player = null # TODO: add existing towers to new peers func _on_peer_disconnected(id): - print("peer disconnected: ", id) + print(multiplayer.get_unique_id(), ": peer disconnected: ", id) # TODO: move towers owned by peer to host - if id == 1: + if id == 1: # if host disconnected go back to Lobby get_tree().change_scene_to_file("res://UI/Lobby.tscn") -func get_ordered_player_ids(): - var keys = players.keys() - keys.sort_custom(func(a, b): +func get_player(id: int) -> Player: + return %Players.get_node(str(id)) + +func get_ordered_player_ids(): # TODO: return type needed for players_list.gd "find" method? + var keys = %Players.get_children().map(func(item: Player): + return item.id + ) + keys = keys.filter(func(item: int): # workaround for MultiplayerSpawner + Synchronizer + return item != 0 + ) + keys.sort_custom(func(a: int, b: int): return int(str(a).substr(0, 8)) < int(str(b).substr(0, 8)) ) return keys -func to_rpc_object(object: Variant): - var remote_object = {} - var properties = object.get_rpc_properties() - for property in properties: - var property_class = properties[property] - if object[property] is Dictionary: - remote_object[property] = {} - for key in object[property]: - remote_object[property][key] = to_rpc_object(object[property][key]) - elif property_class is String and property_class.begins_with("node://"): - remote_object[property] = object[property] - elif property_class: - remote_object[property] = to_rpc_object(object[property]) - else: - remote_object[property] = object[property] - - return remote_object - - -func from_rpc_object(remote_object: Dictionary, remote_class_path: String): - var object - var remote_class = load(remote_class_path) - if remote_class is PackedScene: - object = remote_class.instantiate() - elif remote_class is GDScript: - object = remote_class.new() - else: - assert(false, "unexpected remote class type") - - var properties = object.get_rpc_properties() - for property in properties: - var property_class = properties[property] - if object[property] is Dictionary: - for key in object[property]: - object[property][key] = from_rpc_object(remote_object[property], property_class) - elif property_class is String and property_class.begins_with("node://"): - var node_path = property_class.substr(7) # after node:// - object.remove_child(object.get_node(node_path)) - remote_object[property].name = node_path.get_basename() - object[property] = remote_object[property] - object.add_child(remote_object[property]) - elif property_class: - object[property] = from_rpc_object(remote_object[property], property_class) - else: - object[property] = remote_object[property] - - return object - - -func merge_with_rpc_object(object: Variant, remote_object: Dictionary): - var properties = object.get_rpc_properties() - for property in properties: - var property_class = properties[property] - if object[property] is Dictionary: - object[property] = {} - for key in remote_object[property]: - object[property][key] = from_rpc_object(remote_object[property][key], property_class) - elif property_class: - object[property] = merge_with_rpc_object(object[property], remote_object[property]) - else: - object[property] = remote_object[property] - - return object - - -@rpc("call_local", "any_peer") -func add_to_players(remote_player: Dictionary): - var id = multiplayer.get_remote_sender_id() - var player = from_rpc_object(remote_player, "res://Game/Player.gd") - player.id = id - players[id] = player - players_changed.emit() - - -@rpc("call_local", "any_peer") -func update_player(remote_player: Dictionary): +@rpc("any_peer") +func add_to_players(remote_data: Dictionary): var id = multiplayer.get_remote_sender_id() - var player = merge_with_rpc_object(players[id], remote_player) + + var player = preload("res://Game/Player.tscn").instantiate() player.id = id - players[id] = player - players_changed.emit() - - -@rpc("any_peer", "reliable") -func update_node(node_path: NodePath, properties: Dictionary): - var root_node = get_tree().root.get_node(node_path) + player.username = remote_data.username - for property in properties: - if property.contains(":"): - var child_node = get_nested_node_and_property(root_node, property) - child_node.node[child_node.property] = properties[property] - else: - root_node[property] = properties[property] - -func get_nested_node_and_property(node: Node, property: String) -> Dictionary: - if property.contains(":"): - var nested_node_path = property.substr(0, property.find(":")) - var nested_property = property.substr(property.find(":") + 1) - return get_nested_node_and_property(node.get_node(nested_node_path), nested_property) - return { "node": node, "property": property } + %Players.add_child(player) + + players_changed.emit() @rpc("any_peer") @@ -164,7 +90,7 @@ func place_tower(remote_data: Dictionary): var tower = Tower.from_network_data(data) tower.owner_id = remote_player_id - players[remote_player_id].towers[tower.global_position] = tower + Network.get_player(remote_player_id).towers[tower.global_position] = tower Client.stage.place_tower(tower, tower.global_position) @@ -173,23 +99,19 @@ func place_tower(remote_data: Dictionary): #func destroy_tower(remote_tower: Dictionary): func destroy_tower(position: Vector2): var owner_id = multiplayer.get_remote_sender_id() - var player = players[owner_id] as Player + var player = get_player(owner_id) var tower = player.towers.get(position) Client.stage.destroy_tower(tower) @rpc("any_peer") -func update_tower(remote_tower_node_path, data): +func update_tower(remote_tower_node_path: NodePath, remote_data: Dictionary): + var data: Tower.NetworkData = dict_to_inst(remote_data) var tower: Tower = get_tree().current_scene.get_node_or_null(remote_tower_node_path) + if tower: - if "components" in data: - for c in tower.components.duplicate(): - tower.remove_component(c.name) - for c in data.components: - tower.add_component( - load("res://Towers/Components/" + c + "Component.gd").new() - ) + tower.update_with_network_data(data) @rpc("any_peer") |