From d6cfca36dde9293000480cf0ef89474f45fcba8b Mon Sep 17 00:00:00 2001 From: Mooshua <43320783+Mooshua@users.noreply.github.com> Date: Thu, 28 Sep 2023 19:16:26 -0700 Subject: [PATCH] Expand provision capability, fix chat command handling --- .../BitMod.Commands/Hosts/ChatCommandHost.cs | 4 +- .../Sources/Internal/InGameSource.cs | 2 +- .../Config/ProvisionServerAdapter.cs | 19 ++++++- .../Helpers/GamemodeValidator.cs | 36 ++++++++++++++ .../Helpers/MapcycleValidator.cs | 49 +++++++++++++++++++ .../BitMod.Provision/Host/ProvisionHost.cs | 15 ++++++ .../BitMod.Launcher/BitMod.Launcher.csproj | 3 ++ .../BitMod.Launcher/configs/provisions.cfg | 5 ++ 8 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 builtin/BitMod.Provision/Helpers/GamemodeValidator.cs create mode 100644 builtin/BitMod.Provision/Helpers/MapcycleValidator.cs diff --git a/builtin/BitMod.Commands/Hosts/ChatCommandHost.cs b/builtin/BitMod.Commands/Hosts/ChatCommandHost.cs index 3d4b048..4ec2eb7 100644 --- a/builtin/BitMod.Commands/Hosts/ChatCommandHost.cs +++ b/builtin/BitMod.Commands/Hosts/ChatCommandHost.cs @@ -28,8 +28,10 @@ public Task OnChatMessage(PlayerTypedMessageEventArgs ev, BitServer s { // This is a command (starts with ! or /) // Send to command handler and prevent it from being shown in chat. + var withoutPrefix = ev.Message.Substring(1); + var source = new InGameSource(server, sender, _logger); - var input = CommandInput.FromString(source, ev.Message); + var input = CommandInput.FromString(source, withoutPrefix); _logger.Information("Player {@Name} {@SteamId} used command: {@Command} {@Args} (From string {@Message})", sender.Name, sender.SteamID, input.Command, input.Arguments, ev.Message); diff --git a/builtin/BitMod.Commands/Sources/Internal/InGameSource.cs b/builtin/BitMod.Commands/Sources/Internal/InGameSource.cs index 27b7b63..27687e5 100644 --- a/builtin/BitMod.Commands/Sources/Internal/InGameSource.cs +++ b/builtin/BitMod.Commands/Sources/Internal/InGameSource.cs @@ -38,6 +38,6 @@ public void Reply(string message) _player.SteamID, message); - _player.Message(message); + _player.SayToChat(message); } } diff --git a/builtin/BitMod.Provision/Config/ProvisionServerAdapter.cs b/builtin/BitMod.Provision/Config/ProvisionServerAdapter.cs index 24173e1..46d612d 100644 --- a/builtin/BitMod.Provision/Config/ProvisionServerAdapter.cs +++ b/builtin/BitMod.Provision/Config/ProvisionServerAdapter.cs @@ -6,6 +6,9 @@ public class ProvisionServerAdapter { private const string MAPCYCLE = "mapcycle"; private const string GAMEMODES = "gamemodes"; + private const string LOADING_TEXT = "loading_text"; + private const string MIN_PLAYERS = "min_players"; + private IConfigObject _configObject; public ProvisionServerAdapter(IConfigObject configObject) @@ -14,10 +17,16 @@ public ProvisionServerAdapter(IConfigObject configObject) } public bool HasMapcycle() - => _configObject.Get(MAPCYCLE) != null; + => _configObject.Get(MAPCYCLE) != null; public bool HasGamemodes() - => _configObject.Get(GAMEMODES) != null; + => _configObject.Get(GAMEMODES) != null; + + public bool HasLoadingText() + => _configObject.Get(LOADING_TEXT) != null; + + public bool HasMinPlayers() + => _configObject.Get(MIN_PLAYERS) != null; public string[]? GetMapcycle() => _configObject.Get(MAPCYCLE)?.AsList() @@ -33,5 +42,11 @@ public bool HasGamemodes() ?.Select(symbol => symbol.Symbol) ?.ToArray(); + public string? GetLoadingText() + => _configObject.Get(LOADING_TEXT)?.Symbol; + + public long? GetMinPlayers() + => _configObject.Get(MIN_PLAYERS)?.AsInt; + } diff --git a/builtin/BitMod.Provision/Helpers/GamemodeValidator.cs b/builtin/BitMod.Provision/Helpers/GamemodeValidator.cs new file mode 100644 index 0000000..8e7b290 --- /dev/null +++ b/builtin/BitMod.Provision/Helpers/GamemodeValidator.cs @@ -0,0 +1,36 @@ +using Serilog; + +namespace BitMod.Provision.Helpers; + +public class GamemodeValidator +{ + public static IEnumerable Known = new[] + { + // infantry conquest + "INFCONQ", + // rush (bomb defusal) + "RUSH", + // conquest + "CONQ", + // team deathmatch + "TDM", + // domination + "DOMI", + "FRONTLINE", + "Elimination", + "CaptureTheFlag", + "CashRun", + "VoxelTrench", + "VoxelFortify", + + }; + + public static void ValidateGamemodes(ILogger logger, IEnumerable chosen) + { + var notInKnown = chosen + .Where(opt => !Known.Contains(opt)); + + foreach (string s in notInKnown) + logger.Warning("[BitMod Provision] Gamemode {@Gamemode} is not known to BitMod, it may be invalid! Check your spelling.", s); + } +} diff --git a/builtin/BitMod.Provision/Helpers/MapcycleValidator.cs b/builtin/BitMod.Provision/Helpers/MapcycleValidator.cs new file mode 100644 index 0000000..c1f62ab --- /dev/null +++ b/builtin/BitMod.Provision/Helpers/MapcycleValidator.cs @@ -0,0 +1,49 @@ +using Serilog; + +namespace BitMod.Provision.Helpers; + +public class MapcycleValidator +{ + public static IEnumerable Known = new[] + { + + "Azagor", + "Basra", + "Construction", + "District", + "Dustydew", + "Eduardovo", + "Frugis", + "Isle", + "Lonovo", + "MultiIslands", + "Namak", + "OilDunes", + "River", + "Salhan", + "SandySunset", + "TensaTown", + "Valley", + "Wakistan", + "WineParadise", + + // old versions of maps + "Old_District", + "Old_Eduardovo", + "Old_MultuIslands", + "Old_Namak", + "Old_OilDunes", + + // not visible in polls + "EventMap" + }; + + public static void ValidateMaps(ILogger logger, IEnumerable chosen) + { + var notInKnown = chosen + .Where(opt => !Known.Contains(opt)); + + foreach (string s in notInKnown) + logger.Warning("[BitMod Provision] Map {@Map} is not known to BitMod, it may be invalid! Check your spelling.", s); + } +} diff --git a/builtin/BitMod.Provision/Host/ProvisionHost.cs b/builtin/BitMod.Provision/Host/ProvisionHost.cs index 41eb3e0..028da21 100644 --- a/builtin/BitMod.Provision/Host/ProvisionHost.cs +++ b/builtin/BitMod.Provision/Host/ProvisionHost.cs @@ -8,6 +8,7 @@ using BitMod.Events.Meta; using BitMod.Events.Server; using BitMod.Provision.Config; +using BitMod.Provision.Helpers; using BitMod.Public; using Lilikoi.Standard; @@ -50,13 +51,27 @@ private void Provision(BitServer server) if (localAdapter.HasMapcycle()) { _logger.Debug("Provisioning {@Server}'s mapcycle to {@Mapcycle}", server.ToString(), localAdapter.GetMapcycle()); + MapcycleValidator.ValidateMaps(_logger, localAdapter.GetMapcycle()); server.MapRotation.SetRotation(localAdapter.GetMapcycle()); } if (localAdapter.HasGamemodes()) { _logger.Debug("Provisioning {@Server}'s gamemodes to {@Gamemodes}", server.ToString(), localAdapter.GetGamemodes()); + GamemodeValidator.ValidateGamemodes(_logger, localAdapter.GetGamemodes()); server.GamemodeRotation.SetRotation(localAdapter.GetGamemodes()); } + + if (localAdapter.HasLoadingText()) + { + _logger.Debug("Provisioning {@Server}'s loading text to {@Text}", server.ToString(), localAdapter.GetLoadingText()); + server.SetLoadingScreenText(localAdapter.GetLoadingText()); + } + + if (localAdapter.HasMinPlayers()) + { + _logger.Debug("Provisioning {@Server}'s min players to {@MinPlayers}", server.ToString(), localAdapter.GetMinPlayers()); + server.RoundSettings.PlayersToStart = (int) localAdapter.GetMinPlayers(); + } } } diff --git a/standalone/BitMod.Launcher/BitMod.Launcher.csproj b/standalone/BitMod.Launcher/BitMod.Launcher.csproj index 7ccebeb..8445363 100644 --- a/standalone/BitMod.Launcher/BitMod.Launcher.csproj +++ b/standalone/BitMod.Launcher/BitMod.Launcher.csproj @@ -39,6 +39,9 @@ Always + + Always + diff --git a/standalone/BitMod.Launcher/configs/provisions.cfg b/standalone/BitMod.Launcher/configs/provisions.cfg index 38f2a5f..bb6fb8b 100644 --- a/standalone/BitMod.Launcher/configs/provisions.cfg +++ b/standalone/BitMod.Launcher/configs/provisions.cfg @@ -12,6 +12,11 @@ "1" "CONQ" } + // If you want a description to show on the loading screen, add it here. + // You can use unity rich text, as documented here: + // https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/StyledText.html + // "loading_text" "Welcome to this awesome server!" + // "mapcycle" // { // If you want to enforce a custom mapcycle, do it here.