diff --git a/FactorioClient.py b/FactorioClient.py index df36a611..ce5cee54 100644 --- a/FactorioClient.py +++ b/FactorioClient.py @@ -72,7 +72,6 @@ class FactorioContext(CommonContext): self.awaiting_bridge = False self.raw_json_text_parser = RawJSONtoTextParser(self) self.factorio_json_text_parser = FactorioJSONtoTextParser(self) - self.bridge_file = None async def server_auth(self, password_requested): if password_requested and not self.password: @@ -110,27 +109,31 @@ class FactorioContext(CommonContext): async def game_watcher(ctx: FactorioContext): bridge_logger = logging.getLogger("FactorioWatcher") from worlds.factorio.Technologies import lookup_id_to_name - bridge_file = ctx.bridge_file try: while not ctx.exit_event.is_set(): - if ctx.awaiting_bridge and os.path.exists(bridge_file): + if ctx.awaiting_bridge and ctx.rcon_client: ctx.awaiting_bridge = False - with open(bridge_file) as f: - data = json.load(f) + data = json.loads(ctx.rcon_client.send_command("/ap-sync")) + if data["slot_name"] != ctx.auth: + logger.warning(f"Connected World is not the expected one {data['slot_name']} != {ctx.auth}") + elif data["seed_name"] != ctx.seed_name: + logger.warning(f"Connected Multiworld is not the expected one {data['seed_name']} != {ctx.seed_name}") + else: + data = data["info"] research_data = data["research_done"] research_data = {int(tech_name.split("-")[1]) for tech_name in research_data} victory = data["victory"] - if not ctx.finished_game and victory: - await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}]) - ctx.finished_game = True + if not ctx.finished_game and victory: + await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}]) + ctx.finished_game = True - if ctx.locations_checked != research_data: - bridge_logger.info( - f"New researches done: " - f"{[lookup_id_to_name[rid] for rid in research_data - ctx.locations_checked]}") - ctx.locations_checked = research_data - await ctx.send_msgs([{"cmd": 'LocationChecks', "locations": tuple(research_data)}]) + if ctx.locations_checked != research_data: + bridge_logger.info( + f"New researches done: " + f"{[lookup_id_to_name[rid] for rid in research_data - ctx.locations_checked]}") + ctx.locations_checked = research_data + await ctx.send_msgs([{"cmd": 'LocationChecks', "locations": tuple(research_data)}]) await asyncio.sleep(1) except Exception as e: @@ -183,8 +186,7 @@ async def factorio_server_watcher(ctx: FactorioContext): # trigger lua interface confirmation ctx.rcon_client.send_command("/sc game.print('Starting Archipelago Bridge')") ctx.rcon_client.send_command("/sc game.print('Starting Archipelago Bridge')") - ctx.rcon_client.send_command("/ap-sync") - if not ctx.awaiting_bridge and "Archipelago Bridge File written for game tick " in msg: + if not ctx.awaiting_bridge and "Archipelago Bridge Data available for game tick " in msg: ctx.awaiting_bridge = True if ctx.rcon_client: while ctx.send_index < len(ctx.items_received): @@ -233,10 +235,9 @@ async def factorio_spinup_server(ctx: FactorioContext): factorio_queue = Queue() stream_factorio_output(factorio_process.stdout, factorio_queue, factorio_process) stream_factorio_output(factorio_process.stderr, factorio_queue, factorio_process) - write_folder = None rcon_client = None try: - while not ctx.auth or not write_folder: + while not ctx.auth: while not factorio_queue.empty(): msg = factorio_queue.get() factorio_server_logger.info(msg) @@ -244,13 +245,6 @@ async def factorio_spinup_server(ctx: FactorioContext): rcon_client = factorio_rcon.RCONClient("localhost", rcon_port, rcon_password) get_info(ctx, rcon_client) - if not write_folder and "Write data path:" in msg: - write_folder = msg.split("Write data path: ", 1)[1].split("[", 1)[0].strip() - bridge_file = os.path.join(write_folder, "script-output", "ap_bridge.json") - if os.path.exists(bridge_file): - os.remove(bridge_file) - ctx.bridge_file = bridge_file - logging.info(f"Bridge File Path: {bridge_file}") await asyncio.sleep(0.01) diff --git a/FactorioClientGUI.py b/FactorioClientGUI.py index 244ed250..cc6c3063 100644 --- a/FactorioClientGUI.py +++ b/FactorioClientGUI.py @@ -43,7 +43,7 @@ class FactorioManager(App): pairs = [ ("Client", "Archipelago"), ("FactorioServer", "Factorio Server Log"), - ("FactorioWatcher", "Bridge File Log"), + ("FactorioWatcher", "Bridge Data Log"), ] self.tabs.default_tab_content = UILog(*(logging.getLogger(logger_name) for logger_name, name in pairs)) for logger_name, display_name in pairs: diff --git a/data/factorio/mod_template/control.lua b/data/factorio/mod_template/control.lua index 2a65b3d0..56536be0 100644 --- a/data/factorio/mod_template/control.lua +++ b/data/factorio/mod_template/control.lua @@ -141,13 +141,6 @@ script.on_init(function() end end) --- for testing --- script.on_event(defines.events.on_tick, function(event) --- if event.tick%3600 == 300 then --- dumpInfo(game.forces["player"]) --- end --- end) - -- hook into researches done script.on_event(defines.events.on_research_finished, function(event) local technology = event.research @@ -185,26 +178,12 @@ script.on_event(defines.events.on_research_finished, function(event) end end) + function dumpInfo(force) - local research_done = {} - local data_collection = { - ["research_done"] = research_done, - ["victory"] = chain_lookup(global, "forcedata", force.name, "victory"), - } - - for tech_name, tech in pairs(force.technologies) do - if tech.researched and string.find(tech_name, "ap%-") == 1 then - research_done[tech_name] = tech.researched - end - end - game.write_file("ap_bridge.json", game.table_to_json(data_collection), false, 0) - log("Archipelago Bridge File written for game tick ".. game.tick .. ".") - -- game.write_file("research_done.json", game.table_to_json(data_collection), false, 0) - -- game.print("Sent progress to Archipelago.") + log("Archipelago Bridge Data available for game tick ".. game.tick .. ".") -- notifies client end - function chain_lookup(table, ...) for _, k in ipairs{...} do table = table[k] @@ -215,17 +194,30 @@ function chain_lookup(table, ...) return table end --- add / commands -commands.add_command("ap-sync", "Run manual Research Sync with Archipelago.", function(call) +-- add / commands +commands.add_command("ap-sync", "Used by the Archipelago client to get progress information", function(call) + local force if call.player_index == nil then - dumpInfo(game.forces.player) + force = game.forces.player else - dumpInfo(game.players[call.player_index].force) + force = game.players[call.player_index].force end - game.print("Wrote bridge file.") + local research_done = {} + local data_collection = { + ["research_done"] = research_done, + ["victory"] = chain_lookup(global, "forcedata", force.name, "victory"), + } + + for tech_name, tech in pairs(force.technologies) do + if tech.researched and string.find(tech_name, "ap%-") == 1 then + research_done[tech_name] = tech.researched + end + end + rcon.print(game.table_to_json({["slot_name"] = SLOT_NAME, ["seed_name"] = SEED_NAME, ["info"] = data_collection})) end) + commands.add_command("ap-get-technology", "Grant a technology, used by the Archipelago Client.", function(call) local force = game.forces["player"] chunks = {} @@ -246,6 +238,7 @@ commands.add_command("ap-get-technology", "Grant a technology, used by the Archi end end) + commands.add_command("ap-rcon-info", "Used by the Archipelago client to get information", function(call) rcon.print(game.table_to_json({["slot_name"] = SLOT_NAME, ["seed_name"] = SEED_NAME})) end) \ No newline at end of file