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