Merge pull request #640 from EraOSBeta/master

QoL for Teams Sessions, FFA Sessions, and Servers
This commit is contained in:
Eric Froemling 2024-03-01 20:08:55 -08:00 committed by GitHub
commit 1f811a2f52
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 81 additions and 21 deletions

View File

@ -31,7 +31,7 @@
(Thanks 3alTemp!). (Thanks 3alTemp!).
- Leaving the game or dying while touching your team's flag will no longer recover - Leaving the game or dying while touching your team's flag will no longer recover
& return it indefinitely in a teams game of Capture the Flag. (Thanks 3alTemp!) & return it indefinitely in a teams game of Capture the Flag. (Thanks 3alTemp!)
### 1.7.32 (build 21741, api 8, 2023-12-20) ### 1.7.32 (build 21741, api 8, 2023-12-20)
- Fixed a screen message that no one will ever see (Thanks vishal332008?...) - Fixed a screen message that no one will ever see (Thanks vishal332008?...)
- Plugins window now displays 'No Plugins Installed' when no plugins are present (Thanks vishal332008!) - Plugins window now displays 'No Plugins Installed' when no plugins are present (Thanks vishal332008!)
@ -74,7 +74,7 @@
intended. Now, however, such commands get scheduled to a current intended. Now, however, such commands get scheduled to a current
'ui-operation' and then run *almost* immediately, which should prevent such 'ui-operation' and then run *almost* immediately, which should prevent such
situations. Please holler if you run into any UI weirdness at this point. situations. Please holler if you run into any UI weirdness at this point.
### 1.7.30 (build 21697, api 8, 2023-12-08) ### 1.7.30 (build 21697, api 8, 2023-12-08)
- Continued work on the big 1.7.28 update. - Continued work on the big 1.7.28 update.
- Got the Android version back up and running. There's been lots of cleanup and - Got the Android version back up and running. There's been lots of cleanup and
@ -351,7 +351,7 @@
- Added a 'glow_type' arg to `bauiv1.textwidget()` to adjust the glow used when - Added a 'glow_type' arg to `bauiv1.textwidget()` to adjust the glow used when
the text is selected. The default is 'gradient' but there is now a 'uniform' the text is selected. The default is 'gradient' but there is now a 'uniform'
option which may look better in some circumstances. option which may look better in some circumstances.
### 1.7.27 (build 21282, api 8, 2023-08-30) ### 1.7.27 (build 21282, api 8, 2023-08-30)
- Fixed a rare crash that could occur if the app shuts down while a background - Fixed a rare crash that could occur if the app shuts down while a background
@ -472,7 +472,7 @@
Visual Studio Code (and potentially other editors), so am seeing if it is Visual Studio Code (and potentially other editors), so am seeing if it is
worth officially supporting in addition to or as a replacement for Mypy. See worth officially supporting in addition to or as a replacement for Mypy. See
`tools/pcommand pyright` `tools/pcommand pyright`
### 1.7.24 (build 21199, api 8, 2023-07-27) ### 1.7.24 (build 21199, api 8, 2023-07-27)
- Fixed an issue where respawn icons could disappear in epic mode (Thanks for - Fixed an issue where respawn icons could disappear in epic mode (Thanks for
@ -527,7 +527,7 @@
can be useful for core engine code to directly and clearly point out problems can be useful for core engine code to directly and clearly point out problems
that cannot be recovered from (Exceptions in such cases can tend to be that cannot be recovered from (Exceptions in such cases can tend to be
'handled' which leads to a broken or crashing app). 'handled' which leads to a broken or crashing app).
### 1.7.23 (build 21178, api 8, 2023-07-19) ### 1.7.23 (build 21178, api 8, 2023-07-19)
- Network security improvements. (Thanks Dliwk!) - Network security improvements. (Thanks Dliwk!)

View File

@ -37,12 +37,12 @@
- Added feature - Added feature
### Vishal332008 ### Vishal332008
- Bug Fixer - QoL and Bug Fixer
- Modder - Modder
### Era0S ### Era0S
- Community Suggestions Implementer - Community Suggestions Implementer
- Bug Fixer - QoL and Bug Fixer
- Modder - Modder
### VinniTR ### VinniTR
@ -52,6 +52,7 @@
- Created the original "reject_recently_left_players" plugin - Created the original "reject_recently_left_players" plugin
### Temp (3alTemp) ### Temp (3alTemp)
- Original idea for customizable series length on GUI builds
- Modder & Bug Fixer - Modder & Bug Fixer
### brostos ### brostos

View File

@ -406,6 +406,10 @@ class ServerController:
else: else:
raise RuntimeError(f'Unknown session type {sessiontype}') raise RuntimeError(f'Unknown session type {sessiontype}')
appcfg['Teams Series Length'] = self._config.teams_series_length
appcfg['FFA Series Length'] = self._config.ffa_series_length
# deprecated, left here in order to not break mods
classic.teams_series_length = self._config.teams_series_length classic.teams_series_length = self._config.teams_series_length
classic.ffa_series_length = self._config.ffa_series_length classic.ffa_series_length = self._config.ffa_series_length
@ -427,6 +431,10 @@ class ServerController:
self._config.player_rejoin_cooldown self._config.player_rejoin_cooldown
) )
bascenev1.set_max_players_override(
self._config.session_max_players_override
)
# And here.. we.. go. # And here.. we.. go.
if self._config.stress_test_players is not None: if self._config.stress_test_players is not None:
# Special case: run a stress test. # Special case: run a stress test.

View File

@ -103,8 +103,8 @@ class ClassicSubsystem(babase.AppSubsystem):
self.maps: dict[str, type[bascenev1.Map]] = {} self.maps: dict[str, type[bascenev1.Map]] = {}
# Gameplay. # Gameplay.
self.teams_series_length = 7 self.teams_series_length = 7 # deprecated, left for old mods
self.ffa_series_length = 24 self.ffa_series_length = 24 # deprecated, left for old mods
self.coop_session_args: dict = {} self.coop_session_args: dict = {}
# UI. # UI.

View File

@ -231,7 +231,9 @@ from bascenev1._settings import (
IntSetting, IntSetting,
Setting, Setting,
) )
from bascenev1._session import Session, set_player_rejoin_cooldown from bascenev1._session import (
Session, set_player_rejoin_cooldown, set_max_players_override
)
from bascenev1._stats import PlayerScoredMessage, PlayerRecord, Stats from bascenev1._stats import PlayerScoredMessage, PlayerRecord, Stats
from bascenev1._team import SessionTeam, Team, EmptyTeam from bascenev1._team import SessionTeam, Team, EmptyTeam
from bascenev1._teamgame import TeamGameActivity from bascenev1._teamgame import TeamGameActivity
@ -426,6 +428,7 @@ __all__ = [
'set_public_party_queue_enabled', 'set_public_party_queue_enabled',
'set_public_party_stats_url', 'set_public_party_stats_url',
'set_player_rejoin_cooldown', 'set_player_rejoin_cooldown',
'set_max_players_override',
'set_replay_speed_exponent', 'set_replay_speed_exponent',
'set_touchscreen_editing', 'set_touchscreen_editing',
'setmusic', 'setmusic',

View File

@ -67,8 +67,8 @@ class MultiTeamSession(Session):
max_players=self.get_max_players(), max_players=self.get_max_players(),
) )
self._series_length: int = classic.teams_series_length self._series_length: int = int(cfg.get('Teams Series Length', 7))
self._ffa_series_length: int = classic.ffa_series_length self._ffa_series_length: int = int(cfg.get('FFA Series Length', 24))
show_tutorial = cfg.get('Show Tutorial', True) show_tutorial = cfg.get('Show Tutorial', True)

View File

@ -23,6 +23,9 @@ if TYPE_CHECKING:
# such as skipping respawn waits. # such as skipping respawn waits.
_g_player_rejoin_cooldown: float = 0.0 _g_player_rejoin_cooldown: float = 0.0
# overrides the session's decision of max_players
_max_players_override: int | None = None
def set_player_rejoin_cooldown(cooldown: float) -> None: def set_player_rejoin_cooldown(cooldown: float) -> None:
"""Set the cooldown for individual players rejoining after leaving.""" """Set the cooldown for individual players rejoining after leaving."""
@ -30,6 +33,12 @@ def set_player_rejoin_cooldown(cooldown: float) -> None:
_g_player_rejoin_cooldown = max(0.0, cooldown) _g_player_rejoin_cooldown = max(0.0, cooldown)
def set_max_players_override(max_players: int | None) -> None:
"""Set the override for how many players can join a session"""
global _max_players_override # pylint: disable=global-statement
_max_players_override = max_players
class Session: class Session:
"""Defines a high level series of bascenev1.Activity-es. """Defines a high level series of bascenev1.Activity-es.
@ -161,7 +170,11 @@ class Session:
self.sessionteams = [] self.sessionteams = []
self.sessionplayers = [] self.sessionplayers = []
self.min_players = min_players self.min_players = min_players
self.max_players = max_players self.max_players = (
max_players
if _max_players_override is None
else _max_players_override
)
self.customdata = {} self.customdata = {}
self._in_set_activity = False self._in_set_activity = False
@ -255,7 +268,7 @@ class Session:
babase.app.classic is not None babase.app.classic is not None
and babase.app.classic.stress_test_update_timer is None and babase.app.classic.stress_test_update_timer is None
): ):
if len(self.sessionplayers) >= self.max_players: if len(self.sessionplayers) >= self.max_players >= 0:
# Print a rejection message *only* to the client trying to # Print a rejection message *only* to the client trying to
# join (prevents spamming everyone else in the game). # join (prevents spamming everyone else in the game).
_bascenev1.getsound('error').play() _bascenev1.getsound('error').play()

View File

@ -94,6 +94,8 @@ class ConfigNumberEdit:
changesound: bool = True, changesound: bool = True,
textscale: float = 1.0, textscale: float = 1.0,
as_percent: bool = False, as_percent: bool = False,
fallback_value: float = 0.0,
f: int = 1,
): ):
if displayname is None: if displayname is None:
displayname = configkey displayname = configkey
@ -103,8 +105,12 @@ class ConfigNumberEdit:
self._maxval = maxval self._maxval = maxval
self._increment = increment self._increment = increment
self._callback = callback self._callback = callback
self._value = bui.app.config.resolve(configkey) try:
self._value = bui.app.config.resolve(configkey)
except ValueError:
self._value = bui.app.config.get(configkey, fallback_value)
self._as_percent = as_percent self._as_percent = as_percent
self._f = f
self.nametext = bui.textwidget( self.nametext = bui.textwidget(
parent=parent, parent=parent,
@ -171,5 +177,5 @@ class ConfigNumberEdit:
if self._as_percent: if self._as_percent:
val = f'{round(self._value*100.0)}%' val = f'{round(self._value*100.0)}%'
else: else:
val = f'{self._value:.1f}' val = f'{self._value:.{self._f}f}'
bui.textwidget(edit=self.valuetext, text=val) bui.textwidget(edit=self.valuetext, text=val)

View File

@ -33,6 +33,7 @@ class PlayOptionsWindow(PopupWindow):
# pylint: disable=too-many-locals # pylint: disable=too-many-locals
from bascenev1 import filter_playlist, get_map_class from bascenev1 import filter_playlist, get_map_class
from bauiv1lib.playlist import PlaylistTypeVars from bauiv1lib.playlist import PlaylistTypeVars
from bauiv1lib.config import ConfigNumberEdit
self._r = 'gameListWindow' self._r = 'gameListWindow'
self._delegate = delegate self._delegate = delegate
@ -52,7 +53,7 @@ class PlayOptionsWindow(PopupWindow):
self._playlist = playlist self._playlist = playlist
self._width = 500.0 self._width = 500.0
self._height = 330.0 - 50.0 self._height = 370.0 - 50.0
# In teams games, show the custom names/colors button. # In teams games, show the custom names/colors button.
if self._sessiontype is bs.DualTeamSession: if self._sessiontype is bs.DualTeamSession:
@ -275,13 +276,37 @@ class PlayOptionsWindow(PopupWindow):
texture=bui.gettexture('lock'), texture=bui.gettexture('lock'),
) )
y_offs = 50 if show_shuffle_check_box else 0
# Series Length
y_offs2 = 40 if self._sessiontype is bs.DualTeamSession else 0
self._series_length_numedit = ConfigNumberEdit(
parent=self.root_widget,
position=(100, 200 + y_offs + y_offs2),
configkey=(
'FFA' if self._sessiontype is bs.FreeForAllSession else 'Teams'
) + ' Series Length',
displayname=bui.Lstr(
resource=self._r + (
'.pointsToWinText'
if self._sessiontype is bs.FreeForAllSession
else '.seriesLengthText'
)
),
minval=1.0,
increment=1.0 if self._sessiontype is bs.FreeForAllSession else 2.0,
fallback_value=(
24 if self._sessiontype is bs.FreeForAllSession else 7
),
f=0,
)
# Team names/colors. # Team names/colors.
self._custom_colors_names_button: bui.Widget | None self._custom_colors_names_button: bui.Widget | None
if self._sessiontype is bs.DualTeamSession: if self._sessiontype is bs.DualTeamSession:
y_offs = 50 if show_shuffle_check_box else 0
self._custom_colors_names_button = bui.buttonwidget( self._custom_colors_names_button = bui.buttonwidget(
parent=self.root_widget, parent=self.root_widget,
position=(100, 200 + y_offs), position=(100, 195 + y_offs),
size=(290, 35), size=(290, 35),
on_activate_call=bui.WeakCall(self._custom_colors_names_press), on_activate_call=bui.WeakCall(self._custom_colors_names_press),
autoselect=True, autoselect=True,

View File

@ -47,10 +47,14 @@ class ServerConfig:
# Max devices in the party. Note that this does *NOT* mean max players. # Max devices in the party. Note that this does *NOT* mean max players.
# Any device in the party can have more than one player on it if they have # Any device in the party can have more than one player on it if they have
# multiple controllers. Also, this number currently includes the server so # multiple controllers. Also, this number currently includes the server so
# generally make it 1 bigger than you need. Max-players is not currently # generally make it 1 bigger than you need.
# exposed but I'll try to add that soon.
max_party_size: int = 6 max_party_size: int = 6
# Max players that can join a session. If present this will override the
# session's preferred max_players. if a value below 0 is given player limit
# will be removed.
session_max_players_override: int | None = None
# Options here are 'ffa' (free-for-all), 'teams' and 'coop' (cooperative) # Options here are 'ffa' (free-for-all), 'teams' and 'coop' (cooperative)
# This value is ignored if you supply a playlist_code (see below). # This value is ignored if you supply a playlist_code (see below).
session_type: str = 'ffa' session_type: str = 'ffa'