Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webhost: Sphere Tracker #3412

Merged
merged 7 commits into from
Jun 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion WebHostLib/templates/hostRoom.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
<br />
{% endif %}
{% if room.tracker %}
This room has a <a href="{{ url_for("get_multiworld_tracker", tracker=room.tracker) }}">Multiworld Tracker</a> enabled.
This room has a <a href="{{ url_for("get_multiworld_tracker", tracker=room.tracker) }}">Multiworld Tracker</a>
and a <a href="{{ url_for("get_multiworld_sphere_tracker", tracker=room.tracker) }}">Sphere Tracker</a> enabled.
<br />
{% endif %}
The server for this room will be paused after {{ room.timeout//60//60 }} hours of inactivity.
Expand Down
72 changes: 72 additions & 0 deletions WebHostLib/templates/multispheretracker.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
{% extends "tablepage.html" %}
{% block head %}
{{ super() }}
<title>Multiworld Sphere Tracker</title>
<link rel="stylesheet" type="text/css" href="{{ url_for("static", filename="styles/tracker.css") }}" />
<script type="application/ecmascript" src="{{ url_for("static", filename="assets/trackerCommon.js") }}"></script>
{% endblock %}

{% block body %}
{% include "header/dirtHeader.html" %}

<div id="tracker-wrapper" data-tracker="{{ room.tracker | suuid }}">
<div id="tracker-header-bar">
<input placeholder="Search" id="search" />

<div class="info">
{% if tracker_data.get_spheres() %}
This tracker lists already found locations by their logical access sphere.
It ignores items that cannot be sent
and will therefore differ from the sphere numbers in the spoiler playthrough.
This tracker will automatically update itself periodically.
{% else %}
This Multiworld has no Sphere data, likely due to being too old, cannot display data.
{% endif %}
</div>
</div>

<div id="tables-container">
{%- for team, players in tracker_data.get_all_players().items() %}
<div class="table-wrapper">
<table id="checks-table" class="table non-unique-item-table">
<thead>
<tr>
<th>Sphere</th>
{#- Mimicking hint table header for familiarity. #}
<th>Finder</th>
<th>Receiver</th>
<th>Item</th>
<th>Location</th>
<th>Game</th>
</tr>
</thead>
<tbody>
{%- for sphere in tracker_data.get_spheres() %}
{%- set current_sphere = loop.index %}
{%- for player, sphere_location_ids in sphere.items() %}
{%- set checked_locations = tracker_data.get_player_checked_locations(team, player) %}
{%- set finder_game = tracker_data.get_player_game(team, player) %}
{%- set player_location_data = tracker_data.get_player_locations(team, player) %}
{%- for location_id in sphere_location_ids.intersection(checked_locations) %}
<tr>
{%- set item_id, receiver, item_flags = player_location_data[location_id] %}
{%- set receiver_game = tracker_data.get_player_game(team, receiver) %}
<td>{{ current_sphere }}</td>
<td>{{ tracker_data.get_player_name(team, player) }}</td>
<td>{{ tracker_data.get_player_name(team, receiver) }}</td>
<td>{{ tracker_data.item_id_to_name[receiver_game][item_id] }}</td>
<td>{{ tracker_data.location_id_to_name[finder_game][location_id] }}</td>
<td>{{ finder_game }}</td>
</tr>
{%- endfor %}

{%- endfor %}
{%- endfor %}
</tbody>
</table>
</div>

{%- endfor -%}
</div>
</div>
{% endblock %}
25 changes: 25 additions & 0 deletions WebHostLib/tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,11 @@ def get_room_videos(self) -> Dict[TeamPlayer, Tuple[str, str]]:

return video_feeds

@_cache_results
def get_spheres(self) -> List[List[int]]:
""" each sphere is { player: { location_id, ... } } """
return self._multidata.get("spheres", [])


@app.route("/tracker/<suuid:tracker>/<int:tracked_team>/<int:tracked_player>")
def get_player_tracker(tracker: UUID, tracked_team: int, tracked_player: int, generic: bool = False) -> str:
Expand Down Expand Up @@ -414,6 +419,26 @@ def render_generic_multiworld_tracker(tracker_data: TrackerData, enabled_tracker
)


def render_generic_multiworld_sphere_tracker(tracker_data: TrackerData) -> str:
return render_template(
"multispheretracker.html",
room=tracker_data.room,
tracker_data=tracker_data,
)


@app.route("/sphere_tracker/<suuid:tracker>")
@cache.memoize(timeout=TRACKER_CACHE_TIMEOUT_IN_SECONDS)
def get_multiworld_sphere_tracker(tracker: UUID):
# Room must exist.
room = Room.get(tracker=tracker)
if not room:
abort(404)

tracker_data = TrackerData(room)
return render_generic_multiworld_sphere_tracker(tracker_data)


# TODO: This is a temporary solution until a proper Tracker API can be implemented for tracker templates and data to
# live in their respective world folders.

Expand Down
Loading