Factorio: Automatically find and force create bridge file

This commit is contained in:
Fabian Dill 2021-05-09 16:49:47 +02:00
parent eb02d65dbb
commit 37755cd362
4 changed files with 29 additions and 14 deletions

View File

@ -35,8 +35,6 @@ if not os.path.exists(executable):
else: else:
raise FileNotFoundError(executable) raise FileNotFoundError(executable)
script_folder = options["factorio_options"]["script-output"]
threadpool = ThreadPoolExecutor(10) threadpool = ThreadPoolExecutor(10)
class FactorioCommandProcessor(ClientCommandProcessor): class FactorioCommandProcessor(ClientCommandProcessor):
@ -93,11 +91,8 @@ class FactorioContext(CommonContext):
cleaned_text = self.raw_json_text_parser(copy_data).replace('"', '') cleaned_text = self.raw_json_text_parser(copy_data).replace('"', '')
self.rcon_client.send_command(f"/sc game.print(\"Archipelago: {cleaned_text}\")") self.rcon_client.send_command(f"/sc game.print(\"Archipelago: {cleaned_text}\")")
async def game_watcher(ctx: FactorioContext): async def game_watcher(ctx: FactorioContext, bridge_file: str):
bridge_logger = logging.getLogger("FactorioWatcher") bridge_logger = logging.getLogger("FactorioWatcher")
bridge_file = os.path.join(script_folder, "ap_bridge.json")
if os.path.exists(bridge_file):
os.remove(bridge_file)
from worlds.factorio.Technologies import lookup_id_to_name from worlds.factorio.Technologies import lookup_id_to_name
bridge_counter = 0 bridge_counter = 0
try: try:
@ -157,6 +152,7 @@ async def factorio_server_watcher(ctx: FactorioContext):
factorio_queue = Queue() factorio_queue = Queue()
stream_factorio_output(factorio_process.stdout, factorio_queue) stream_factorio_output(factorio_process.stdout, factorio_queue)
stream_factorio_output(factorio_process.stderr, factorio_queue) stream_factorio_output(factorio_process.stderr, factorio_queue)
script_folder = None
try: try:
while 1: while 1:
while not factorio_queue.empty(): while not factorio_queue.empty():
@ -167,6 +163,14 @@ async def factorio_server_watcher(ctx: FactorioContext):
# trigger lua interface confirmation # 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("/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 script_folder and "Write data path:" in msg:
script_folder = msg.split("Write data path: ", 1)[1].split("[", 1)[0].strip()
bridge_file = os.path.join(script_folder, "script-output", "ap_bridge.json")
if os.path.exists(bridge_file):
os.remove(bridge_file)
logging.info(f"Bridge File Path: {bridge_file}")
asyncio.create_task(game_watcher(ctx, bridge_file), name="FactorioProgressionWatcher")
if ctx.rcon_client: if ctx.rcon_client:
while ctx.send_index < len(ctx.items_received): while ctx.send_index < len(ctx.items_received):
transfer_item: NetworkItem = ctx.items_received[ctx.send_index] transfer_item: NetworkItem = ctx.items_received[ctx.send_index]
@ -179,8 +183,8 @@ async def factorio_server_watcher(ctx: FactorioContext):
factorio_server_logger.info(f"Sending {item_name} to Nauvis from {player_name}.") factorio_server_logger.info(f"Sending {item_name} to Nauvis from {player_name}.")
ctx.rcon_client.send_command(f'/ap-get-technology {item_name} {player_name}') ctx.rcon_client.send_command(f'/ap-get-technology {item_name} {player_name}')
ctx.send_index += 1 ctx.send_index += 1
await asyncio.sleep(1) await asyncio.sleep(1)
except Exception as e: except Exception as e:
logging.exception(e) logging.exception(e)
logging.error("Aborted Factorio Server Bridge") logging.error("Aborted Factorio Server Bridge")
@ -194,14 +198,13 @@ async def main():
if ctx.server_task is None: if ctx.server_task is None:
ctx.server_task = asyncio.create_task(server_loop(ctx), name="ServerLoop") ctx.server_task = asyncio.create_task(server_loop(ctx), name="ServerLoop")
await asyncio.sleep(3) await asyncio.sleep(3)
watcher_task = asyncio.create_task(game_watcher(ctx), name="FactorioProgressionWatcher")
input_task = asyncio.create_task(console_loop(ctx), name="Input") input_task = asyncio.create_task(console_loop(ctx), name="Input")
factorio_server_task = asyncio.create_task(factorio_server_watcher(ctx), name="FactorioServer") factorio_server_task = asyncio.create_task(factorio_server_watcher(ctx), name="FactorioServer")
await ctx.exit_event.wait() await ctx.exit_event.wait()
ctx.server_address = None ctx.server_address = None
ctx.snes_reconnect_address = None ctx.snes_reconnect_address = None
await asyncio.gather(watcher_task, input_task, factorio_server_task) await asyncio.gather(input_task, factorio_server_task)
if ctx.server is not None and not ctx.server.socket.closed: if ctx.server is not None and not ctx.server.socket.closed:
await ctx.server.socket.close() await ctx.server.socket.close()

View File

@ -170,7 +170,6 @@ def get_default_options() -> dict:
}, },
"factorio_options": { "factorio_options": {
"executable": "factorio\\bin\\x64\\factorio", "executable": "factorio\\bin\\x64\\factorio",
"script-output": "factorio\\script-output",
}, },
"lttp_options": { "lttp_options": {
"rom_file": "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc", "rom_file": "Zelda no Densetsu - Kamigami no Triforce (Japan).sfc",

View File

@ -183,7 +183,7 @@ function dumpInfo(force)
local research_done = {} local research_done = {}
local data_collection = { local data_collection = {
["research_done"] = research_done, ["research_done"] = research_done,
["victory"] = global.forcedata[force.name]["victory"] ["victory"] = chain_lookup(global, "forcedata", force.name, "victory")
} }
for tech_name, tech in pairs(force.technologies) do for tech_name, tech in pairs(force.technologies) do
@ -198,10 +198,24 @@ end
function chain_lookup(table, ...)
for _, k in ipairs{...} do
table = table[k]
if not table then
return nil
end
end
return table
end
-- add / commands -- add / commands
commands.add_command("ap-sync", "Run manual Research Sync with Archipelago.", function(call) commands.add_command("ap-sync", "Run manual Research Sync with Archipelago.", function(call)
dumpInfo(game.players[call.player_index].force) if call.player_index == nil then
dumpInfo(game.forces.player)
else
dumpInfo(game.players[call.player_index].force)
end
game.print("Wrote bridge file.") game.print("Wrote bridge file.")
end) end)

View File

@ -115,4 +115,3 @@ lttp_options:
rom_start: true rom_start: true
factorio_options: factorio_options:
executable: "factorio\\bin\\x64\\factorio" executable: "factorio\\bin\\x64\\factorio"
script-output: "factorio\\script-output"