def __init__(self, depsets: Sequence[ba.DependencySet], team_names: Sequence[str] = None, team_colors: Sequence[Sequence[float]] = None, use_team_colors: bool = True, min_players: int = 1, max_players: int = 8, allow_mid_activity_joins: bool = True): """Instantiate a session. depsets should be a sequence of successfully resolved ba.DependencySet instances; one for each ba.Activity the session may potentially run. """ # pylint: disable=too-many-statements # pylint: disable=too-many-locals # pylint: disable=cyclic-import from ba._lobby import Lobby from ba._stats import Stats from ba._gameutils import sharedobj from ba._gameactivity import GameActivity from ba._team import Team from ba._error import DependencyError from ba._dependency import Dependency, AssetPackage # First off, resolve all dependency-sets we were passed. # If things are missing, we'll try to gather them into a single # missing-deps exception if possible to give the caller a clean # path to download missing stuff and try again. missing_asset_packages: Set[str] = set() for depset in depsets: try: depset.resolve() except DependencyError as exc: # Gather/report missing assets only; barf on anything else. if all(issubclass(d.cls, AssetPackage) for d in exc.deps): for dep in exc.deps: assert isinstance(dep.config, str) missing_asset_packages.add(dep.config) else: missing_info = [(d.cls, d.config) for d in exc.deps] raise RuntimeError( f'Missing non-asset dependencies: {missing_info}') # Throw a combined exception if we found anything missing. if missing_asset_packages: raise DependencyError([ Dependency(AssetPackage, set_id) for set_id in missing_asset_packages ]) # Ok; looks like our dependencies check out. # Now give the engine a list of asset-set-ids to pass along to clients. required_asset_packages: Set[str] = set() for depset in depsets: required_asset_packages.update(depset.get_asset_package_ids()) # print('Would set host-session asset-reqs to:', # required_asset_packages) # First thing, wire up our internal engine data. self._sessiondata = _ba.register_session(self) self.tournament_id: Optional[str] = None # FIXME: This stuff shouldn't be here. self.sharedobjs: Dict[str, Any] = {} # TeamGameActivity uses this to display a help overlay on the first # activity only. self.have_shown_controls_help_overlay = False self.campaign = None # FIXME: Should be able to kill this I think. self.campaign_state: Dict[str, str] = {} self._use_teams = (team_names is not None) self._use_team_colors = use_team_colors self._in_set_activity = False self._allow_mid_activity_joins = allow_mid_activity_joins self.teams = [] self.players = [] self._next_team_id = 0 self._activity_retained: Optional[ba.Activity] = None self.launch_end_session_activity_time: Optional[float] = None self._activity_end_timer: Optional[ba.Timer] = None # Hacky way to create empty weak ref; must be a better way. class _EmptyObj: pass self._activity_weak: ReferenceType[ba.Activity] self._activity_weak = weakref.ref(_EmptyObj()) # type: ignore if self._activity_weak() is not None: raise Exception('Error creating empty activity weak ref.') self._next_activity: Optional[ba.Activity] = None self.wants_to_end = False self._ending = False self.min_players = min_players self.max_players = max_players # Create Teams. if self._use_teams: assert team_names is not None assert team_colors is not None for i, color in enumerate(team_colors): team = Team(team_id=self._next_team_id, name=GameActivity.get_team_display_string( team_names[i]), color=color) self.teams.append(team) self._next_team_id += 1 try: with _ba.Context(self): self.on_team_join(team) except Exception: from ba import _error _error.print_exception( f'Error in on_team_join for {self}.') self.lobby = Lobby() self.stats = Stats() # Instantiate our session globals node # (so it can apply default settings). sharedobj('globals')
def __init__(self, depsets: Sequence[ba.DependencySet], team_names: Sequence[str] = None, team_colors: Sequence[Sequence[float]] = None, min_players: int = 1, max_players: int = 8): """Instantiate a session. depsets should be a sequence of successfully resolved ba.DependencySet instances; one for each ba.Activity the session may potentially run. """ # pylint: disable=too-many-statements # pylint: disable=too-many-locals # pylint: disable=cyclic-import from ba._lobby import Lobby from ba._stats import Stats from ba._gameactivity import GameActivity from ba._activity import Activity from ba._team import SessionTeam from ba._error import DependencyError from ba._dependency import Dependency, AssetPackage from efro.util import empty_weakref # First off, resolve all dependency-sets we were passed. # If things are missing, we'll try to gather them into a single # missing-deps exception if possible to give the caller a clean # path to download missing stuff and try again. missing_asset_packages: Set[str] = set() for depset in depsets: try: depset.resolve() except DependencyError as exc: # Gather/report missing assets only; barf on anything else. if all(issubclass(d.cls, AssetPackage) for d in exc.deps): for dep in exc.deps: assert isinstance(dep.config, str) missing_asset_packages.add(dep.config) else: missing_info = [(d.cls, d.config) for d in exc.deps] raise RuntimeError( f'Missing non-asset dependencies: {missing_info}' ) from exc # Throw a combined exception if we found anything missing. if missing_asset_packages: raise DependencyError([ Dependency(AssetPackage, set_id) for set_id in missing_asset_packages ]) # Ok; looks like our dependencies check out. # Now give the engine a list of asset-set-ids to pass along to clients. required_asset_packages: Set[str] = set() for depset in depsets: required_asset_packages.update(depset.get_asset_package_ids()) # print('Would set host-session asset-reqs to:', # required_asset_packages) # Init our C++ layer data. self._sessiondata = _ba.register_session(self) # Should remove this if possible. self.tournament_id: Optional[str] = None self.sessionteams = [] self.sessionplayers = [] self.min_players = min_players self.max_players = max_players self.customdata = {} self._in_set_activity = False self._next_team_id = 0 self._activity_retained: Optional[ba.Activity] = None self._launch_end_session_activity_time: Optional[float] = None self._activity_end_timer: Optional[ba.Timer] = None self._activity_weak = empty_weakref(Activity) self._next_activity: Optional[ba.Activity] = None self._wants_to_end = False self._ending = False self._activity_should_end_immediately = False self._activity_should_end_immediately_results: ( Optional[ba.GameResults]) = None self._activity_should_end_immediately_delay = 0.0 # Create static teams if we're using them. if self.use_teams: assert team_names is not None assert team_colors is not None for i, color in enumerate(team_colors): team = SessionTeam(team_id=self._next_team_id, name=GameActivity.get_team_display_string( team_names[i]), color=color) self.sessionteams.append(team) self._next_team_id += 1 try: with _ba.Context(self): self.on_team_join(team) except Exception: print_exception(f'Error in on_team_join for {self}.') self.lobby = Lobby() self.stats = Stats() # Instantiate our session globals node which will apply its settings. self._sessionglobalsnode = _ba.newnode('sessionglobals')