CustomServer: don't mutate static server data (#3334)

when switching to multiple rooms per process, we ended up modifying the static server data
because that's how _load works and the data is now shared between multiple rooms.
This commit is contained in:
black-sliver 2024-05-19 15:32:11 +02:00 committed by GitHub
parent 663b50b33e
commit cf34f125d6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 22 additions and 2 deletions

View File

@ -73,6 +73,7 @@ class WebHostContext(Context):
def _load_game_data(self): def _load_game_data(self):
for key, value in self.static_server_data.items(): for key, value in self.static_server_data.items():
# NOTE: attributes are mutable and shared, so they will have to be copied before being modified
setattr(self, key, value) setattr(self, key, value)
self.non_hintable_names = collections.defaultdict(frozenset, self.non_hintable_names) self.non_hintable_names = collections.defaultdict(frozenset, self.non_hintable_names)
@ -100,18 +101,37 @@ class WebHostContext(Context):
multidata = self.decompress(room.seed.multidata) multidata = self.decompress(room.seed.multidata)
game_data_packages = {} game_data_packages = {}
static_gamespackage = self.gamespackage # this is shared across all rooms
static_item_name_groups = self.item_name_groups
static_location_name_groups = self.location_name_groups
self.gamespackage = {} # this may be modified by _load
self.item_name_groups = {}
self.location_name_groups = {}
for game in list(multidata.get("datapackage", {})): for game in list(multidata.get("datapackage", {})):
game_data = multidata["datapackage"][game] game_data = multidata["datapackage"][game]
if "checksum" in game_data: if "checksum" in game_data:
if self.gamespackage.get(game, {}).get("checksum") == game_data["checksum"]: if static_gamespackage.get(game, {}).get("checksum") == game_data["checksum"]:
# non-custom. remove from multidata # non-custom. remove from multidata and use static data
# games package could be dropped from static data once all rooms embed data package # games package could be dropped from static data once all rooms embed data package
del multidata["datapackage"][game] del multidata["datapackage"][game]
else: else:
row = GameDataPackage.get(checksum=game_data["checksum"]) row = GameDataPackage.get(checksum=game_data["checksum"])
if row: # None if rolled on >= 0.3.9 but uploaded to <= 0.3.8. multidata should be complete if row: # None if rolled on >= 0.3.9 but uploaded to <= 0.3.8. multidata should be complete
game_data_packages[game] = Utils.restricted_loads(row.data) game_data_packages[game] = Utils.restricted_loads(row.data)
continue
else:
self.logger.warning(f"Did not find game_data_package for {game}: {game_data['checksum']}")
self.gamespackage[game] = static_gamespackage.get(game, {})
self.item_name_groups[game] = static_item_name_groups.get(game, {})
self.location_name_groups[game] = static_location_name_groups.get(game, {})
if not game_data_packages:
# all static -> use the static dicts directly
self.gamespackage = static_gamespackage
self.item_name_groups = static_item_name_groups
self.location_name_groups = static_location_name_groups
return self._load(multidata, game_data_packages, True) return self._load(multidata, game_data_packages, True)
@db_session @db_session