LuneSession hält den autoritativen Matchzustand; Clients senden nur Absichten. Fremde Sitze, veraltete Befehle und Doppelkäufe sind geprüft, Disconnect führt zur Bot-Übernahme statt zum Kernverlust. Exporte und entpackbare Demos 0.16.0-m4 für Linux und Windows.
72 lines
2.9 KiB
GDScript
72 lines
2.9 KiB
GDScript
extends Node
|
|
## Two-process loopback smoke test. Launch twice:
|
|
## godot --headless --path . res://tools/luneraria/net_pair.tscn -- --role=host --port=24571
|
|
## godot --headless --path . res://tools/luneraria/net_pair.tscn -- --role=client --port=24571
|
|
## This is a local two-process loopback test, not a six-player internet match.
|
|
const Session = preload("res://scripts/luneraria/net/lune_session.gd")
|
|
var role: String = "host"
|
|
var port: int = 24571
|
|
var address: String = "127.0.0.1"
|
|
var session: Node
|
|
var steps: int = 0
|
|
|
|
func _ready() -> void:
|
|
for arg: String in OS.get_cmdline_user_args():
|
|
if arg.begins_with("--role="):
|
|
role = arg.substr(7)
|
|
elif arg.begins_with("--port="):
|
|
port = int(arg.substr(7))
|
|
elif arg.begins_with("--address="):
|
|
address = arg.substr(10)
|
|
session = Session.new()
|
|
session.name = "LuneSession"
|
|
add_child(session)
|
|
session.session_message.connect(func(text: String, is_error: bool) -> void:
|
|
print("NET_MSG ", "ERR " if is_error else "OK ", text))
|
|
call_deferred("start")
|
|
|
|
func start() -> void:
|
|
if role == "host":
|
|
var options := {"seed": 42, "human_slot": 0,
|
|
"bunds": ["glutpakt", "wurzelbund", "glutpakt", "wurzelbund", "glutpakt", "wurzelbund"]}
|
|
var err: int = session.host_enet(port, options, "Host")
|
|
print("NET_HOST ", "OK" if err == OK else session.last_error)
|
|
if err != OK:
|
|
get_tree().quit(1)
|
|
return
|
|
session.lobby_changed.connect(func() -> void:
|
|
print("NET_LOBBY ", session.lobby))
|
|
else:
|
|
var err: int = session.join_enet(address, port, "Gast")
|
|
print("NET_JOIN ", "OK" if err == OK else session.last_error)
|
|
if err != OK:
|
|
get_tree().quit(1)
|
|
return
|
|
session.match_resetup.connect(func() -> void:
|
|
print("NET_SETUP seat=", session.local_slot, " players=", session.match_state.players.size())
|
|
var spoof: Dictionary = session.host_command(1, 5, {"type": "buy", "type_id": "w01"})
|
|
print("NET_SPOOF ", "REJECTED" if not spoof.ok else "ACCEPTED-BAD")
|
|
var ids: Array[String] = session.match_state.base_ids(session.match_state.players[session.local_slot].bund)
|
|
var buy: Dictionary = session.submit({"type": "buy", "type_id": ids[0]})
|
|
print("NET_BUY_SENT ", buy.ok)
|
|
print("NET_CLIENT_DONE seat=", session.local_slot)
|
|
get_tree().quit(0 if (not spoof.ok and buy.ok) else 1), CONNECT_ONE_SHOT)
|
|
|
|
func _process(_delta: float) -> void:
|
|
steps += 1
|
|
if steps > 1200:
|
|
print("NET_TIMEOUT role=", role)
|
|
get_tree().quit(2)
|
|
return
|
|
if role == "host" and session != null and session.match_state != null:
|
|
if session.match_state.phase == LuneMatch.Phase.PLANNING and steps == 400:
|
|
session.plan_bot_seats()
|
|
session.host_ready(0)
|
|
if session.match_state.phase == LuneMatch.Phase.COMBAT:
|
|
session.broadcast_combat_units()
|
|
if steps % 20 == 0:
|
|
session.match_state.step_combat()
|
|
if steps >= 700:
|
|
session.host_finish_combat()
|
|
print("NET_HOST_DONE round=", session.match_state.round_number, " phase=", session.match_state.phase)
|
|
get_tree().quit(0)
|