diff --git a/CHANGELOG.md b/CHANGELOG.md index 10f4103d..773edb2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Fixes an issue where repeated curses could use incorrect countdown times (Thanks EraOSBeta!). - Last manual party connect port is now saved. Previously, it always assumed the port to be 43210 (Thanks ritiek!). - Added a plugin-settings window under the plugins UI for enabling/disabling, and setting whether plugins are auto-enabled (Thanks vishal332008!). +- Missing maps are now cleanly filtered out of playlists instead of causing errors/hangs (Thanks imayushsaini!). ### 1.7.18 (build 20989, api 7, 2023-01-16) - Reworked some low level asynchronous messaging functionality in efro.message and efro.rpc. Previously these were a little *too* asynchronous which could lead to messages being received in a different order than they were sent, which is not desirable. diff --git a/assets/src/ba_data/python/ba/__init__.py b/assets/src/ba_data/python/ba/__init__.py index 82738c9e..54be9f96 100644 --- a/assets/src/ba_data/python/ba/__init__.py +++ b/assets/src/ba_data/python/ba/__init__.py @@ -102,6 +102,7 @@ from ba._error import ( WidgetNotFoundError, ActivityNotFoundError, TeamNotFoundError, + MapNotFoundError, SessionTeamNotFoundError, SessionNotFoundError, DelegateNotFoundError, @@ -282,6 +283,7 @@ __all__ = [ 'Lobby', 'Lstr', 'Map', + 'MapNotFoundError', 'Material', 'MetadataSubsystem', 'Model', diff --git a/assets/src/ba_data/python/ba/_error.py b/assets/src/ba_data/python/ba/_error.py index fb8803b6..960f9e57 100644 --- a/assets/src/ba_data/python/ba/_error.py +++ b/assets/src/ba_data/python/ba/_error.py @@ -69,6 +69,13 @@ class TeamNotFoundError(NotFoundError): """ +class MapNotFoundError(NotFoundError): + """Exception raised when an expected ba.Map does not exist. + + Category: **Exception Classes** + """ + + class DelegateNotFoundError(NotFoundError): """Exception raised when an expected delegate object does not exist. diff --git a/assets/src/ba_data/python/ba/_gameactivity.py b/assets/src/ba_data/python/ba/_gameactivity.py index 697c14ad..8dab307d 100644 --- a/assets/src/ba_data/python/ba/_gameactivity.py +++ b/assets/src/ba_data/python/ba/_gameactivity.py @@ -14,7 +14,7 @@ from ba._activity import Activity from ba._score import ScoreConfig from ba._language import Lstr from ba._messages import PlayerDiedMessage, StandMessage -from ba._error import NotFoundError, print_error, print_exception +from ba._error import MapNotFoundError, print_error, print_exception from ba._general import Call, WeakCall from ba._player import PlayerInfo from ba import _map @@ -274,10 +274,10 @@ class GameActivity(Activity[PlayerType, TeamType]): def map(self) -> ba.Map: """The map being used for this game. - Raises a ba.NotFoundError if the map does not currently exist. + Raises a ba.MapNotFoundError if the map does not currently exist. """ if self._map is None: - raise NotFoundError + raise MapNotFoundError return self._map def get_instance_display_string(self) -> ba.Lstr: diff --git a/assets/src/ba_data/python/ba/_playlist.py b/assets/src/ba_data/python/ba/_playlist.py index 9b68ba73..fc26a912 100644 --- a/assets/src/ba_data/python/ba/_playlist.py +++ b/assets/src/ba_data/python/ba/_playlist.py @@ -35,6 +35,7 @@ def filter_playlist( # pylint: disable=too-many-branches # pylint: disable=too-many-statements from ba._map import get_filtered_map_name + from ba._error import MapNotFoundError from ba._store import get_unowned_maps, get_unowned_game_types from ba._general import getclass from ba._gameactivity import GameActivity @@ -161,9 +162,7 @@ def filter_playlist( gameclass = getclass(entry['type'], GameActivity) if entry['settings']['map'] not in available_maps: - raise ImportError( - f"Map not found: '{entry['settings']['map']}'" - ) + raise MapNotFoundError() if remove_unowned and gameclass in unowned_game_types: continue @@ -179,7 +178,15 @@ def filter_playlist( for setting in neededsettings: if setting.name not in entry['settings']: entry['settings'][setting.name] = setting.default + goodlist.append(entry) + + except MapNotFoundError: + logging.warning( + 'Map \'%s\' not found while scanning playlist \'%s\'.', + name, + entry['settings']['map'], + ) except ImportError as exc: logging.warning( 'Import failed while scanning playlist \'%s\': %s', name, exc