implement map and gametype command

This commit is contained in:
RaidMax 2021-11-28 10:04:37 -06:00
parent e739c91b52
commit 15cb114c15
9 changed files with 724 additions and 80 deletions

View File

@ -0,0 +1,126 @@
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Data.Models.Client;
using IW4MAdmin.Application.Extensions;
using Microsoft.Extensions.Logging;
using SharedLibraryCore;
using SharedLibraryCore.Commands;
using SharedLibraryCore.Configuration;
using SharedLibraryCore.Interfaces;
using ILogger = Microsoft.Extensions.Logging.ILogger;
namespace IW4MAdmin.Application.Commands
{
public class MapAndGameTypeCommand : Command
{
private const string ArgumentRegexPattern = "(?:\"([^\"]+)\"|([^\\s]+)) (?:\"([^\"]+)\"|([^\\s]+))";
private readonly ILogger _logger;
private readonly DefaultSettings _defaultSettings;
public MapAndGameTypeCommand(ILogger<MapAndGameTypeCommand> logger, CommandConfiguration config,
DefaultSettings defaultSettings, ITranslationLookup layout) : base(config, layout)
{
Name = "mapandgametype";
Description = _translationLookup["COMMANDS_MAG_DESCRIPTION"];
Alias = "mag";
Permission = EFClient.Permission.Administrator;
RequiresTarget = false;
Arguments = new[]
{
new CommandArgument
{
Name = _translationLookup["COMMADS_MAG_ARG_1"],
Required = true
},
new CommandArgument
{
Name = _translationLookup["COMMADS_MAG_ARG_2"],
Required = true
}
};
_logger = logger;
_defaultSettings = defaultSettings;
}
public override async Task ExecuteAsync(GameEvent gameEvent)
{
var match = Regex.Match(gameEvent.Data.Trim(), ArgumentRegexPattern,
RegexOptions.Compiled | RegexOptions.IgnoreCase);
if (!match.Success)
{
gameEvent.Origin.Tell(Syntax);
return;
}
string map;
string gametype;
if (match.Groups.Count > 3)
{
map = match.Groups[2].ToString();
gametype = match.Groups[4].ToString();
}
else
{
map = match.Groups[1].ToString();
gametype = match.Groups[3].ToString();
}
var matchingMaps = gameEvent.Owner.FindMap(map);
var matchingGametypes = _defaultSettings.FindGametype(gametype, gameEvent.Owner.GameName);
if (matchingMaps.Count > 1)
{
gameEvent.Origin.Tell(_translationLookup["COMMANDS_MAG_MULTIPLE_MAPS"]);
foreach (var matchingMap in matchingMaps)
{
gameEvent.Origin.Tell(
$"[(Color::Yellow){matchingMap.Alias}(Color::White)] [(Color::Yellow){matchingMap.Name}(Color::White)]");
}
return;
}
if (matchingGametypes.Count > 1)
{
gameEvent.Origin.Tell(_translationLookup["COMMANDS_MAG_MULTIPLE_GAMETYPES"]);
foreach (var matchingGametype in matchingGametypes)
{
gameEvent.Origin.Tell(
$"[(Color::Yellow){matchingGametype.Alias}(Color::White)] [(Color::Yellow){matchingGametype.Name}(Color::White)]");
}
return;
}
map = matchingMaps.FirstOrDefault()?.Name ?? map;
gametype = matchingGametypes.FirstOrDefault()?.Name ?? gametype;
var hasMatchingGametype = matchingGametypes.Any();
_logger.LogDebug("Changing map to {Map} and gametype {Gametype}", map, gametype);
await gameEvent.Owner.SetDvarAsync("g_gametype", gametype);
gameEvent.Owner.Broadcast(_translationLookup["COMMANDS_MAP_SUCCESS"].FormatExt(map));
await Task.Delay(gameEvent.Owner.Manager.GetApplicationSettings().Configuration().MapChangeDelaySeconds);
switch (gameEvent.Owner.GameName)
{
case Server.Game.IW5:
await gameEvent.Owner.ExecuteCommandAsync(
$"load_dsr {(hasMatchingGametype ? gametype.ToUpper() + "_default" : gametype)};map {map}");
break;
case Server.Game.T6:
await gameEvent.Owner.ExecuteCommandAsync($"exec {gametype}.cfg;map {map}");
break;
default:
await gameEvent.Owner.ExecuteCommandAsync($"map {map}");
break;
}
}
}
}

View File

@ -68,6 +68,504 @@
} }
} }
], ],
"Gametypes": [
{
"Game": "IW4",
"Gametypes": [
{
"Name": "arena",
"Alias": "Arena"
},
{
"Name": "ctf",
"Alias": "Capture The Flag"
},
{
"Name": "dd",
"Alias": "Demolition"
},
{
"Name": "dm",
"Alias": "Free For All"
},
{
"Name": "dom",
"Alias": "Domination"
},
{
"Name": "gtnw",
"Alias": "Global Thermo-Nuclear War"
},
{
"Name": "koth",
"Alias": "Headquarters"
},
{
"Name": "oneflag",
"Alias": "One-Flag CTF"
},
{
"Name": "sab",
"Alias": "Sabotage"
},
{
"Name": "sd",
"Alias": "Search & Destroy"
},
{
"Name": "war",
"Alias": "Team Deathmatch"
}
]
},
{
"Game": "T4",
"Gametypes": [
{
"Name": "ctf",
"Alias": "Capture The Flag"
},
{
"Name": "dom",
"Alias": "Domination"
},
{
"Name": "dm",
"Alias": "Free For All"
},
{
"Name": "koth",
"Alias": "Headquarters"
},
{
"Name": "tdm",
"Alias": "Team Deathmatch"
},
{
"Name": "sab",
"Alias": "Sabotage"
},
{
"Name": "sd",
"Alias": "Search & Destroy"
},
{
"Name": "twar",
"Alias": "War"
}
]
},
{
"Game": "IW5",
"Gametypes": [
{
"Name": "tdm",
"Alias": "Team Deathmatch"
},
{
"Name": "dom",
"Alias": "Domination"
},
{
"Name": "ctf",
"Alias": "Capture The Flag"
},
{
"Name": "dd",
"Alias": "Demolition"
},
{
"Name": "dz",
"Alias": "Drop Zone"
},
{
"Name": "ffa",
"Alias": "Free For All"
},
{
"Name": "gg",
"Alias": "Gun Game"
},
{
"Name": "hq",
"Alias": "Headquarters"
},
{
"Name": "koth",
"Alias": "Headquarters"
},
{
"Name": "inf",
"Alias": "Infected"
},
{
"Name": "jug",
"Alias": "Juggernaut"
},
{
"Name": "kc",
"Alias": "Kill Confirmed"
},
{
"Name": "oic",
"Alias": "One In The Chamber"
},
{
"Name": "sab",
"Alias": "Sabotage"
},
{
"Name": "sd",
"Alias": "Search & Destroy"
},
{
"Name": "tdef",
"Alias": "Team Defender"
},
{
"Name": "tj",
"Alias": "Team Juggernaut"
}
]
},
{
"Game": "T5",
"Gametypes": [
{
"Name": "ctf",
"Alias": "Capture The Flag"
},
{
"Name": "dem",
"Alias": "Demolition"
},
{
"Name": "dom",
"Alias": "Domination"
},
{
"Name": "dm",
"Alias": "Free For All"
},
{
"Name": "gun",
"Alias": "Gun Game"
},
{
"Name": "hlnd",
"Alias": "Sticks & Stones"
},
{
"Name": "koth",
"Alias": "Headquarters"
},
{
"Name": "oic",
"Alias": "One In The Chamber"
},
{
"Name": "sab",
"Alias": "Sabotage"
},
{
"Name": "sd",
"Alias": "Search & Destroy"
},
{
"Name": "shrp",
"Alias": "Sharpshooter"
},
{
"Name": "tdm",
"Alias": "Team Deathmatch"
}
]
},
{
"Game": "IW6",
"Gametypes": [
{
"Name": "blitz",
"Alias": "Blitz"
},
{
"Name": "conf",
"Alias": "Kill Confirmed"
},
{
"Name": "cranked",
"Alias": "Cranked"
},
{
"Name": "dm",
"Alias": "Free For All"
},
{
"Name": "dom",
"Alias": "Domination"
},
{
"Name": "grind",
"Alias": "Grind"
},
{
"Name": "grnd",
"Alias": "Drop Zone"
},
{
"Name": "gun",
"Alias": "Gun Game"
},
{
"Name": "horde",
"Alias": "Safeguard"
},
{
"Name": "infect",
"Alias": "Infected"
},
{
"Name": "sd",
"Alias": "Search & Destroy"
},
{
"Name": "siege",
"Alias": "Reinforce"
},
{
"Name": "sotf",
"Alias": "Hunted"
},
{
"Name": "sotf_ffa",
"Alias": "Hunted FFA"
},
{
"Name": "sr",
"Alias": "Search & Rescue"
},
{
"Name": "war",
"Alias": "Team Deathmatch"
}
]
},
{
"Game": "T6",
"Gametypes": [
{
"Name": "conf",
"Alias": "Kill Confirmed"
},
{
"Name": "ctf",
"Alias": "Capture The Flag"
},
{
"Name": "dem",
"Alias": "Demolition"
},
{
"Name": "dm",
"Alias": "Free For All"
},
{
"Name": "dom",
"Alias": "Domination"
},
{
"Name": "gun",
"Alias": "Gun Game"
},
{
"Name": "hq",
"Alias": "Headquarters"
},
{
"Name": "koth",
"Alias": "Hardpoint"
},
{
"Name": "oic",
"Alias": "One In The Chamber"
},
{
"Name": "oneflag",
"Alias": "One-Flag CTF"
},
{
"Name": "sas",
"Alias": "Sticks & Stones"
},
{
"Name": "sd",
"Alias": "Search & Destroy"
},
{
"Name": "shrp",
"Alias": "Sharpshooter"
},
{
"Name": "tdm",
"Alias": "Team Deathmatch"
}
]
},
{
"Game": "T7",
"Gametypes": [
{
"Name": "ball",
"Alias": "Uplink"
},
{
"Name": "clean",
"Alias": "Fracture"
},
{
"Name": "conf",
"Alias": "Kill Confirmed"
},
{
"Name": "ctf",
"Alias": "Capture The Flag"
},
{
"Name": "dom",
"Alias": "Domination"
},
{
"Name": "dem",
"Alias": "Demolition"
},
{
"Name": "dm",
"Alias": "Free For All"
},
{
"Name": "escort",
"Alias": "Safeguard"
},
{
"Name": "gun",
"Alias": "Gun Game"
},
{
"Name": "koth",
"Alias": "Hardpoint"
},
{
"Name": "sd",
"Alias": "Search & Destroy"
},
{
"Name": "tdm",
"Alias": "Team Deathmatch"
},
{
"Name": "hc_ball",
"Alias": "Hardcore Uplink"
},
{
"Name": "hc_clean",
"Alias": "Hardcore Fracture"
},
{
"Name": "hc_conf",
"Alias": "Hardcore Kill Confirmed"
},
{
"Name": "hc_ctf",
"Alias": "Hardcore Capture The Flag"
},
{
"Name": "hc_dom",
"Alias": "Hardcore Domination"
},
{
"Name": "hc_dem",
"Alias": "Hardcore Demolition"
},
{
"Name": "hc_dm",
"Alias": "Hardcore Free For All"
},
{
"Name": "hc_escort",
"Alias": "Hardcore Safeguard"
},
{
"Name": "hc_gun",
"Alias": "Hardcore Gun Game"
},
{
"Name": "hc_koth",
"Alias": "Hardcore Hardpoint"
},
{
"Name": "hc_sd",
"Alias": "Hardcore Search & Destroy"
},
{
"Name": "hc_tdm",
"Alias": "Hardcore Team Deathmatch"
}
]
},
{
"Game": "SHG1",
"Gametypes": [
{
"Name": "ball",
"Alias": "Uplink"
},
{
"Name": "conf",
"Alias": "Kill Confirmed"
},
{
"Name": "ctf",
"Alias": "Capture The Flag"
},
{
"Name": "dom",
"Alias": "Domination"
},
{
"Name": "dm",
"Alias": "Free For All"
},
{
"Name": "gun",
"Alias": "Gun Game"
},
{
"Name": "hp",
"Alias": "Hardpoint"
},
{
"Name": "infect",
"Alias": "Infected"
},
{
"Name": "sd",
"Alias": "Search & Destroy"
},
{
"Name": "sr",
"Alias": "Search & Rescue"
},
{
"Name": "war",
"Alias": "Team Deathmatch"
},
{
"Name": "twar",
"Alias": "Momentum"
}
]
}
],
"Maps": [ "Maps": [
{ {
"Game": "IW3", "Game": "IW3",

View File

@ -1,6 +1,10 @@
using IW4MAdmin.Application.Misc; using System;
using System.Collections.Generic;
using IW4MAdmin.Application.Misc;
using SharedLibraryCore.Interfaces; using SharedLibraryCore.Interfaces;
using System.Linq; using System.Linq;
using SharedLibraryCore;
using SharedLibraryCore.Configuration;
namespace IW4MAdmin.Application.Extensions namespace IW4MAdmin.Application.Extensions
{ {
@ -13,9 +17,19 @@ namespace IW4MAdmin.Application.Extensions
/// <returns></returns> /// <returns></returns>
public static string CommandConfigNameForType(this IManagerCommand command) public static string CommandConfigNameForType(this IManagerCommand command)
{ {
return command.GetType() == typeof(ScriptCommand) ? return command.GetType() == typeof(ScriptCommand)
$"{char.ToUpper(command.Name[0])}{command.Name.Substring(1)}Command" : ? $"{char.ToUpper(command.Name[0])}{command.Name.Substring(1)}Command"
command.GetType().Name; : command.GetType().Name;
} }
public static IList<Map> FindMap(this Server server, string mapName) => server.Maps.Where(map =>
map.Name.Equals(mapName, StringComparison.InvariantCultureIgnoreCase) ||
map.Alias.Equals(mapName, StringComparison.InvariantCultureIgnoreCase)).ToList();
public static IList<Gametype> FindGametype(this DefaultSettings settings, string gameType, Server.Game? game = null) =>
settings.Gametypes?.Where(gt => game == null || gt.Game == game)
.SelectMany(gt => gt.Gametypes).Where(gt =>
gt.Alias.Contains(gameType, StringComparison.CurrentCultureIgnoreCase) ||
gt.Name.Contains(gameType, StringComparison.CurrentCultureIgnoreCase)).ToList();
} }
} }

View File

@ -7,6 +7,7 @@ namespace SharedLibraryCore.Configuration
public string[] AutoMessages { get; set; } public string[] AutoMessages { get; set; }
public string[] GlobalRules { get; set; } public string[] GlobalRules { get; set; }
public MapConfiguration[] Maps { get; set; } public MapConfiguration[] Maps { get; set; }
public GametypeConfiguration[] Gametypes { get; set; }
public QuickMessageConfiguration[] QuickMessages {get; set;} public QuickMessageConfiguration[] QuickMessages {get; set;}
public string[] DisallowedClientNames { get; set; } public string[] DisallowedClientNames { get; set; }
public GameStringConfiguration GameStrings { get; set; } public GameStringConfiguration GameStrings { get; set; }

View File

@ -0,0 +1,8 @@
namespace SharedLibraryCore.Configuration
{
public class GametypeConfiguration
{
public Server.Game Game { get; set; }
public Gametype[] Gametypes { get; set; }
}
}

View File

@ -1,16 +1,8 @@
using System; namespace SharedLibraryCore.Configuration
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static SharedLibraryCore.Server;
namespace SharedLibraryCore.Configuration
{ {
public class MapConfiguration public class MapConfiguration
{ {
public Game Game { get; set; } public Server.Game Game { get; set; }
public List<Map> Maps { get; set; } public Map[] Maps { get; set; }
} }
} }

View File

@ -0,0 +1,8 @@
namespace SharedLibraryCore
{
public class Gametype
{
public string Name { get; set; }
public string Alias { get; set; }
}
}

View File

@ -0,0 +1,10 @@
namespace SharedLibraryCore
{
public class Map
{
public string Name { get; set; }
public string Alias { get; set; }
public override string ToString() => Alias;
}
}

View File

@ -1,13 +0,0 @@
using System;
using System.Reflection;
namespace SharedLibraryCore
{
public class Map
{
public String Name { get; set; }
public String Alias { get; set; }
public override string ToString() => Alias;
}
}