From 31a3c1cf332ff758ba8eab79237d4676063b30ba Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Wed, 19 May 2021 21:55:18 +0200 Subject: [PATCH] Add a generic fallback tracker for all games --- Main.py | 2 +- WebHostLib/templates/genericTracker.html | 63 +++++++++++ .../{playerTracker.html => lttpTracker.html} | 0 WebHostLib/tracker.py | 101 ++++++++++-------- 4 files changed, 118 insertions(+), 48 deletions(-) create mode 100644 WebHostLib/templates/genericTracker.html rename WebHostLib/templates/{playerTracker.html => lttpTracker.html} (100%) diff --git a/Main.py b/Main.py index 51eb2040..4008f8f5 100644 --- a/Main.py +++ b/Main.py @@ -414,7 +414,7 @@ def main(args, seed=None): return player, team, bytes(rom.name) pool = concurrent.futures.ThreadPoolExecutor() - multidata_task = None + check_accessibility_task = pool.submit(world.fulfills_accessibility) rom_futures = [] diff --git a/WebHostLib/templates/genericTracker.html b/WebHostLib/templates/genericTracker.html new file mode 100644 index 00000000..6594c10d --- /dev/null +++ b/WebHostLib/templates/genericTracker.html @@ -0,0 +1,63 @@ +{% extends 'tablepage.html' %} +{% block head %} + {{ super() }} + {{ player_name }}'s Tracker + + + +{% endblock %} + +{% block body %} + {% include 'header/dirtHeader.html' %} +
+
+ + This tracker will automatically update itself periodically. +
+
+ + + + + + + + + + {% for name, count in acquired_items.items() %} + + + + + {%- endfor -%} + + +
ItemAmount
{{ name }}{{ count }}
+
+
+ + + + + + + + + {% for name in checked_locations %} + + + + + {%- endfor -%} + {% for name in not_checked_locations %} + + + + + {%- endfor -%} + +
LocationChecked
{{ name | location_name}}
{{ name | location_name}}
+
+
+ +{% endblock %} diff --git a/WebHostLib/templates/playerTracker.html b/WebHostLib/templates/lttpTracker.html similarity index 100% rename from WebHostLib/templates/playerTracker.html rename to WebHostLib/templates/lttpTracker.html diff --git a/WebHostLib/tracker.py b/WebHostLib/tracker.py index 9ee5cd42..9f1a3aef 100644 --- a/WebHostLib/tracker.py +++ b/WebHostLib/tracker.py @@ -5,7 +5,7 @@ from werkzeug.exceptions import abort import datetime from uuid import UUID -from worlds.alttp import Items, Regions +from worlds.alttp import Items from WebHostLib import app, cache, Room from Utils import restricted_loads from worlds import lookup_any_item_id_to_name, lookup_any_location_id_to_name @@ -327,7 +327,8 @@ def get_static_room_data(room: Room): player_small_key_locations[item_player].add(ids_small_key[item_id]) result = locations, names, use_door_tracker, player_checks_in_area, player_location_to_area, \ - player_big_key_locations, player_small_key_locations, multidata["precollected_items"] + player_big_key_locations, player_small_key_locations, multidata["precollected_items"], \ + multidata["games"] _multidata_cache[room.seed.id] = result return result @@ -344,9 +345,9 @@ def getPlayerTracker(tracker: UUID, tracked_team: int, tracked_player: int): abort(404) # Collect seed information and pare it down to a single player - locations, names, use_door_tracker, seed_checks_in_area, player_location_to_area, player_big_key_locations, player_small_key_locations, precollected_items = get_static_room_data(room) + locations, names, use_door_tracker, seed_checks_in_area, player_location_to_area, \ + player_big_key_locations, player_small_key_locations, precollected_items, games = get_static_room_data(room) player_name = names[tracked_team][tracked_player - 1] - seed_checks_in_area = seed_checks_in_area[tracked_player] location_to_area = player_location_to_area[tracked_player] inventory = collections.Counter() checks_done = {loc_name: 0 for loc_name in default_locations} @@ -361,6 +362,7 @@ def getPlayerTracker(tracker: UUID, tracked_team: int, tracked_player: int): multisave = restricted_loads(room.multisave) else: multisave = {} + checked_locations = set() # Add items to player inventory for (ms_team, ms_player), locations_checked in multisave.get("location_checks", {}).items(): @@ -368,6 +370,7 @@ def getPlayerTracker(tracker: UUID, tracked_team: int, tracked_player: int): # Skip teams and players not matching the request player_locations = locations[ms_player] if ms_team == tracked_team: + checked_locations = locations_checked # If the player does not have the item, do nothing for location in locations_checked: if location in player_locations: @@ -377,52 +380,57 @@ def getPlayerTracker(tracker: UUID, tracked_team: int, tracked_player: int): if ms_player == tracked_player: # a check done by the tracked player checks_done[location_to_area[location]] += 1 checks_done["Total"] += 1 + if games[tracked_player] == "A Link to the Past": + # Note the presence of the triforce item + game_state = multisave.get("client_game_state", {}).get((tracked_team, tracked_player), 0) + if game_state == 30: + inventory[106] = 1 # Triforce - # Note the presence of the triforce item - game_state = multisave.get("client_game_state", {}).get((tracked_team, tracked_player), 0) - if game_state == 30: - inventory[106] = 1 # Triforce + # Progressive items need special handling for icons and class + progressive_items = { + "Progressive Sword": 94, + "Progressive Glove": 97, + "Progressive Bow": 100, + "Progressive Mail": 96, + "Progressive Shield": 95, + } + progressive_names = { + "Progressive Sword": [None, 'Fighter Sword', 'Master Sword', 'Tempered Sword', 'Golden Sword'], + "Progressive Glove": [None, 'Power Glove', 'Titan Mitts'], + "Progressive Bow": [None, "Bow", "Silver Bow"], + "Progressive Mail": ["Green Mail", "Blue Mail", "Red Mail"], + "Progressive Shield": [None, "Blue Shield", "Red Shield", "Mirror Shield"] + } - # Progressive items need special handling for icons and class - progressive_items = { - "Progressive Sword": 94, - "Progressive Glove": 97, - "Progressive Bow": 100, - "Progressive Mail": 96, - "Progressive Shield": 95, - } - progressive_names = { - "Progressive Sword": [None, 'Fighter Sword', 'Master Sword', 'Tempered Sword', 'Golden Sword'], - "Progressive Glove": [None, 'Power Glove', 'Titan Mitts'], - "Progressive Bow": [None, "Bow", "Silver Bow"], - "Progressive Mail": ["Green Mail", "Blue Mail", "Red Mail"], - "Progressive Shield": [None, "Blue Shield", "Red Shield", "Mirror Shield"] - } - - # Determine which icon to use - display_data = {} - for item_name, item_id in progressive_items.items(): - level = min(inventory[item_id], len(progressive_names[item_name])) - display_name = progressive_names[item_name][level] - acquired = True - if not display_name: - acquired = False - display_name = progressive_names[item_name][level+1] - base_name = item_name.split(maxsplit=1)[1].lower() - display_data[base_name+"_acquired"] = acquired - display_data[base_name+"_url"] = icons[display_name] + # Determine which icon to use + display_data = {} + for item_name, item_id in progressive_items.items(): + level = min(inventory[item_id], len(progressive_names[item_name])) + display_name = progressive_names[item_name][level] + acquired = True + if not display_name: + acquired = False + display_name = progressive_names[item_name][level+1] + base_name = item_name.split(maxsplit=1)[1].lower() + display_data[base_name+"_acquired"] = acquired + display_data[base_name+"_url"] = icons[display_name] - # The single player tracker doesn't care about overworld, underworld, and total checks. Maybe it should? - sp_areas = ordered_areas[2:15] + # The single player tracker doesn't care about overworld, underworld, and total checks. Maybe it should? + sp_areas = ordered_areas[2:15] - return render_template("playerTracker.html", inventory=inventory, get_item_name_from_id=get_item_name_from_id, - player_name=player_name, room=room, icons=icons, checks_done=checks_done, - checks_in_area=seed_checks_in_area, acquired_items={lookup_any_item_id_to_name[id] for id in inventory}, - small_key_ids=small_key_ids, big_key_ids=big_key_ids, sp_areas=sp_areas, - key_locations=player_small_key_locations[tracked_player], - big_key_locations=player_big_key_locations[tracked_player], - **display_data) + return render_template("lttpTracker.html", inventory=inventory, + player_name=player_name, room=room, icons=icons, checks_done=checks_done, + checks_in_area=seed_checks_in_area[tracked_player], acquired_items={lookup_any_item_id_to_name[id] for id in inventory}, + small_key_ids=small_key_ids, big_key_ids=big_key_ids, sp_areas=sp_areas, + key_locations=player_small_key_locations[tracked_player], + big_key_locations=player_big_key_locations[tracked_player], + **display_data) + else: + return render_template("genericTracker.html", + acquired_items={lookup_any_item_id_to_name[id]: count for id, count in inventory.items()}, + player=tracked_player, team=tracked_team, room=room, player_name=player_name, + checked_locations= checked_locations, not_checked_locations = set(locations[tracked_player])-checked_locations) @app.route('/tracker/') @@ -432,7 +440,7 @@ def getTracker(tracker: UUID): if not room: abort(404) locations, names, use_door_tracker, seed_checks_in_area, player_location_to_area, player_big_key_locations, \ - player_small_key_locations, precollected_items = get_static_room_data(room) + player_small_key_locations, precollected_items, games = get_static_room_data(room) inventory = {teamnumber: {playernumber: collections.Counter() for playernumber in range(1, len(team) + 1)} for teamnumber, team in enumerate(names)} @@ -447,7 +455,6 @@ def getTracker(tracker: UUID): else: multisave = {} if "hints" in multisave: - for (team, slot), slot_hints in multisave["hints"].items(): hints[team] |= set(slot_hints)