Клиент постоянно собирает данные о FunTime: какие ивенты идут, где открылись шахты, что лежит в медных данжах и городах стража, кого забанили. Объект funtime отдаёт всё это скрипту обычными списками и словарями.
Данные приходят двумя путями. Быстрые методы читают то, что клиент уже собрал: они отвечают сразу и ничего не грузят из сети. Методы fetch_* идут на сервер и отвечают позже, поэтому им передают функцию, которую позовут с готовым ответом.
if not funtime.ready():
client.warn("данных пока нет: клиент ещё не собрал их")
for event in funtime.events():
client.msg("%s на %s%s, осталось %s"
% (event["name"], event["server_type"], event["server_id"], event["time_left"]))
info = funtime.system_info()
client.msg("ивентов сейчас: %d" % info["events"])| Метод | Что отдаёт |
|---|---|
funtime.ready() | Собраны ли уже данные. На запросы fetch не влияет |
funtime.events() | Ивенты: name, status, level, time_left, coordinates, server_id |
funtime.mines() | Шахты: rarity, time_left, server_id |
funtime.copper_dungeons() | Медные данжи: сундуки и игроки рядом |
funtime.warden_cities() | Города стража, устроены так же |
funtime.system_info() | Сводка: сколько всего ивентов, шахт, данжей |
Запрос уходит в сеть, поэтому ответ приходит не сразу. Скрипт передаёт функцию, а клиент зовёт её, когда ответ готов, и уже в главном потоке игры: внутри можно спокойно трогать mc и рисовать.
def got_players(players):
if not players:
client.warn("игроков не пришло")
return
client.msg("игроков онлайн: %d" % len(players))
for player in players[:5]:
client.msg(" %s на %s%s" % (player["name"], player["server_type"], player["server_id"]))
funtime.fetch_players(got_players)
funtime.fetch_bans(lambda bans: client.msg("банов: %d" % len(bans)), {"playerName": "Nick"})| Метод | Что приходит в функцию |
|---|---|
funtime.fetch_events(fn, params=None) | Ответ сервера строкой, как есть |
funtime.fetch_mines(fn, params=None) | То же самое про шахты |
funtime.fetch_players(fn, params=None) | Список игроков: name, donate, server_id |
funtime.fetch_bans(fn, params=None) | Список банов: name, reason, end |
funtime.fetch_copper_dungeon(fn) / fetch_warden_city(fn) | Ответ сервера строкой |
funtime.solve_captcha(base64, fn) | Разбор капчи: solved, text, percent |
Там, где приходит строка, это ответ сервера целиком. Разбирают его обычным json.loads.
import json
def got_events(raw):
data = json.loads(raw)
items = data.get("data", data)
client.msg("записей: %d" % len(items))
funtime.fetch_events(got_events)Раз в несколько секунд смотрим, не начался ли нужный ивент, и сообщаем об этом плашкой. Проверка по таймеру, а не каждый тик: данные всё равно обновляются не чаще.
mod = Module("EventWatch", "Other")
mod.setDesc("Следит за ивентами FunTime")
timer = Timer()
seen = set()
WANTED = ["Метеорит", "Аномалия"]
@events.tick
def on_tick(event):
if not mod.isEnabled() or not funtime.ready():
return
if not timer.finished(5000):
return
timer.reset()
for item in funtime.events():
name = item.get("name") or ""
key = "%s:%s" % (name, item.get("server_id"))
if key in seen or item.get("status") != "active":
continue
if not any(word.lower() in name.lower() for word in WANTED):
continue
seen.add(key)
notify.success("%s: %s%s" % (name, item.get("server_type"), item.get("server_id")))