allow Factorio Client to recognize if it's trying to connect to the wrong multiworld.
This commit is contained in:
parent
8e27ad3547
commit
3e1941a561
|
@ -44,6 +44,7 @@ class MultiWorld():
|
|||
self.shops = []
|
||||
self.itempool = []
|
||||
self.seed = None
|
||||
self.seed_name: str = "Unavailable"
|
||||
self.precollected_items = []
|
||||
self.state = CollectionState(self)
|
||||
self._cached_entrances = None
|
||||
|
|
|
@ -112,6 +112,7 @@ class CommonContext():
|
|||
self.team = None
|
||||
self.slot = None
|
||||
self.auth = None
|
||||
self.seed_name = None
|
||||
|
||||
self.locations_checked: typing.Set[int] = set()
|
||||
self.locations_scouted: typing.Set[int] = set()
|
||||
|
@ -278,39 +279,42 @@ async def process_server_cmd(ctx: CommonContext, args: dict):
|
|||
logger.exception(f"Could not get command from {args}")
|
||||
raise
|
||||
if cmd == 'RoomInfo':
|
||||
logger.info('--------------------------------')
|
||||
logger.info('Room Information:')
|
||||
logger.info('--------------------------------')
|
||||
version = args["version"]
|
||||
ctx.server_version = tuple(version)
|
||||
version = ".".join(str(item) for item in version)
|
||||
|
||||
logger.info(f'Server protocol version: {version}')
|
||||
logger.info("Server protocol tags: " + ", ".join(args["tags"]))
|
||||
if args['password']:
|
||||
logger.info('Password required')
|
||||
logger.info(f"Forfeit setting: {args['forfeit_mode']}")
|
||||
logger.info(f"Remaining setting: {args['remaining_mode']}")
|
||||
logger.info(f"A !hint costs {args['hint_cost']}% of checks points and you get {args['location_check_points']}"
|
||||
f" for each location checked. Use !hint for more information.")
|
||||
ctx.hint_cost = int(args['hint_cost'])
|
||||
ctx.check_points = int(args['location_check_points'])
|
||||
ctx.forfeit_mode = args['forfeit_mode']
|
||||
ctx.remaining_mode = args['remaining_mode']
|
||||
if len(args['players']) < 1:
|
||||
logger.info('No player connected')
|
||||
if ctx.seed_name and ctx.seed_name != args["seed_name"]:
|
||||
logger.info("The server is running a different multiworld than your client is. (invalid seed_name)")
|
||||
else:
|
||||
args['players'].sort()
|
||||
current_team = -1
|
||||
logger.info('Players:')
|
||||
for network_player in args['players']:
|
||||
if network_player.team != current_team:
|
||||
logger.info(f' Team #{network_player.team + 1}')
|
||||
current_team = network_player.team
|
||||
logger.info(' %s (Player %d)' % (network_player.alias, network_player.slot))
|
||||
if args["datapackage_version"] > network_data_package["version"] or args["datapackage_version"] == 0:
|
||||
await ctx.send_msgs([{"cmd": "GetDataPackage"}])
|
||||
await ctx.server_auth(args['password'])
|
||||
logger.info('--------------------------------')
|
||||
logger.info('Room Information:')
|
||||
logger.info('--------------------------------')
|
||||
version = args["version"]
|
||||
ctx.server_version = tuple(version)
|
||||
version = ".".join(str(item) for item in version)
|
||||
|
||||
logger.info(f'Server protocol version: {version}')
|
||||
logger.info("Server protocol tags: " + ", ".join(args["tags"]))
|
||||
if args['password']:
|
||||
logger.info('Password required')
|
||||
logger.info(f"Forfeit setting: {args['forfeit_mode']}")
|
||||
logger.info(f"Remaining setting: {args['remaining_mode']}")
|
||||
logger.info(f"A !hint costs {args['hint_cost']}% of checks points and you get {args['location_check_points']}"
|
||||
f" for each location checked. Use !hint for more information.")
|
||||
ctx.hint_cost = int(args['hint_cost'])
|
||||
ctx.check_points = int(args['location_check_points'])
|
||||
ctx.forfeit_mode = args['forfeit_mode']
|
||||
ctx.remaining_mode = args['remaining_mode']
|
||||
if len(args['players']) < 1:
|
||||
logger.info('No player connected')
|
||||
else:
|
||||
args['players'].sort()
|
||||
current_team = -1
|
||||
logger.info('Players:')
|
||||
for network_player in args['players']:
|
||||
if network_player.team != current_team:
|
||||
logger.info(f' Team #{network_player.team + 1}')
|
||||
current_team = network_player.team
|
||||
logger.info(' %s (Player %d)' % (network_player.alias, network_player.slot))
|
||||
if args["datapackage_version"] > network_data_package["version"] or args["datapackage_version"] == 0:
|
||||
await ctx.send_msgs([{"cmd": "GetDataPackage"}])
|
||||
await ctx.server_auth(args['password'])
|
||||
|
||||
elif cmd == 'DataPackage':
|
||||
logger.info("Got new ID/Name Datapackage")
|
||||
|
|
|
@ -107,6 +107,7 @@ async def game_watcher(ctx: FactorioContext, bridge_file: str):
|
|||
research_data = {int(tech_name.split("-")[1]) for tech_name in research_data}
|
||||
victory = data["victory"]
|
||||
ctx.auth = data["slot_name"]
|
||||
ctx.seed_name = data["seed_name"]
|
||||
|
||||
if not ctx.finished_game and victory:
|
||||
await ctx.send_msgs([{"cmd": "StatusUpdate", "status": ClientStatus.CLIENT_GOAL}])
|
||||
|
|
10
Main.py
10
Main.py
|
@ -67,6 +67,7 @@ def main(args, seed=None):
|
|||
world.secure()
|
||||
else:
|
||||
world.random.seed(world.seed)
|
||||
world.seed_name = str(args.outputname if args.outputname else world.seed)
|
||||
|
||||
world.shuffle = args.shuffle.copy()
|
||||
world.logic = args.logic.copy()
|
||||
|
@ -314,7 +315,7 @@ def main(args, seed=None):
|
|||
balance_multiworld_progression(world)
|
||||
|
||||
logger.info('Generating output files.')
|
||||
outfilebase = 'AP_%s' % (args.outputname if args.outputname else world.seed)
|
||||
outfilebase = 'AP_' + world.seed_name
|
||||
rom_names = []
|
||||
|
||||
def _gen_rom(team: int, player: int):
|
||||
|
@ -422,8 +423,7 @@ def main(args, seed=None):
|
|||
for player in world.alttp_player_ids:
|
||||
rom_futures.append(pool.submit(_gen_rom, team, player))
|
||||
for player in world.factorio_player_ids:
|
||||
mod_futures.append(pool.submit(generate_mod, world, player,
|
||||
str(args.outputname if args.outputname else world.seed)))
|
||||
mod_futures.append(pool.submit(generate_mod, world, player))
|
||||
|
||||
def get_entrance_to_region(region: Region):
|
||||
for entrance in region.entrances:
|
||||
|
@ -559,7 +559,7 @@ def main(args, seed=None):
|
|||
"version": tuple(_version_tuple),
|
||||
"tags": ["AP"],
|
||||
"minimum_versions": minimum_versions,
|
||||
"seed_name": str(args.outputname if args.outputname else world.seed)
|
||||
"seed_name": world.seed_name
|
||||
}), 9)
|
||||
|
||||
with open(output_path('%s.archipelago' % outfilebase), 'wb') as f:
|
||||
|
@ -578,7 +578,7 @@ def main(args, seed=None):
|
|||
multidata_task.result() # retrieve exception if one exists
|
||||
pool.shutdown() # wait for all queued tasks to complete
|
||||
for player in world.minecraft_player_ids: # Doing this after shutdown prevents the .apmc from being generated if there's an error
|
||||
generate_mc_data(world, player, str(args.outputname if args.outputname else world.seed))
|
||||
generate_mc_data(world, player)
|
||||
if not args.skip_playthrough:
|
||||
logger.info('Calculating playthrough.')
|
||||
create_playthrough(world)
|
||||
|
|
|
@ -43,7 +43,7 @@ class Client(Endpoint):
|
|||
version = Version(0, 0, 0)
|
||||
tags: typing.List[str] = []
|
||||
|
||||
def __init__(self, socket: websockets.server.WebSocketServerProtocol, ctx: Context):
|
||||
def __init__(self, socket: websockets.WebSocketServerProtocol, ctx: Context):
|
||||
super().__init__(socket)
|
||||
self.auth = False
|
||||
self.name = None
|
||||
|
|
|
@ -10,6 +10,7 @@ require "util"
|
|||
|
||||
FREE_SAMPLES = {{ free_samples }}
|
||||
SLOT_NAME = "{{ slot_name }}"
|
||||
SEED_NAME = "{{ seed_name }}"
|
||||
--SUPPRESS_INVENTORY_EVENTS = false
|
||||
|
||||
-- Initialize force data, either from it being created or already being part of the game when the mod was added.
|
||||
|
@ -180,7 +181,8 @@ function dumpInfo(force)
|
|||
local data_collection = {
|
||||
["research_done"] = research_done,
|
||||
["victory"] = chain_lookup(global, "forcedata", force.name, "victory"),
|
||||
["slot_name"] = SLOT_NAME
|
||||
["slot_name"] = SLOT_NAME,
|
||||
["seed_name"] = SEED_NAME
|
||||
}
|
||||
|
||||
for tech_name, tech in pairs(force.technologies) do
|
||||
|
|
|
@ -46,7 +46,7 @@ rocket_recipes = {
|
|||
'{{"copper-cable", 10}, {"iron-plate", 10}, {"wood", 10}}'
|
||||
}
|
||||
|
||||
def generate_mod(world: MultiWorld, player: int, seedname: str):
|
||||
def generate_mod(world: MultiWorld, player: int):
|
||||
global template, locale_template, control_template
|
||||
with template_load_lock:
|
||||
if not template:
|
||||
|
@ -59,7 +59,7 @@ def generate_mod(world: MultiWorld, player: int, seedname: str):
|
|||
locations = []
|
||||
for location in world.get_filled_locations(player):
|
||||
locations.append((location.name, location.item.name, location.item.player))
|
||||
mod_name = f"AP-{seedname}-P{player}-{world.player_names[player][0]}"
|
||||
mod_name = f"AP-{world.seed_name}-P{player}-{world.player_names[player][0]}"
|
||||
tech_cost = {0: 0.1,
|
||||
1: 0.25,
|
||||
2: 0.5,
|
||||
|
@ -72,10 +72,12 @@ def generate_mod(world: MultiWorld, player: int, seedname: str):
|
|||
"tech_cost_scale": tech_cost, "custom_data": world.custom_data[player],
|
||||
"tech_tree_layout_prerequisites": world.tech_tree_layout_prerequisites[player],
|
||||
"rocket_recipe" : rocket_recipes[world.max_science_pack[player].value],
|
||||
"slot_name": world.player_names[player][0],
|
||||
"slot_name": world.player_names[player][0], "seed_name": world.seed_name,
|
||||
"starting_items": world.starting_items[player]}
|
||||
|
||||
for factorio_option in Options.factorio_options:
|
||||
template_data[factorio_option] = getattr(world, factorio_option)[player].value
|
||||
|
||||
control_code = control_template.render(**template_data)
|
||||
data_final_fixes_code = template.render(**template_data)
|
||||
|
||||
|
|
|
@ -9,20 +9,21 @@ from Options import minecraft_options
|
|||
|
||||
client_version = (0, 3)
|
||||
|
||||
def generate_mc_data(world: MultiWorld, player: int, seedname: str):
|
||||
def generate_mc_data(world: MultiWorld, player: int):
|
||||
import base64, json
|
||||
from Utils import output_path
|
||||
|
||||
exits = ["Overworld Structure 1", "Overworld Structure 2", "Nether Structure 1", "Nether Structure 2", "The End Structure"]
|
||||
data = {
|
||||
'world_seed': Random(world.rom_seeds[player]).getrandbits(32), # consistent and doesn't interfere with other generation
|
||||
'seed_name': seedname,
|
||||
'seed_name': world.seed_name,
|
||||
'player_name': world.get_player_names(player),
|
||||
'player_id': player,
|
||||
'client_version': client_version,
|
||||
'structures': {exit: world.get_entrance(exit, player).connected_region.name for exit in exits}
|
||||
}
|
||||
|
||||
filename = f"AP_{seedname}_P{player}_{world.get_player_names(player)}.apmc"
|
||||
filename = f"AP_{world.seed_name}_P{player}_{world.get_player_names(player)}.apmc"
|
||||
with open(output_path(filename), 'wb') as f:
|
||||
f.write(base64.b64encode(bytes(json.dumps(data), 'utf-8')))
|
||||
|
||||
|
|
Loading…
Reference in New Issue