Files

68 lines
3.3 KiB
GDScript

extends SceneTree
var game: Node3D
var checks := 0
var failures := 0
func _initialize() -> void:
call_deferred("run")
func check(value: bool, title: String) -> void:
checks += 1
if value:
print("PASS ", title)
else:
failures += 1
printerr("FAIL ", title)
func run() -> void:
create_timer(30).timeout.connect(func(): quit(1))
var good := ServerSettings.DEFAULTS.duplicate()
check(ServerSettings.validate(good).is_empty(), "Default dedicated configuration is valid")
for item in [["port", -1], ["port", 27841], ["max_players", 9], ["bots", "8"], ["mode", "CTF"],
["bind", "bad address"], ["difficulty", 8], ["round_delay", 0], ["discovery", "true"], ["typo", 1]]:
var bad := good.duplicate()
bad[item[0]] = item[1]
check(not ServerSettings.validate(bad).is_empty(), "Invalid server setting rejected: %s" % item[0])
var loaded := ServerSettings.read(PackedStringArray(["--dedicated", "--port=27989", "--bots=0", "--name=LAN Test", "--mode=FFA"]))
check(loaded.error.is_empty() and loaded.settings.port == 27989 and loaded.settings.bots == 0 and loaded.settings.server_name == "LAN Test", "CLI overrides config without changing the file")
check(not ServerSettings.read(PackedStringArray(["--port=oops"])).error.is_empty(), "Malformed CLI value is rejected")
check(not ServerSettings.read(PackedStringArray(["--config=res://missing-server.json"])).error.is_empty(), "Missing configuration fails clearly")
game = load("res://scenes/main.tscn").instantiate()
root.add_child(game)
await physics_frame
var server := DedicatedServer.new()
server.game = game
game.add_child(server)
server.start(PackedStringArray(["--dedicated", "--port=27989", "--bots=8", "--round-delay=3", "--discovery=false"]))
check(game.active and game.is_host and game.dedicated and game.local_id == 0, "Dedicated server owns authority without a local player")
check(not game.players.has(1) and game.players.size() == 8, "All eight slots can be bots; server consumes no slot")
game.set_physics_process(false)
server.set_physics_process(false)
for fighter: Fighter in game.players.values():
fighter.set_physics_process(false)
var player: Fighter = game.players[-1]
player.kills = 5
player.deaths = 2
player.hp = 0
player.killer_id = -2
game.scores = [9, 4]
game.time_left = 0
game.finish_match()
server._physics_process(0.1)
check(game.match_over and server.round_number == 1, "Round end preserves scoreboard during intermission")
server._physics_process(3.1)
check(not game.match_over and game.scores == [0, 0] and game.time_left == game.config.time_limit and server.round_number == 2, "Dedicated runtime automatically starts next round")
check(player.hp == 100 and player.kills == 0 and player.deaths == 0 and player.killer_id == 0, "New round resets fighters, scores and death-camera identity")
game.config.mode = "FFA"
game.finish_match()
check(game.match_over and not game.winner.is_empty(), "FFA can finish and restart as dedicated match")
game.remove_player(-1)
game.add_player(123, "Remote", false, 0).set_physics_process(false)
game._disconnected(123)
check(game.players.size() == 8 and not game.players.has(123), "Disconnected client slot is refilled by a bot")
game.leave()
await process_frame
print("DEDICATED ", checks, " checks, ", failures, " failures")
quit(0 if failures == 0 else 1)