add initial CS:GO support

This commit is contained in:
RaidMax
2021-06-03 10:51:03 -05:00
parent 9488f754d4
commit be08d49f0a
38 changed files with 873 additions and 197 deletions

View File

@ -11,20 +11,20 @@ namespace SharedLibraryCore.Interfaces
/// </summary>
public enum GroupType
{
EventType,
OriginNetworkId,
TargetNetworkId,
OriginClientNumber,
TargetClientNumber,
OriginName,
TargetName,
OriginTeam,
TargetTeam,
Weapon,
Damage,
MeansOfDeath,
HitLocation,
Message,
EventType = 0,
OriginNetworkId = 1,
TargetNetworkId = 2,
OriginClientNumber = 3,
TargetClientNumber = 4,
OriginName = 5,
TargetName = 6,
OriginTeam = 7,
TargetTeam = 8,
Weapon = 9,
Damage = 10,
MeansOfDeath = 11,
HitLocation = 12,
Message = 13,
RConClientNumber = 100,
RConScore = 101,
RConPing = 102,
@ -38,6 +38,8 @@ namespace SharedLibraryCore.Interfaces
RConDvarDomain = 110,
RConStatusMap = 111,
RConStatusGametype = 112,
RConStatusHostname = 113,
RConStatusMaxPlayers = 114,
AdditionalGroup = 200
}

View File

@ -45,6 +45,16 @@ namespace SharedLibraryCore.Interfaces
/// </summary>
ParserRegex Time { get; set; }
/// <summary>
/// stores the regex information for the map change game log
/// </summary>
ParserRegex MapChange { get; }
/// <summary>
/// stores the regex information for the map end game log
/// </summary>
ParserRegex MapEnd { get; }
/// <summary>
/// indicates the format expected for parsed guids
/// </summary>

View File

@ -11,7 +11,8 @@
/// <param name="ipAddress">ip address of the server</param>
/// <param name="port">port of the server</param>
/// <param name="password"> password of the server</param>
/// <param name="rconEngine">engine to create the rcon connection to</param>
/// <returns>instance of rcon connection</returns>
IRConConnection CreateConnection(string ipAddress, int port, string password);
IRConConnection CreateConnection(string ipAddress, int port, string password, string rconEngine);
}
}

View File

@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using SharedLibraryCore.Database.Models;
using static SharedLibraryCore.Server;
namespace SharedLibraryCore.Interfaces
@ -39,8 +37,8 @@ namespace SharedLibraryCore.Interfaces
/// get the list of connected clients from status response
/// </summary>
/// <param name="connection">RCon connection to use</param>
/// <returns>list of clients, current map, and current gametype</returns>
Task<(List<EFClient>, string, string)> GetStatusAsync(IRConConnection connection);
/// <returns><see cref="IStatusResponse"/></returns>
Task<IStatusResponse> GetStatusAsync(IRConConnection connection);
/// <summary>
/// stores the RCon configuration
@ -50,23 +48,29 @@ namespace SharedLibraryCore.Interfaces
/// <summary>
/// stores the game/client specific version (usually the value of the "version" DVAR)
/// </summary>
string Version { get; set; }
string Version { get; }
/// <summary>
/// specifies the game name (usually the internal studio iteration ie: IW4, T5 etc...)
/// </summary>
Game GameName { get; set; }
Game GameName { get; }
/// <summary>
/// indicates if the game supports generating a log path from DVAR retrieval
/// of fs_game, fs_basepath, g_log
/// </summary>
bool CanGenerateLogPath { get; set; }
bool CanGenerateLogPath { get; }
/// <summary>
/// specifies the name of the parser
/// </summary>
string Name { get; set; }
string Name { get; }
/// <summary>
/// specifies the type of rcon engine
/// eg: COD, Source
/// </summary>
string RConEngine { get; }
/// <summary>
/// retrieves the value of given dvar key if it exists in the override dict

View File

@ -9,59 +9,69 @@ namespace SharedLibraryCore.Interfaces
/// <summary>
/// stores the command format for console commands
/// </summary>
CommandPrefix CommandPrefixes { get; set; }
CommandPrefix CommandPrefixes { get; }
/// <summary>
/// stores the regex info for parsing get status response
/// </summary>
ParserRegex Status { get; set; }
ParserRegex Status { get; }
/// <summary>
/// stores regex info for parsing the map line from rcon status response
/// </summary>
ParserRegex MapStatus { get; set; }
ParserRegex MapStatus { get; }
/// <summary>
/// stores regex info for parsing the gametype line from rcon status response
/// </summary>
ParserRegex GametypeStatus { get; set; }
ParserRegex GametypeStatus { get; }
/// <summary>
/// stores regex info for parsing hostname line from rcon status response
/// </summary>
ParserRegex HostnameStatus { get; }
/// <summary>
/// stores regex info for parsing max players line from rcon status response
/// </summary>
ParserRegex MaxPlayersStatus { get; }
/// <summary>
/// stores the regex info for parsing get DVAR responses
/// </summary>
ParserRegex Dvar { get; set; }
ParserRegex Dvar { get; }
/// <summary>
/// stores the regex info for parsing the header of a status response
/// </summary>
ParserRegex StatusHeader { get; set; }
ParserRegex StatusHeader { get; }
/// <summary>
/// Specifies the expected response message from rcon when the server is not running
/// </summary>
string ServerNotRunningResponse { get; set; }
string ServerNotRunningResponse { get; }
/// <summary>
/// indicates if the application should wait for response from server
/// when executing a command
/// </summary>
bool WaitForResponse { get; set; }
bool WaitForResponse { get; }
/// <summary>
/// indicates the format expected for parsed guids
/// </summary>
NumberStyles GuidNumberStyle { get; set; }
NumberStyles GuidNumberStyle { get; }
/// <summary>
/// specifies simple mappings for dvar names in scenarios where the needed
/// information is not stored in a traditional dvar name
/// </summary>
IDictionary<string, string> OverrideDvarNameMapping { get; set; }
IDictionary<string, string> OverrideDvarNameMapping { get; }
/// <summary>
/// specifies the default dvar values for games that don't support certain dvars
/// </summary>
IDictionary<string, string> DefaultDvarValues { get; set; }
IDictionary<string, string> DefaultDvarValues { get; }
/// <summary>
/// specifies how many lines can be used for ingame notice
@ -71,11 +81,11 @@ namespace SharedLibraryCore.Interfaces
/// <summary>
/// specifies how many characters can be displayed per notice line
/// </summary>
int NoticeMaxCharactersPerLine { get; set; }
int NoticeMaxCharactersPerLine { get; }
/// <summary>
/// specifies the characters used to split a line
/// </summary>
string NoticeLineSeparator { get; set; }
string NoticeLineSeparator { get; }
}
}

View File

@ -0,0 +1,35 @@
using SharedLibraryCore.Database.Models;
namespace SharedLibraryCore.Interfaces
{
/// <summary>
/// describes the collection of data returned from a status query
/// </summary>
public interface IStatusResponse
{
/// <summary>
/// name of the map
/// </summary>
string Map { get; }
/// <summary>
/// gametype/mode
/// </summary>
string GameType { get; }
/// <summary>
/// server name
/// </summary>
string Hostname { get; }
/// <summary>
/// max number of players
/// </summary>
int? MaxClients { get; }
/// <summary>
/// active clients
/// </summary>
EFClient[] Clients { get; }
}
}

View File

@ -29,7 +29,8 @@ namespace SharedLibraryCore
T5 = 6,
T6 = 7,
T7 = 8,
SHG1 = 9
SHG1 = 9,
CSGO = 10
}
public Server(ILogger<Server> logger, SharedLibraryCore.Interfaces.ILogger deprecatedLogger,
@ -42,7 +43,6 @@ namespace SharedLibraryCore
Manager = mgr;
Logger = deprecatedLogger;
ServerConfig = config;
RemoteConnection = rconConnectionFactory.CreateConnection(IP, Port, Password);
EventProcessing = new SemaphoreSlim(1, 1);
Clients = new List<EFClient>(new EFClient[64]);
Reports = new List<Report>();
@ -52,6 +52,7 @@ namespace SharedLibraryCore
CustomSayEnabled = Manager.GetApplicationSettings().Configuration().EnableCustomSayName;
CustomSayName = Manager.GetApplicationSettings().Configuration().CustomSayName;
this.gameLogReaderFactory = gameLogReaderFactory;
RConConnectionFactory = rconConnectionFactory;
ServerLogger = logger;
InitializeTokens();
InitializeAutoMessages();
@ -158,24 +159,28 @@ namespace SharedLibraryCore
/// Send a message to a particular players
/// </summary>
/// <param name="message">Message to send</param>
/// <param name="target">EFClient to send message to</param>
protected async Task Tell(string message, EFClient target)
/// <param name="targetClient">EFClient to send message to</param>
protected async Task Tell(string message, EFClient targetClient)
{
if (!Utilities.IsDevelopment)
{
var temporalClientId = targetClient.GetAdditionalProperty<string>("ConnectionClientId");
var parsedClientId = string.IsNullOrEmpty(temporalClientId) ? (int?)null : int.Parse(temporalClientId);
var clientNumber = parsedClientId ?? targetClient.ClientNumber;
var formattedMessage = string.Format(RconParser.Configuration.CommandPrefixes.Tell,
target.ClientNumber,
clientNumber,
$"{(CustomSayEnabled && GameName == Game.IW4 ? $"{CustomSayName}: " : "")}{message.FixIW4ForwardSlash()}");
if (target.ClientNumber > -1 && message.Length > 0 && target.Level != EFClient.Permission.Console)
if (targetClient.ClientNumber > -1 && message.Length > 0 && targetClient.Level != EFClient.Permission.Console)
await this.ExecuteCommandAsync(formattedMessage);
}
else
{
ServerLogger.LogDebug("Tell[{clientNumber}]->{message}", target.ClientNumber, message.StripColors());
ServerLogger.LogDebug("Tell[{clientNumber}]->{message}", targetClient.ClientNumber, message.StripColors());
}
if (target.Level == EFClient.Permission.Console)
if (targetClient.Level == EFClient.Permission.Console)
{
Console.ForegroundColor = ConsoleColor.Green;
using (LogContext.PushProperty("Server", ToString()))
@ -340,6 +345,7 @@ namespace SharedLibraryCore
protected DateTime LastPoll;
protected ManualResetEventSlim OnRemoteCommandResponse;
protected IGameLogReaderFactory gameLogReaderFactory;
protected IRConConnectionFactory RConConnectionFactory;
// only here for performance
private readonly bool CustomSayEnabled;

View File

@ -44,7 +44,7 @@
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.10" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.10" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="RaidMax.IW4MAdmin.Data" Version="1.0.0" />
<PackageReference Include="RaidMax.IW4MAdmin.Data" Version="1.0.1" />
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
<PackageReference Include="SimpleCrypto.NetCore" Version="1.0.0" />
</ItemGroup>

View File

@ -322,6 +322,8 @@ namespace SharedLibraryCore
/// <returns></returns>
public static long ConvertGuidToLong(this string str, NumberStyles numberStyle, long? fallback = null)
{
// added for source games that provide the steam ID
str = str.Replace("STEAM_1", "").Replace(":", "");
str = str.Substring(0, Math.Min(str.Length, 19));
var parsableAsNumber = Regex.Match(str, @"([A-F]|[a-f]|[0-9])+").Value;
@ -732,7 +734,7 @@ namespace SharedLibraryCore
return await server.RconParser.ExecuteCommandAsync(server.RemoteConnection, commandName);
}
public static Task<(List<EFClient>, string, string)> GetStatusAsync(this Server server)
public static Task<IStatusResponse> GetStatusAsync(this Server server)
{
return server.RconParser.GetStatusAsync(server.RemoteConnection);
}