update CoD4x parser
tweak handling segmented status response actually support more than 18 clients LOL
This commit is contained in:
parent
bd3f0caf60
commit
6648b75255
@ -5,12 +5,13 @@ using Microsoft.Data.Sqlite;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Configuration;
|
using SharedLibraryCore.Configuration;
|
||||||
using SharedLibraryCore.Database;
|
|
||||||
using SharedLibraryCore.Database.MigrationContext;
|
using SharedLibraryCore.Database.MigrationContext;
|
||||||
|
using ILogger = Serilog.ILogger;
|
||||||
|
|
||||||
namespace IW4MAdmin.Application.Extensions
|
namespace IW4MAdmin.Application.Extensions
|
||||||
{
|
{
|
||||||
@ -45,6 +46,8 @@ namespace IW4MAdmin.Application.Extensions
|
|||||||
}
|
}
|
||||||
|
|
||||||
services.AddLogging(builder => builder.AddSerilog(_defaultLogger, dispose: true));
|
services.AddLogging(builder => builder.AddSerilog(_defaultLogger, dispose: true));
|
||||||
|
services.AddSingleton(new LoggerFactory()
|
||||||
|
.AddSerilog(_defaultLogger, true));
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,18 +79,19 @@ namespace IW4MAdmin.Application.Extensions
|
|||||||
case "mysql":
|
case "mysql":
|
||||||
var appendTimeout = !appConfig.ConnectionString.Contains("default command timeout",
|
var appendTimeout = !appConfig.ConnectionString.Contains("default command timeout",
|
||||||
StringComparison.InvariantCultureIgnoreCase);
|
StringComparison.InvariantCultureIgnoreCase);
|
||||||
var mysqlBuilder = new DbContextOptionsBuilder<MySqlDatabaseContext>()
|
services.AddSingleton(sp => (DbContextOptions) new DbContextOptionsBuilder<MySqlDatabaseContext>()
|
||||||
.UseMySql(appConfig.ConnectionString + (appendTimeout ? ";default command timeout=0" : ""),
|
.UseMySql(appConfig.ConnectionString + (appendTimeout ? ";default command timeout=0" : ""),
|
||||||
mysqlOptions => mysqlOptions.EnableRetryOnFailure());
|
mysqlOptions => mysqlOptions.EnableRetryOnFailure())
|
||||||
services.AddSingleton((DbContextOptions) mysqlBuilder.Options);
|
.UseLoggerFactory(sp.GetRequiredService<ILoggerFactory>()).Options);
|
||||||
return services;
|
return services;
|
||||||
case "postgresql":
|
case "postgresql":
|
||||||
appendTimeout = !appConfig.ConnectionString.Contains("Command Timeout",
|
appendTimeout = !appConfig.ConnectionString.Contains("Command Timeout",
|
||||||
StringComparison.InvariantCultureIgnoreCase);
|
StringComparison.InvariantCultureIgnoreCase);
|
||||||
var postgresqlBuilder = new DbContextOptionsBuilder<PostgresqlDatabaseContext>()
|
services.AddSingleton(sp =>
|
||||||
.UseNpgsql(appConfig.ConnectionString + (appendTimeout ? ";Command Timeout=0" : ""),
|
(DbContextOptions) new DbContextOptionsBuilder<PostgresqlDatabaseContext>()
|
||||||
postgresqlOptions => postgresqlOptions.EnableRetryOnFailure());
|
.UseNpgsql(appConfig.ConnectionString + (appendTimeout ? ";Command Timeout=0" : ""),
|
||||||
services.AddSingleton((DbContextOptions) postgresqlBuilder.Options);
|
postgresqlOptions => postgresqlOptions.EnableRetryOnFailure())
|
||||||
|
.UseLoggerFactory(sp.GetRequiredService<ILoggerFactory>()).Options);
|
||||||
return services;
|
return services;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentException($"No context available for {appConfig.DatabaseProvider}");
|
throw new ArgumentException($"No context available for {appConfig.DatabaseProvider}");
|
||||||
|
@ -18,7 +18,7 @@ namespace IW4MAdmin.Application.RCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int ConnectionAttempts { get; set; }
|
public int ConnectionAttempts { get; set; }
|
||||||
const int BufferSize = 4096;
|
const int BufferSize = 8192;
|
||||||
public readonly byte[] ReceiveBuffer = new byte[BufferSize];
|
public readonly byte[] ReceiveBuffer = new byte[BufferSize];
|
||||||
public readonly SemaphoreSlim OnComplete = new SemaphoreSlim(1, 1);
|
public readonly SemaphoreSlim OnComplete = new SemaphoreSlim(1, 1);
|
||||||
public readonly ManualResetEventSlim OnSentData = new ManualResetEventSlim(false);
|
public readonly ManualResetEventSlim OnSentData = new ManualResetEventSlim(false);
|
||||||
|
@ -407,37 +407,39 @@ namespace IW4MAdmin.Application.RCon
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sender is Socket sock)
|
if (!(sender is Socket sock))
|
||||||
{
|
{
|
||||||
var state = ActiveQueries[this.Endpoint];
|
return;
|
||||||
state.BytesReadPerSegment.Add(e.BytesTransferred);
|
}
|
||||||
|
|
||||||
try
|
var state = ActiveQueries[this.Endpoint];
|
||||||
|
state.BytesReadPerSegment.Add(e.BytesTransferred);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var totalBytesTransferred = e.BytesTransferred;
|
||||||
|
// we still have available data so the payload was segmented
|
||||||
|
while (sock.Available > 0)
|
||||||
{
|
{
|
||||||
// we still have available data so the payload was segmented
|
state.ReceiveEventArgs.SetBuffer(state.ReceiveBuffer, totalBytesTransferred, sock.Available);
|
||||||
if (sock.Available > 0)
|
|
||||||
{
|
|
||||||
state.ReceiveEventArgs.SetBuffer(state.ReceiveBuffer, e.BytesTransferred, state.ReceiveBuffer.Length - e.BytesTransferred);
|
|
||||||
|
|
||||||
if (!sock.ReceiveAsync(state.ReceiveEventArgs))
|
if (sock.ReceiveAsync(state.ReceiveEventArgs))
|
||||||
{
|
{
|
||||||
_log.LogDebug("Read {bytesTransferred} synchronous bytes from {endpoint}", state.ReceiveEventArgs.BytesTransferred, e.RemoteEndPoint);
|
continue;
|
||||||
// we need to increment this here because the callback isn't executed if there's no pending IO
|
|
||||||
state.BytesReadPerSegment.Add(state.ReceiveEventArgs.BytesTransferred);
|
|
||||||
ActiveQueries[this.Endpoint].OnReceivedData.Set();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
_log.LogDebug("Read {bytesTransferred} synchronous bytes from {endpoint}", state.ReceiveEventArgs.BytesTransferred, e.RemoteEndPoint);
|
||||||
{
|
// we need to increment this here because the callback isn't executed if there's no pending IO
|
||||||
ActiveQueries[this.Endpoint].OnReceivedData.Set();
|
state.BytesReadPerSegment.Add(state.ReceiveEventArgs.BytesTransferred);
|
||||||
}
|
totalBytesTransferred += state.ReceiveEventArgs.BytesTransferred;
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (ObjectDisposedException)
|
ActiveQueries[this.Endpoint].OnReceivedData.Set();
|
||||||
{
|
}
|
||||||
ActiveQueries[this.Endpoint].OnReceivedData.Set();
|
|
||||||
}
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
ActiveQueries[this.Endpoint].OnReceivedData.Set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +205,8 @@ namespace IW4MAdmin.Application.RconParsers
|
|||||||
|
|
||||||
if (match.Success)
|
if (match.Success)
|
||||||
{
|
{
|
||||||
if (match.Values[Configuration.Status.GroupMapping[ParserRegex.GroupType.RConPing]] == "ZMBI")
|
if (match.Values[Configuration.Status.GroupMapping[ParserRegex.GroupType.RConPing]] == "ZMBI" ||
|
||||||
|
match.Values[Configuration.Status.GroupMapping[ParserRegex.GroupType.RConPing]] == "CNCT")
|
||||||
{
|
{
|
||||||
_logger.LogDebug("Ignoring detected client {client} because they are zombie state", string.Join(",", match.Values));
|
_logger.LogDebug("Ignoring detected client {client} because they are zombie state", string.Join(",", match.Values));
|
||||||
continue;
|
continue;
|
||||||
|
@ -15,9 +15,10 @@ var plugin = {
|
|||||||
eventParser = manager.GenerateDynamicEventParser(this.name);
|
eventParser = manager.GenerateDynamicEventParser(this.name);
|
||||||
|
|
||||||
rconParser.Configuration.StatusHeader.Pattern = 'num +score +ping +playerid +steamid +name +lastmsg +address +qport +rate *';
|
rconParser.Configuration.StatusHeader.Pattern = 'num +score +ping +playerid +steamid +name +lastmsg +address +qport +rate *';
|
||||||
rconParser.Configuration.Status.Pattern = '^ *([0-9]+) +-?([0-9]+) +((?:[A-Z]+|[0-9]+)) +((?:[a-z]|[0-9]{16,32})|bot[0-9]+) ([0-9]+) +(.{0,32}) +([0-9]+) +(\\d+\\.\\d+\\.\\d+.\\d+\\:-*\\d{1,5}|0+.0+:-*\\d{1,5}|loopback) +(-*[0-9]+) +([0-9]+) *$';
|
rconParser.Configuration.Status.Pattern = '^ *([0-9]+) +-?([0-9]+) +((?:[A-Z]+|[0-9]+)) +((?:[a-z]|[0-9]{16,32})|0) +([[0-9]+|0]) +(.{0,32}) +([0-9]+) +(\\d+\\.\\d+\\.\\d+.\\d+\\:-*\\d{1,5}|0+.0+:-*\\d{1,5}|loopback|bot) +(-*[0-9]+) +([0-9]+) *$';
|
||||||
rconParser.Configuration.Status.AddMapping(104, 6); // RConName
|
rconParser.Configuration.Status.AddMapping(104, 6); // RConName
|
||||||
rconParser.Configuration.Status.AddMapping(105, 8); // RConIPAddress
|
rconParser.Configuration.Status.AddMapping(105, 8); // RConIPAddress
|
||||||
|
rconParser.Configuration.CommandPrefixes.RConResponse = '\xff\xff\xff\xffprint\n';
|
||||||
|
|
||||||
rconParser.Configuration.Dvar.Pattern = '^"(.+)" is: "(.+)?" default: "(.+)?" info: "(.+)?"$';
|
rconParser.Configuration.Dvar.Pattern = '^"(.+)" is: "(.+)?" default: "(.+)?" info: "(.+)?"$';
|
||||||
rconParser.Configuration.Dvar.AddMapping(109, 2); // DVAR latched value
|
rconParser.Configuration.Dvar.AddMapping(109, 2); // DVAR latched value
|
||||||
|
@ -42,7 +42,7 @@ namespace SharedLibraryCore
|
|||||||
ServerConfig = config;
|
ServerConfig = config;
|
||||||
RemoteConnection = rconConnectionFactory.CreateConnection(IP, Port, Password);
|
RemoteConnection = rconConnectionFactory.CreateConnection(IP, Port, Password);
|
||||||
EventProcessing = new SemaphoreSlim(1, 1);
|
EventProcessing = new SemaphoreSlim(1, 1);
|
||||||
Clients = new List<EFClient>(new EFClient[18]);
|
Clients = new List<EFClient>(new EFClient[64]);
|
||||||
Reports = new List<Report>();
|
Reports = new List<Report>();
|
||||||
ClientHistory = new Queue<PlayerHistory>();
|
ClientHistory = new Queue<PlayerHistory>();
|
||||||
ChatHistory = new List<ChatInfo>();
|
ChatHistory = new List<ChatInfo>();
|
||||||
|
Loading…
Reference in New Issue
Block a user