WebHost: Fix upload of .archipelago file (#1657)

* Fix upload

* simple fix for slot data

* remove extra patch.data check

* remove extra parens

* Update WebHostLib/upload.py

Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com>

* Update WebHostLib/upload.py

Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com>

* parse -> process

* Update WebHostLib/upload.py

Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com>

---------

Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com>
This commit is contained in:
zig-for 2023-04-06 15:24:03 -07:00 committed by GitHub
parent a86c0aa37d
commit ccb89dd65c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 67 additions and 63 deletions

View File

@ -25,6 +25,7 @@
<td data-tooltip="Connect via TextClient"><a href="archipelago://{{ patch.player_name | e}}:@{{ config['HOST_ADDRESS'] }}:{{ room.last_port }}">{{ patch.player_name }}</a></td>
<td>{{ patch.game }}</td>
<td>
{% if patch.data %}
{% if patch.game == "Minecraft" %}
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
Download APMC File...</a>
@ -46,12 +47,15 @@
{% elif patch.game | supports_apdeltapatch %}
<a href="{{ url_for("download_patch", patch_id=patch.id, room_id=room.id) }}" download>
Download Patch File...</a>
{% elif patch.game == "Dark Souls III" and patch.data %}
{% elif patch.game == "Dark Souls III" %}
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
Download JSON File...</a>
{% else %}
No file to download for this game.
{% endif %}
{% else %}
No file to download for this game.
{% endif %}
</td>
<td><a href="{{ url_for("get_player_tracker", tracker=room.tracker, tracked_team=0, tracked_player=patch.player_id) }}">Tracker</a></td>
</tr>

View File

@ -20,6 +20,41 @@ from .models import Seed, Room, Slot, GameDataPackage
banned_zip_contents = (".sfc", ".z64", ".n64", ".sms", ".gb")
def process_multidata(compressed_multidata, files={}):
decompressed_multidata = MultiServer.Context.decompress(compressed_multidata)
slots: typing.Set[Slot] = set()
if "datapackage" in decompressed_multidata:
# strip datapackage from multidata, leaving only the checksums
game_data_packages: typing.List[GameDataPackage] = []
for game, game_data in decompressed_multidata["datapackage"].items():
if game_data.get("checksum"):
game_data_package = GameDataPackage(checksum=game_data["checksum"],
data=pickle.dumps(game_data))
decompressed_multidata["datapackage"][game] = {
"version": game_data.get("version", 0),
"checksum": game_data["checksum"]
}
try:
commit() # commit game data package
game_data_packages.append(game_data_package)
except TransactionIntegrityError:
del game_data_package
rollback()
if "slot_info" in decompressed_multidata:
for slot, slot_info in decompressed_multidata["slot_info"].items():
# Ignore Player Groups (e.g. item links)
if slot_info.type == SlotType.group:
continue
slots.add(Slot(data=files.get(slot, None),
player_name=slot_info.name,
player_id=slot,
game=slot_info.game))
flush() # commit slots
compressed_multidata = compressed_multidata[0:1] + zlib.compress(pickle.dumps(decompressed_multidata), 9)
return slots, compressed_multidata
def upload_zip_to_db(zfile: zipfile.ZipFile, owner=None, meta={"race": False}, sid=None):
if not owner:
@ -29,7 +64,7 @@ def upload_zip_to_db(zfile: zipfile.ZipFile, owner=None, meta={"race": False}, s
flash(Markup("Error: Your .zip file only contains .yaml files. "
'Did you mean to <a href="/generate">generate a game</a>?'))
return
slots: typing.Set[Slot] = set()
spoiler = ""
files = {}
multidata = None
@ -80,42 +115,7 @@ def upload_zip_to_db(zfile: zipfile.ZipFile, owner=None, meta={"race": False}, s
# Load multi data.
if multidata:
decompressed_multidata = MultiServer.Context.decompress(multidata)
recompress = False
if "datapackage" in decompressed_multidata:
# strip datapackage from multidata, leaving only the checksums
game_data_packages: typing.List[GameDataPackage] = []
for game, game_data in decompressed_multidata["datapackage"].items():
if game_data.get("checksum"):
game_data_package = GameDataPackage(checksum=game_data["checksum"],
data=pickle.dumps(game_data))
decompressed_multidata["datapackage"][game] = {
"version": game_data.get("version", 0),
"checksum": game_data["checksum"]
}
recompress = True
try:
commit() # commit game data package
game_data_packages.append(game_data_package)
except TransactionIntegrityError:
del game_data_package
rollback()
if "slot_info" in decompressed_multidata:
for slot, slot_info in decompressed_multidata["slot_info"].items():
# Ignore Player Groups (e.g. item links)
if slot_info.type == SlotType.group:
continue
slots.add(Slot(data=files.get(slot, None),
player_name=slot_info.name,
player_id=slot,
game=slot_info.game))
flush() # commit slots
if recompress:
multidata = multidata[0:1] + zlib.compress(pickle.dumps(decompressed_multidata), 9)
slots, multidata = process_multidata(multidata, files)
seed = Seed(multidata=multidata, spoiler=spoiler, slots=slots, owner=owner, meta=json.dumps(meta),
id=sid if sid else uuid.uuid4())
@ -156,11 +156,11 @@ def uploads():
# noinspection PyBroadException
try:
multidata = file.read()
MultiServer.Context.decompress(multidata)
slots, multidata = process_multidata(multidata)
except Exception as e:
flash(f"Could not load multidata. File may be corrupted or incompatible. ({e})")
else:
seed = Seed(multidata=multidata, owner=session["_id"])
seed = Seed(multidata=multidata, slots=slots, owner=session["_id"])
flush() # place into DB and generate ids
return redirect(url_for("view_seed", seed=seed.id))
else: