Add direct-connect multiplayer foundation

This commit is contained in:
Alexander Sellite 2026-07-29 15:01:46 -04:00
parent 9e9850dd20
commit 24f8263175
36 changed files with 2633 additions and 45 deletions

View file

@ -0,0 +1,69 @@
class_name EndpointParser
extends RefCounted
const DEFAULT_PORT: int = 7777
static func parse(value: String, default_port: int = DEFAULT_PORT) -> ConnectionEndpoint:
var result := ConnectionEndpoint.new()
result.original_display = value.strip_edges()
result.port = default_port
if default_port < 1 or default_port > 65535:
result.error_message = "The configured default port is invalid."
return result
var input: String = result.original_display
if input.is_empty():
result.error_message = "Enter a hostname or IP address."
return result
var host: String = ""
var port_text: String = ""
if input.begins_with("["):
var closing: int = input.find("]")
if closing < 0:
result.error_message = "The IPv6 address is missing a closing bracket."
return result
host = input.substr(1, closing - 1).strip_edges()
var suffix: String = input.substr(closing + 1).strip_edges()
if not suffix.is_empty():
if not suffix.begins_with(":") or suffix.length() == 1:
result.error_message = "Use [IPv6]:port for an IPv6 port."
return result
port_text = suffix.substr(1).strip_edges()
elif input.contains("[") or input.contains("]"):
result.error_message = "IPv6 brackets are malformed."
return result
else:
var colon_count: int = input.count(":")
if colon_count == 1:
var separator: int = input.rfind(":")
host = input.substr(0, separator).strip_edges()
port_text = input.substr(separator + 1).strip_edges()
else:
# Zero colons is a hostname/IPv4 host. More than one is a raw
# IPv6 host; an explicit port for it must use brackets.
host = input.strip_edges()
if host.is_empty():
result.error_message = "The hostname or IP address is empty."
return result
if host.contains(" ") or host.contains("\t") or host.contains("\n"):
result.error_message = "The hostname or IP address contains whitespace."
return result
if not port_text.is_empty():
if not port_text.is_valid_int():
result.error_message = "The port must be a number from 1 to 65535."
return result
result.port = int(port_text)
if result.port < 1 or result.port > 65535:
result.error_message = "The port must be from 1 to 65535."
return result
result.host = host.to_lower()
var is_ipv6: bool = result.host.contains(":")
result.normalized_display = (
"[%s]:%d" % [result.host, result.port]
if is_ipv6
else "%s:%d" % [result.host, result.port]
)
return result