Compare commits

..

1 Commits

Author SHA1 Message Date
Fabian Dill
c7c2cda333 MultiServer: prevent loading files out of temp 2025-03-10 20:17:42 +01:00
4 changed files with 27 additions and 23 deletions

View File

@@ -2536,6 +2536,25 @@ async def main(args: argparse.Namespace):
logging.info("No file selected. Exiting.")
import sys
sys.exit(1)
elif not args.disable_save:
import tempfile
import os
import sys
try:
common = os.path.commonpath((tempfile.gettempdir(), data_filename))
if not os.path.samefile(tempfile.gettempdir(), common):
raise ValueError
except ValueError:
# win32 built-in zip-folder handling, uses "temporary internet files" to store
if (sys.platform == "win32" and
"/AppData/Local/Microsoft/Windows/INetCache/IE/" in data_filename):
logging.info("File inside temporary directory (likely a zip file, just load the zip directly). "
"Exiting.")
sys.exit(1)
else:
logging.info("File inside temporary directory. Exiting.")
sys.exit(1)
try:
ctx.load(data_filename, args.use_embedded_options)

View File

@@ -756,8 +756,8 @@ Tags are represented as a list of strings, the common client tags follow:
### DeathLink
A special kind of Bounce packet that can be supported by any AP game. It targets the tag "DeathLink" and carries the following data:
| Name | Type | Notes |
|--------|-------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| time | float | Unix Time Stamp of time of death. |
| cause | str | Optional. Text to explain the cause of death. When provided, or checked, if the string is non-empty, it should contain the player name, ex. "Berserker was run over by a train." |
| source | str | Name of the player who first died. Can be a slot name, but can also be a name from within a multiplayer game. |
| Name | Type | Notes |
|--------|-------|--------------------------------------------------------------------------------------------------------------------------------------------------------|
| time | float | Unix Time Stamp of time of death. |
| cause | str | Optional. Text to explain the cause of death. When provided, or checked, this should contain the player name, ex. "Berserker was run over by a train." |
| source | str | Name of the player who first died. Can be a slot name, but can also be a name from within a multiplayer game. |

View File

@@ -51,12 +51,6 @@ class TransitionPlando(PlandoConnections):
entrances = frozenset(RANDOMIZED_CONNECTIONS.keys())
exits = frozenset(RANDOMIZED_CONNECTIONS.values())
@classmethod
def can_connect(cls, entrance: str, exit: str) -> bool:
if entrance != "Glacial Peak - Left" and entrance.lower() in cls.exits:
return exit.lower() in cls.entrances
return exit.lower() not in cls.entrances
class Logic(Choice):
"""

View File

@@ -30,19 +30,10 @@ def connect_plando(world: "MessengerWorld", plando_connections: TransitionPlando
for plando_connection in plando_connections:
# get the connecting regions
# need to handle these special because the names are unique but have the same parent region
if plando_connection.entrance in ("Artificer", "Tower HQ"):
reg1 = world.get_region("Tower HQ")
if plando_connection.entrance == "Artificer":
dangling_exit = world.get_entrance("Artificer's Portal")
else:
dangling_exit = world.get_entrance("Artificer's Challenge")
reg1.exits.remove(dangling_exit)
else:
reg1 = world.get_region(plando_connection.entrance)
remove_dangling_exit(reg1)
reg1 = world.get_region(plando_connection.entrance)
reg2 = world.get_region(plando_connection.exit)
remove_dangling_exit(reg1)
remove_dangling_entrance(reg2)
# connect the regions
reg1.connect(reg2)