diff --git a/Content.Client/GameTicking/Managers/ClientGameTicker.cs b/Content.Client/GameTicking/Managers/ClientGameTicker.cs index c15d0e3ae5..78d5abf0e7 100644 --- a/Content.Client/GameTicking/Managers/ClientGameTicker.cs +++ b/Content.Client/GameTicking/Managers/ClientGameTicker.cs @@ -37,7 +37,7 @@ namespace Content.Client.GameTicking.Managers [ViewVariables] public TimeSpan StartTime { get; private set; } [ViewVariables] public TimeSpan RoundStartTimeSpan { get; private set; } [ViewVariables] public new bool Paused { get; private set; } - [ViewVariables] public Dictionary Status { get; private set; } = new(); + [ViewVariables] public IReadOnlyDictionary> JobsAvailable => _jobsAvailable; [ViewVariables] public IReadOnlyDictionary StationNames => _stationNames; @@ -66,7 +66,6 @@ namespace Content.Client.GameTicking.Managers SubscribeNetworkEvent(UpdateJobsAvailable); SubscribeNetworkEvent(RoundRestartCleanup); - Status = new Dictionary(); _initialized = true; } @@ -97,8 +96,6 @@ namespace Content.Client.GameTicking.Managers LobbySong = message.LobbySong; LobbyBackground = message.LobbyBackground; Paused = message.Paused; - if (IsGameStarted) - Status.Clear(); LobbyStatusUpdated?.Invoke(); } @@ -123,11 +120,6 @@ namespace Content.Client.GameTicking.Managers private void LobbyReady(TickerLobbyReadyEvent message) { - // Merge the Dictionaries - foreach (var p in message.Status) - { - Status[p.Key] = p.Value; - } LobbyReadyUpdated?.Invoke(); } diff --git a/Content.Client/Lobby/LobbyState.cs b/Content.Client/Lobby/LobbyState.cs index bdb4b227cf..77bce6d65c 100644 --- a/Content.Client/Lobby/LobbyState.cs +++ b/Content.Client/Lobby/LobbyState.cs @@ -109,7 +109,6 @@ namespace Content.Client.Lobby _lobby.OptionsButton.OnPressed += _ => new OptionsMenu().Open(); - _playerManager.PlayerListUpdated += PlayerManagerOnPlayerListUpdated; _gameTicker.InfoBlobUpdated += UpdateLobbyUi; _gameTicker.LobbyStatusUpdated += LobbyStatusUpdated; _gameTicker.LobbyLateJoinStatusUpdated += LobbyLateJoinStatusUpdated; @@ -117,7 +116,6 @@ namespace Content.Client.Lobby public override void Shutdown() { - _playerManager.PlayerListUpdated -= PlayerManagerOnPlayerListUpdated; _gameTicker.InfoBlobUpdated -= UpdateLobbyUi; _gameTicker.LobbyStatusUpdated -= LobbyStatusUpdated; _gameTicker.LobbyLateJoinStatusUpdated -= LobbyLateJoinStatusUpdated; @@ -164,23 +162,6 @@ namespace Content.Client.Lobby _lobby.StartTime.Text = Loc.GetString("lobby-state-round-start-countdown-text", ("timeLeft", text)); } - private void PlayerManagerOnPlayerListUpdated(object? sender, EventArgs e) - { - var gameTicker = EntitySystem.Get(); - // Remove disconnected sessions from the Ready Dict - foreach (var p in gameTicker.Status) - { - if (!_playerManager.SessionsDict.TryGetValue(p.Key, out _)) - { - // This is a shitty fix. Observers can rejoin because they are already in the game. - // So we don't delete them, but keep them if they decide to rejoin - if (p.Value != LobbyPlayerStatus.Observer) - gameTicker.Status.Remove(p.Key); - } - } - - } - private void LobbyStatusUpdated() { UpdateLobbyBackground(); diff --git a/Content.Server/Administration/Commands/ReadyAll.cs b/Content.Server/Administration/Commands/ReadyAll.cs index 93b71dda77..d55ef09660 100644 --- a/Content.Server/Administration/Commands/ReadyAll.cs +++ b/Content.Server/Administration/Commands/ReadyAll.cs @@ -29,11 +29,7 @@ namespace Content.Server.Administration.Commands return; } - foreach (var (player, status) in gameTicker.PlayersInLobby) - { - if(status != LobbyPlayerStatus.Observer) - gameTicker.ToggleReady(player, ready); - } + gameTicker.ToggleReadyAll(ready); } } } diff --git a/Content.Server/Connection/ConnectionManager.cs b/Content.Server/Connection/ConnectionManager.cs index 5663015fe2..8319dbfffc 100644 --- a/Content.Server/Connection/ConnectionManager.cs +++ b/Content.Server/Connection/ConnectionManager.cs @@ -4,6 +4,7 @@ using Content.Server.Database; using Content.Server.GameTicking; using Content.Server.Preferences.Managers; using Content.Shared.CCVar; +using Content.Shared.GameTicking; using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Network; @@ -114,7 +115,9 @@ The ban reason is: ""{ban.Reason}"" } } - var wasInGame = EntitySystem.TryGet(out var ticker) && ticker.PlayersInGame.Contains(userId); + var wasInGame = EntitySystem.TryGet(out var ticker) && + ticker.PlayerGameStatuses.TryGetValue(userId, out var status) && + status == PlayerGameStatus.JoinedGame; if ((_plyMgr.PlayerCount >= _cfg.GetCVar(CCVars.SoftMaxPlayers) && adminData is null) && !wasInGame) { return (ConnectionDenyReason.Full, Loc.GetString("soft-player-cap-full"), null); diff --git a/Content.Server/GameTicking/Commands/JoinGameCommand.cs b/Content.Server/GameTicking/Commands/JoinGameCommand.cs index c3e8492f7b..acb211d8bd 100644 --- a/Content.Server/GameTicking/Commands/JoinGameCommand.cs +++ b/Content.Server/GameTicking/Commands/JoinGameCommand.cs @@ -40,7 +40,7 @@ namespace Content.Server.GameTicking.Commands var stationSystem = EntitySystem.Get(); var stationJobs = EntitySystem.Get(); - if (!ticker.PlayersInLobby.ContainsKey(player) || ticker.PlayersInLobby[player] == LobbyPlayerStatus.Observer) + if (ticker.PlayerGameStatuses.TryGetValue(player.UserId, out var status) && status == PlayerGameStatus.JoinedGame) { Logger.InfoS("security", $"{player.Name} ({player.UserId}) attempted to latejoin while in-game."); shell.WriteError($"{player.Name} is not in the lobby. This incident will be reported."); diff --git a/Content.Server/GameTicking/Commands/ObserveCommand.cs b/Content.Server/GameTicking/Commands/ObserveCommand.cs index 3998c27d1e..e5eda2b7d9 100644 --- a/Content.Server/GameTicking/Commands/ObserveCommand.cs +++ b/Content.Server/GameTicking/Commands/ObserveCommand.cs @@ -1,4 +1,5 @@ using Content.Shared.Administration; +using Content.Shared.GameTicking; using Robust.Server.Player; using Robust.Shared.Console; @@ -26,10 +27,15 @@ namespace Content.Server.GameTicking.Commands return; } - if (ticker.PlayersInLobby.ContainsKey(player)) + if (ticker.PlayerGameStatuses.TryGetValue(player.UserId, out var status) && + status != PlayerGameStatus.JoinedGame) + { ticker.MakeObserve(player); + } else + { shell.WriteError($"{player.Name} is not in the lobby. This incident will be reported."); + } } } } diff --git a/Content.Server/GameTicking/GameTicker.CVars.cs b/Content.Server/GameTicking/GameTicker.CVars.cs index 09917c81dc..bc8dfb6783 100644 --- a/Content.Server/GameTicking/GameTicker.CVars.cs +++ b/Content.Server/GameTicking/GameTicker.CVars.cs @@ -1,11 +1,12 @@ using Content.Shared.CCVar; +using Content.Shared.GameTicking; namespace Content.Server.GameTicking { public sealed partial class GameTicker { [ViewVariables] - public bool LobbyEnabled { get; private set; } = false; + public bool LobbyEnabled { get; private set; } [ViewVariables] public bool DummyTicker { get; private set; } = false; @@ -32,7 +33,17 @@ namespace Content.Server.GameTicking private void InitializeCVars() { - _configurationManager.OnValueChanged(CCVars.GameLobbyEnabled, value => LobbyEnabled = value, true); + _configurationManager.OnValueChanged(CCVars.GameLobbyEnabled, value => + { + LobbyEnabled = value; + foreach (var (userId, status) in _playerGameStatuses) + { + if (status == PlayerGameStatus.JoinedGame) + continue; + _playerGameStatuses[userId] = + LobbyEnabled ? PlayerGameStatus.NotReadyToPlay : PlayerGameStatus.ReadyToPlay; + } + }, true); _configurationManager.OnValueChanged(CCVars.GameDummyTicker, value => DummyTicker = value, true); _configurationManager.OnValueChanged(CCVars.GameLobbyDuration, value => LobbyDuration = TimeSpan.FromSeconds(value), true); _configurationManager.OnValueChanged(CCVars.GameDisallowLateJoins, diff --git a/Content.Server/GameTicking/GameTicker.Lobby.cs b/Content.Server/GameTicking/GameTicker.Lobby.cs index 54e7f7d33d..2af5bd0c60 100644 --- a/Content.Server/GameTicking/GameTicker.Lobby.cs +++ b/Content.Server/GameTicking/GameTicker.Lobby.cs @@ -9,9 +9,7 @@ namespace Content.Server.GameTicking public sealed partial class GameTicker { [ViewVariables] - private readonly Dictionary _playersInLobby = new(); - - [ViewVariables] private readonly HashSet _playersInGame = new(); + private readonly Dictionary _playerGameStatuses = new(); [ViewVariables] private TimeSpan _roundStartTime; @@ -25,12 +23,14 @@ namespace Content.Server.GameTicking [ViewVariables] private bool _roundStartCountdownHasNotStartedYetDueToNoPlayers; - public IReadOnlyDictionary PlayersInLobby => _playersInLobby; - public IReadOnlySet PlayersInGame => _playersInGame; + /// + /// The game status of a players user Id. May contain disconnected players + /// + public IReadOnlyDictionary PlayerGameStatuses => _playerGameStatuses; public void UpdateInfoText() { - RaiseNetworkEvent(GetInfoMsg(), Filter.Empty().AddPlayers(_playersInLobby.Keys)); + RaiseNetworkEvent(GetInfoMsg(), Filter.Empty().AddPlayers(_playerManager.NetworkedSessions)); } private string GetInfoText() @@ -48,31 +48,31 @@ namespace Content.Server.GameTicking return Loc.GetString("game-ticker-get-info-text",("roundId", RoundId), ("playerCount", playerCount),("mapName", mapName),("gmTitle", gmTitle),("desc", desc)); } - private TickerLobbyReadyEvent GetStatusSingle(ICommonSession player, LobbyPlayerStatus status) + private TickerLobbyReadyEvent GetStatusSingle(ICommonSession player, PlayerGameStatus gameStatus) { - return new (new Dictionary { { player.UserId, status } }); + return new (new Dictionary { { player.UserId, gameStatus } }); } private TickerLobbyReadyEvent GetPlayerStatus() { - var players = new Dictionary(); - foreach (var player in _playersInLobby.Keys) + var players = new Dictionary(); + foreach (var player in _playerGameStatuses.Keys) { - _playersInLobby.TryGetValue(player, out var status); - players.Add(player.UserId, status); + _playerGameStatuses.TryGetValue(player, out var status); + players.Add(player, status); } return new TickerLobbyReadyEvent(players); } private TickerLobbyStatusEvent GetStatusMsg(IPlayerSession session) { - _playersInLobby.TryGetValue(session, out var status); - return new TickerLobbyStatusEvent(RunLevel != GameRunLevel.PreRoundLobby, LobbySong, LobbyBackground,status == LobbyPlayerStatus.Ready, _roundStartTime, _roundStartTimeSpan, Paused); + _playerGameStatuses.TryGetValue(session.UserId, out var status); + return new TickerLobbyStatusEvent(RunLevel != GameRunLevel.PreRoundLobby, LobbySong, LobbyBackground,status == PlayerGameStatus.ReadyToPlay, _roundStartTime, _roundStartTimeSpan, Paused); } private void SendStatusToAll() { - foreach (var player in _playersInLobby.Keys) + foreach (var player in _playerManager.ServerSessions) { RaiseNetworkEvent(GetStatusMsg(player), player.ConnectedClient); } @@ -121,16 +121,29 @@ namespace Content.Server.GameTicking return Paused; } + public void ToggleReadyAll(bool ready) + { + var status = ready ? PlayerGameStatus.ReadyToPlay : PlayerGameStatus.NotReadyToPlay; + foreach (var playerUserId in _playerGameStatuses.Keys) + { + _playerGameStatuses[playerUserId] = status; + if (!_playerManager.TryGetSessionById(playerUserId, out var playerSession)) + continue; + RaiseNetworkEvent(GetStatusMsg(playerSession), playerSession.ConnectedClient); + RaiseNetworkEvent(GetStatusSingle(playerSession, status)); + } + } + public void ToggleReady(IPlayerSession player, bool ready) { - if (!_playersInLobby.ContainsKey(player)) + if (!_playerGameStatuses.ContainsKey(player.UserId)) return; if (!_userDb.IsLoadComplete(player)) return; - var status = ready ? LobbyPlayerStatus.Ready : LobbyPlayerStatus.NotReady; - _playersInLobby[player] = ready ? LobbyPlayerStatus.Ready : LobbyPlayerStatus.NotReady; + var status = ready ? PlayerGameStatus.ReadyToPlay : PlayerGameStatus.NotReadyToPlay; + _playerGameStatuses[player.UserId] = ready ? PlayerGameStatus.ReadyToPlay : PlayerGameStatus.NotReadyToPlay; RaiseNetworkEvent(GetStatusMsg(player), player.ConnectedClient); RaiseNetworkEvent(GetStatusSingle(player, status)); } diff --git a/Content.Server/GameTicking/GameTicker.Player.cs b/Content.Server/GameTicking/GameTicker.Player.cs index 7e9dc9dd08..aa07f70cc0 100644 --- a/Content.Server/GameTicking/GameTicker.Player.cs +++ b/Content.Server/GameTicking/GameTicker.Player.cs @@ -86,7 +86,7 @@ namespace Content.Server.GameTicking case SessionStatus.Disconnected: { - if (_playersInLobby.ContainsKey(session)) _playersInLobby.Remove(session); + _playerGameStatuses.Remove(session.UserId); _chatManager.SendAdminAnnouncement(Loc.GetString("player-leave-message", ("name", args.Session.Name))); @@ -121,18 +121,17 @@ namespace Content.Server.GameTicking { _chatManager.DispatchServerMessage(session, Loc.GetString("game-ticker-player-join-game-message")); - if (_playersInLobby.ContainsKey(session)) - _playersInLobby.Remove(session); + if (!_playerGameStatuses.ContainsKey(session.UserId)) + _playerGameStatuses.Remove(session.UserId); - _playersInGame.Add(session.UserId); + _playerGameStatuses[session.UserId] = PlayerGameStatus.JoinedGame; RaiseNetworkEvent(new TickerJoinGameEvent(), session.ConnectedClient); } private void PlayerJoinLobby(IPlayerSession session) { - _playersInLobby[session] = LobbyPlayerStatus.NotReady; - _playersInGame.Remove(session.UserId); + _playerGameStatuses[session.UserId] = LobbyEnabled ? PlayerGameStatus.NotReadyToPlay : PlayerGameStatus.ReadyToPlay; var client = session.ConnectedClient; RaiseNetworkEvent(new TickerJoinLobbyEvent(), client); diff --git a/Content.Server/GameTicking/GameTicker.RoundFlow.cs b/Content.Server/GameTicking/GameTicker.RoundFlow.cs index 649299fd2b..20fe19a159 100644 --- a/Content.Server/GameTicking/GameTicker.RoundFlow.cs +++ b/Content.Server/GameTicking/GameTicker.RoundFlow.cs @@ -20,6 +20,7 @@ using Robust.Shared.Random; using Robust.Shared.Utility; using System.Linq; using System.Threading.Tasks; +using Robust.Shared.Players; namespace Content.Server.GameTicking { @@ -150,7 +151,7 @@ namespace Content.Server.GameTicking RoundLengthMetric.Set(0); - var playerIds = _playersInLobby.Keys.Select(player => player.UserId.UserId).ToArray(); + var playerIds = _playerGameStatuses.Keys.Select(player => player.UserId).ToArray(); var serverName = _configurationManager.GetCVar(CCVars.AdminLogsServerName); // TODO FIXME AAAAAAAAAAAAAAAAAAAH THIS IS BROKEN // Task.Run as a terrible dirty workaround to avoid synchronization context deadlock from .Result here. @@ -166,44 +167,32 @@ namespace Content.Server.GameTicking var startingEvent = new RoundStartingEvent(RoundId); RaiseLocalEvent(startingEvent); - List readyPlayers; - if (LobbyEnabled) - { - readyPlayers = _playersInLobby.Where(p => p.Value == LobbyPlayerStatus.Ready).Select(p => p.Key) - .ToList(); - } - else - { - readyPlayers = _playersInLobby.Keys.ToList(); - } + var readyPlayers = new List(); + var readyPlayerProfiles = new Dictionary(); + foreach (var (userId, status) in _playerGameStatuses) + { + if (LobbyEnabled && status != PlayerGameStatus.ReadyToPlay) continue; + if (!_playerManager.TryGetSessionById(userId, out var session)) continue; #if DEBUG - foreach (var player in readyPlayers) - { - DebugTools.Assert(_userDb.IsLoadComplete(player), $"Player was readied up but didn't have user DB data loaded yet??"); - } + DebugTools.Assert(_userDb.IsLoadComplete(session), $"Player was readied up but didn't have user DB data loaded yet??"); #endif - - readyPlayers.RemoveAll(p => - { - if (_roleBanManager.GetRoleBans(p.UserId) != null) - return false; - Logger.ErrorS("RoleBans", $"Role bans for player {p} {p.UserId} have not been loaded yet."); - return true; - }); - - // Get the profiles for each player for easier lookup. - var profiles = _prefsManager.GetSelectedProfilesForPlayers( - readyPlayers - .Select(p => p.UserId).ToList()) - .ToDictionary(p => p.Key, p => (HumanoidCharacterProfile) p.Value); - - foreach (var readyPlayer in readyPlayers) - { - if (!profiles.ContainsKey(readyPlayer.UserId)) + if (_roleBanManager.GetRoleBans(userId) == null) { - profiles.Add(readyPlayer.UserId, HumanoidCharacterProfile.Random()); + Logger.ErrorS("RoleBans", $"Role bans for player {session} {userId} have not been loaded yet."); + continue; } + readyPlayers.Add(session); + HumanoidCharacterProfile profile; + if (_prefsManager.TryGetCachedPreferences(userId, out var preferences)) + { + profile = (HumanoidCharacterProfile) preferences.GetProfile(preferences.SelectedCharacterIndex); + } + else + { + profile = HumanoidCharacterProfile.Random(); + } + readyPlayerProfiles.Add(userId, profile); } var origReadyPlayers = readyPlayers.ToArray(); @@ -214,7 +203,7 @@ namespace Content.Server.GameTicking // MapInitialize *before* spawning players, our codebase is too shit to do it afterwards... _mapManager.DoMapInitialize(DefaultMap); - SpawnPlayers(readyPlayers, profiles, force); + SpawnPlayers(readyPlayers, readyPlayerProfiles, force); _roundStartDateTime = DateTime.UtcNow; RunLevel = GameRunLevel.InRound; @@ -340,7 +329,6 @@ namespace Content.Server.GameTicking } // This ordering mechanism isn't great (no ordering of minds) but functions var listOfPlayerInfoFinal = listOfPlayerInfo.OrderBy(pi => pi.PlayerOOCName).ToArray(); - _playersInGame.Clear(); RaiseNetworkEvent(new RoundEndMessageEvent(gamemodeTitle, roundEndText, roundDuration, RoundId, listOfPlayerInfoFinal.Length, listOfPlayerInfoFinal, LobbySong, @@ -445,6 +433,11 @@ namespace Content.Server.GameTicking RaiseNetworkEvent(ev, Filter.Broadcast()); DisallowLateJoin = false; + _playerGameStatuses.Clear(); + foreach (var session in _playerManager.ServerSessions) + { + _playerGameStatuses[session.UserId] = LobbyEnabled ? PlayerGameStatus.NotReadyToPlay : PlayerGameStatus.ReadyToPlay; + } } public bool DelayStart(TimeSpan time) diff --git a/Content.Server/GameTicking/GameTicker.Spawning.cs b/Content.Server/GameTicking/GameTicker.Spawning.cs index 10f318af5b..8af49e18db 100644 --- a/Content.Server/GameTicking/GameTicker.Spawning.cs +++ b/Content.Server/GameTicking/GameTicker.Spawning.cs @@ -231,7 +231,7 @@ namespace Content.Server.GameTicking public void MakeJoinGame(IPlayerSession player, EntityUid station, string? jobId = null) { - if (!_playersInLobby.ContainsKey(player)) + if (!_playerGameStatuses.ContainsKey(player.UserId)) return; if (!_userDb.IsLoadComplete(player)) @@ -265,8 +265,8 @@ namespace Content.Server.GameTicking EntitySystem.Get().SetCanReturnToBody(ghost, false); newMind.TransferTo(mob); - _playersInLobby[player] = LobbyPlayerStatus.Observer; - RaiseNetworkEvent(GetStatusSingle(player, LobbyPlayerStatus.Observer)); + _playerGameStatuses[player.UserId] = PlayerGameStatus.JoinedGame; + RaiseNetworkEvent(GetStatusSingle(player, PlayerGameStatus.JoinedGame)); } #region Mob Spawning Helpers diff --git a/Content.Server/Preferences/Managers/IServerPreferencesManager.cs b/Content.Server/Preferences/Managers/IServerPreferencesManager.cs index dde606663c..83df700b71 100644 --- a/Content.Server/Preferences/Managers/IServerPreferencesManager.cs +++ b/Content.Server/Preferences/Managers/IServerPreferencesManager.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; using Content.Shared.Preferences; @@ -13,6 +14,7 @@ namespace Content.Server.Preferences.Managers Task LoadData(IPlayerSession session, CancellationToken cancel); void OnClientDisconnected(IPlayerSession session); + bool TryGetCachedPreferences(NetUserId userId, [NotNullWhen(true)] out PlayerPreferences? playerPreferences); PlayerPreferences GetPreferences(NetUserId userId); IEnumerable> GetSelectedProfilesForPlayers(List userIds); } diff --git a/Content.Server/Preferences/Managers/ServerPreferencesManager.cs b/Content.Server/Preferences/Managers/ServerPreferencesManager.cs index 6c9d8d0244..fcd5d55c91 100644 --- a/Content.Server/Preferences/Managers/ServerPreferencesManager.cs +++ b/Content.Server/Preferences/Managers/ServerPreferencesManager.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -215,6 +216,26 @@ namespace Content.Server.Preferences.Managers return _cachedPlayerPrefs.ContainsKey(session.UserId); } + + /// + /// Tries to get the preferences from the cache + /// + /// User Id to get preferences for + /// The user preferences if true, otherwise null + /// If preferences are not null + public bool TryGetCachedPreferences(NetUserId userId, + [NotNullWhen(true)] out PlayerPreferences? playerPreferences) + { + if (_cachedPlayerPrefs.TryGetValue(userId, out var prefs)) + { + playerPreferences = prefs.Prefs; + return prefs.Prefs != null; + } + + playerPreferences = null; + return false; + } + /// /// Retrieves preferences for the given username from storage. /// Creates and saves default preferences if they are not found, then returns them. diff --git a/Content.Server/Station/Systems/StationJobsSystem.cs b/Content.Server/Station/Systems/StationJobsSystem.cs index 5c2865d8e4..f8dac0688c 100644 --- a/Content.Server/Station/Systems/StationJobsSystem.cs +++ b/Content.Server/Station/Systems/StationJobsSystem.cs @@ -24,6 +24,7 @@ public sealed partial class StationJobsSystem : EntitySystem [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly GameTicker _gameTicker = default!; [Dependency] private readonly StationSystem _stationSystem = default!; + [Dependency] private readonly IPlayerManager _playerManager = default!; /// public override void Initialize() @@ -40,7 +41,7 @@ public sealed partial class StationJobsSystem : EntitySystem if (_availableJobsDirty) { _cachedAvailableJobs = GenerateJobsAvailableEvent(); - RaiseNetworkEvent(_cachedAvailableJobs, Filter.Empty().AddPlayers(_gameTicker.PlayersInLobby.Keys)); + RaiseNetworkEvent(_cachedAvailableJobs, Filter.Empty().AddPlayers(_playerManager.ServerSessions)); _availableJobsDirty = false; } } diff --git a/Content.Shared/GameTicking/SharedGameTicker.cs b/Content.Shared/GameTicking/SharedGameTicker.cs index c70ab6f012..7c93f85a3e 100644 --- a/Content.Shared/GameTicking/SharedGameTicker.cs +++ b/Content.Shared/GameTicking/SharedGameTicker.cs @@ -97,9 +97,9 @@ namespace Content.Shared.GameTicking /// /// The Status of the Player in the lobby (ready, observer, ...) /// - public Dictionary Status { get; } + public Dictionary Status { get; } - public TickerLobbyReadyEvent(Dictionary status) + public TickerLobbyReadyEvent(Dictionary status) { Status = status; } @@ -168,11 +168,11 @@ namespace Content.Shared.GameTicking [Serializable, NetSerializable] - public enum LobbyPlayerStatus : sbyte + public enum PlayerGameStatus : sbyte { - NotReady = 0, - Ready, - Observer, + NotReadyToPlay = 0, + ReadyToPlay, + JoinedGame, } }