Add dedicated server / host / client modes via NetworkManager autoload, PlayerSyncComponent (20 Hz unreliable RPC), WorldSyncComponent (authoritative block break/place), ChatManager (F2), LobbyMenu scene, updated MainMenu with Solo/Heberger/Rejoindre/Quitter buttons. Port changed to 7777 (9999 occupied by sntlkeyssrvr on this machine). Mobs disabled in multi (spawn solo only). Solo mode untouched. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
133 lines
3.4 KiB
GDScript
133 lines
3.4 KiB
GDScript
extends Node
|
|
|
|
signal connection_succeeded()
|
|
signal connection_failed()
|
|
signal server_started()
|
|
signal server_closed()
|
|
signal peer_connected(id: int)
|
|
signal peer_disconnected(id: int)
|
|
|
|
enum Mode { NONE, SOLO, HOST, CLIENT, DEDICATED }
|
|
var current_mode: Mode = Mode.NONE
|
|
|
|
const DEFAULT_PORT := 7777
|
|
const MAX_PLAYERS := 16
|
|
|
|
var peer: ENetMultiplayerPeer = null
|
|
|
|
|
|
func _ready() -> void:
|
|
multiplayer.peer_connected.connect(_on_peer_connected)
|
|
multiplayer.peer_disconnected.connect(_on_peer_disconnected)
|
|
multiplayer.connected_to_server.connect(_on_connection_ok)
|
|
multiplayer.connection_failed.connect(_on_connection_failed)
|
|
multiplayer.server_disconnected.connect(_on_server_disconnected)
|
|
|
|
# Auto-start from command line args
|
|
var args := OS.get_cmdline_user_args()
|
|
if "--server" in args:
|
|
start_dedicated_server(DEFAULT_PORT)
|
|
elif "--client" in args:
|
|
var idx := args.find("--client")
|
|
var address := "127.0.0.1"
|
|
if idx + 1 < args.size():
|
|
address = args[idx + 1]
|
|
join_server(address, DEFAULT_PORT)
|
|
|
|
|
|
func start_dedicated_server(port: int = DEFAULT_PORT) -> bool:
|
|
peer = ENetMultiplayerPeer.new()
|
|
var err := peer.create_server(port, MAX_PLAYERS)
|
|
if err != OK:
|
|
push_error("NetworkManager: server creation failed — error %d" % err)
|
|
peer = null
|
|
return false
|
|
multiplayer.multiplayer_peer = peer
|
|
current_mode = Mode.DEDICATED
|
|
print("[NET] Dedicated server listening on port %d" % port)
|
|
server_started.emit()
|
|
return true
|
|
|
|
|
|
func start_host(port: int = DEFAULT_PORT) -> bool:
|
|
peer = ENetMultiplayerPeer.new()
|
|
var err := peer.create_server(port, MAX_PLAYERS)
|
|
if err != OK:
|
|
push_error("NetworkManager: host creation failed — error %d" % err)
|
|
peer = null
|
|
return false
|
|
multiplayer.multiplayer_peer = peer
|
|
current_mode = Mode.HOST
|
|
print("[NET] Host server listening on port %d" % port)
|
|
server_started.emit()
|
|
return true
|
|
|
|
|
|
func join_server(address: String, port: int = DEFAULT_PORT) -> bool:
|
|
peer = ENetMultiplayerPeer.new()
|
|
var err := peer.create_client(address, port)
|
|
if err != OK:
|
|
push_error("NetworkManager: client connection failed — error %d" % err)
|
|
peer = null
|
|
return false
|
|
multiplayer.multiplayer_peer = peer
|
|
current_mode = Mode.CLIENT
|
|
print("[NET] Connecting to %s:%d" % [address, port])
|
|
return true
|
|
|
|
|
|
func disconnect_from_server() -> void:
|
|
if peer != null:
|
|
peer.close()
|
|
peer = null
|
|
multiplayer.multiplayer_peer = null
|
|
current_mode = Mode.NONE
|
|
server_closed.emit()
|
|
|
|
|
|
func _on_peer_connected(id: int) -> void:
|
|
print("[NET] Peer connected: %d" % id)
|
|
peer_connected.emit(id)
|
|
|
|
|
|
func _on_peer_disconnected(id: int) -> void:
|
|
print("[NET] Peer disconnected: %d" % id)
|
|
peer_disconnected.emit(id)
|
|
|
|
|
|
func _on_connection_ok() -> void:
|
|
print("[NET] Connected to server (my id: %d)" % multiplayer.get_unique_id())
|
|
connection_succeeded.emit()
|
|
|
|
|
|
func _on_connection_failed() -> void:
|
|
push_warning("[NET] Connection failed")
|
|
peer = null
|
|
multiplayer.multiplayer_peer = null
|
|
current_mode = Mode.NONE
|
|
connection_failed.emit()
|
|
|
|
|
|
func _on_server_disconnected() -> void:
|
|
push_warning("[NET] Server disconnected")
|
|
peer = null
|
|
multiplayer.multiplayer_peer = null
|
|
current_mode = Mode.NONE
|
|
server_closed.emit()
|
|
|
|
|
|
func is_server() -> bool:
|
|
return current_mode == Mode.HOST or current_mode == Mode.DEDICATED
|
|
|
|
|
|
func is_client() -> bool:
|
|
return current_mode == Mode.CLIENT
|
|
|
|
|
|
func is_solo() -> bool:
|
|
return current_mode == Mode.SOLO or current_mode == Mode.NONE
|
|
|
|
|
|
func get_my_id() -> int:
|
|
return multiplayer.get_unique_id()
|