diff --git a/Application/Application.csproj b/Application/Application.csproj
index 370817d2..d9edbf93 100644
--- a/Application/Application.csproj
+++ b/Application/Application.csproj
@@ -5,7 +5,7 @@
netcoreapp2.0
false
RaidMax.IW4MAdmin.Application
- 2.1.0
+ 2.1.1
RaidMax
Forever None
IW4MAdmin
diff --git a/Application/Main.cs b/Application/Main.cs
index 77fa06db..ea8ff5cc 100644
--- a/Application/Main.cs
+++ b/Application/Main.cs
@@ -28,8 +28,10 @@ namespace IW4MAdmin.Application
Console.OutputEncoding = Encoding.UTF8;
Console.ForegroundColor = ConsoleColor.Gray;
- Version = Assembly.GetExecutingAssembly().GetName().Version.Major + Assembly.GetExecutingAssembly().GetName().Version.Minor / 10.0f;
- Version = Math.Round(Version, 2);
+ Version = Assembly.GetExecutingAssembly().GetName().Version.Major +
+ Assembly.GetExecutingAssembly().GetName().Version.Minor / 10.0f +
+ Assembly.GetExecutingAssembly().GetName().Version.Build / 100.0f;
+ Version = Math.Round(Version, 3);
Console.WriteLine("=====================================================");
Console.WriteLine(" IW4M ADMIN");
diff --git a/Application/Manager.cs b/Application/Manager.cs
index f1686621..8e781516 100644
--- a/Application/Manager.cs
+++ b/Application/Manager.cs
@@ -81,14 +81,18 @@ namespace IW4MAdmin.Application
public async Task UpdateStatus(object state)
{
- var taskList = new List();
+ var taskList = new Dictionary();
while (Running)
{
- taskList.Clear();
+ var tasksToRemove = taskList.Where(t => t.Value.Status == TaskStatus.RanToCompletion)
+ .Select(t => t.Key).ToList();
+
+ tasksToRemove.ForEach(t => taskList.Remove(t));
+
foreach (var server in Servers)
{
- taskList.Add(Task.Run(async () =>
+ var newTask = Task.Run(async () =>
{
try
{
@@ -101,7 +105,12 @@ namespace IW4MAdmin.Application
Logger.WriteDebug($"Exception: {e.Message}");
Logger.WriteDebug($"StackTrace: {e.StackTrace}");
}
- }));
+ });
+
+ if (!taskList.ContainsKey(server.GetHashCode()))
+ {
+ taskList.Add(server.GetHashCode(), newTask);
+ }
}
#if DEBUG
Logger.WriteDebug($"{taskList.Count} servers queued for stats updates");
@@ -110,7 +119,7 @@ namespace IW4MAdmin.Application
Logger.WriteDebug($"There are {workerThreads - availableThreads} active threading tasks");
#endif
- await Task.WhenAll(taskList.ToArray());
+ await Task.WhenAny(taskList.Values.ToArray());
GameEvent sensitiveEvent;
while ((sensitiveEvent = Handler.GetNextSensitiveEvent()) != null)
diff --git a/Application/Server.cs b/Application/Server.cs
index 3a6c8b13..3462e539 100644
--- a/Application/Server.cs
+++ b/Application/Server.cs
@@ -145,7 +145,7 @@ namespace IW4MAdmin
{
client.CurrentAlias = existingAlias;
client.CurrentAliasId = existingAlias.AliasId;
- await Manager.GetClientService().Update(client);
+ client = await Manager.GetClientService().Update(client);
}
player = client.AsPlayer();
}
@@ -160,11 +160,14 @@ namespace IW4MAdmin
var activePenalties = await Manager.GetPenaltyService().GetActivePenaltiesAsync(player.AliasLinkId, player.IPAddress);
var currentBan = activePenalties.FirstOrDefault(b => b.Expires > DateTime.UtcNow);
var currentAutoFlag = activePenalties.Where(p => p.Type == Penalty.PenaltyType.Flag && p.PunisherId == 1)
+ .Where(p => p.Active)
.OrderByDescending(p => p.When)
.FirstOrDefault();
// remove their auto flag status after a week
- if (currentAutoFlag != null && (DateTime.Now - currentAutoFlag.When).TotalDays > 7)
+ if (player.Level == Player.Permission.Flagged &&
+ currentAutoFlag != null &&
+ (DateTime.Now - currentAutoFlag.When).TotalDays > 7)
{
player.Level = Player.Permission.User;
}
@@ -193,7 +196,6 @@ namespace IW4MAdmin
Logger.WriteInfo($"Client {player} connecting...");
-
if (!Manager.GetApplicationSettings().Configuration().EnableClientVPNs &&
await VPNCheck.UsingVPN(player.IPAddressString, Manager.GetApplicationSettings().Configuration().IPHubAPIKey))
{
@@ -831,7 +833,7 @@ namespace IW4MAdmin
CustomCallback = await ScriptLoaded();
string mainPath = EventParser.GetGameDir();
#if DEBUG
- basepath.Value = @"\\192.168.88.253\mw2";
+ basepath.Value = @"\\192.168.88.253\logs\games_mp.log";
#endif
string logPath;
if (GameName == Game.IW5)
@@ -1064,6 +1066,7 @@ namespace IW4MAdmin
Manager.GetMessageTokens().Add(new SharedLibraryCore.Helpers.MessageToken("TOTALPLAYERS", (Server s) => Manager.GetClientService().GetTotalClientsAsync().Result.ToString()));
Manager.GetMessageTokens().Add(new SharedLibraryCore.Helpers.MessageToken("VERSION", (Server s) => Application.Program.Version.ToString()));
Manager.GetMessageTokens().Add(new SharedLibraryCore.Helpers.MessageToken("NEXTMAP", (Server s) => SharedLibraryCore.Commands.CNextMap.GetNextMap(s).Result));
+ Manager.GetMessageTokens().Add(new SharedLibraryCore.Helpers.MessageToken("ADMINS", (Server s) => SharedLibraryCore.Commands.CListAdmins.OnlineAdmins(s)));
}
}
}
diff --git a/Plugins/Stats/Cheat/Detection.cs b/Plugins/Stats/Cheat/Detection.cs
index ad70a1d5..09859251 100644
--- a/Plugins/Stats/Cheat/Detection.cs
+++ b/Plugins/Stats/Cheat/Detection.cs
@@ -85,7 +85,7 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
double newAverage = (previousAverage * (hitLoc.HitCount - 1) + realAgainstPredict) / hitLoc.HitCount;
hitLoc.HitOffsetAverage = (float)newAverage;
- if (hitLoc.HitOffsetAverage > Thresholds.MaxOffset &&
+ if (hitLoc.HitOffsetAverage > Thresholds.MaxOffset(hitLoc.HitCount) &&
hitLoc.HitCount > 100)
{
Log.WriteDebug("*** Reached Max Lifetime Average for Angle Difference ***");
@@ -107,7 +107,7 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
double sessAverage = (AngleDifferenceAverage * (HitCount - 1) + realAgainstPredict) / HitCount;
AngleDifferenceAverage = sessAverage;
- if (sessAverage > Thresholds.MaxOffset &&
+ if (sessAverage > Thresholds.MaxOffset(HitCount) &&
HitCount > 30)
{
Log.WriteDebug("*** Reached Max Session Average for Angle Difference ***");
diff --git a/Plugins/Stats/Cheat/Thresholds.cs b/Plugins/Stats/Cheat/Thresholds.cs
index de0919ad..409b6245 100644
--- a/Plugins/Stats/Cheat/Thresholds.cs
+++ b/Plugins/Stats/Cheat/Thresholds.cs
@@ -28,7 +28,9 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
public const double KillTimeThreshold = 0.2;
public const double MaxStrainBan = 1.12;
- public const double MaxOffset = 1.2;
+
+ //=exp((MAX(-3.07+(-3.07/sqrt(J20)),-3.07-(-3.07/sqrt(J20))))+(4*(0.869)))
+ public static double MaxOffset(int sampleSize) => Math.Exp(Math.Max(-3.07 + (-3.07 / Math.Sqrt(sampleSize)), -3.07 - (-3.07 / Math.Sqrt(sampleSize))) + 4 * (0.869));
public const double MaxStrainFlag = 0.36;
public static double GetMarginOfError(int numKills) => 1.6455 / Math.Sqrt(numKills);
diff --git a/Plugins/Stats/Helpers/StatManager.cs b/Plugins/Stats/Helpers/StatManager.cs
index a1d00bf2..11dd1f75 100644
--- a/Plugins/Stats/Helpers/StatManager.cs
+++ b/Plugins/Stats/Helpers/StatManager.cs
@@ -942,7 +942,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
int serverId = sv.GetHashCode();
var statsSvc = ContextThreads[serverId];
- Log.WriteDebug("Syncing stats contexts");
+ // Log.WriteDebug("Syncing stats contexts");
await statsSvc.ServerStatsSvc.SaveChangesAsync();
//await statsSvc.ClientStatSvc.SaveChangesAsync();
await statsSvc.KillStatsSvc.SaveChangesAsync();
diff --git a/SharedLibraryCore/Commands/NativeCommands.cs b/SharedLibraryCore/Commands/NativeCommands.cs
index 71570305..517ab0b0 100644
--- a/SharedLibraryCore/Commands/NativeCommands.cs
+++ b/SharedLibraryCore/Commands/NativeCommands.cs
@@ -531,24 +531,27 @@ namespace SharedLibraryCore.Commands
base("admins", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_ADMINS_DESC"], "a", Player.Permission.User, false)
{ }
+ public static string OnlineAdmins(Server S)
+ {
+ var onlineAdmins = S.GetPlayersAsList()
+ .Where(p => p.Level > Player.Permission.Flagged)
+ .Where(p => !p.Masked)
+ .Select(p => $"[^3{Utilities.ConvertLevelToColor(p.Level)}^7] {p.Name}");
+
+ return onlineAdmins.Count() > 0 ?
+ string.Join(Environment.NewLine, onlineAdmins) :
+ Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_ADMINS_NONE"];
+ }
+
public override async Task ExecuteAsync(GameEvent E)
{
- int numOnline = 0;
- for (int i = 0; i < E.Owner.Players.Count; i++)
+ foreach (string line in OnlineAdmins(E.Owner).Split(Environment.NewLine))
{
- var P = E.Owner.Players[i];
- if (P != null && P.Level > Player.Permission.Flagged && !P.Masked)
- {
- numOnline++;
- if (E.Message[0] == '@')
- await E.Owner.Broadcast(String.Format("[^3{0}^7] {1}", Utilities.ConvertLevelToColor(P.Level), P.Name));
- else
- await E.Origin.Tell(String.Format("[^3{0}^7] {1}", Utilities.ConvertLevelToColor(P.Level), P.Name));
- }
+ if (E.Message[0] == '@')
+ await E.Owner.Broadcast(line);
+ else
+ await E.Origin.Tell(line);
}
-
- if (numOnline == 0)
- await E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_ADMINS_NONE"]);
}
}
diff --git a/SharedLibraryCore/Services/ClientService.cs b/SharedLibraryCore/Services/ClientService.cs
index 52f502b9..06b93fd0 100644
--- a/SharedLibraryCore/Services/ClientService.cs
+++ b/SharedLibraryCore/Services/ClientService.cs
@@ -151,7 +151,7 @@ namespace SharedLibraryCore.Services
.AsNoTracking()
.Include(c => c.CurrentAlias)
.Include(c => c.AliasLink.Children)
- .SingleOrDefaultAsync(c => c.NetworkId == (long)entityAttribute);
+ .SingleOrDefaultAsync(c => c.NetworkId == entityAttribute);
}
}
@@ -164,7 +164,7 @@ namespace SharedLibraryCore.Services
.Include(c => c.AliasLink)
.Include(c => c.CurrentAlias)
.Single(e => e.ClientId == entity.ClientId);
-
+
// if their level has been changed
if (entity.Level != client.Level)
{
@@ -177,8 +177,7 @@ namespace SharedLibraryCore.Services
// update all related clients level
await matchingClients.ForEachAsync(c =>
{
- c.Level = (client.Level == Player.Permission.Banned) ? client.Level : entity.Level;
-
+ c.Level = entity.Level;
});
}
diff --git a/WebfrontCore/Controllers/BaseController.cs b/WebfrontCore/Controllers/BaseController.cs
index 3cc9f55f..c4340a90 100644
--- a/WebfrontCore/Controllers/BaseController.cs
+++ b/WebfrontCore/Controllers/BaseController.cs
@@ -16,7 +16,7 @@ namespace WebfrontCore.Controllers
{
protected IManager Manager;
protected readonly DatabaseContext Context;
- protected bool Authorized { get; private set; }
+ protected bool Authorized { get; set; }
protected SharedLibraryCore.Localization.Index Localization { get; private set; }
protected EFClient Client { get; private set; }
private static byte[] LocalHost = { 127, 0, 0, 1 };
diff --git a/WebfrontCore/Controllers/ClientController.cs b/WebfrontCore/Controllers/ClientController.cs
index c1557672..4c3732d3 100644
--- a/WebfrontCore/Controllers/ClientController.cs
+++ b/WebfrontCore/Controllers/ClientController.cs
@@ -20,6 +20,10 @@ namespace WebfrontCore.Controllers
return NotFound();
}
+#if DEBUG
+ Authorized = true;
+#endif
+
var clientDto = new PlayerInfo()
{
Name = client.Name,
@@ -78,6 +82,12 @@ namespace WebfrontCore.Controllers
}));
}
+ if (Authorized)
+ {
+ penaltyMeta.ForEach(p => p.Value.Offense = p.Value.AutomatedOffense ?? p.Value.Offense);
+ administeredPenaltiesMeta.ForEach(p => p.Value.Offense = p.Value.AutomatedOffense ?? p.Value.Offense);
+ }
+
clientDto.Meta.AddRange(Authorized ? meta : meta.Where(m => !m.Sensitive));
clientDto.Meta.AddRange(Authorized ? penaltyMeta : penaltyMeta.Where(m => !m.Sensitive));
clientDto.Meta.AddRange(Authorized ? administeredPenaltiesMeta : administeredPenaltiesMeta.Where(m => !m.Sensitive));
diff --git a/WebfrontCore/ViewComponents/PenaltyListViewComponent.cs b/WebfrontCore/ViewComponents/PenaltyListViewComponent.cs
index d97bca15..dbed9bda 100644
--- a/WebfrontCore/ViewComponents/PenaltyListViewComponent.cs
+++ b/WebfrontCore/ViewComponents/PenaltyListViewComponent.cs
@@ -21,7 +21,11 @@ namespace WebfrontCore.ViewComponents
PunisherId = p.PunisherId,
PunisherName = p.Punisher.Name,
PunisherLevel = p.Punisher.Level.ToString(),
+#if DEBUG
+ Offense = !string.IsNullOrEmpty(p.AutomatedOffense) ? p.AutomatedOffense : p.Offense,
+#else
Offense = User.Identity.IsAuthenticated && !string.IsNullOrEmpty(p.AutomatedOffense) ? p.AutomatedOffense : p.Offense,
+#endif
Type = p.Type.ToString(),
TimePunished = Utilities.GetTimePassed(p.When, false),
// show time passed if ban
@@ -30,7 +34,11 @@ namespace WebfrontCore.ViewComponents
AutomatedOffense = p.AutomatedOffense
});
+#if DEBUG
+ penaltiesDto = penaltiesDto.ToList();
+#else
penaltiesDto = User.Identity.IsAuthenticated ? penaltiesDto.ToList() : penaltiesDto.Where(p => !p.Sensitive).ToList();
+#endif
return View("_List", penaltiesDto);
}