replace with multiplayer-coop files
This commit is contained in:
157
src/scripts/network_manager.gd
Normal file
157
src/scripts/network_manager.gd
Normal file
@@ -0,0 +1,157 @@
|
||||
extends Node
|
||||
|
||||
# Network Manager - Handles multiplayer connections and player spawning
|
||||
# Supports both hosting and joining games
|
||||
|
||||
signal player_connected(peer_id, player_info)
|
||||
signal player_disconnected(peer_id)
|
||||
signal connection_failed()
|
||||
signal connection_succeeded()
|
||||
|
||||
const DEFAULT_PORT = 7777
|
||||
const MAX_PLAYERS = 8
|
||||
|
||||
var players_info = {} # Dictionary of peer_id -> {local_player_count: int, player_names: []}
|
||||
var local_player_count = 1 # How many local players on this machine
|
||||
var is_hosting = false
|
||||
|
||||
func _ready():
|
||||
# Connect multiplayer signals
|
||||
multiplayer.peer_connected.connect(_on_peer_connected)
|
||||
multiplayer.peer_disconnected.connect(_on_peer_disconnected)
|
||||
multiplayer.connected_to_server.connect(_on_connected_to_server)
|
||||
multiplayer.connection_failed.connect(_on_connection_failed)
|
||||
multiplayer.server_disconnected.connect(_on_server_disconnected)
|
||||
|
||||
func host_game(port: int = DEFAULT_PORT) -> bool:
|
||||
var peer = ENetMultiplayerPeer.new()
|
||||
var error = peer.create_server(port, MAX_PLAYERS)
|
||||
|
||||
if error != OK:
|
||||
push_error("Failed to create server: " + str(error))
|
||||
return false
|
||||
|
||||
multiplayer.multiplayer_peer = peer
|
||||
is_hosting = true
|
||||
|
||||
# Register the host as a player
|
||||
var my_id = multiplayer.get_unique_id()
|
||||
players_info[my_id] = {
|
||||
"local_player_count": local_player_count,
|
||||
"player_names": _generate_player_names(local_player_count, my_id)
|
||||
}
|
||||
|
||||
print("Server started on port ", port)
|
||||
return true
|
||||
|
||||
func join_game(address: String, port: int = DEFAULT_PORT) -> bool:
|
||||
var peer = ENetMultiplayerPeer.new()
|
||||
var error = peer.create_client(address, port)
|
||||
|
||||
if error != OK:
|
||||
push_error("Failed to create client: " + str(error))
|
||||
return false
|
||||
|
||||
multiplayer.multiplayer_peer = peer
|
||||
is_hosting = false
|
||||
|
||||
print("Attempting to connect to ", address, ":", port)
|
||||
return true
|
||||
|
||||
func disconnect_from_game():
|
||||
if multiplayer.multiplayer_peer:
|
||||
multiplayer.multiplayer_peer.close()
|
||||
multiplayer.multiplayer_peer = null
|
||||
players_info.clear()
|
||||
is_hosting = false
|
||||
|
||||
func set_local_player_count(count: int):
|
||||
local_player_count = max(1, min(count, 4)) # Limit to 1-4 local players
|
||||
|
||||
func _generate_player_names(count: int, peer_id: int) -> Array:
|
||||
var names = []
|
||||
for i in range(count):
|
||||
names.append("Player%d_%d" % [peer_id, i + 1])
|
||||
return names
|
||||
|
||||
# Called when a peer connects to the server
|
||||
func _on_peer_connected(id: int):
|
||||
print("Peer connected: ", id)
|
||||
|
||||
# Called when a peer disconnects
|
||||
func _on_peer_disconnected(id: int):
|
||||
print("Peer disconnected: ", id)
|
||||
if players_info.has(id):
|
||||
players_info.erase(id)
|
||||
player_disconnected.emit(id)
|
||||
|
||||
# Called on client when successfully connected to server
|
||||
func _on_connected_to_server():
|
||||
print("Successfully connected to server")
|
||||
connection_succeeded.emit()
|
||||
|
||||
# Send our player info to the server
|
||||
var my_id = multiplayer.get_unique_id()
|
||||
_register_player.rpc_id(1, my_id, local_player_count)
|
||||
|
||||
# Called on client when connection fails
|
||||
func _on_connection_failed():
|
||||
print("Connection failed")
|
||||
multiplayer.multiplayer_peer = null
|
||||
connection_failed.emit()
|
||||
|
||||
# Called on client when disconnected from server
|
||||
func _on_server_disconnected():
|
||||
print("Server disconnected")
|
||||
multiplayer.multiplayer_peer = null
|
||||
players_info.clear()
|
||||
|
||||
# RPC to register a player with the server
|
||||
@rpc("any_peer", "reliable")
|
||||
func _register_player(peer_id: int, local_count: int):
|
||||
if not multiplayer.is_server():
|
||||
return
|
||||
|
||||
players_info[peer_id] = {
|
||||
"local_player_count": local_count,
|
||||
"player_names": _generate_player_names(local_count, peer_id)
|
||||
}
|
||||
|
||||
print("NetworkManager: Registered player ", peer_id, " with ", local_count, " local players")
|
||||
print("NetworkManager: Total players_info: ", players_info)
|
||||
|
||||
# Sync all player info to the new client (so they know about everyone)
|
||||
_sync_players.rpc_id(peer_id, players_info)
|
||||
|
||||
# Notify all clients (including the new one) about the new player
|
||||
_notify_player_joined.rpc(peer_id, players_info[peer_id])
|
||||
|
||||
# Emit signal on server
|
||||
player_connected.emit(peer_id, players_info[peer_id])
|
||||
|
||||
# RPC to sync all player info to a newly connected client
|
||||
@rpc("authority", "reliable")
|
||||
func _sync_players(all_players_info: Dictionary):
|
||||
players_info = all_players_info
|
||||
print("NetworkManager: Client synced all player info: ", players_info)
|
||||
|
||||
# Emit signals for all existing players (so game world can spawn them)
|
||||
for peer_id in players_info.keys():
|
||||
# Emit for ALL players including ourselves (game world will handle it)
|
||||
print("NetworkManager: Emitting player_connected for peer ", peer_id)
|
||||
player_connected.emit(peer_id, players_info[peer_id])
|
||||
|
||||
# RPC to notify all clients when a player joins
|
||||
@rpc("authority", "reliable")
|
||||
func _notify_player_joined(peer_id: int, player_info: Dictionary):
|
||||
print("NetworkManager: Notified about player ", peer_id, " joining")
|
||||
if not players_info.has(peer_id):
|
||||
players_info[peer_id] = player_info
|
||||
player_connected.emit(peer_id, player_info)
|
||||
|
||||
func get_all_player_ids() -> Array:
|
||||
return players_info.keys()
|
||||
|
||||
func get_player_info(peer_id: int) -> Dictionary:
|
||||
return players_info.get(peer_id, {})
|
||||
|
||||
Reference in New Issue
Block a user