Initial Void Bastion 0.20 prototype
This commit is contained in:
commit
7362ca0f02
251 files changed
+29688
No files matched your search
@@ -0,0 +1,101 @@
|
||||
extends SceneTree
|
||||
|
||||
var matched_a = null
|
||||
var matched_b = null
|
||||
var snapshot_a: Dictionary = {}
|
||||
var snapshot_b: Dictionary = {}
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
call_deferred("_run")
|
||||
|
||||
|
||||
func _run() -> void:
|
||||
var nakama = root.get_node("Nakama")
|
||||
var test_host := OS.get_environment("VOID_BASTION_TEST_HOST")
|
||||
var test_scheme := OS.get_environment("VOID_BASTION_TEST_SCHEME")
|
||||
var test_port_text := OS.get_environment("VOID_BASTION_TEST_PORT")
|
||||
if test_host.is_empty():
|
||||
test_host = "192.168.178.20"
|
||||
if test_scheme.is_empty():
|
||||
test_scheme = "http"
|
||||
var test_port := int(test_port_text) if not test_port_text.is_empty() else 7350
|
||||
var client_a: NakamaClient = nakama.create_client("voidbastion-public-v1", test_host, test_port, test_scheme, 5, NakamaLogger.LOG_LEVEL.ERROR)
|
||||
var client_b: NakamaClient = nakama.create_client("voidbastion-public-v1", test_host, test_port, test_scheme, 5, NakamaLogger.LOG_LEVEL.ERROR)
|
||||
var suffix := str(Time.get_ticks_usec())
|
||||
var session_a: NakamaSession = await client_a.authenticate_device_async("voidbastion_godot_test_a_" + suffix, "godot_a_" + suffix, true)
|
||||
var session_b: NakamaSession = await client_b.authenticate_device_async("voidbastion_godot_test_b_" + suffix, "godot_b_" + suffix, true)
|
||||
assert(not session_a.is_exception() and session_a.is_valid(), "Godot-Client A muss ein Gastkonto anmelden können: %s" % session_a)
|
||||
assert(not session_b.is_exception() and session_b.is_valid(), "Godot-Client B muss ein Gastkonto anmelden können: %s" % session_b)
|
||||
|
||||
var info = await client_a.rpc_async(session_a, "server_info", "{}")
|
||||
assert(not info.is_exception(), "Die Godot-Anbindung muss Server-RPCs erreichen.")
|
||||
var info_data = JSON.parse_string(info.payload)
|
||||
assert(info_data is Dictionary and info_data.get("status") == "online", "Der Server muss seinen Onlinestatus melden.")
|
||||
assert(info_data.get("version") == "0.20", "Der Server muss die aktuelle Runtime 0.20 geladen haben: %s" % info_data)
|
||||
|
||||
var run_payload := JSON.stringify({"map": 1, "difficulty": 1, "mode": "mission", "wave": 4, "score": 4700, "client_version": "0.19-integration"})
|
||||
var submitted = await client_a.rpc_async(session_a, "submit_run", run_payload)
|
||||
assert(not submitted.is_exception(), "Ein plausibles Ergebnis muss serverseitig angenommen werden.")
|
||||
var records = await client_a.list_leaderboard_records_async(session_a, "mission_map1_difficulty1", null, null, 10)
|
||||
assert(not records.is_exception() and records.records.size() >= 1, "Das Ergebnis muss über das Godot-SDK aus der Rangliste lesbar sein.")
|
||||
|
||||
var socket_a: NakamaSocket = nakama.create_socket_from(client_a)
|
||||
var socket_b: NakamaSocket = nakama.create_socket_from(client_b)
|
||||
assert(not (await socket_a.connect_async(session_a, true, 5)).is_exception(), "Spieler A benötigt eine Echtzeitverbindung.")
|
||||
assert(not (await socket_b.connect_async(session_b, true, 5)).is_exception(), "Spieler B benötigt eine Echtzeitverbindung.")
|
||||
socket_a.received_matchmaker_matched.connect(func(value): matched_a = value)
|
||||
socket_b.received_matchmaker_matched.connect(func(value): matched_b = value)
|
||||
socket_a.received_match_state.connect(func(value): _capture_snapshot(value, true))
|
||||
socket_b.received_match_state.connect(func(value): _capture_snapshot(value, false))
|
||||
var props := {"game": "void_bastion", "mode": "quick"}
|
||||
var production_query := "+properties.game:void_bastion +properties.mode:quick +properties.difficulty:1"
|
||||
var ticket_a = await socket_a.add_matchmaker_async(production_query, 2, 2, props, {"difficulty": 1.0})
|
||||
var ticket_b = await socket_b.add_matchmaker_async(production_query, 2, 2, props, {"difficulty": 1.0})
|
||||
assert(not ticket_a.is_exception() and not ticket_b.is_exception(), "Beide Spieler müssen die Mitspielersuche starten können.")
|
||||
for attempt in 300:
|
||||
if matched_a != null and matched_b != null:
|
||||
break
|
||||
await create_timer(0.05).timeout
|
||||
assert(matched_a != null and matched_b != null, "Der Server muss zwei passende Spieler vermitteln.")
|
||||
var match_a = await socket_a.join_matched_async(matched_a)
|
||||
var match_b = await socket_b.join_matched_async(matched_b)
|
||||
assert(not match_a.is_exception() and not match_b.is_exception(), "Beide Spieler müssen der autoritativen Koop-Partie beitreten können.")
|
||||
assert(match_a.match_id == match_b.match_id, "Beide Spieler müssen dieselbe Koop-Partie erhalten.")
|
||||
for attempt in 100:
|
||||
if bool(snapshot_a.get("started", false)) and bool(snapshot_b.get("started", false)):
|
||||
break
|
||||
await create_timer(0.05).timeout
|
||||
assert(bool(snapshot_a.get("started", false)) and bool(snapshot_b.get("started", false)), "Beide Clients müssen den gestarteten Serverzustand empfangen.")
|
||||
var slot_a := int((snapshot_a.get("slots", {}) as Dictionary).get(session_a.user_id, -1))
|
||||
var slot_b := int((snapshot_b.get("slots", {}) as Dictionary).get(session_b.user_id, -1))
|
||||
assert(slot_a != slot_b and slot_a in [0, 1] and slot_b in [0, 1], "Der Server muss beiden Spielern unterschiedliche Seiten zuweisen.")
|
||||
var build_a := {"tower_type": 0, "x": 200.0 if slot_a == 0 else 2760.0, "y": 200.0}
|
||||
var build_b := {"tower_type": 1, "x": 200.0 if slot_b == 0 else 2760.0, "y": 200.0}
|
||||
await socket_a.send_match_state_async(match_a.match_id, 10, JSON.stringify(build_a))
|
||||
await socket_b.send_match_state_async(match_b.match_id, 10, JSON.stringify(build_b))
|
||||
await socket_a.send_match_state_async(match_a.match_id, 13, "{}")
|
||||
for attempt in 120:
|
||||
if int(snapshot_a.get("wave", 0)) == 1 and (snapshot_a.get("towers", []) as Array).size() == 2 and int(snapshot_b.get("wave", 0)) == 1:
|
||||
break
|
||||
await create_timer(0.05).timeout
|
||||
assert(int(snapshot_a.get("wave", 0)) == 1, "Der Server muss die gemeinsame Welle starten.")
|
||||
assert((snapshot_a.get("towers", []) as Array).size() == 2, "Beide autorisierten Bauaufträge müssen serverseitig sichtbar sein.")
|
||||
assert(JSON.stringify(snapshot_a.get("towers", [])) == JSON.stringify(snapshot_b.get("towers", [])), "Beide Clients müssen denselben Turmzustand erhalten.")
|
||||
assert(int(snapshot_a.get("reactor_lives", 0)) == int(snapshot_b.get("reactor_lives", -1)), "Beide Clients müssen dieselben gemeinsamen Reaktorleben sehen.")
|
||||
socket_a.close()
|
||||
socket_b.close()
|
||||
print("VOID_BASTION_ONLINE_INTEGRATION_OK")
|
||||
quit()
|
||||
|
||||
|
||||
func _capture_snapshot(message, client_a: bool) -> void:
|
||||
if int(message.op_code) != 1:
|
||||
return
|
||||
var parsed = JSON.parse_string(message.data)
|
||||
if not parsed is Dictionary:
|
||||
return
|
||||
if client_a:
|
||||
snapshot_a = parsed
|
||||
else:
|
||||
snapshot_b = parsed
|
||||
Reference in new issue
Block a user