From a29f93045ecfaea5151c2e02932a30dd71947577 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Tue, 10 Mar 2020 00:38:29 +0100 Subject: [PATCH] performance improvements and small adjustments --- Items.py | 2 -- MultiClient.py | 15 +++++++++++++-- MultiServer.py | 33 +++++++++++++++++++-------------- Patch.py | 9 +++++---- Regions.py | 3 +-- appveyor.yml | 2 +- 6 files changed, 39 insertions(+), 25 deletions(-) diff --git a/Items.py b/Items.py index f46e8488..6c9bbed9 100644 --- a/Items.py +++ b/Items.py @@ -176,8 +176,6 @@ item_table = {'Bow': (True, False, None, 0x0B, 'You have\nchosen the\narcher cla 'Open Floodgate': (True, False, 'Event', None, None, None, None, None, None, None, None), } -lookup_lower_name_to_id = {name.lower(): data[3] for name, data in item_table.items()} -lookup_lower_name_to_name = {name.lower(): name for name in item_table} lookup_id_to_name = {data[3]: name for name, data in item_table.items()} hint_blacklist = {"Triforce"} \ No newline at end of file diff --git a/MultiClient.py b/MultiClient.py index cef4dd99..f96bf63a 100644 --- a/MultiClient.py +++ b/MultiClient.py @@ -953,6 +953,12 @@ async def game_watcher(ctx : Context): await send_msgs(ctx.socket, [['LocationScouts', [scout_location]]]) await track_locations(ctx, roomid, roomdata) + +async def run_game(romfile): + import webbrowser + webbrowser.open(romfile) + + async def main(): parser = argparse.ArgumentParser() parser.add_argument('diff_file', default="", type=str, nargs="?", @@ -962,10 +968,15 @@ async def main(): parser.add_argument('--password', default=None, help='Password of the multiworld host.') parser.add_argument('--loglevel', default='info', choices=['debug', 'info', 'warning', 'error', 'critical']) args = parser.parse_args() + + logging.basicConfig(format='%(message)s', level=getattr(logging, args.loglevel.upper(), logging.INFO)) + if args.diff_file: import Patch - args.connect = Patch.create_rom_file(args.diff_file)["server"] - logging.basicConfig(format='%(message)s', level=getattr(logging, args.loglevel.upper(), logging.INFO)) + meta, romfile = Patch.create_rom_file(args.diff_file) + args.connect = meta["server"] + logging.info(f"Wrote rom file to {romfile}") + asyncio.create_task(run_game(romfile)) ctx = Context(args.snes, args.connect, args.password) diff --git a/MultiServer.py b/MultiServer.py index 6f5f29d4..e4808ff6 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -163,7 +163,7 @@ async def on_client_connected(ctx: Context, client: Client): # tags are for additional features in the communication. # Name them by feature or fork, as you feel is appropriate. 'tags': ['Berserker'], - 'version': [1, 1, 0] + 'version': [1, 2, 0] }]]) async def on_client_disconnected(ctx: Context, client: Client): @@ -271,7 +271,7 @@ def save(ctx: Context): def collect_hints(ctx: Context, team: int, slot: int, item: str) -> typing.List[Utils.Hint]: hints = [] - seeked_item_id = Items.lookup_lower_name_to_id[item.lower()] + seeked_item_id = Items.item_table[item][3] for check, result in ctx.locations.items(): item_id, receiving_player = result if receiving_player == slot and item_id == seeked_item_id: @@ -284,7 +284,6 @@ def collect_hints(ctx: Context, team: int, slot: int, item: str) -> typing.List[ def collect_hints_location(ctx: Context, team: int, slot: int, location: str) -> typing.List[Utils.Hint]: hints = [] - location = Regions.lookup_lower_name_to_name[location.lower()] seeked_location = Regions.location_table[location][0] for check, result in ctx.locations.items(): location_id, finding_player = check @@ -572,7 +571,8 @@ async def console(ctx: Context): import traceback traceback.print_exc() -def forward_port(port: int): + +async def forward_port(port: int): import upnpy import socket @@ -582,7 +582,7 @@ def forward_port(port: int): service = device['WANPPPConnection.1'] - #get own lan IP + # get own lan IP ip = socket.gethostbyname(socket.gethostname()) # This specific action returns an empty dict: {} @@ -621,11 +621,10 @@ async def main(): if value is not None: setattr(args, key, value) logging.basicConfig(format='[%(asctime)s] %(message)s', level=getattr(logging, args.loglevel.upper(), logging.INFO)) + portforwardtask = None if not args.disable_port_forward: - try: - forward_port(args.port) - except: - logging.exception("Automatic port forwarding failed with:") + portforwardtask = asyncio.create_task(forward_port(args.port)) + ctx = Context(args.host, args.port, args.password, args.location_check_points, args.hint_cost, not args.disable_item_cheat) @@ -653,14 +652,13 @@ async def main(): ip = Utils.get_public_ipv4() - logging.info('Hosting game at %s:%d (%s)' % ( - ip, ctx.port, 'No password' if not ctx.password else 'Password: %s' % ctx.password)) + ctx.disable_save = args.disable_save if not ctx.disable_save: if not ctx.save_filename: ctx.save_filename = (ctx.data_filename[:-9] if ctx.data_filename[-9:] == 'multidata' else ( - ctx.data_filename + '_')) + 'multisave' + ctx.data_filename + '_')) + 'multisave' try: with open(ctx.save_filename, 'rb') as f: jsonobj = json.loads(zlib.decompress(f.read()).decode("utf-8")) @@ -669,8 +667,15 @@ async def main(): logging.error('No save data found, starting a new game') except Exception as e: logging.exception(e) - - ctx.server = websockets.serve(functools.partial(server,ctx=ctx), ctx.host, ctx.port, ping_timeout=None, ping_interval=None) + if portforwardtask: + try: + await portforwardtask + except: + logging.exception("Automatic port forwarding failed with:") + ctx.server = websockets.serve(functools.partial(server, ctx=ctx), ctx.host, ctx.port, ping_timeout=None, + ping_interval=None) + logging.info('Hosting game at %s:%d (%s)' % (ip, ctx.port, + 'No password' if not ctx.password else 'Password: %s' % ctx.password)) await ctx.server await console(ctx) diff --git a/Patch.py b/Patch.py index a404ff54..6ebc161a 100644 --- a/Patch.py +++ b/Patch.py @@ -3,7 +3,7 @@ import yaml import os import lzma import hashlib -import logging +from typing import Tuple import Utils from Rom import JAP10HASH, read_rom @@ -45,12 +45,13 @@ def create_patch_file(rom_file_to_patch: str, server: str = "") -> str: return target -def create_rom_file(patch_file) -> dict: +def create_rom_file(patch_file) -> Tuple[dict, str]: data = Utils.parse_yaml(lzma.decompress(load_bytes(patch_file)).decode("utf-8-sig")) patched_data = bsdiff4.patch(get_base_rom_bytes(), data["patch"]) - with open(os.path.splitext(patch_file)[0] + ".sfc", "wb") as f: + target = os.path.splitext(patch_file)[0] + ".sfc" + with open(target, "wb") as f: f.write(patched_data) - return data["meta"] + return data["meta"], target def load_bytes(path: str): diff --git a/Regions.py b/Regions.py index eb482af5..5011b85c 100644 --- a/Regions.py +++ b/Regions.py @@ -621,5 +621,4 @@ location_table = {'Mushroom': (0x180013, 0x186338, False, 'in the woods'), 'Misery Mire - Prize': ([0x120A2, 0x53F48, 0x53F49, 0x180057, 0x180075, 0xC703], None, True, 'Misery Mire'), 'Turtle Rock - Prize': ([0x120A7, 0x53F24, 0x53F25, 0x18005C, 0x180079, 0xC708], None, True, 'Turtle Rock')} -lookup_id_to_name = {data[0] : name for name, data in location_table.items() if type(data[0]) == int} -lookup_lower_name_to_name = {name.lower() : name for name in location_table} +lookup_id_to_name = {data[0] : name for name, data in location_table.items() if type(data[0]) == int} \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index f64e23b6..86182c1f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -22,7 +22,7 @@ deploy: provider: GitHub auth_token: secure: +cRWefLphFutZuzCcCsNS0tl7nNj/IpnJmfht6hZFh2z9eQdFgcu6zwGS3lWItat - artifact: /.*\.zip/ # upload all NuGet packages to release assets + artifact: /.*\.zip/ draft: false prerelease: false on: