mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 20:21:32 -06:00
WebHost: allow APPlayerContainers from "custom" worlds to be displayed in rooms (#4981)
Gives WebHost the ability to verify that a patch file is an APPlayerContainer (defined by #4331 as a APContainer containing the "player" field), and allowed it to display any patch file that it can verify is an APPlayerContainer.
This commit is contained in:
@@ -80,10 +80,8 @@ def register():
|
|||||||
"""Import submodules, triggering their registering on flask routing.
|
"""Import submodules, triggering their registering on flask routing.
|
||||||
Note: initializes worlds subsystem."""
|
Note: initializes worlds subsystem."""
|
||||||
# has automatic patch integration
|
# has automatic patch integration
|
||||||
import worlds.AutoWorld
|
|
||||||
import worlds.Files
|
import worlds.Files
|
||||||
app.jinja_env.filters['supports_apdeltapatch'] = lambda game_name: \
|
app.jinja_env.filters['is_applayercontainer'] = worlds.Files.is_ap_player_container
|
||||||
game_name in worlds.Files.AutoPatchRegister.patch_types
|
|
||||||
|
|
||||||
from WebHostLib.customserver import run_server_process
|
from WebHostLib.customserver import run_server_process
|
||||||
# to trigger app routing picking up on it
|
# to trigger app routing picking up on it
|
||||||
|
@@ -17,9 +17,7 @@
|
|||||||
This page allows you to host a game which was not generated by the website. For example, if you have
|
This page allows you to host a game which was not generated by the website. For example, if you have
|
||||||
generated a game on your own computer, you may upload the zip file created by the generator to
|
generated a game on your own computer, you may upload the zip file created by the generator to
|
||||||
host the game here. This will also provide a tracker, and the ability for your players to download
|
host the game here. This will also provide a tracker, and the ability for your players to download
|
||||||
their patch files if the game is core-verified. For Custom Games, you can find the patch files in
|
their patch files.
|
||||||
the output .zip file you are uploading here. You need to manually distribute those patch files to
|
|
||||||
your players.
|
|
||||||
</p>
|
</p>
|
||||||
<p>In addition to the zip file created by the generator, you may upload a multidata file here as well.</p>
|
<p>In addition to the zip file created by the generator, you may upload a multidata file here as well.</p>
|
||||||
<div id="host-game-form-wrapper">
|
<div id="host-game-form-wrapper">
|
||||||
|
@@ -29,27 +29,15 @@
|
|||||||
{% if patch.game == "Minecraft" %}
|
{% if patch.game == "Minecraft" %}
|
||||||
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
||||||
Download APMC File...</a>
|
Download APMC File...</a>
|
||||||
{% elif patch.game == "Factorio" %}
|
|
||||||
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
|
||||||
Download Factorio Mod...</a>
|
|
||||||
{% elif patch.game == "Kingdom Hearts 2" %}
|
|
||||||
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
|
||||||
Download Kingdom Hearts 2 Mod...</a>
|
|
||||||
{% elif patch.game == "Ocarina of Time" %}
|
|
||||||
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
|
||||||
Download APZ5 File...</a>
|
|
||||||
{% elif patch.game == "VVVVVV" and room.seed.slots|length == 1 %}
|
{% elif patch.game == "VVVVVV" and room.seed.slots|length == 1 %}
|
||||||
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
||||||
Download APV6 File...</a>
|
Download APV6 File...</a>
|
||||||
{% elif patch.game == "Super Mario 64" and room.seed.slots|length == 1 %}
|
{% elif patch.game == "Super Mario 64" and room.seed.slots|length == 1 %}
|
||||||
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
||||||
Download APSM64EX File...</a>
|
Download APSM64EX File...</a>
|
||||||
{% elif patch.game | supports_apdeltapatch %}
|
{% elif patch.game | is_applayercontainer(patch.data, patch.player_id) %}
|
||||||
<a href="{{ url_for("download_patch", patch_id=patch.id, room_id=room.id) }}" download>
|
<a href="{{ url_for("download_patch", patch_id=patch.id, room_id=room.id) }}" download>
|
||||||
Download Patch File...</a>
|
Download Patch File...</a>
|
||||||
{% elif patch.game == "Final Fantasy Mystic Quest" %}
|
|
||||||
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
|
||||||
Download APMQ File...</a>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
No file to download for this game.
|
No file to download for this game.
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@@ -6,6 +6,7 @@ import zipfile
|
|||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
from typing import ClassVar, Dict, List, Literal, Tuple, Any, Optional, Union, BinaryIO, overload, Sequence
|
from typing import ClassVar, Dict, List, Literal, Tuple, Any, Optional, Union, BinaryIO, overload, Sequence
|
||||||
|
|
||||||
@@ -70,6 +71,18 @@ class AutoPatchExtensionRegister(abc.ABCMeta):
|
|||||||
container_version: int = 6
|
container_version: int = 6
|
||||||
|
|
||||||
|
|
||||||
|
def is_ap_player_container(game: str, data: bytes, player: int):
|
||||||
|
if not zipfile.is_zipfile(BytesIO(data)):
|
||||||
|
return False
|
||||||
|
with zipfile.ZipFile(BytesIO(data), mode='r') as zf:
|
||||||
|
if "archipelago.json" in zf.namelist():
|
||||||
|
manifest = json.loads(zf.read("archipelago.json"))
|
||||||
|
if "game" in manifest and "player" in manifest:
|
||||||
|
if game == manifest["game"] and player == manifest["player"]:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class InvalidDataError(Exception):
|
class InvalidDataError(Exception):
|
||||||
"""
|
"""
|
||||||
Since games can override `read_contents` in APContainer,
|
Since games can override `read_contents` in APContainer,
|
||||||
|
Reference in New Issue
Block a user