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:
parent
a86c0aa37d
commit
ccb89dd65c
|
@ -25,30 +25,34 @@
|
||||||
<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 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>{{ patch.game }}</td>
|
||||||
<td>
|
<td>
|
||||||
{% if patch.game == "Minecraft" %}
|
{% if patch.data %}
|
||||||
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
{% if patch.game == "Minecraft" %}
|
||||||
Download APMC File...</a>
|
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
||||||
{% elif patch.game == "Factorio" %}
|
Download APMC File...</a>
|
||||||
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
{% elif patch.game == "Factorio" %}
|
||||||
Download Factorio Mod...</a>
|
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
||||||
{% elif patch.game == "Kingdom Hearts 2" %}
|
Download Factorio Mod...</a>
|
||||||
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
{% elif patch.game == "Kingdom Hearts 2" %}
|
||||||
Download Kingdom Hearts 2 Mod...</a>
|
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
||||||
{% elif patch.game == "Ocarina of Time" %}
|
Download Kingdom Hearts 2 Mod...</a>
|
||||||
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
{% elif patch.game == "Ocarina of Time" %}
|
||||||
Download APZ5 File...</a>
|
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
||||||
{% elif patch.game == "VVVVVV" and room.seed.slots|length == 1 %}
|
Download APZ5 File...</a>
|
||||||
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
{% elif patch.game == "VVVVVV" and room.seed.slots|length == 1 %}
|
||||||
Download APV6 File...</a>
|
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
||||||
{% elif patch.game == "Super Mario 64" and room.seed.slots|length == 1 %}
|
Download APV6 File...</a>
|
||||||
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
{% elif patch.game == "Super Mario 64" and room.seed.slots|length == 1 %}
|
||||||
Download APSM64EX File...</a>
|
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
||||||
{% elif patch.game | supports_apdeltapatch %}
|
Download APSM64EX File...</a>
|
||||||
<a href="{{ url_for("download_patch", patch_id=patch.id, room_id=room.id) }}" download>
|
{% elif patch.game | supports_apdeltapatch %}
|
||||||
Download Patch File...</a>
|
<a href="{{ url_for("download_patch", patch_id=patch.id, room_id=room.id) }}" download>
|
||||||
{% elif patch.game == "Dark Souls III" and patch.data %}
|
Download Patch File...</a>
|
||||||
<a href="{{ url_for("download_slot_file", room_id=room.id, player_id=patch.player_id) }}" download>
|
{% elif patch.game == "Dark Souls III" %}
|
||||||
Download JSON File...</a>
|
<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 %}
|
{% else %}
|
||||||
No file to download for this game.
|
No file to download for this game.
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -20,6 +20,41 @@ from .models import Seed, Room, Slot, GameDataPackage
|
||||||
|
|
||||||
banned_zip_contents = (".sfc", ".z64", ".n64", ".sms", ".gb")
|
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):
|
def upload_zip_to_db(zfile: zipfile.ZipFile, owner=None, meta={"race": False}, sid=None):
|
||||||
if not owner:
|
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. "
|
flash(Markup("Error: Your .zip file only contains .yaml files. "
|
||||||
'Did you mean to <a href="/generate">generate a game</a>?'))
|
'Did you mean to <a href="/generate">generate a game</a>?'))
|
||||||
return
|
return
|
||||||
slots: typing.Set[Slot] = set()
|
|
||||||
spoiler = ""
|
spoiler = ""
|
||||||
files = {}
|
files = {}
|
||||||
multidata = None
|
multidata = None
|
||||||
|
@ -80,42 +115,7 @@ def upload_zip_to_db(zfile: zipfile.ZipFile, owner=None, meta={"race": False}, s
|
||||||
|
|
||||||
# Load multi data.
|
# Load multi data.
|
||||||
if multidata:
|
if multidata:
|
||||||
decompressed_multidata = MultiServer.Context.decompress(multidata)
|
slots, multidata = process_multidata(multidata, files)
|
||||||
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)
|
|
||||||
|
|
||||||
seed = Seed(multidata=multidata, spoiler=spoiler, slots=slots, owner=owner, meta=json.dumps(meta),
|
seed = Seed(multidata=multidata, spoiler=spoiler, slots=slots, owner=owner, meta=json.dumps(meta),
|
||||||
id=sid if sid else uuid.uuid4())
|
id=sid if sid else uuid.uuid4())
|
||||||
|
@ -156,11 +156,11 @@ def uploads():
|
||||||
# noinspection PyBroadException
|
# noinspection PyBroadException
|
||||||
try:
|
try:
|
||||||
multidata = file.read()
|
multidata = file.read()
|
||||||
MultiServer.Context.decompress(multidata)
|
slots, multidata = process_multidata(multidata)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
flash(f"Could not load multidata. File may be corrupted or incompatible. ({e})")
|
flash(f"Could not load multidata. File may be corrupted or incompatible. ({e})")
|
||||||
else:
|
else:
|
||||||
seed = Seed(multidata=multidata, owner=session["_id"])
|
seed = Seed(multidata=multidata, slots=slots, owner=session["_id"])
|
||||||
flush() # place into DB and generate ids
|
flush() # place into DB and generate ids
|
||||||
return redirect(url_for("view_seed", seed=seed.id))
|
return redirect(url_for("view_seed", seed=seed.id))
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in New Issue