Skip to content

Commit

Permalink
Merge branch 'main' into ladx/stop-randomly-swapping-rupees-in-pool
Browse files Browse the repository at this point in the history
  • Loading branch information
threeandthreee authored Nov 14, 2024
2 parents 3ab75d5 + eac3e3c commit f7ec487
Show file tree
Hide file tree
Showing 75 changed files with 555 additions and 335 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
Expand All @@ -58,7 +58,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
uses: github/codeql-action/autobuild@v3

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
Expand All @@ -72,4 +72,4 @@ jobs:
# make release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3
2 changes: 1 addition & 1 deletion .github/workflows/unittests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,4 @@ jobs:
run: |
source venv/bin/activate
export PYTHONPATH=$(pwd)
python test/hosting/__main__.py
timeout 600 python test/hosting/__main__.py
4 changes: 4 additions & 0 deletions BaseClasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,10 @@ def useful(self) -> bool:
def trap(self) -> bool:
return ItemClassification.trap in self.classification

@property
def excludable(self) -> bool:
return not (self.advancement or self.useful)

@property
def flags(self) -> int:
return self.classification.as_flag()
Expand Down
2 changes: 1 addition & 1 deletion Generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def main(args=None) -> Tuple[argparse.Namespace, int]:
player_files = {}
for file in os.scandir(args.player_files_path):
fname = file.name
if file.is_file() and not fname.startswith(".") and \
if file.is_file() and not fname.startswith(".") and not fname.lower().endswith(".ini") and \
os.path.join(args.player_files_path, fname) not in {args.meta_file_path, args.weights_file_path}:
path = os.path.join(args.player_files_path, fname)
try:
Expand Down
1 change: 1 addition & 0 deletions Launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ def update_settings():
Component("Open host.yaml", func=open_host_yaml),
Component("Open Patch", func=open_patch),
Component("Generate Template Options", func=generate_yamls),
Component("Archipelago Website", func=lambda: webbrowser.open("https://archipelago.gg/")),
Component("Discord Server", icon="discord", func=lambda: webbrowser.open("https://discord.gg/8Z65BR2")),
Component("Unrated/18+ Discord Server", icon="discord", func=lambda: webbrowser.open("https://discord.gg/fqvNCCRsu4")),
Component("Browse Files", func=browse_files),
Expand Down
6 changes: 4 additions & 2 deletions MultiServer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1960,8 +1960,10 @@ def _cmd_status(self, tag: str = "") -> bool:

def _cmd_exit(self) -> bool:
"""Shutdown the server"""
self.ctx.server.ws_server.close()
self.ctx.exit_event.set()
try:
self.ctx.server.ws_server.close()
finally:
self.ctx.exit_event.set()
return True

@mark_raw
Expand Down
2 changes: 1 addition & 1 deletion WebHostLib/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
flask>=3.0.3
werkzeug>=3.0.4
werkzeug>=3.0.6
pony>=0.7.19
waitress>=3.0.0
Flask-Caching>=2.3.0
Expand Down
20 changes: 14 additions & 6 deletions WebHostLib/tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from uuid import UUID
from email.utils import parsedate_to_datetime

from flask import render_template, make_response, Response, request
from flask import make_response, render_template, request, Request, Response
from werkzeug.exceptions import abort

from MultiServer import Context, get_saving_second
Expand Down Expand Up @@ -298,17 +298,25 @@ def get_spheres(self) -> List[List[int]]:
return self._multidata.get("spheres", [])


def _process_if_request_valid(incoming_request, room: Optional[Room]) -> Optional[Response]:
def _process_if_request_valid(incoming_request: Request, room: Optional[Room]) -> Optional[Response]:
if not room:
abort(404)

if_modified = incoming_request.headers.get("If-Modified-Since", None)
if if_modified:
if_modified = parsedate_to_datetime(if_modified)
if_modified_str: Optional[str] = incoming_request.headers.get("If-Modified-Since", None)
if if_modified_str:
if_modified = parsedate_to_datetime(if_modified_str)
if if_modified.tzinfo is None:
abort(400) # standard requires "GMT" timezone
# database may use datetime.utcnow(), which is timezone-naive. convert to timezone-aware.
last_activity = room.last_activity
if last_activity.tzinfo is None:
last_activity = room.last_activity.replace(tzinfo=datetime.timezone.utc)
# if_modified has less precision than last_activity, so we bring them to same precision
if if_modified >= room.last_activity.replace(microsecond=0):
if if_modified >= last_activity.replace(microsecond=0):
return make_response("", 304)

return None


@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) -> Response:
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
colorama>=0.4.6
websockets>=13.0.1
websockets>=13.0.1,<14
PyYAML>=6.0.2
jellyfish>=1.1.0
jinja2>=3.1.4
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ def find_lib(lib: str, arch: str, libc: str) -> Optional[str]:
"packages": ["worlds", "kivy", "cymem", "websockets"],
"includes": [],
"excludes": ["numpy", "Cython", "PySide2", "PIL",
"pandas"],
"pandas", "zstandard"],
"zip_include_packages": ["*"],
"zip_exclude_packages": ["worlds", "sc2", "orjson"], # TODO: remove orjson here once we drop py3.8 support
"include_files": [], # broken in cx 6.14.0, we use more special sauce now
Expand Down
1 change: 1 addition & 0 deletions test/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import settings

warnings.simplefilter("always")
warnings.filterwarnings(action="ignore", category=DeprecationWarning, module="s2clientprotocol")
settings.no_gui = True
settings.skip_autosave = True

Expand Down
Binary file added test/webhost/data/One_Archipelago.archipelago
Binary file not shown.
95 changes: 95 additions & 0 deletions test/webhost/test_tracker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import os
import pickle
from pathlib import Path
from typing import ClassVar
from uuid import UUID, uuid4

from flask import url_for

from . import TestBase


class TestTracker(TestBase):
room_id: UUID
tracker_uuid: UUID
log_filename: str
data: ClassVar[bytes]

@classmethod
def setUpClass(cls) -> None:
super().setUpClass()
with (Path(__file__).parent / "data" / "One_Archipelago.archipelago").open("rb") as f:
cls.data = f.read()

def setUp(self) -> None:
from pony.orm import db_session
from MultiServer import Context as MultiServerContext
from Utils import user_path
from WebHostLib.models import GameDataPackage, Room, Seed

super().setUp()

multidata = MultiServerContext.decompress(self.data)

with self.client.session_transaction() as session:
session["_id"] = uuid4()
self.tracker_uuid = uuid4()
with db_session:
# store game datapackage(s)
for game, game_data in multidata["datapackage"].items():
if not GameDataPackage.get(checksum=game_data["checksum"]):
GameDataPackage(checksum=game_data["checksum"],
data=pickle.dumps(game_data))
# create an empty seed and a room from it
seed = Seed(multidata=self.data, owner=session["_id"])
room = Room(seed=seed, owner=session["_id"], tracker=self.tracker_uuid)
self.room_id = room.id
self.log_filename = user_path("logs", f"{self.room_id}.txt")

def tearDown(self) -> None:
from pony.orm import db_session, select
from WebHostLib.models import Command, Room

with db_session:
for command in select(command for command in Command if command.room.id == self.room_id): # type: ignore
command.delete()
room: Room = Room.get(id=self.room_id)
room.seed.delete()
room.delete()

try:
os.unlink(self.log_filename)
except FileNotFoundError:
pass

def test_valid_if_modified_since(self) -> None:
"""
Verify that we get a 200 response for valid If-Modified-Since
"""
with self.app.app_context(), self.app.test_request_context():
response = self.client.get(
url_for(
"get_player_tracker",
tracker=self.tracker_uuid,
tracked_team=0,
tracked_player=1,
),
headers={"If-Modified-Since": "Wed, 21 Oct 2015 07:28:00 GMT"},
)
self.assertEqual(response.status_code, 200)

def test_invalid_if_modified_since(self) -> None:
"""
Verify that we get a 400 response for invalid If-Modified-Since
"""
with self.app.app_context(), self.app.test_request_context():
response = self.client.get(
url_for(
"get_player_tracker",
tracker=self.tracker_uuid,
tracked_team=1,
tracked_player=0,
),
headers={"If-Modified-Since": "Wed, 21 Oct 2015 07:28:00"}, # missing timezone
)
self.assertEqual(response.status_code, 400)
3 changes: 2 additions & 1 deletion worlds/AutoWorld.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from typing import (Any, Callable, ClassVar, Dict, FrozenSet, List, Mapping, Optional, Set, TextIO, Tuple,
TYPE_CHECKING, Type, Union)

from Options import item_and_loc_options, OptionGroup, PerGameCommonOptions
from Options import item_and_loc_options, ItemsAccessibility, OptionGroup, PerGameCommonOptions
from BaseClasses import CollectionState

if TYPE_CHECKING:
Expand Down Expand Up @@ -480,6 +480,7 @@ def create_group(cls, multiworld: "MultiWorld", new_player_id: int, players: Set
group = cls(multiworld, new_player_id)
group.options = cls.options_dataclass(**{option_key: option.from_any(option.default)
for option_key, option in cls.options_dataclass.type_hints.items()})
group.options.accessibility = ItemsAccessibility(ItemsAccessibility.option_items)

return group

Expand Down
19 changes: 0 additions & 19 deletions worlds/alttp/EntranceShuffle.py
Original file line number Diff line number Diff line change
Expand Up @@ -3338,25 +3338,6 @@ def plando_connect(world, player: int):
('Turtle Rock Exit (Front)', 'Dark Death Mountain'),
('Ice Palace Exit', 'Dark Lake Hylia')]

# Regions that can be required to access entrances through rules, not paths
indirect_connections = {
"Turtle Rock (Top)": "Turtle Rock",
"East Dark World": "Pyramid Fairy",
"Dark Desert": "Pyramid Fairy",
"West Dark World": "Pyramid Fairy",
"South Dark World": "Pyramid Fairy",
"Light World": "Pyramid Fairy",
"Old Man Cave": "Old Man S&Q"
}

indirect_connections_inverted = {
"Inverted Big Bomb Shop": "Pyramid Fairy",
}

indirect_connections_not_inverted = {
"Big Bomb Shop": "Pyramid Fairy",
}

# format:
# Key=Name
# addr = (door_index, exitdata) # multiexit
Expand Down
14 changes: 2 additions & 12 deletions worlds/alttp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
import Utils
from BaseClasses import Item, CollectionState, Tutorial, MultiWorld
from .Dungeons import create_dungeons, Dungeon
from .EntranceShuffle import link_entrances, link_inverted_entrances, plando_connect, \
indirect_connections, indirect_connections_inverted, indirect_connections_not_inverted
from .EntranceShuffle import link_entrances, link_inverted_entrances, plando_connect
from .InvertedRegions import create_inverted_regions, mark_dark_world_regions
from .ItemPool import generate_itempool, difficulties
from .Items import item_init_table, item_name_groups, item_table, GetBeemizerItem
Expand Down Expand Up @@ -137,6 +136,7 @@ class ALTTPWorld(World):
settings_key = "lttp_options"
settings: typing.ClassVar[ALTTPSettings]
topology_present = True
explicit_indirect_conditions = False
item_name_groups = item_name_groups
location_name_groups = {
"Blind's Hideout": {"Blind's Hideout - Top", "Blind's Hideout - Left", "Blind's Hideout - Right",
Expand Down Expand Up @@ -394,23 +394,13 @@ def create_regions(self):
if multiworld.mode[player] != 'inverted':
link_entrances(multiworld, player)
mark_light_world_regions(multiworld, player)
for region_name, entrance_name in indirect_connections_not_inverted.items():
multiworld.register_indirect_condition(multiworld.get_region(region_name, player),
multiworld.get_entrance(entrance_name, player))
else:
link_inverted_entrances(multiworld, player)
mark_dark_world_regions(multiworld, player)
for region_name, entrance_name in indirect_connections_inverted.items():
multiworld.register_indirect_condition(multiworld.get_region(region_name, player),
multiworld.get_entrance(entrance_name, player))

multiworld.random = old_random
plando_connect(multiworld, player)

for region_name, entrance_name in indirect_connections.items():
multiworld.register_indirect_condition(multiworld.get_region(region_name, player),
multiworld.get_entrance(entrance_name, player))

def collect_item(self, state: CollectionState, item: Item, remove=False):
item_name = item.name
if item_name.startswith('Progressive '):
Expand Down
2 changes: 1 addition & 1 deletion worlds/alttp/test/items/TestDifficulty.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from worlds.alttp.ItemPool import difficulties
from test.TestBase import TestBase
from test.bases import TestBase

base_items = 41
extra_counts = (15, 15, 10, 5, 25)
Expand Down
2 changes: 1 addition & 1 deletion worlds/alttp/test/items/TestPrizes.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import List

from BaseClasses import Item, Location
from test.TestBase import WorldTestBase
from test.bases import WorldTestBase


class TestPrizes(WorldTestBase):
Expand Down
2 changes: 1 addition & 1 deletion worlds/alttp/test/minor_glitches/TestMinor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from worlds.alttp.InvertedRegions import mark_dark_world_regions
from worlds.alttp.ItemPool import difficulties
from worlds.alttp.Items import item_factory
from test.TestBase import TestBase
from test.bases import TestBase
from worlds.alttp.Options import GlitchesRequired

from worlds.alttp.test import LTTPTestBase
Expand Down
2 changes: 1 addition & 1 deletion worlds/alttp/test/owg/TestVanillaOWG.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from worlds.alttp.InvertedRegions import mark_dark_world_regions
from worlds.alttp.ItemPool import difficulties
from worlds.alttp.Items import item_factory
from test.TestBase import TestBase
from test.bases import TestBase
from worlds.alttp.Options import GlitchesRequired

from worlds.alttp.test import LTTPTestBase
Expand Down
2 changes: 1 addition & 1 deletion worlds/alttp/test/shops/TestSram.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from worlds.alttp.Shops import shop_table
from test.TestBase import TestBase
from test.bases import TestBase


class TestSram(TestBase):
Expand Down
2 changes: 1 addition & 1 deletion worlds/alttp/test/vanilla/TestVanilla.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from worlds.alttp.InvertedRegions import mark_dark_world_regions
from worlds.alttp.ItemPool import difficulties
from worlds.alttp.Items import item_factory
from test.TestBase import TestBase
from test.bases import TestBase
from worlds.alttp.Options import GlitchesRequired
from worlds.alttp.test import LTTPTestBase

Expand Down
2 changes: 1 addition & 1 deletion worlds/bumpstik/test/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from test.TestBase import WorldTestBase
from test.bases import WorldTestBase


class BumpStikTestBase(WorldTestBase):
Expand Down
Loading

0 comments on commit f7ec487

Please sign in to comment.