mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-10 16:04:04 +00:00
feat(multiplayer): add Steam transport foundation
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
extends Node
|
||||
|
||||
# Autoload (project.godot [autoload] NetworkManager). Owns the ENet
|
||||
# transport: hosting, joining, shutdown, and connection-state signals. Lives
|
||||
# Autoload (project.godot [autoload] NetworkManager). Owns transport-neutral
|
||||
# hosting, joining, shutdown, and connection-state signals. Lives
|
||||
# at a fixed autoload path so RPC NodePaths never depend on which scene is
|
||||
# loaded (§1.3 of multiplayer-todo.md's derived decisions).
|
||||
#
|
||||
@@ -52,6 +52,11 @@ signal shutting_down()
|
||||
|
||||
const DEFAULT_PORT := 7777
|
||||
const MAX_CLIENTS := 32
|
||||
const TRANSPORT_ENET := "enet"
|
||||
const TRANSPORT_STEAM := "steam"
|
||||
|
||||
const EnetTransportScript = preload("res://scripts/enet_transport.gd")
|
||||
const SteamTransportScript = preload("res://scripts/steam_transport.gd")
|
||||
|
||||
# Clock (task 1.8, §4.7): client pings the server once a second on the
|
||||
# reliable control channel; clock_offset_ms is the min-RTT sample in a
|
||||
@@ -64,7 +69,8 @@ const CLOCK_WINDOW_SEC := 5.0
|
||||
|
||||
var is_server := false
|
||||
var is_client := false
|
||||
var _peer: ENetMultiplayerPeer # keep a strong ref alongside multiplayer.multiplayer_peer
|
||||
var _peer: MultiplayerPeer # keep a strong ref alongside multiplayer.multiplayer_peer
|
||||
var active_transport := ""
|
||||
|
||||
var rtt_ms := -1.0 # min-RTT sample currently in the window; -1 = no sample yet
|
||||
var clock_offset_ms := 0.0 # add to a local Time.get_ticks_msec() reading to estimate the server's clock
|
||||
@@ -121,31 +127,46 @@ func poll() -> void:
|
||||
multiplayer.poll()
|
||||
|
||||
|
||||
func host(port: int = DEFAULT_PORT, max_clients: int = MAX_CLIENTS) -> Error:
|
||||
func available_transports() -> PackedStringArray:
|
||||
var transports := PackedStringArray([TRANSPORT_ENET])
|
||||
if SteamTransportScript.new().is_available():
|
||||
transports.append(TRANSPORT_STEAM)
|
||||
return transports
|
||||
|
||||
|
||||
func host(port: int = DEFAULT_PORT, max_clients: int = MAX_CLIENTS, transport: String = TRANSPORT_ENET) -> Error:
|
||||
shutdown()
|
||||
var peer := ENetMultiplayerPeer.new()
|
||||
var err := peer.create_server(port, max_clients)
|
||||
var implementation := _make_transport(transport)
|
||||
if implementation == null:
|
||||
return ERR_INVALID_PARAMETER
|
||||
var result: Dictionary = implementation.create_server(port, max_clients)
|
||||
var err := int(result.error)
|
||||
if err != OK:
|
||||
push_error("NetworkManager.host: create_server failed (%s)" % error_string(err))
|
||||
push_error("NetworkManager.host(%s): create_server failed (%s): %s" % [transport, error_string(err), String(result.get("reason", ""))])
|
||||
return err
|
||||
_peer = peer
|
||||
multiplayer.multiplayer_peer = peer
|
||||
_peer = result.peer as MultiplayerPeer
|
||||
multiplayer.multiplayer_peer = _peer
|
||||
multiplayer.server_relay = false
|
||||
active_transport = transport
|
||||
is_server = true
|
||||
is_client = false
|
||||
return OK
|
||||
|
||||
|
||||
func join(address: String, port: int = DEFAULT_PORT) -> Error:
|
||||
func join(address: String, port: int = DEFAULT_PORT, transport: String = TRANSPORT_ENET) -> Error:
|
||||
shutdown()
|
||||
var peer := ENetMultiplayerPeer.new()
|
||||
var err := peer.create_client(address, port)
|
||||
var implementation := _make_transport(transport)
|
||||
if implementation == null:
|
||||
return ERR_INVALID_PARAMETER
|
||||
var result: Dictionary = implementation.create_client(address, port)
|
||||
var err := int(result.error)
|
||||
if err != OK:
|
||||
push_error("NetworkManager.join: create_client failed (%s)" % error_string(err))
|
||||
push_error("NetworkManager.join(%s): create_client failed (%s): %s" % [transport, error_string(err), String(result.get("reason", ""))])
|
||||
return err
|
||||
_peer = peer
|
||||
multiplayer.multiplayer_peer = peer
|
||||
_peer = result.peer as MultiplayerPeer
|
||||
multiplayer.multiplayer_peer = _peer
|
||||
multiplayer.server_relay = false
|
||||
active_transport = transport
|
||||
is_server = false
|
||||
is_client = true
|
||||
return OK
|
||||
@@ -164,6 +185,7 @@ func shutdown() -> void:
|
||||
peer.close()
|
||||
multiplayer.multiplayer_peer = OfflineMultiplayerPeer.new()
|
||||
_peer = null
|
||||
active_transport = ""
|
||||
is_server = false
|
||||
is_client = false
|
||||
rtt_ms = -1.0
|
||||
@@ -174,6 +196,17 @@ func shutdown() -> void:
|
||||
_last_raw_rtt_ms = -1.0
|
||||
|
||||
|
||||
func _make_transport(transport: String) -> NetTransport:
|
||||
match transport:
|
||||
TRANSPORT_ENET:
|
||||
return EnetTransportScript.new()
|
||||
TRANSPORT_STEAM:
|
||||
return SteamTransportScript.new()
|
||||
_:
|
||||
push_error("NetworkManager: unknown transport '%s'" % transport)
|
||||
return null
|
||||
|
||||
|
||||
@rpc("any_peer", "call_remote", "reliable")
|
||||
func _ping(client_send_ms: int) -> void:
|
||||
if not multiplayer.is_server():
|
||||
|
||||
Reference in New Issue
Block a user