Add direct-connect multiplayer foundation
This commit is contained in:
parent
9e9850dd20
commit
24f8263175
36 changed files with 2633 additions and 45 deletions
121
network/network_protocol.gd
Normal file
121
network/network_protocol.gd
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
class_name NetworkProtocol
|
||||
extends RefCounted
|
||||
|
||||
const PROTOCOL_VERSION: int = 1
|
||||
const GAME_BUILD: String = "prealpha"
|
||||
const MAX_DISPLAY_NAME_LENGTH: int = 48
|
||||
const MAX_PROFILE_ID_LENGTH: int = 96
|
||||
const MAX_NONCE_LENGTH: int = 96
|
||||
|
||||
enum RejectionCode {
|
||||
NONE,
|
||||
MALFORMED_HANDSHAKE,
|
||||
PROTOCOL_MISMATCH,
|
||||
SERVER_FULL,
|
||||
DUPLICATE_PROFILE,
|
||||
AUTHENTICATION_TIMEOUT,
|
||||
SERVER_SHUTTING_DOWN,
|
||||
UNSUPPORTED_CLIENT,
|
||||
}
|
||||
|
||||
|
||||
static func make_client_hello(
|
||||
profile_id: String,
|
||||
display_name: String,
|
||||
client_nonce: String,
|
||||
) -> Dictionary:
|
||||
return {
|
||||
"protocol_version": PROTOCOL_VERSION,
|
||||
"game_build": GAME_BUILD,
|
||||
"local_profile_id": profile_id,
|
||||
"display_name": display_name,
|
||||
"client_nonce": client_nonce,
|
||||
"capability_flags": PackedStringArray(),
|
||||
"cosmetic_snapshot": {},
|
||||
}
|
||||
|
||||
|
||||
static func validate_client_hello(data: Variant) -> String:
|
||||
if typeof(data) != TYPE_DICTIONARY:
|
||||
return "Handshake payload is not a dictionary."
|
||||
var payload: Dictionary = data
|
||||
for key: String in [
|
||||
"protocol_version",
|
||||
"game_build",
|
||||
"local_profile_id",
|
||||
"display_name",
|
||||
"client_nonce",
|
||||
"capability_flags",
|
||||
"cosmetic_snapshot",
|
||||
]:
|
||||
if not payload.has(key):
|
||||
return "Handshake is missing %s." % key
|
||||
if typeof(payload["protocol_version"]) != TYPE_INT:
|
||||
return "Protocol version is invalid."
|
||||
if typeof(payload["game_build"]) != TYPE_STRING:
|
||||
return "Game build is invalid."
|
||||
if typeof(payload["local_profile_id"]) != TYPE_STRING:
|
||||
return "Profile ID is invalid."
|
||||
if typeof(payload["display_name"]) != TYPE_STRING:
|
||||
return "Display name is invalid."
|
||||
if typeof(payload["client_nonce"]) != TYPE_STRING:
|
||||
return "Client nonce is invalid."
|
||||
if typeof(payload["capability_flags"]) not in [
|
||||
TYPE_PACKED_STRING_ARRAY,
|
||||
TYPE_ARRAY,
|
||||
]:
|
||||
return "Capabilities are invalid."
|
||||
if typeof(payload["cosmetic_snapshot"]) != TYPE_DICTIONARY:
|
||||
return "Cosmetic snapshot is invalid."
|
||||
var profile_id: String = payload["local_profile_id"]
|
||||
var display_name: String = payload["display_name"]
|
||||
var nonce: String = payload["client_nonce"]
|
||||
if (
|
||||
profile_id.is_empty()
|
||||
or profile_id.length() > MAX_PROFILE_ID_LENGTH
|
||||
or display_name.is_empty()
|
||||
or display_name.length() > MAX_DISPLAY_NAME_LENGTH
|
||||
or nonce.is_empty()
|
||||
or nonce.length() > MAX_NONCE_LENGTH
|
||||
):
|
||||
return "Handshake strings are outside allowed limits."
|
||||
return ""
|
||||
|
||||
|
||||
static func make_server_hello(
|
||||
accepted: bool,
|
||||
rejection_code: RejectionCode,
|
||||
session_id: String,
|
||||
assigned_peer_id: int,
|
||||
player_count: int,
|
||||
max_players: int,
|
||||
) -> Dictionary:
|
||||
return {
|
||||
"accepted": accepted,
|
||||
"rejection_code": int(rejection_code),
|
||||
"protocol_version": PROTOCOL_VERSION,
|
||||
"session_id": session_id,
|
||||
"assigned_peer_id": assigned_peer_id,
|
||||
"server_display_name": "NETFISHING",
|
||||
"player_count": player_count,
|
||||
"max_players": max_players,
|
||||
"capability_flags": PackedStringArray(["movement_v1"]),
|
||||
}
|
||||
|
||||
|
||||
static func rejection_text(code: int) -> String:
|
||||
match code:
|
||||
RejectionCode.PROTOCOL_MISMATCH:
|
||||
return "The server uses a different network protocol."
|
||||
RejectionCode.SERVER_FULL:
|
||||
return "The server is full."
|
||||
RejectionCode.DUPLICATE_PROFILE:
|
||||
return "This local profile is already connected."
|
||||
RejectionCode.AUTHENTICATION_TIMEOUT:
|
||||
return "The server did not finish authentication."
|
||||
RejectionCode.SERVER_SHUTTING_DOWN:
|
||||
return "The server is shutting down."
|
||||
RejectionCode.UNSUPPORTED_CLIENT:
|
||||
return "This game build is not supported by the server."
|
||||
_:
|
||||
return "The server rejected the connection."
|
||||
Loading…
Add table
Add a link
Reference in a new issue