import asyncio import logging import sys import os # Add the lib directory to sys.path so we can import the openttd package sys.path.append(os.path.join(os.path.dirname(__file__), 'lib')) from openttd import OpenTTDAdminClient from openttd.protocol import AdminUpdateType, AdminUpdateFrequency # Configuration SERVER_HOST = "127.0.0.1" ADMIN_PORT = 3977 ADMIN_PASSWORD = "asd" async def run_admin(): admin = OpenTTDAdminClient(host=SERVER_HOST, port=ADMIN_PORT, admin_name="GeminiAdmin") # Setup callbacks def chat_logger(**kwargs): print(f">>> [ADMIN CHAT] <{kwargs.get('client_id')}> {kwargs.get('message')}") def console_logger(**kwargs): print(f">>> [CONSOLE] [{kwargs.get('origin')}] {kwargs.get('text')}") def gamescript_logger(data): print(f">>> [GAMESCRIPT] {data}") admin.on_chat = chat_logger admin.on_console = console_logger admin.on_gamescript = gamescript_logger try: await admin.connect(admin_password=ADMIN_PASSWORD, secure=True) await admin.joined.wait() print("--- Admin joined ---") # Initial poll print("--- Initial Poll ---") await admin.poll_companies() await admin.poll_clients() # Subscribe to everything await admin.update_frequency(AdminUpdateType.ClientInfo, AdminUpdateFrequency.Automatic) await admin.update_frequency(AdminUpdateType.CompanyInfo, AdminUpdateFrequency.Automatic) await admin.update_frequency(AdminUpdateType.Chat, AdminUpdateFrequency.Automatic) await admin.update_frequency(AdminUpdateType.Gamescript, AdminUpdateFrequency.Automatic) print("--- Requesting vehicle info via GameScript ---") await admin.list_vehicles() # Capture station-list replies (delivered to on_gamescript, like list_vehicles) while # still logging every other GameScript message. stations = [] def gamescript_capture(data): if isinstance(data, dict) and "stations" in data: stations.append(data["stations"]) gamescript_logger(data) admin.on_gamescript = gamescript_capture print("--- Requesting station info via GameScript ---") await admin.list_stations() await asyncio.sleep(1) # Fetch one station's authoritative live cargo (real-time waiting + planned). if stations and stations[-1]: sid = stations[-1][0]["id"] try: data = await admin.get_station(sid, timeout=10.0) print(f"--- Station {sid} ({data.get('name')}) cargo: real-time waiting vs planned ---") for cargo in data.get("cargo", []): print(f" cargo {cargo['cargo_id']}: waiting={cargo['waiting']} " f"planned={cargo['planned']} rating={cargo['rating']}") # Break the first cargo down by source station and by next hop (routing destination). if data.get("cargo"): cid = data["cargo"][0]["cargo_id"] flow = await admin.get_station_cargo(sid, cid, timeout=10.0) print(f"--- Station {sid} cargo {cid} flow breakdown (station 65535 = none/deleted) ---") print(f" waiting by source: {flow['waiting_by_from']}") print(f" waiting by next hop: {flow['waiting_by_via']}") print(f" planned by source: {flow['planned_by_from']}") print(f" planned by next hop: {flow['planned_by_via']}") except Exception as e: print(f"!!! station query failed: {e}") await asyncio.sleep(5) print("--- Quitting ---") await admin.quit() except Exception as e: print(f"!!! Error: {e}") if __name__ == "__main__": logging.basicConfig(level=logging.INFO, format='%(levelname)s:%(name)s:%(message)s') try: asyncio.run(run_admin()) except KeyboardInterrupt: pass