From 4098f7fd9b65fed61bfa669f4c07da22296db8d8 Mon Sep 17 00:00:00 2001 From: Vera Aguilera Puerto <6766154+Zumorica@users.noreply.github.com> Date: Thu, 3 Mar 2022 20:15:15 +0100 Subject: [PATCH] Load Maps on Round Start, not Round Restart. Shut down server if Round fails to Start 5 times. (#6977) --- .../Tests/Administration/Logs/AddTests.cs | 10 ++---- .../GameTicking/GameTicker.CVars.cs | 8 +++++ .../GameTicking/GameTicker.RoundFlow.cs | 36 ++++++++++++++----- Content.Server/GameTicking/GameTicker.cs | 2 ++ Content.Shared/CCVar/CCVars.cs | 12 +++++++ 5 files changed, 51 insertions(+), 17 deletions(-) diff --git a/Content.IntegrationTests/Tests/Administration/Logs/AddTests.cs b/Content.IntegrationTests/Tests/Administration/Logs/AddTests.cs index 3ee54af303..4acbdf6dcd 100644 --- a/Content.IntegrationTests/Tests/Administration/Logs/AddTests.cs +++ b/Content.IntegrationTests/Tests/Administration/Logs/AddTests.cs @@ -234,8 +234,6 @@ public sealed class AddTests : ContentIntegrationTest await server.WaitIdleAsync(); var sDatabase = server.ResolveDependency(); - var sEntities = server.ResolveDependency(); - var sMaps = server.ResolveDependency(); var sSystems = server.ResolveDependency(); var sAdminLogSystem = sSystems.GetEntitySystem(); @@ -245,10 +243,7 @@ public sealed class AddTests : ContentIntegrationTest await server.WaitPost(() => { - var coordinates = GetMainEntityCoordinates(sMaps); - var entity = sEntities.SpawnEntity(null, coordinates); - - sAdminLogSystem.Add(LogType.Unknown, $"{entity} test log: {guid}"); + sAdminLogSystem.Add(LogType.Unknown, $"test log: {guid}"); }); await server.WaitPost(() => @@ -284,8 +279,7 @@ public sealed class AddTests : ContentIntegrationTest await foreach (var json in sDatabase.GetAdminLogsJson(filter)) { var root = json.RootElement; - - Assert.That(root.TryGetProperty("entity", out _), Is.True); + Assert.That(root.TryGetProperty("guid", out _), Is.True); json.Dispose(); diff --git a/Content.Server/GameTicking/GameTicker.CVars.cs b/Content.Server/GameTicking/GameTicker.CVars.cs index 5c86dc53bd..ba7aa70468 100644 --- a/Content.Server/GameTicking/GameTicker.CVars.cs +++ b/Content.Server/GameTicking/GameTicker.CVars.cs @@ -27,6 +27,11 @@ namespace Content.Server.GameTicking [ViewVariables] public float MaxStationOffset { get; private set; } = 0f; +#if EXCEPTION_TOLERANCE + [ViewVariables] + public int RoundStartFailShutdownCount { get; private set; } = 0; +#endif + private void InitializeCVars() { _configurationManager.OnValueChanged(CCVars.GameLobbyEnabled, value => LobbyEnabled = value, true); @@ -37,6 +42,9 @@ namespace Content.Server.GameTicking _configurationManager.OnValueChanged(CCVars.StationOffset, value => StationOffset = value, true); _configurationManager.OnValueChanged(CCVars.StationRotation, value => StationRotation = value, true); _configurationManager.OnValueChanged(CCVars.MaxStationOffset, value => MaxStationOffset = value, true); +#if EXCEPTION_TOLERANCE + _configurationManager.OnValueChanged(CCVars.RoundStartFailShutdownCount, value => RoundStartFailShutdownCount = value, true); +#endif } } } diff --git a/Content.Server/GameTicking/GameTicker.RoundFlow.cs b/Content.Server/GameTicking/GameTicker.RoundFlow.cs index 3a782e5994..4ec2f4daa2 100644 --- a/Content.Server/GameTicking/GameTicker.RoundFlow.cs +++ b/Content.Server/GameTicking/GameTicker.RoundFlow.cs @@ -14,6 +14,7 @@ using Content.Shared.GameTicking; using Content.Shared.Preferences; using Content.Shared.Station; using Prometheus; +using Robust.Server; using Robust.Server.Player; using Robust.Shared.GameObjects; using Robust.Shared.IoC; @@ -39,7 +40,10 @@ namespace Content.Server.GameTicking "ss14_round_length", "Round length in seconds."); - [Dependency] private readonly IServerDbManager _db = default!; +#if EXCEPTION_TOLERANCE + [ViewVariables] + private int _roundStartFailCount = 0; +#endif [ViewVariables] private TimeSpan _roundStartTimeSpan; @@ -190,6 +194,8 @@ namespace Content.Server.GameTicking SendServerMessage(Loc.GetString("game-ticker-start-round")); + LoadMaps(); + StartGamePresetRules(); RoundLengthMetric.Set(0); @@ -258,11 +264,24 @@ namespace Content.Server.GameTicking } catch(Exception e) { + _roundStartFailCount++; - Logger.WarningS("ticker", $"Exception caught while trying to start the round! Restarting..."); + if (RoundStartFailShutdownCount > 0 && _roundStartFailCount >= RoundStartFailShutdownCount) + { + Logger.FatalS("ticker", $"Failed to start a round {_roundStartFailCount} time(s) in a row... Shutting down!"); + _runtimeLog.LogException(e, nameof(GameTicker)); + _baseServer.Shutdown("Restarting server"); + return; + } + + Logger.WarningS("ticker", $"Exception caught while trying to start the round! Restarting round..."); _runtimeLog.LogException(e, nameof(GameTicker)); RestartRound(); + return; } + + // Round started successfully! Reset counter... + _roundStartFailCount = 0; #endif } @@ -373,7 +392,6 @@ namespace Content.Server.GameTicking RunLevel = GameRunLevel.PreRoundLobby; LobbySong = _robustRandom.Pick(_lobbyMusicCollection.PickFiles).ToString(); ResettingCleanup(); - LoadMaps(); if (!LobbyEnabled) { @@ -411,18 +429,18 @@ namespace Content.Server.GameTicking unCastData.ContentData()?.WipeMind(); } - // Delete all entities. - foreach (var entity in EntityManager.GetEntities().ToList()) + _startingRound = false; + + _mapManager.Restart(); + + // Delete all remaining entities. + foreach (var entity in EntityManager.GetEntities().ToArray()) { // TODO: Maybe something less naive here? // FIXME: Actually, definitely. EntityManager.DeleteEntity(entity); } - _startingRound = false; - - _mapManager.Restart(); - _roleBanManager.Restart(); // Clear up any game rules. diff --git a/Content.Server/GameTicking/GameTicker.cs b/Content.Server/GameTicking/GameTicker.cs index e3b1ef5518..a74684a47a 100644 --- a/Content.Server/GameTicking/GameTicker.cs +++ b/Content.Server/GameTicking/GameTicker.cs @@ -2,6 +2,7 @@ using Content.Server.Administration.Logs; using Content.Server.Administration.Managers; using Content.Server.CharacterAppearance.Systems; using Content.Server.Chat.Managers; +using Content.Server.Database; using Content.Server.Ghost; using Content.Server.Maps; using Content.Server.PDA; @@ -89,6 +90,7 @@ namespace Content.Server.GameTicking [Dependency] private readonly IBaseServer _baseServer = default!; [Dependency] private readonly IWatchdogApi _watchdogApi = default!; [Dependency] private readonly IGameMapManager _gameMapManager = default!; + [Dependency] private readonly IServerDbManager _db = default!; #if EXCEPTION_TOLERANCE [Dependency] private readonly IRuntimeLog _runtimeLog = default!; #endif diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index 5e0e20d96a..e8ca923a7e 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -60,6 +60,9 @@ namespace Content.Shared.CCVar public static readonly CVarDef EventsEnabled = CVarDef.Create("events.enabled", true, CVar.ARCHIVE | CVar.SERVERONLY); + /// + /// Disables most functionality in the GameTicker. + /// public static readonly CVarDef GameDummyTicker = CVarDef.Create("game.dummyticker", false, CVar.ARCHIVE | CVar.SERVERONLY); @@ -154,6 +157,15 @@ namespace Content.Shared.CCVar public static readonly CVarDef SoftMaxPlayers = CVarDef.Create("game.soft_max_players", 30, CVar.SERVERONLY | CVar.ARCHIVE); +#if EXCEPTION_TOLERANCE + /// + /// Amount of times round start must fail before the server is shut down. + /// Set to 0 or a negative number to disable. + /// + public static readonly CVarDef RoundStartFailShutdownCount = + CVarDef.Create("game.round_start_fail_shutdown_count", 5, CVar.SERVERONLY | CVar.SERVER); +#endif + /* * Discord */