Add dedicated server runtime
This commit is contained in:
parent
e204279b09
commit
74c82696fe
14 changed files with 595 additions and 47 deletions
|
|
@ -87,6 +87,19 @@ func get_base_url() -> String:
|
|||
return _base_url
|
||||
|
||||
|
||||
func set_base_url_override(value: String) -> bool:
|
||||
var normalized: String = value.strip_edges()
|
||||
while normalized.ends_with("/"):
|
||||
normalized = normalized.left(normalized.length() - 1)
|
||||
if not normalized.is_empty() and not (
|
||||
normalized.begins_with("https://")
|
||||
or normalized.begins_with("http://")
|
||||
):
|
||||
return false
|
||||
_base_url = normalized
|
||||
return true
|
||||
|
||||
|
||||
func get_room_name() -> String:
|
||||
return _room_name
|
||||
|
||||
|
|
@ -366,7 +379,7 @@ func _valid_public_room(room: Dictionary) -> bool:
|
|||
and typeof(room.get("game_version")) == TYPE_STRING
|
||||
and str(room.get("game_version")) == expected_version
|
||||
and _valid_json_integer(room.get("port"), 1, 65535)
|
||||
and _valid_json_integer(room.get("current_players"), 1, 128)
|
||||
and _valid_json_integer(room.get("current_players"), 0, 128)
|
||||
and _valid_json_integer(room.get("max_players"), 1, 128)
|
||||
and int(room["current_players"]) <= int(room["max_players"])
|
||||
and _valid_json_integer(
|
||||
|
|
|
|||
|
|
@ -9,11 +9,17 @@ var error_message: String = ""
|
|||
var _private_key: CryptoKey
|
||||
var _prefix: String = ""
|
||||
var _allow_generation: bool = true
|
||||
var _storage_directory: String = ""
|
||||
|
||||
|
||||
func configure(prefix: String, allow_generation: bool = true) -> void:
|
||||
func configure(
|
||||
prefix: String,
|
||||
allow_generation: bool = true,
|
||||
storage_directory: String = "",
|
||||
) -> void:
|
||||
_prefix = prefix
|
||||
_allow_generation = allow_generation
|
||||
_storage_directory = storage_directory.strip_edges()
|
||||
|
||||
|
||||
func load_or_create() -> bool:
|
||||
|
|
@ -225,7 +231,12 @@ func _write_atomic(path: String, content: String) -> bool:
|
|||
|
||||
|
||||
func _path(extension: String) -> String:
|
||||
return "user://%s%s" % [_prefix, extension]
|
||||
var filename: String = "%s%s" % [_prefix, extension]
|
||||
return (
|
||||
_storage_directory.path_join(filename)
|
||||
if not _storage_directory.is_empty()
|
||||
else "user://%s" % filename
|
||||
)
|
||||
|
||||
|
||||
func identity_type() -> String:
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ var _local_appearance_snapshot: Dictionary = (
|
|||
var _moderation_disconnect_message := ""
|
||||
var _host_port: int = 0
|
||||
var _session_display_name: String = "NETfishing Room"
|
||||
var _dedicated_host: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
|
@ -120,6 +121,7 @@ func setup(
|
|||
known_players: KnownPlayerStore,
|
||||
server_trust: ServerTrustStore,
|
||||
host_bans: HostBanStore,
|
||||
dedicated: bool = false,
|
||||
) -> void:
|
||||
_profile = profile
|
||||
_saved_servers = saved_servers
|
||||
|
|
@ -129,9 +131,9 @@ func setup(
|
|||
_known_players = known_players
|
||||
_server_trust = server_trust
|
||||
_host_bans = host_bans
|
||||
if _profile != null:
|
||||
if not dedicated and _profile != null:
|
||||
_profile_ready = _profile.load_or_create()
|
||||
if _player_identity != null:
|
||||
if not dedicated and _player_identity != null:
|
||||
_profile_ready = _profile_ready and _player_identity.load_or_create()
|
||||
|
||||
|
||||
|
|
@ -147,6 +149,34 @@ func start_private_host(
|
|||
or _host_identity == null
|
||||
):
|
||||
return false
|
||||
return _start_host(port, port_attempts, false)
|
||||
|
||||
|
||||
func start_dedicated_host(
|
||||
port: int = DEFAULT_PORT,
|
||||
max_players: int = DEFAULT_SESSION_MAX_PLAYERS,
|
||||
bind_address: String = "*",
|
||||
) -> bool:
|
||||
if (
|
||||
state != State.INACTIVE
|
||||
or _spawn_service == null
|
||||
or _host_identity == null
|
||||
or max_players < 1
|
||||
or max_players > 128
|
||||
or bind_address.is_empty()
|
||||
):
|
||||
return false
|
||||
session_max_players = max_players
|
||||
transport_max_clients = maxi(transport_max_clients, max_players)
|
||||
return _start_host(port, 1, true, bind_address)
|
||||
|
||||
|
||||
func _start_host(
|
||||
port: int,
|
||||
port_attempts: int,
|
||||
dedicated: bool,
|
||||
bind_address: String = "*",
|
||||
) -> bool:
|
||||
if not _host_identity.load_or_create():
|
||||
_fail(_host_identity.error_message)
|
||||
return false
|
||||
|
|
@ -154,16 +184,20 @@ func start_private_host(
|
|||
_fail("The hosting port must be from 1 to 65535.")
|
||||
return false
|
||||
_operation_generation += 1
|
||||
_set_state(State.STARTING_PRIVATE_HOST, "Starting private game...")
|
||||
_set_state(
|
||||
State.STARTING_PRIVATE_HOST,
|
||||
"Starting dedicated server..." if dedicated else "Starting private game...",
|
||||
)
|
||||
var selected_port: int = 0
|
||||
var final_port: int = mini(port + port_attempts - 1, 65535)
|
||||
for candidate_port: int in range(port, final_port + 1):
|
||||
if not _can_bind_udp_port(candidate_port):
|
||||
if not _can_bind_udp_port(candidate_port, bind_address):
|
||||
continue
|
||||
_replace_transport()
|
||||
var error: Error = _transport.start_host(
|
||||
candidate_port,
|
||||
transport_max_clients,
|
||||
bind_address,
|
||||
)
|
||||
if error == OK:
|
||||
selected_port = candidate_port
|
||||
|
|
@ -175,11 +209,28 @@ func start_private_host(
|
|||
)
|
||||
return false
|
||||
_host_port = selected_port
|
||||
_dedicated_host = dedicated
|
||||
var peer: MultiplayerPeer = _transport.get_multiplayer_peer()
|
||||
peer.refuse_new_connections = true
|
||||
multiplayer.multiplayer_peer = peer
|
||||
_session_id = Crypto.new().generate_random_bytes(16).hex_encode()
|
||||
_registry.clear()
|
||||
_spawn_service.clear_remote_players()
|
||||
if not dedicated:
|
||||
_register_player_host()
|
||||
_set_state(
|
||||
State.PRIVATE_HOST,
|
||||
(
|
||||
"Dedicated server • UDP %d"
|
||||
if dedicated else "Private game • UDP %d"
|
||||
) % selected_port,
|
||||
)
|
||||
host_openness_changed.emit(false)
|
||||
_emit_peer_count()
|
||||
return true
|
||||
|
||||
|
||||
func _register_player_host() -> void:
|
||||
_registry.add_peer(
|
||||
1,
|
||||
_profile.profile_id,
|
||||
|
|
@ -215,21 +266,20 @@ func start_private_host(
|
|||
"client_nonce": host_profile_hello["client_nonce"],
|
||||
}
|
||||
_archive_authenticated_identity(host_record)
|
||||
_spawn_service.clear_remote_players()
|
||||
_spawn_service.register_local_player(1)
|
||||
var host_avatar := _spawn_service.get_avatar(1)
|
||||
if host_avatar != null:
|
||||
host_avatar.apply_appearance_snapshot(_local_appearance_snapshot)
|
||||
_set_state(State.PRIVATE_HOST, "Private game • UDP %d" % selected_port)
|
||||
host_openness_changed.emit(false)
|
||||
_emit_peer_count()
|
||||
return true
|
||||
|
||||
|
||||
func get_host_port() -> int:
|
||||
return _host_port if is_host() else 0
|
||||
|
||||
|
||||
func is_dedicated_host() -> bool:
|
||||
return is_host() and _dedicated_host
|
||||
|
||||
|
||||
func set_session_display_name(value: String) -> void:
|
||||
var cleaned: String = value.strip_edges().left(48)
|
||||
if cleaned.is_empty():
|
||||
|
|
@ -244,9 +294,9 @@ func get_session_display_name() -> String:
|
|||
return _session_display_name
|
||||
|
||||
|
||||
static func _can_bind_udp_port(port: int) -> bool:
|
||||
static func _can_bind_udp_port(port: int, bind_address: String = "*") -> bool:
|
||||
var probe := PacketPeerUDP.new()
|
||||
var error: Error = probe.bind(port)
|
||||
var error: Error = probe.bind(port, bind_address)
|
||||
probe.close()
|
||||
return error == OK
|
||||
|
||||
|
|
@ -328,7 +378,9 @@ func set_host_open(is_open: bool) -> bool:
|
|||
_set_state(
|
||||
State.OPEN_HOST if is_open else State.PRIVATE_HOST,
|
||||
(
|
||||
"Open game • UDP %d • %d / %d players"
|
||||
"Dedicated server • UDP %d • %d / %d players"
|
||||
if _dedicated_host
|
||||
else "Open game • UDP %d • %d / %d players"
|
||||
if is_open
|
||||
else "Private game • UDP %d • %d / %d players"
|
||||
) % [_host_port, _registry.size(), session_max_players]
|
||||
|
|
@ -623,6 +675,8 @@ func _apply_display_name(peer_id: int, value: String) -> void:
|
|||
|
||||
|
||||
func get_local_peer_id() -> int:
|
||||
if is_dedicated_host():
|
||||
return 0
|
||||
return multiplayer.get_unique_id() if is_gameplay_session_active() else 0
|
||||
|
||||
|
||||
|
|
@ -1792,3 +1846,4 @@ func _teardown_peer() -> void:
|
|||
_server_identity_public_key = ""
|
||||
_session_identity_keys.clear()
|
||||
_host_port = 0
|
||||
_dedicated_host = false
|
||||
|
|
|
|||
|
|
@ -169,6 +169,13 @@ func use_existing_root(path: String) -> bool:
|
|||
return true
|
||||
|
||||
|
||||
func activate_process_root(path: String) -> bool:
|
||||
_load_bootstrap_identity()
|
||||
override_active = true
|
||||
mode = Mode.COMMAND_LINE_OVERRIDE
|
||||
return _activate_existing(path, "", false)
|
||||
|
||||
|
||||
func path_for(store_owner: StringName) -> String:
|
||||
var relative: String = {
|
||||
&"player_save": "player/player_save.json",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue