From a8e9bf04887829cf18471913b8603f599cd12591 Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Sun, 14 Feb 2021 15:39:24 +0100 Subject: [PATCH] Add game preset attribute, unhardcode game presets (#3166) * Add game preset attribute, unhardcode game presets * Add game preset attribute doc * Add preset attribute to extended * Remove try methods from playerdata --- .../GameTicking/ForcePresetCommand.cs | 2 +- .../GamePresets/GamePresetAttribute.cs | 27 ++++++++++++ .../GamePresets/PresetDeathMatch.cs | 1 + .../GameTicking/GamePresets/PresetExtended.cs | 1 + .../GameTicking/GamePresets/PresetSandbox.cs | 1 + .../GamePresets/PresetSuspicion.cs | 1 + .../GameTicking/GamePresets/PresetTraitor.cs | 5 ++- .../GamePresets/PresetTraitorDeathMatch.cs | 1 + Content.Server/GameTicking/GameTicker.cs | 44 ++++++++++++------- .../Interfaces/GameTicking/IGameTicker.cs | 7 +-- 10 files changed, 68 insertions(+), 22 deletions(-) create mode 100644 Content.Server/GameTicking/GamePresets/GamePresetAttribute.cs diff --git a/Content.Server/Commands/GameTicking/ForcePresetCommand.cs b/Content.Server/Commands/GameTicking/ForcePresetCommand.cs index ed959d0e7a..7f98c52fb1 100644 --- a/Content.Server/Commands/GameTicking/ForcePresetCommand.cs +++ b/Content.Server/Commands/GameTicking/ForcePresetCommand.cs @@ -40,4 +40,4 @@ namespace Content.Server.Commands.GameTicking shell.WriteLine($"Forced the game to start with preset {name}."); } } -} \ No newline at end of file +} diff --git a/Content.Server/GameTicking/GamePresets/GamePresetAttribute.cs b/Content.Server/GameTicking/GamePresets/GamePresetAttribute.cs new file mode 100644 index 0000000000..5f9b2fa397 --- /dev/null +++ b/Content.Server/GameTicking/GamePresets/GamePresetAttribute.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Immutable; +using JetBrains.Annotations; + +namespace Content.Server.GameTicking.GamePresets +{ + /// + /// Attribute that marks a game preset. + /// The id and aliases are registered in lowercase in . + /// A duplicate id or alias will throw an exception. + /// + [AttributeUsage(AttributeTargets.Class, Inherited = false)] + [BaseTypeRequired(typeof(GamePreset))] + [MeansImplicitUse] + public class GamePresetAttribute : Attribute + { + public string Id { get; } + + public ImmutableList Aliases { get; } + + public GamePresetAttribute(string id, params string[] aliases) + { + Id = id; + Aliases = aliases.ToImmutableList(); + } + } +} diff --git a/Content.Server/GameTicking/GamePresets/PresetDeathMatch.cs b/Content.Server/GameTicking/GamePresets/PresetDeathMatch.cs index 87368f6834..a434661c61 100644 --- a/Content.Server/GameTicking/GamePresets/PresetDeathMatch.cs +++ b/Content.Server/GameTicking/GamePresets/PresetDeathMatch.cs @@ -6,6 +6,7 @@ using Robust.Shared.IoC; namespace Content.Server.GameTicking.GamePresets { + [GamePreset("deathmatch")] public sealed class PresetDeathMatch : GamePreset { [Dependency] private readonly IGameTicker _gameTicker = default!; diff --git a/Content.Server/GameTicking/GamePresets/PresetExtended.cs b/Content.Server/GameTicking/GamePresets/PresetExtended.cs index 60b8f099e5..a469cec3c5 100644 --- a/Content.Server/GameTicking/GamePresets/PresetExtended.cs +++ b/Content.Server/GameTicking/GamePresets/PresetExtended.cs @@ -3,6 +3,7 @@ using Robust.Server.Player; namespace Content.Server.GameTicking.GamePresets { + [GamePreset("extended")] public class PresetExtended : GamePreset { public override string Description => "No antagonists, have fun!"; diff --git a/Content.Server/GameTicking/GamePresets/PresetSandbox.cs b/Content.Server/GameTicking/GamePresets/PresetSandbox.cs index 4f370a9159..3288002a2f 100644 --- a/Content.Server/GameTicking/GamePresets/PresetSandbox.cs +++ b/Content.Server/GameTicking/GamePresets/PresetSandbox.cs @@ -5,6 +5,7 @@ using Robust.Shared.IoC; namespace Content.Server.GameTicking.GamePresets { + [GamePreset("sandbox")] public sealed class PresetSandbox : GamePreset { [Dependency] private readonly ISandboxManager _sandboxManager = default!; diff --git a/Content.Server/GameTicking/GamePresets/PresetSuspicion.cs b/Content.Server/GameTicking/GamePresets/PresetSuspicion.cs index 045ac396e3..f373a4571d 100644 --- a/Content.Server/GameTicking/GamePresets/PresetSuspicion.cs +++ b/Content.Server/GameTicking/GamePresets/PresetSuspicion.cs @@ -24,6 +24,7 @@ using Robust.Shared.Random; namespace Content.Server.GameTicking.GamePresets { + [GamePreset("suspicion")] public class PresetSuspicion : GamePreset { [Dependency] private readonly IChatManager _chatManager = default!; diff --git a/Content.Server/GameTicking/GamePresets/PresetTraitor.cs b/Content.Server/GameTicking/GamePresets/PresetTraitor.cs index 6ee10df25c..cca5e0cdc2 100644 --- a/Content.Server/GameTicking/GamePresets/PresetTraitor.cs +++ b/Content.Server/GameTicking/GamePresets/PresetTraitor.cs @@ -25,9 +25,10 @@ using Robust.Shared.Random; namespace Content.Server.GameTicking.GamePresets { + [GamePreset("traitor")] public class PresetTraitor : GamePreset { - [Dependency] private readonly IGameTicker _gameticker = default!; + [Dependency] private readonly IGameTicker _gameTicker = default!; [Dependency] private readonly IChatManager _chatManager = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IConfigurationManager _cfg = default!; @@ -154,7 +155,7 @@ namespace Content.Server.GameTicking.GamePresets traitor.GreetTraitor(codewords); } - _gameticker.AddGameRule(); + _gameTicker.AddGameRule(); return true; } diff --git a/Content.Server/GameTicking/GamePresets/PresetTraitorDeathMatch.cs b/Content.Server/GameTicking/GamePresets/PresetTraitorDeathMatch.cs index 6ae9e41904..4cdce1a01e 100644 --- a/Content.Server/GameTicking/GamePresets/PresetTraitorDeathMatch.cs +++ b/Content.Server/GameTicking/GamePresets/PresetTraitorDeathMatch.cs @@ -29,6 +29,7 @@ using Robust.Shared.Random; namespace Content.Server.GameTicking.GamePresets { + [GamePreset("traitordm", "traitordeathmatch")] public sealed class PresetTraitorDeathMatch : GamePreset { [Dependency] private readonly IConfigurationManager _cfg = default!; diff --git a/Content.Server/GameTicking/GameTicker.cs b/Content.Server/GameTicking/GameTicker.cs index 6876d1872e..25fc426ef4 100644 --- a/Content.Server/GameTicking/GameTicker.cs +++ b/Content.Server/GameTicking/GameTicker.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; using System.Linq; +using System.Reflection; using System.Threading; using Content.Server.GameObjects.Components.Access; using Content.Server.GameObjects.Components.GUI; @@ -41,6 +44,7 @@ using Robust.Shared.Map; using Robust.Shared.Network; using Robust.Shared.Prototypes; using Robust.Shared.Random; +using Robust.Shared.Reflection; using Robust.Shared.Timing; using Robust.Shared.Utility; using Robust.Shared.ViewVariables; @@ -118,6 +122,8 @@ namespace Content.Server.GameTicking set => _preset = value; } + public ImmutableDictionary Presets { get; private set; } + private GamePreset _preset; public event Action OnRunLevelChanged; @@ -132,6 +138,22 @@ namespace Content.Server.GameTicking DebugTools.Assert(!_initialized); + var presets = new Dictionary(); + + foreach (var type in _reflectionManager.FindTypesWithAttribute()) + { + var attribute = type.GetCustomAttribute(); + + presets.Add(attribute!.Id.ToLowerInvariant(), type); + + foreach (var alias in attribute.Aliases) + { + presets.Add(alias.ToLowerInvariant(), type); + } + } + + Presets = presets.ToImmutableDictionary(); + _netManager.RegisterNetMessage(nameof(MsgTickerJoinLobby)); _netManager.RegisterNetMessage(nameof(MsgTickerJoinGame)); _netManager.RegisterNetMessage(nameof(MsgTickerLobbyStatus)); @@ -479,21 +501,10 @@ namespace Content.Server.GameTicking public IEnumerable ActiveGameRules => _gameRules; - public bool TryGetPreset(string name, out Type type) + public bool TryGetPreset(string name, [NotNullWhen(true)] out Type type) { - type = name.ToLower() switch - { - "sandbox" => typeof(PresetSandbox), - "deathmatch" => typeof(PresetDeathMatch), - "suspicion" => typeof(PresetSuspicion), - "traitor" => typeof(PresetTraitor), - "traitordm" => typeof(PresetTraitorDeathMatch), - "traitordeathmatch" => typeof(PresetTraitorDeathMatch), - "extended" => typeof(PresetExtended), - _ => default - }; - - return type != default; + name = name.ToLowerInvariant(); + return Presets.TryGetValue(name, out type); } public void SetStartPreset(Type type, bool force = false) @@ -513,7 +524,7 @@ namespace Content.Server.GameTicking { if (!TryGetPreset(name, out var type)) { - throw new NotSupportedException(); + throw new NotSupportedException($"No preset found with name {name}"); } SetStartPreset(type, force); @@ -576,7 +587,7 @@ namespace Content.Server.GameTicking private IEntity _spawnPlayerMob(Job job, HumanoidCharacterProfile profile, bool lateJoin = true) { - EntityCoordinates coordinates = lateJoin ? GetLateJoinSpawnPoint() : GetJobSpawnPoint(job.Prototype.ID); + var coordinates = lateJoin ? GetLateJoinSpawnPoint() : GetJobSpawnPoint(job.Prototype.ID); var entity = _entityManager.SpawnEntity(PlayerPrototypeName, coordinates); var startingGear = _prototypeManager.Index(job.StartingGear); EquipStartingGear(entity, startingGear, profile); @@ -1071,6 +1082,7 @@ The current game mode is: [color=white]{0}[/color]. [Dependency] private readonly IBaseServer _baseServer = default!; [Dependency] private readonly IWatchdogApi _watchdogApi = default!; [Dependency] private readonly IEntitySystemManager _entitySystemManager = default!; + [Dependency] private readonly IReflectionManager _reflectionManager = default!; } public enum GameRunLevel diff --git a/Content.Server/Interfaces/GameTicking/IGameTicker.cs b/Content.Server/Interfaces/GameTicking/IGameTicker.cs index 404070aba9..e719f55020 100644 --- a/Content.Server/Interfaces/GameTicking/IGameTicker.cs +++ b/Content.Server/Interfaces/GameTicking/IGameTicker.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Content.Server.GameTicking; using Content.Server.Mobs; using Content.Shared.Roles; @@ -17,12 +18,12 @@ namespace Content.Server.Interfaces.GameTicking public interface IGameTicker { GameRunLevel RunLevel { get; } - + /// /// The map loaded by the GameTicker on round start. /// MapId DefaultMap { get; } - + /// /// The GridId loaded by the GameTicker on round start. /// @@ -59,7 +60,7 @@ namespace Content.Server.Interfaces.GameTicking void RemoveGameRule(GameRule rule); IEnumerable ActiveGameRules { get; } - bool TryGetPreset(string name, out Type type); + bool TryGetPreset(string name, [NotNullWhen(true)] out Type type); void SetStartPreset(Type type, bool force = false); void SetStartPreset(string name, bool force = false);