diff --git a/WebHostLib/tracker.py b/WebHostLib/tracker.py index c0b83e4d..4565f608 100644 --- a/WebHostLib/tracker.py +++ b/WebHostLib/tracker.py @@ -5,6 +5,7 @@ from typing import Counter, Optional, Dict, Any, Tuple from uuid import UUID from flask import render_template +from jinja2 import pass_context, runtime from werkzeug.exceptions import abort from MultiServer import Context, get_saving_second @@ -83,9 +84,6 @@ def get_alttp_id(item_name): return Items.item_table[item_name][2] -app.jinja_env.filters["location_name"] = lambda location: lookup_any_location_id_to_name.get(location, location) -app.jinja_env.filters['item_name'] = lambda id: lookup_any_item_id_to_name.get(id, id) - links = {"Bow": "Progressive Bow", "Silver Arrows": "Progressive Bow", "Silver Bow": "Progressive Bow", @@ -237,6 +235,22 @@ def render_timedelta(delta: datetime.timedelta): return f"{hours}:{minutes}" +@pass_context +def get_location_name(context: runtime.Context, loc: int) -> str: + context_locations = context.get("custom_locations", {}) + return collections.ChainMap(lookup_any_location_id_to_name, context_locations).get(loc, loc) + + +@pass_context +def get_item_name(context: runtime.Context, item: int) -> str: + context_items = context.get("custom_items", {}) + return collections.ChainMap(lookup_any_item_id_to_name, context_items).get(item, item) + + +app.jinja_env.filters["location_name"] = get_location_name +app.jinja_env.filters["item_name"] = get_item_name + + _multidata_cache = {} @@ -258,10 +272,23 @@ def get_static_room_data(room: Room): # in > 100 players this can take a bit of time and is the main reason for the cache locations: Dict[int, Dict[int, Tuple[int, int, int]]] = multidata['locations'] names: Dict[int, Dict[int, str]] = multidata["names"] + games = {} groups = {} + custom_locations = {} + custom_items = {} if "slot_info" in multidata: + games = {slot: slot_info.game for slot, slot_info in multidata["slot_info"].items()} groups = {slot: slot_info.group_members for slot, slot_info in multidata["slot_info"].items() if slot_info.type == SlotType.group} + + for game in games.values(): + if game in multidata["datapackage"]: + custom_locations.update( + {id: name for name, id in multidata["datapackage"][game]["location_name_to_id"].items()}) + custom_items.update( + {id: name for name, id in multidata["datapackage"][game]["item_name_to_id"].items()}) + elif "games" in multidata: + games = multidata["games"] seed_checks_in_area = checks_in_area.copy() use_door_tracker = False @@ -282,7 +309,8 @@ def get_static_room_data(room: Room): if playernumber not in groups} saving_second = get_saving_second(multidata["seed_name"]) result = locations, names, use_door_tracker, player_checks_in_area, player_location_to_area, \ - multidata["precollected_items"], multidata["games"], multidata["slot_data"], groups, saving_second + multidata["precollected_items"], games, multidata["slot_data"], groups, saving_second, \ + custom_locations, custom_items _multidata_cache[room.seed.id] = result return result @@ -309,7 +337,8 @@ def _get_player_tracker(tracker: UUID, tracked_team: int, tracked_player: int, w # Collect seed information and pare it down to a single player locations, names, use_door_tracker, seed_checks_in_area, player_location_to_area, \ - precollected_items, games, slot_data, groups, saving_second = get_static_room_data(room) + precollected_items, games, slot_data, groups, saving_second, custom_locations, custom_items = \ + get_static_room_data(room) player_name = names[tracked_team][tracked_player - 1] location_to_area = player_location_to_area[tracked_player] inventory = collections.Counter() @@ -351,7 +380,7 @@ def _get_player_tracker(tracker: UUID, tracked_team: int, tracked_player: int, w seed_checks_in_area, checks_done, slot_data[tracked_player], saving_second) else: tracker = __renderGenericTracker(multisave, room, locations, inventory, tracked_team, tracked_player, player_name, - seed_checks_in_area, checks_done, saving_second) + seed_checks_in_area, checks_done, saving_second, custom_locations, custom_items) return (saving_second - datetime.datetime.now().second) % 60 or 60, tracker @@ -1194,7 +1223,7 @@ def __renderSC2WoLTracker(multisave: Dict[str, Any], room: Room, locations: Dict def __renderGenericTracker(multisave: Dict[str, Any], room: Room, locations: Dict[int, Dict[int, Tuple[int, int, int]]], inventory: Counter, team: int, player: int, playerName: str, seed_checks_in_area: Dict[int, Dict[str, int]], checks_done: Dict[str, int], - saving_second: int) -> str: + saving_second: int, custom_locations: Dict[int, str], custom_items: Dict[int, str]) -> str: checked_locations = multisave.get("location_checks", {}).get((team, player), set()) player_received_items = {} @@ -1212,8 +1241,8 @@ def __renderGenericTracker(multisave: Dict[str, Any], room: Room, locations: Dic player=player, team=team, room=room, player_name=playerName, checked_locations=checked_locations, not_checked_locations=set(locations[player]) - checked_locations, - received_items=player_received_items, - saving_second=saving_second) + received_items=player_received_items, saving_second=saving_second, + custom_items=custom_items, custom_locations=custom_locations) @app.route('/tracker/') @@ -1223,7 +1252,8 @@ def getTracker(tracker: UUID): if not room: abort(404) locations, names, use_door_tracker, seed_checks_in_area, player_location_to_area, \ - precollected_items, games, slot_data, groups, saving_second = get_static_room_data(room) + precollected_items, games, slot_data, groups, saving_second, custom_locations, custom_items = \ + get_static_room_data(room) inventory = {teamnumber: {playernumber: collections.Counter() for playernumber in range(1, len(team) + 1) if playernumber not in groups} for teamnumber, team in enumerate(names)}