extends Node # Клиент-сценарий для проверки ников и рейтинга (см. nicks_lb_test.py): выполняет команды из --cmds=a;b;c # и печатает факты строками «[имя] ФАКТ …». Без игрока и карты, если не вызвана команда scene:hub. # godot --headless --path <копия> res://tools/test/lb_client.tscn -- --client --name=A --profile=/tmp/a.cfg --cmds="nick:Алиса;map:race;sleep:2;show;quit" # Команды: wait_connected, nick:<текст>, map:, scene:hub, sleep:<с>, waitghosts:, show, rec:<карта>:<время>, # recn:<карта>:<сколько>:<время0> (подряд, время каждый раз на 1 с меньше), req:<карта>, reqn:<карта>:<сколько>, # bad (заведомо неверные submit_record), last:<карта>, quit. var label := "?" var cmds: Array = [] var results := 0 var board_updates := 0 func _ready() -> void: for a in OS.get_cmdline_user_args(): if a.begins_with("--name="): label = a.substr(7) if a.begins_with("--cmds="): cmds = a.substr(7).split(";") Net.record_result.connect(func(m, t, r, pb, mr): results += 1; say("ФАКТ РЕЗУЛЬТАТ %s время=%.3f место=%d личный=%s рекорд_карты=%s" % [m, t, r, pb, mr])) Net.leaderboard_updated.connect(func(_m): board_updates += 1) _run.call_deferred() func say(text: String) -> void: print("[%s] %s" % [label, text]) func _wait_until(cond: Callable, timeout := 8.0) -> bool: var t := 0.0 while not cond.call(): await get_tree().create_timer(0.1).timeout t += 0.1 if t > timeout: return false return true func _board_text(m: String) -> String: var b = Net.boards.get(m) if b == null: return "нет данных" var parts := [] for e in b.top: parts.append("%s:%.3f" % [e[0], e[1]]) return "n=%d место=%d моё=%.3f топ=%s" % [b.top.size(), b.my_rank, b.my_time, "|".join(parts)] func _run() -> void: for c in cmds: var p: PackedStringArray = c.split(":", true, 3) match p[0]: "wait_connected": say("ФАКТ ПОДКЛЮЧЁН %s" % await _wait_until(func(): return Net.connected)) "nick": Net.set_nick(c.substr(5)) "map": Net.enter_map(p[1]) say("ФАКТ КАРТА %s готова=%s" % [p[1], await _wait_until(func(): return Net.map_ready)]) "scene": add_child((load("res://maps/hub/hub.tscn") as PackedScene).instantiate()) say("ФАКТ ХАБ готов=%s" % await _wait_until(func(): return Net.map_ready)) "sleep": await get_tree().create_timer(float(p[1])).timeout "waitghosts": say("ФАКТ ПРИЗРАКИ %s" % await _wait_until(func(): return Net.ghosts.size() >= int(p[1]), 10.0)) await get_tree().create_timer(0.7).timeout "show": var gl := [] for id in Net.ghosts: var g = Net.ghosts[id] var l: Label3D = g.label gl.append("%d=%s(%s)" % [id, l.text, Net.nick_of(id)]) var ps := [] for id in Net.nicks: ps.append("%d=%s" % [id, Net.nicks[id]]) ps.sort() gl.sort() say("ФАКТ НИКИ свой=%s ники=%s призраки=%s" % [Net.nick_of(Net.own_id()), ",".join(ps), ",".join(gl)]) "rec": Net.submit_my_record(p[1], float(p[2])) await get_tree().create_timer(0.6).timeout "recn": for i in int(p[2]): Net.submit_my_record(p[1], float(p[3]) - i) await get_tree().create_timer(1.5).timeout say("ФАКТ ОТВЕТОВ_НА_ЗАПИСИ %d" % results) "req": var before := board_updates Net.request_board(p[1]) await _wait_until(func(): return board_updates > before, 3.0) say("ФАКТ ТАБЛИЦА %s %s" % [p[1], _board_text(p[1])]) "reqn": var before := board_updates for i in int(p[2]): Net.request_leaderboard.rpc_id(1, p[1]) await get_tree().create_timer(1.5).timeout say("ФАКТ ОТВЕТОВ_НА_ЗАПРОСЫ %d" % (board_updates - before)) "bad": var before := results Net.submit_record.rpc_id(1, "zzz", 60.0) # нет такой карты Net.submit_record.rpc_id(1, "race", 5.0) # быстрее допустимого Net.submit_record.rpc_id(1, "race", 99999.0) # дольше допустимого Net.submit_record.rpc_id(1, "race", NAN) Net.submit_record.rpc_id(1, "race", -3.0) Net.submit_record.rpc_id(1, "parkour", 90.0) # карта, на которой мы не находимся Net.request_leaderboard.rpc_id(1, "zzz") await get_tree().create_timer(1.5).timeout say("ФАКТ НЕВЕРНЫЕ_ПРИНЯТЫ %d" % (results - before)) "last": say("ФАКТ ПОСЛЕДНИЙ %s" % str(Net.last_record.get(p[1]))) "quit": say("ГОТОВО") get_tree().quit() return say("ГОТОВО") get_tree().quit()