Factorio: RIP Bridge File
This commit is contained in:
parent
8030db03ad
commit
85ce2aff47
|
@ -72,7 +72,6 @@ class FactorioContext(CommonContext):
|
||||||
self.awaiting_bridge = False
|
self.awaiting_bridge = False
|
||||||
self.raw_json_text_parser = RawJSONtoTextParser(self)
|
self.raw_json_text_parser = RawJSONtoTextParser(self)
|
||||||
self.factorio_json_text_parser = FactorioJSONtoTextParser(self)
|
self.factorio_json_text_parser = FactorioJSONtoTextParser(self)
|
||||||
self.bridge_file = None
|
|
||||||
|
|
||||||
async def server_auth(self, password_requested):
|
async def server_auth(self, password_requested):
|
||||||
if password_requested and not self.password:
|
if password_requested and not self.password:
|
||||||
|
@ -110,27 +109,31 @@ class FactorioContext(CommonContext):
|
||||||
async def game_watcher(ctx: FactorioContext):
|
async def game_watcher(ctx: FactorioContext):
|
||||||
bridge_logger = logging.getLogger("FactorioWatcher")
|
bridge_logger = logging.getLogger("FactorioWatcher")
|
||||||
from worlds.factorio.Technologies import lookup_id_to_name
|
from worlds.factorio.Technologies import lookup_id_to_name
|
||||||
bridge_file = ctx.bridge_file
|
|
||||||
try:
|
try:
|
||||||
while not ctx.exit_event.is_set():
|
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
|
ctx.awaiting_bridge = False
|
||||||
with open(bridge_file) as f:
|
data = json.loads(ctx.rcon_client.send_command("/ap-sync"))
|
||||||
data = json.load(f)
|
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 = data["research_done"]
|
||||||
research_data = {int(tech_name.split("-")[1]) for tech_name in research_data}
|
research_data = {int(tech_name.split("-")[1]) for tech_name in research_data}
|
||||||
victory = data["victory"]
|
victory = data["victory"]
|
||||||
|
|
||||||
if not ctx.finished_game and victory:
|
if not ctx.finished_game and victory:
|
||||||
await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}])
|
await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}])
|
||||||
ctx.finished_game = True
|
ctx.finished_game = True
|
||||||
|
|
||||||
if ctx.locations_checked != research_data:
|
if ctx.locations_checked != research_data:
|
||||||
bridge_logger.info(
|
bridge_logger.info(
|
||||||
f"New researches done: "
|
f"New researches done: "
|
||||||
f"{[lookup_id_to_name[rid] for rid in research_data - ctx.locations_checked]}")
|
f"{[lookup_id_to_name[rid] for rid in research_data - ctx.locations_checked]}")
|
||||||
ctx.locations_checked = research_data
|
ctx.locations_checked = research_data
|
||||||
await ctx.send_msgs([{"cmd": 'LocationChecks', "locations": tuple(research_data)}])
|
await ctx.send_msgs([{"cmd": 'LocationChecks', "locations": tuple(research_data)}])
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -183,8 +186,7 @@ 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 ctx.awaiting_bridge and "Archipelago Bridge Data available for game tick " in msg:
|
||||||
if not ctx.awaiting_bridge and "Archipelago Bridge File written for game tick " in msg:
|
|
||||||
ctx.awaiting_bridge = True
|
ctx.awaiting_bridge = True
|
||||||
if ctx.rcon_client:
|
if ctx.rcon_client:
|
||||||
while ctx.send_index < len(ctx.items_received):
|
while ctx.send_index < len(ctx.items_received):
|
||||||
|
@ -233,10 +235,9 @@ async def factorio_spinup_server(ctx: FactorioContext):
|
||||||
factorio_queue = Queue()
|
factorio_queue = Queue()
|
||||||
stream_factorio_output(factorio_process.stdout, factorio_queue, factorio_process)
|
stream_factorio_output(factorio_process.stdout, factorio_queue, factorio_process)
|
||||||
stream_factorio_output(factorio_process.stderr, factorio_queue, factorio_process)
|
stream_factorio_output(factorio_process.stderr, factorio_queue, factorio_process)
|
||||||
write_folder = None
|
|
||||||
rcon_client = None
|
rcon_client = None
|
||||||
try:
|
try:
|
||||||
while not ctx.auth or not write_folder:
|
while not ctx.auth:
|
||||||
while not factorio_queue.empty():
|
while not factorio_queue.empty():
|
||||||
msg = factorio_queue.get()
|
msg = factorio_queue.get()
|
||||||
factorio_server_logger.info(msg)
|
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)
|
rcon_client = factorio_rcon.RCONClient("localhost", rcon_port, rcon_password)
|
||||||
get_info(ctx, rcon_client)
|
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)
|
await asyncio.sleep(0.01)
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ class FactorioManager(App):
|
||||||
pairs = [
|
pairs = [
|
||||||
("Client", "Archipelago"),
|
("Client", "Archipelago"),
|
||||||
("FactorioServer", "Factorio Server Log"),
|
("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))
|
self.tabs.default_tab_content = UILog(*(logging.getLogger(logger_name) for logger_name, name in pairs))
|
||||||
for logger_name, display_name in pairs:
|
for logger_name, display_name in pairs:
|
||||||
|
|
|
@ -141,13 +141,6 @@ script.on_init(function()
|
||||||
end
|
end
|
||||||
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
|
-- hook into researches done
|
||||||
script.on_event(defines.events.on_research_finished, function(event)
|
script.on_event(defines.events.on_research_finished, function(event)
|
||||||
local technology = event.research
|
local technology = event.research
|
||||||
|
@ -185,26 +178,12 @@ script.on_event(defines.events.on_research_finished, function(event)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
function dumpInfo(force)
|
function dumpInfo(force)
|
||||||
local research_done = {}
|
log("Archipelago Bridge Data available for game tick ".. game.tick .. ".") -- notifies client
|
||||||
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.")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function chain_lookup(table, ...)
|
function chain_lookup(table, ...)
|
||||||
for _, k in ipairs{...} do
|
for _, k in ipairs{...} do
|
||||||
table = table[k]
|
table = table[k]
|
||||||
|
@ -215,17 +194,30 @@ function chain_lookup(table, ...)
|
||||||
return table
|
return table
|
||||||
end
|
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
|
if call.player_index == nil then
|
||||||
dumpInfo(game.forces.player)
|
force = game.forces.player
|
||||||
else
|
else
|
||||||
dumpInfo(game.players[call.player_index].force)
|
force = game.players[call.player_index].force
|
||||||
end
|
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)
|
end)
|
||||||
|
|
||||||
|
|
||||||
commands.add_command("ap-get-technology", "Grant a technology, used by the Archipelago Client.", function(call)
|
commands.add_command("ap-get-technology", "Grant a technology, used by the Archipelago Client.", function(call)
|
||||||
local force = game.forces["player"]
|
local force = game.forces["player"]
|
||||||
chunks = {}
|
chunks = {}
|
||||||
|
@ -246,6 +238,7 @@ commands.add_command("ap-get-technology", "Grant a technology, used by the Archi
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
commands.add_command("ap-rcon-info", "Used by the Archipelago client to get information", function(call)
|
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}))
|
rcon.print(game.table_to_json({["slot_name"] = SLOT_NAME, ["seed_name"] = SEED_NAME}))
|
||||||
end)
|
end)
|
Loading…
Reference in New Issue