extends Node var player_script := preload("res://scripts/Player.gd") var server_map var player_model = preload("res://models/player.tscn") var peer = ENetMultiplayerPeer.new() var settings var clients = {} var last_client_id = 1 func _ready(): if "--server" in OS.get_cmdline_args(): await get_tree().create_timer(0.01).timeout #костыль пиздец но мне похую как-то get_tree().change_scene_to_file("res://scenes/test_map.tscn") await get_tree().create_timer(0.05).timeout #костыль server_map = get_tree().root.get_node("test_map") StartServer() #######################################SERVER#################################### func StartServer(): settings = GameData.server_settings var port = int(settings["port"]) var maxclients = int(settings["maxclients"]) if (peer.create_server(port, maxclients) != OK): print("Couldn't create server. Check if another proccess binds port " + str(port)) return multiplayer.multiplayer_peer = peer print("Server started") peer.connect("peer_connected", _Peer_Connected) peer.connect("peer_disconnected", _Peer_Disconnected) func send_everyone_except(client_id, args): if (typeof(args[0]) == 4): #string for current_client_id in clients.keys(): if (str(current_client_id) == str(client_id)): continue if (args.size() == 1): rpc_id(int(current_client_id), args[0]) elif (args.size() == 2): rpc_id(int(current_client_id), args[0], args[1]) elif (args.size() == 3): rpc_id(int(current_client_id), args[0], args[1], args[2]) else: rpc_id(int(current_client_id), args[0], args[1], args[2], args[3]) else: for current_client_id in clients.keys(): if (str(current_client_id) == str(client_id)): continue if (args.size() == 1): args[0].rpc_id(int(current_client_id)) elif (args.size() == 2): args[0].rpc_id(int(current_client_id), args[1]) elif (args.size() == 3): args[0].rpc_id(int(current_client_id), args[1], args[2]) else: args[0].rpc_id(int(current_client_id), args[1], args[2], args[3]) func _Peer_Connected(client_id): print("User " + str(client_id) + " has conected") var internal_id = last_client_id + 1 last_client_id += 1 clients[str(client_id)] = player_script.new().properties.duplicate() clients[str(client_id)]["position"] = Vector3(0, 10, 0) clients[str(client_id)]["internal_id"] = internal_id var puppet = player_model.instantiate() var CB3D = puppet.find_child("CharacterBody3D") CB3D.set_is_playable(false) CB3D.set_internal_id(internal_id) CB3D.set_player_name("player" + str(internal_id)) CB3D.set_nickname(clients[str(client_id)]["nickname"]) server_map.add_child(puppet) @rpc("any_peer", "reliable", "call_remote") func client_ready(client_id): var client = clients[str(client_id)] var internal_id = client["internal_id"] send_everyone_except(client_id, ["spawn_puppet", clients[str(client_id)]]) clients[str(client_id)]["ready"] = true func _Peer_Disconnected(client_id): print("User " + str(client_id) + " has disconnected") var client = clients[str(client_id)] var internal_id = client["internal_id"] rpc("despawn_puppet", internal_id) var puppet = server_map.get_node("player" + str(internal_id)) server_map.remove_child(puppet) clients.erase(str(client_id)) @rpc ("any_peer", "reliable", "call_remote") func get_character_properties(client_id): if !clients.has(str(client_id)): return var to_send = clients[str(client_id)] rpc_id(client_id, "set_character_properties", to_send.duplicate()) @rpc("any_peer", "call_remote", "unreliable") func sync_client(client_id, position, rotation): #if(settings["enableAntiCheat"]): if(position > 10): return # нормально допилить надо var client = clients[str(client_id)] var internal_id = client["internal_id"] client["position"] = position client["rotation"] = rotation send_everyone_except(client_id, [server_map.get_node("player" + str(internal_id)).find_child("CharacterBody3D").sync_puppet, internal_id, position, rotation]) @rpc ("any_peer", "call_remote", "reliable") func get_client_list(client_id): for current_client_id in clients.keys(): if (current_client_id == str(client_id)): continue rpc_id(client_id, "spawn_puppet", clients[str(current_client_id)]) @rpc ("any_peer", "call_remote", "reliable") func get_server_settings(client_id): print("Sending game settings") var client = clients[str(client_id)] var internal_id = client["internal_id"] server_map.get_node("player" + str(internal_id)).find_child("CharacterBody3D").set_game_settings.rpc_id(int(client_id), settings["game"]) @rpc ("any_peer", "call_remote", "reliable") func set_nickname(client_id, nickname): print("Got nickname from client: " + str(nickname)) clients[str(client_id)]["nickname"] = nickname ##########################################CLIENT####################### var player var menu = preload("res://scenes/menu.tscn") var test_map = preload("res://scenes/test_map.tscn") var current_map_instance @rpc ("reliable", "call_remote") func set_character_properties(p): print("Setting player properties to " + str(p)) player = p @rpc("authority", "reliable", "call_remote") func spawn_puppet(properties): var puppet = player_model.instantiate() var internal_id = int(properties["internal_id"]) var CB3D = puppet.find_child("CharacterBody3D") CB3D.set_is_playable(false) CB3D.set_internal_id(internal_id) CB3D.set_player_name("player" + str(internal_id)) CB3D.set_nickname(properties["nickname"]) CB3D.set_ready(true) puppet.name = "player" + str(internal_id) current_map_instance.add_child(puppet) @rpc("authority", "reliable", "call_remote") func despawn_puppet(internal_id): var puppet = current_map_instance.get_node("player" + str(internal_id)) current_map_instance.remove_child(puppet) func ConnectToServer(ip, port): peer.create_client(ip, port) multiplayer.multiplayer_peer = peer if not multiplayer.connected_to_server.is_connected(_Connection_Succseeded): multiplayer.connected_to_server.connect(_Connection_Succseeded) if not multiplayer.connection_failed.is_connected(_Connection_Failed): multiplayer.connection_failed.connect(_Connection_Failed) if not multiplayer.server_disconnected.is_connected(_Server_Disconnected): multiplayer.server_disconnected.connect(_Server_Disconnected) func _Connection_Failed(): print("Failed to connect to server") multiplayer.multiplayer_peer = null peer = ENetMultiplayerPeer.new() multiplayer.multiplayer_peer = peer func _Connection_Succseeded(): print("Succsessfully connected to the server") var nickname = GameData.client_settings["nickname"] rpc_id(1, "set_nickname", multiplayer.get_unique_id(), nickname) rpc_id(1, "get_character_properties", multiplayer.get_unique_id()) get_tree().change_scene_to_file("res://scenes/test_map.tscn") await get_tree().create_timer(1).timeout # костыль current_map_instance = get_tree().root.get_node("test_map") rpc_id(1, "get_client_list", multiplayer.get_unique_id()) await get_tree().create_timer(0.05).timeout # костыль # tp rpc_id(1, "get_server_settings", multiplayer.get_unique_id()) var player_node = player_model.instantiate() var CB3D = player_node.find_child("CharacterBody3D") CB3D.set_is_playable(true) CB3D.set_internal_id(player["internal_id"]) CB3D.set_player_name("player" + str(player["internal_id"])) CB3D.set_nickname(nickname) CB3D.set_ready(true) current_map_instance.add_child(player_node) await get_tree().create_timer(0.05).timeout # костыль rpc_id(1, "client_ready", multiplayer.get_unique_id()) func _Server_Disconnected(): print("Server has disconnected") Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) get_tree().change_scene_to_file("res://scenes/menu.tscn") multiplayer.multiplayer_peer = null peer = ENetMultiplayerPeer.new() multiplayer.multiplayer_peer = peer