more stability changes

This commit is contained in:
RaidMax 2018-10-03 21:20:49 -05:00
parent f4ac815d07
commit 9d946d1bad
12 changed files with 108 additions and 32 deletions

View File

@ -30,6 +30,7 @@
<PropertyGroup> <PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection> <ServerGarbageCollection>true</ServerGarbageCollection>
<TieredCompilation>true</TieredCompilation> <TieredCompilation>true</TieredCompilation>
<AssemblyVersion>2.1.9.3</AssemblyVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -432,6 +432,11 @@ namespace IW4MAdmin
await Kick(E.Data, E.Target, E.Origin); await Kick(E.Data, E.Target, E.Origin);
} }
else if (E.Type == GameEvent.EventType.Warn)
{
await Warn(E.Data, E.Target, E.Origin);
}
else if (E.Type == GameEvent.EventType.Quit) else if (E.Type == GameEvent.EventType.Quit)
{ {
var origin = Players.FirstOrDefault(p => p != null && p.NetworkId == E.Origin.NetworkId); var origin = Players.FirstOrDefault(p => p != null && p.NetworkId == E.Origin.NetworkId);
@ -888,7 +893,7 @@ namespace IW4MAdmin
#endif #endif
} }
public override async Task Warn(String Reason, Player Target, Player Origin) protected override async Task Warn(String Reason, Player Target, Player Origin)
{ {
// ensure player gets warned if command not performed on them in game // ensure player gets warned if command not performed on them in game
if (Target.ClientNumber < 0) if (Target.ClientNumber < 0)

View File

@ -25,7 +25,7 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment
public Task OnEventAsync(GameEvent E, Server S) public Task OnEventAsync(GameEvent E, Server S)
{ {
if (!Settings.Configuration().EnableProfanityDeterment) if (!Settings.Configuration().EnableProfanityDeterment)
return Task.CompletedTask; ; return Task.CompletedTask;
if (E.Type == GameEvent.EventType.Connect) if (E.Type == GameEvent.EventType.Connect)
{ {
@ -50,7 +50,8 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment
{ {
E.Origin.Kick(Settings.Configuration().ProfanityKickMessage, new Player() E.Origin.Kick(Settings.Configuration().ProfanityKickMessage, new Player()
{ {
ClientId = 1 ClientId = 1,
CurrentServer = E.Owner
}); });
}; };
} }
@ -86,7 +87,8 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment
{ {
clientProfanity.Client.Kick(Settings.Configuration().ProfanityKickMessage, new Player() clientProfanity.Client.Kick(Settings.Configuration().ProfanityKickMessage, new Player()
{ {
ClientId = 1 ClientId = 1,
CurrentServer = E.Owner
}); });
} }
@ -96,7 +98,8 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment
clientProfanity.Client.Warn(Settings.Configuration().ProfanityWarningMessage, new Player() clientProfanity.Client.Warn(Settings.Configuration().ProfanityWarningMessage, new Player()
{ {
ClientId = 1 ClientId = 1,
CurrentServer = E.Owner
}); });
} }
} }

View File

@ -194,8 +194,11 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
var statsSvc = new ThreadSafeStatsService(); var statsSvc = new ThreadSafeStatsService();
ContextThreads.TryAdd(serverId, statsSvc); ContextThreads.TryAdd(serverId, statsSvc);
var serverSvc = statsSvc.ServerSvc;
// get the server from the database if it exists, otherwise create and insert a new one // get the server from the database if it exists, otherwise create and insert a new one
var server = statsSvc.ServerSvc.Find(c => c.ServerId == serverId).FirstOrDefault(); var server = statsSvc.ServerSvc.Find(c => c.ServerId == serverId).FirstOrDefault();
if (server == null) if (server == null)
{ {
server = new EFServer() server = new EFServer()
@ -205,11 +208,11 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
ServerId = serverId ServerId = serverId
}; };
statsSvc.ServerSvc.Insert(server); serverSvc.Insert(server);
} }
// this doesn't need to be async as it's during initialization // this doesn't need to be async as it's during initialization
statsSvc.ServerSvc.SaveChanges(); serverSvc.SaveChanges();
// check to see if the stats have ever been initialized // check to see if the stats have ever been initialized
InitializeServerStats(sv); InitializeServerStats(sv);
statsSvc.ServerStatsSvc.SaveChanges(); statsSvc.ServerStatsSvc.SaveChanges();
@ -278,7 +281,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
}; };
// insert if they've not been added // insert if they've not been added
clientStats = clientStatsSvc.Insert(clientStats); clientStatsSvc.Insert(clientStats);
await clientStatsSvc.SaveChangesAsync(); await clientStatsSvc.SaveChangesAsync();
} }
@ -471,6 +474,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
var clientStatsSvc = statsSvc.ClientStatSvc; var clientStatsSvc = statsSvc.ClientStatSvc;
clientStatsSvc.Update(clientStats); clientStatsSvc.Update(clientStats);
// increment their hit count // increment their hit count
if (hit.DeathType == IW4Info.MeansOfDeath.MOD_PISTOL_BULLET || if (hit.DeathType == IW4Info.MeansOfDeath.MOD_PISTOL_BULLET ||
hit.DeathType == IW4Info.MeansOfDeath.MOD_RIFLE_BULLET || hit.DeathType == IW4Info.MeansOfDeath.MOD_RIFLE_BULLET ||
@ -496,13 +500,25 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
await ApplyPenalty(clientDetection.ProcessTotalRatio(clientStats), clientDetection, attacker, ctx); await ApplyPenalty(clientDetection.ProcessTotalRatio(clientStats), clientDetection, attacker, ctx);
} }
await clientStatsSvc.SaveChangesAsync(); ctx.Set<EFHitLocationCount>().UpdateRange(clientStats.HitLocations);
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.WriteError("AC ERROR"); Log.WriteError("Could not save hit or AC info");
Log.WriteDebug(ex.GetExceptionInfo());
}
try
{
await clientStatsSvc.SaveChangesAsync();
}
catch (Exception ex)
{
Log.WriteError("Could save save client stats");
Log.WriteDebug(ex.GetExceptionInfo()); Log.WriteDebug(ex.GetExceptionInfo());
} }
@ -1116,10 +1132,11 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
{ {
int serverId = sv.GetHashCode(); int serverId = sv.GetHashCode();
var statsSvc = ContextThreads[serverId]; var statsSvc = ContextThreads[serverId];
var serverSvc = statsSvc.ServerSvc;
serverSvc.Update(Servers[serverId].Server);
await serverSvc.SaveChangesAsync();
// Log.WriteDebug("Syncing stats contexts");
await statsSvc.ServerStatsSvc.SaveChangesAsync();
//await statsSvc.ClientStatSvc.SaveChangesAsync();
await statsSvc.KillStatsSvc.SaveChangesAsync(); await statsSvc.KillStatsSvc.SaveChangesAsync();
await statsSvc.ServerSvc.SaveChangesAsync(); await statsSvc.ServerSvc.SaveChangesAsync();

View File

@ -14,10 +14,16 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
{ {
get get
{ {
return new GenericRepository<EFClientStatistics>(true); return new GenericRepository<EFClientStatistics>(false);
}
}
public GenericRepository<EFServer> ServerSvc
{
get
{
return new GenericRepository<EFServer>(false);
} }
} }
public GenericRepository<EFServer> ServerSvc { get; private set; }
public GenericRepository<EFClientKill> KillStatsSvc { get; private set; } public GenericRepository<EFClientKill> KillStatsSvc { get; private set; }
public GenericRepository<EFServerStatistics> ServerStatsSvc { get; private set; } public GenericRepository<EFServerStatistics> ServerStatsSvc { get; private set; }
public GenericRepository<EFClientMessage> MessageSvc public GenericRepository<EFClientMessage> MessageSvc
@ -30,7 +36,6 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
public ThreadSafeStatsService() public ThreadSafeStatsService()
{ {
ServerSvc = new GenericRepository<EFServer>();
KillStatsSvc = new GenericRepository<EFClientKill>(); KillStatsSvc = new GenericRepository<EFClientKill>();
ServerStatsSvc = new GenericRepository<EFServerStatistics>(); ServerStatsSvc = new GenericRepository<EFServerStatistics>();
} }

View File

@ -23,6 +23,5 @@ namespace IW4MAdmin.Plugins.Stats.Models
public int ServerId { get; set; } public int ServerId { get; set; }
[ForeignKey("ServerId"), Column(Order = 1)] [ForeignKey("ServerId"), Column(Order = 1)]
public EFServer Server { get; set; } public EFServer Server { get; set; }
} }
} }

View File

@ -53,13 +53,15 @@ namespace Tests
Assert.False(client == null, "no client found to warn"); Assert.False(client == null, "no client found to warn");
var warnEvent = client.Warn("test warn", new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer }); var warnEvent = client.Warn("test warn", new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
warnEvent.OnProcessed.Wait(TestTimeout); warnEvent.OnProcessed.Wait();
Assert.True(client.Warnings == 1 || Assert.True((client.Warnings == 1 ||
warnEvent.Failed, "warning did not get applied"); warnEvent.Failed) &&
Manager.GetPenaltyService().GetClientPenaltiesAsync(client.ClientId).Result.Count(p => p.Type == Penalty.PenaltyType.Warning) == 1,
"warning did not get applied");
warnEvent = client.Warn("test warn", new Player() { ClientId = 1, Level = Player.Permission.Banned, CurrentServer = client.CurrentServer }); warnEvent = client.Warn("test warn", new Player() { ClientId = 1, Level = Player.Permission.Banned, CurrentServer = client.CurrentServer });
warnEvent.OnProcessed.Wait(TestTimeout); warnEvent.OnProcessed.Wait();
Assert.True(warnEvent.FailReason == GameEvent.EventFailReason.Permission && Assert.True(warnEvent.FailReason == GameEvent.EventFailReason.Permission &&
client.Warnings == 1, "warning was applied without proper permissions"); client.Warnings == 1, "warning was applied without proper permissions");
@ -86,8 +88,17 @@ namespace Tests
var client = Manager.Servers.First().GetPlayersAsList().FirstOrDefault(); var client = Manager.Servers.First().GetPlayersAsList().FirstOrDefault();
Assert.False(client == null, "no client found to report"); Assert.False(client == null, "no client found to report");
// fail
var player = new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer };
player.SetAdditionalProperty("_reportCount", 3);
var reportEvent = client.Report("test report", player);
reportEvent.OnProcessed.Wait(TestTimeout);
Assert.True(reportEvent.FailReason == GameEvent.EventFailReason.Throttle &
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 0, $"too many reports were applied [{reportEvent.FailReason.ToString()}]");
// succeed // succeed
var reportEvent = client.Report("test report", new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer }); reportEvent = client.Report("test report", new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
reportEvent.OnProcessed.Wait(TestTimeout); reportEvent.OnProcessed.Wait(TestTimeout);
Assert.True(!reportEvent.Failed && Assert.True(!reportEvent.Failed &&

View File

@ -773,12 +773,12 @@ namespace SharedLibraryCore.Commands
else if (unflagEvent.FailReason == GameEvent.EventFailReason.Invalid) else if (unflagEvent.FailReason == GameEvent.EventFailReason.Invalid)
{ {
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_FLAG_UNFLAG"]} ^5{E.Target.Name}"); E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_UNFLAG_NOTFLAGGED"]);
} }
else else
{ {
E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_UNFLAG_NOTFLAGGED"]); E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_FLAG_UNFLAG"]} ^5{E.Target.Name}");
} }
return Task.CompletedTask; return Task.CompletedTask;
@ -825,6 +825,11 @@ namespace SharedLibraryCore.Commands
commandEvent.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_REPORT_FAIL_SELF"]); commandEvent.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_REPORT_FAIL_SELF"]);
} }
else if (reportEvent.FailReason == GameEvent.EventFailReason.Throttle)
{
commandEvent.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_REPORT_FAIL_TOOMANY"]);
}
else if (reportEvent.Failed) else if (reportEvent.Failed)
{ {
commandEvent.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_REPORT_FAIL_DUPLICATE"]); commandEvent.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_REPORT_FAIL_DUPLICATE"]);
@ -1324,6 +1329,7 @@ namespace SharedLibraryCore.Commands
var nextMapMatch = currentMap.First().Index != lastMap.Index ? var nextMapMatch = currentMap.First().Index != lastMap.Index ?
regexMatches[regexMatches.IndexOf(currentMap.First()) + 1] : regexMatches[regexMatches.IndexOf(currentMap.First()) + 1] :
regexMatches.First(); regexMatches.First();
nextMap = s.Maps.FirstOrDefault(m => m.Name == nextMapMatch.Groups[3].ToString()) ?? nextMap; nextMap = s.Maps.FirstOrDefault(m => m.Name == nextMapMatch.Groups[3].ToString()) ?? nextMap;
string nextGametype = nextMapMatch.Groups[2].ToString().Length == 0 ? string nextGametype = nextMapMatch.Groups[2].ToString().Length == 0 ?
Utilities.GetLocalizedGametype(s.Gametype) : Utilities.GetLocalizedGametype(s.Gametype) :

View File

@ -26,7 +26,11 @@ namespace SharedLibraryCore
/// <summary> /// <summary>
/// executing the event would cause an invalid state /// executing the event would cause an invalid state
/// </summary> /// </summary>
Invalid Invalid,
/// <summary>
/// client is doing too much of something
/// </summary>
Throttle
} }
public enum EventType public enum EventType

View File

@ -81,7 +81,10 @@ namespace SharedLibraryCore.Objects
ConnectionTime = DateTime.UtcNow; ConnectionTime = DateTime.UtcNow;
ClientNumber = -1; ClientNumber = -1;
DelayedEvents = new Queue<GameEvent>(); DelayedEvents = new Queue<GameEvent>();
_additionalProperties = new Dictionary<string, object>(); _additionalProperties = new Dictionary<string, object>
{
{ "_reportCount", 0 }
};
} }
public override string ToString() => $"{Name}::{NetworkId}"; public override string ToString() => $"{Name}::{NetworkId}";
@ -116,19 +119,22 @@ namespace SharedLibraryCore.Objects
{ {
Type = GameEvent.EventType.Warn, Type = GameEvent.EventType.Warn,
Message = warnReason, Message = warnReason,
Data = warnReason,
Origin = sender, Origin = sender,
Target = this, Target = this,
Owner = sender.CurrentServer Owner = sender.CurrentServer
}; };
// enforce level restrictions // enforce level restrictions
if (sender.Level <= this.Level) if (this.Level > sender.Level)
{ {
e.FailReason = GameEvent.EventFailReason.Permission; e.FailReason = GameEvent.EventFailReason.Permission;
return e;
} }
else
{
this.Warnings++; this.Warnings++;
}
sender.CurrentServer.Manager.GetEventHandler().AddEvent(e); sender.CurrentServer.Manager.GetEventHandler().AddEvent(e);
return e; return e;
@ -181,6 +187,8 @@ namespace SharedLibraryCore.Objects
Owner = sender.CurrentServer Owner = sender.CurrentServer
}; };
int reportCount = sender.GetAdditionalProperty<int>("_reportCount");
if (this.Level > sender.Level) if (this.Level > sender.Level)
{ {
e.FailReason = GameEvent.EventFailReason.Permission; e.FailReason = GameEvent.EventFailReason.Permission;
@ -191,12 +199,18 @@ namespace SharedLibraryCore.Objects
e.FailReason = GameEvent.EventFailReason.Invalid; e.FailReason = GameEvent.EventFailReason.Invalid;
} }
else if (reportCount > 2)
{
e.FailReason = GameEvent.EventFailReason.Throttle;
}
else if (CurrentServer.Reports.Count(report => (report.Origin.NetworkId == sender.NetworkId && else if (CurrentServer.Reports.Count(report => (report.Origin.NetworkId == sender.NetworkId &&
report.Target.NetworkId == this.NetworkId)) > 0) report.Target.NetworkId == this.NetworkId)) > 0)
{ {
e.FailReason = GameEvent.EventFailReason.Exception; e.FailReason = GameEvent.EventFailReason.Exception;
} }
sender.SetAdditionalProperty("_reportCount", reportCount + 1);
sender.CurrentServer.Manager.GetEventHandler().AddEvent(e); sender.CurrentServer.Manager.GetEventHandler().AddEvent(e);
return e; return e;
} }
@ -391,7 +405,18 @@ namespace SharedLibraryCore.Objects
[NotMapped] [NotMapped]
Dictionary<string, object> _additionalProperties; Dictionary<string, object> _additionalProperties;
public T GetAdditionalProperty<T>(string name) => (T)_additionalProperties[name]; public T GetAdditionalProperty<T>(string name) => (T)_additionalProperties[name];
public void SetAdditionalProperty(string name, object value) => _additionalProperties.Add(name, value); public void SetAdditionalProperty(string name, object value)
{
if (_additionalProperties.ContainsKey(name))
{
_additionalProperties[name] = value;
}
else
{
_additionalProperties.Add(name, value);
}
}
[NotMapped] [NotMapped]
public int ClientNumber { get; set; } public int ClientNumber { get; set; }
[NotMapped] [NotMapped]

View File

@ -209,7 +209,7 @@ namespace SharedLibraryCore
/// <param name="Origin">The person who banned the target</param> /// <param name="Origin">The person who banned the target</param>
abstract protected Task Ban(String Reason, Player Target, Player Origin); abstract protected Task Ban(String Reason, Player Target, Player Origin);
abstract public Task Warn(String Reason, Player Target, Player Origin); abstract protected Task Warn(String Reason, Player Target, Player Origin);
/// <summary> /// <summary>
/// Unban a player by npID / GUID /// Unban a player by npID / GUID

View File

@ -28,7 +28,7 @@ namespace SharedLibraryCore.Services
{ {
if (_context == null) if (_context == null)
{ {
_context = new DatabaseContext(ShouldTrack); _context = new DatabaseContext(!ShouldTrack);
} }
return _context; return _context;