update application version
ignore stat events of bots if they are ignored limit max number of bot profiles to 18, greater than 18 wraps prevent anti cheat from running on bot events create localization folder on publish so copying over doesn't fail include quick message mapping on webfront server history chat make gravatar on profile not repeat
This commit is contained in:
parent
03ae3b5822
commit
02622ea7de
@ -6,7 +6,7 @@
|
||||
<RuntimeFrameworkVersion>2.2.2</RuntimeFrameworkVersion>
|
||||
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
|
||||
<PackageId>RaidMax.IW4MAdmin.Application</PackageId>
|
||||
<Version>2.2.6.4</Version>
|
||||
<Version>2.2.6.5</Version>
|
||||
<Authors>RaidMax</Authors>
|
||||
<Company>Forever None</Company>
|
||||
<Product>IW4MAdmin</Product>
|
||||
@ -31,8 +31,8 @@
|
||||
<PropertyGroup>
|
||||
<ServerGarbageCollection>true</ServerGarbageCollection>
|
||||
<TieredCompilation>true</TieredCompilation>
|
||||
<AssemblyVersion>2.2.6.4</AssemblyVersion>
|
||||
<FileVersion>2.2.6.4</FileVersion>
|
||||
<AssemblyVersion>2.2.6.5</AssemblyVersion>
|
||||
<FileVersion>2.2.6.5</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -133,7 +133,7 @@ namespace IW4MAdmin.Application
|
||||
catch (Exception ex)
|
||||
{
|
||||
newEvent.FailReason = GameEvent.EventFailReason.Exception;
|
||||
Logger.WriteError($"{Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_EXCEPTION"]} {newEvent.Owner}");
|
||||
Logger.WriteError(Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_EXCEPTION"].FormatExt(newEvent.Owner));
|
||||
Logger.WriteDebug(ex.GetExceptionInfo());
|
||||
}
|
||||
|
||||
|
@ -97,6 +97,16 @@ if "%CurrentConfiguration%" == "Release" (
|
||||
if exist "%SolutionDir%Publish\Windows\refs" move "%SolutionDir%Publish\Windows\refs" "%SolutionDir%Publish\Windows\Lib\refs"
|
||||
)
|
||||
|
||||
if "%CurrentConfiguration%" == "Prerelease" (
|
||||
echo PR-LOC
|
||||
if not exist "%SolutionDir%Publish\WindowsPrerelease\Localization" md "%SolutionDir%Publish\WindowsPrerelease\Localization"
|
||||
)
|
||||
|
||||
if "%CurrentConfiguration%" == "Release" (
|
||||
echo R-LOC
|
||||
if not exist "%SolutionDir%Publish\Windows\Localization" md "%SolutionDir%Publish\Windows\Localization"
|
||||
)
|
||||
|
||||
echo making start scripts
|
||||
@(echo @echo off && echo @title IW4MAdmin && echo dotnet Lib\IW4MAdmin.dll && echo pause) > "%SolutionDir%Publish\WindowsPrerelease\StartIW4MAdmin.cmd"
|
||||
@(echo @echo off && echo @title IW4MAdmin && echo dotnet Lib\IW4MAdmin.dll && echo pause) > "%SolutionDir%Publish\Windows\StartIW4MAdmin.cmd"
|
||||
|
@ -189,6 +189,10 @@ namespace IW4MAdmin
|
||||
|
||||
if (E.Type == GameEvent.EventType.ConnectionRestored)
|
||||
{
|
||||
if (Throttled)
|
||||
{
|
||||
Logger.WriteVerbose(loc["MANAGER_CONNECTION_REST"].FormatExt($"[{IP}:{Port}]"));
|
||||
}
|
||||
Logger.WriteInfo("Connection restored to server, so we are no longer throttling the poll rate");
|
||||
Throttled = false;
|
||||
}
|
||||
@ -390,18 +394,27 @@ namespace IW4MAdmin
|
||||
{
|
||||
E.Data = E.Data.StripColors();
|
||||
|
||||
if (E.Data.Length > 0)
|
||||
if (E.Data?.Length > 0)
|
||||
{
|
||||
// this may be a fix for a hard to reproduce null exception error
|
||||
lock (ChatHistory)
|
||||
string message = E.Data;
|
||||
if (E.Data.IsQuickMessage())
|
||||
{
|
||||
ChatHistory.Add(new ChatInfo()
|
||||
try
|
||||
{
|
||||
Name = E.Origin.Name,
|
||||
Message = E.Data ?? "NULL",
|
||||
Time = DateTime.UtcNow
|
||||
});
|
||||
message = Manager.GetApplicationSettings().Configuration()
|
||||
.QuickMessages
|
||||
.First(_qm => _qm.Game == GameName)
|
||||
.Messages[E.Data.Substring(1)];
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
ChatHistory.Add(new ChatInfo()
|
||||
{
|
||||
Name = E.Origin.Name,
|
||||
Message = message,
|
||||
Time = DateTime.UtcNow
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -649,8 +662,6 @@ namespace IW4MAdmin
|
||||
|
||||
if (ConnectionErrors > 0)
|
||||
{
|
||||
Logger.WriteVerbose(loc["MANAGER_CONNECTION_REST"].FormatExt($"[{IP}:{Port}]"));
|
||||
|
||||
var _event = new GameEvent()
|
||||
{
|
||||
Type = GameEvent.EventType.ConnectionRestored,
|
||||
@ -921,7 +932,7 @@ namespace IW4MAdmin
|
||||
#if !DEBUG
|
||||
else
|
||||
{
|
||||
string formattedKick = String.Format(RconParser.Configuration.CommandPrefixes.Kick, Target.ClientNumber, $"{loc["SERVER_KICK_TEXT"]} - ^5{Reason}^7");
|
||||
string formattedKick = string.Format(RconParser.Configuration.CommandPrefixes.Kick, Target.ClientNumber, $"{loc["SERVER_KICK_TEXT"]} - ^5{Reason}^7");
|
||||
await Target.CurrentServer.ExecuteCommandAsync(formattedKick);
|
||||
}
|
||||
#endif
|
||||
|
@ -91,7 +91,6 @@ namespace IW4MAdmin.Plugins.Stats.Web.Controllers
|
||||
.First(_qm => _qm.Game == message.ServerGame);
|
||||
message.Message = quickMessages.Messages[message.Message.Substring(1)];
|
||||
message.IsQuickMessage = true;
|
||||
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -537,7 +536,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
return;
|
||||
}
|
||||
|
||||
// incase the add palyer event get delayed
|
||||
// incase the add player event get delayed
|
||||
if (!Servers[serverId].PlayerStats.ContainsKey(attacker.ClientId))
|
||||
{
|
||||
await AddPlayer(attacker);
|
||||
@ -571,7 +570,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
ctx.Set<EFClientKill>().Add(hit);
|
||||
}
|
||||
|
||||
if (Plugin.Config.Configuration().EnableAntiCheat)
|
||||
if (Plugin.Config.Configuration().EnableAntiCheat && !attacker.IsBot)
|
||||
{
|
||||
if (clientDetection.QueuedHits.Count > Detection.QUEUE_COUNT)
|
||||
{
|
||||
@ -580,7 +579,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
clientDetection.QueuedHits = clientDetection.QueuedHits.OrderBy(_hits => _hits.TimeOffset).ToList();
|
||||
var oldestHit = clientDetection.QueuedHits.First();
|
||||
clientDetection.QueuedHits.RemoveAt(0);
|
||||
ApplyPenalty(clientDetection.ProcessHit(oldestHit, isDamage), clientDetection, attacker, ctx);
|
||||
await ApplyPenalty(clientDetection.ProcessHit(oldestHit, isDamage), clientDetection, attacker, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -589,7 +588,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
clientDetection.QueuedHits.Add(hit);
|
||||
}
|
||||
|
||||
ApplyPenalty(clientDetection.ProcessTotalRatio(clientStats), clientDetection, attacker, ctx);
|
||||
await ApplyPenalty(clientDetection.ProcessTotalRatio(clientStats), clientDetection, attacker, ctx);
|
||||
}
|
||||
|
||||
ctx.Set<EFHitLocationCount>().UpdateRange(clientStats.HitLocations);
|
||||
@ -607,8 +606,9 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyPenalty(DetectionPenaltyResult penalty, Detection clientDetection, EFClient attacker, DatabaseContext ctx)
|
||||
async Task ApplyPenalty(DetectionPenaltyResult penalty, Detection clientDetection, EFClient attacker, DatabaseContext ctx)
|
||||
{
|
||||
var penaltyClient = Utilities.IW4MAdminClient(attacker.CurrentServer);
|
||||
switch (penalty.ClientPenalty)
|
||||
{
|
||||
case Penalty.PenaltyType.Ban:
|
||||
@ -616,22 +616,19 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
{
|
||||
break;
|
||||
}
|
||||
attacker.Ban(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_CHEAT_DETECTED"], new EFClient()
|
||||
{
|
||||
ClientId = 1,
|
||||
AdministeredPenalties = new List<EFPenalty>()
|
||||
{
|
||||
new EFPenalty()
|
||||
{
|
||||
AutomatedOffense = penalty.Type == Cheat.Detection.DetectionType.Bone ?
|
||||
$"{penalty.Type}-{(int)penalty.Location}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}" :
|
||||
$"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}",
|
||||
}
|
||||
},
|
||||
Level = EFClient.Permission.Console,
|
||||
CurrentServer = attacker.CurrentServer,
|
||||
|
||||
}, false);
|
||||
penaltyClient.AdministeredPenalties = new List<EFPenalty>()
|
||||
{
|
||||
new EFPenalty()
|
||||
{
|
||||
AutomatedOffense = penalty.Type == Detection.DetectionType.Bone ?
|
||||
$"{penalty.Type}-{(int)penalty.Location}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}" :
|
||||
$"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}",
|
||||
}
|
||||
};
|
||||
|
||||
await attacker.Ban(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_CHEAT_DETECTED"], penaltyClient, false).WaitAsync();
|
||||
|
||||
if (clientDetection.Tracker.HasChanges)
|
||||
{
|
||||
SaveTrackedSnapshots(clientDetection, ctx);
|
||||
@ -647,23 +644,17 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
$"{penalty.Type}-{(int)penalty.Location}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}" :
|
||||
$"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}";
|
||||
|
||||
attacker.Flag(flagReason, new EFClient()
|
||||
{
|
||||
ClientId = 1,
|
||||
Level = EFClient.Permission.Console,
|
||||
CurrentServer = attacker.CurrentServer,
|
||||
});
|
||||
await attacker.Flag(flagReason, penaltyClient).WaitAsync();
|
||||
|
||||
if (clientDetection.Tracker.HasChanges)
|
||||
{
|
||||
SaveTrackedSnapshots(clientDetection, ctx);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SaveTrackedSnapshots(Cheat.Detection clientDetection, DatabaseContext ctx)
|
||||
void SaveTrackedSnapshots(Detection clientDetection, DatabaseContext ctx)
|
||||
{
|
||||
// todo: why does this cause duplicate primary key
|
||||
var change = clientDetection.Tracker.GetNextChange();
|
||||
|
@ -5,6 +5,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Configuration;
|
||||
using SharedLibraryCore.Database;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Dtos;
|
||||
using SharedLibraryCore.Helpers;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
@ -76,13 +77,8 @@ namespace IW4MAdmin.Plugins.Stats
|
||||
break;
|
||||
case GameEvent.EventType.ScriptKill:
|
||||
string[] killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0];
|
||||
if (killInfo.Length >= 14)
|
||||
if (killInfo.Length >= 14 && !ShouldIgnoreEvent(E.Origin, E.Target))
|
||||
{
|
||||
if (E.Origin.ClientId <= 1 && E.Target.ClientId <= 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// this treats "world" damage as self damage
|
||||
if (E.Origin.ClientId <= 1)
|
||||
{
|
||||
@ -99,13 +95,8 @@ namespace IW4MAdmin.Plugins.Stats
|
||||
}
|
||||
break;
|
||||
case GameEvent.EventType.Kill:
|
||||
if (!E.Owner.CustomCallback)
|
||||
if (!E.Owner.CustomCallback && !ShouldIgnoreEvent(E.Origin, E.Target))
|
||||
{
|
||||
if (E.Origin.ClientId <= 1 && E.Target.ClientId <= 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// this treats "world" damage as self damage
|
||||
if (E.Origin.ClientId <= 1)
|
||||
{
|
||||
@ -121,13 +112,8 @@ namespace IW4MAdmin.Plugins.Stats
|
||||
}
|
||||
break;
|
||||
case GameEvent.EventType.Damage:
|
||||
if (!E.Owner.CustomCallback)
|
||||
if (!E.Owner.CustomCallback && !ShouldIgnoreEvent(E.Origin, E.Target))
|
||||
{
|
||||
if (E.Origin.ClientId <= 1 && E.Target.ClientId <= 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// this treats "world" damage as self damage
|
||||
if (E.Origin.ClientId <= 1)
|
||||
{
|
||||
@ -144,13 +130,8 @@ namespace IW4MAdmin.Plugins.Stats
|
||||
break;
|
||||
case GameEvent.EventType.ScriptDamage:
|
||||
killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0];
|
||||
if (killInfo.Length >= 14)
|
||||
if (killInfo.Length >= 14 && !ShouldIgnoreEvent(E.Origin, E.Target))
|
||||
{
|
||||
if (E.Origin.ClientId <= 1 && E.Target.ClientId <= 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// this treats "world" damage as self damage
|
||||
if (E.Origin.ClientId <= 1)
|
||||
{
|
||||
@ -500,5 +481,17 @@ namespace IW4MAdmin.Plugins.Stats
|
||||
await Manager.Sync(sv);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the event should be ignored
|
||||
/// (If the client id or target id is not a real client or the target/origin is a bot and ignore bots is turned on)
|
||||
/// </summary>
|
||||
/// <param name="origin"></param>
|
||||
/// <param name="target"></param>
|
||||
/// <returns></returns>
|
||||
private bool ShouldIgnoreEvent(EFClient origin, EFClient target)
|
||||
{
|
||||
return ((origin.ClientId <= 1 && target.ClientId <= 1) || (target.IsBot || origin.IsBot) && ServerManager.GetApplicationSettings().Configuration().IgnoreBots);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -267,7 +267,7 @@ namespace SharedLibraryCore
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{IP}-{Port}";
|
||||
return $"{IP}:{Port}";
|
||||
}
|
||||
|
||||
protected async Task<bool> ScriptLoaded()
|
||||
|
@ -269,6 +269,7 @@ namespace SharedLibraryCore
|
||||
public static long ConvertLong(this string str)
|
||||
{
|
||||
str = str.Substring(0, Math.Min(str.Length, 16));
|
||||
int maxBots = 18;
|
||||
long id;
|
||||
|
||||
if (str.Length <= 11) // 10 numeric characters + signed character
|
||||
@ -288,7 +289,7 @@ namespace SharedLibraryCore
|
||||
if (!string.IsNullOrEmpty(bot))
|
||||
{
|
||||
// should set their GUID to the negation of their 1 based index (-1 - -18)
|
||||
return -(Convert.ToInt64(bot.Substring(3)) + 1);
|
||||
return -(Convert.ToInt64(bot.Substring(3)) + 1) % maxBots;
|
||||
}
|
||||
|
||||
return long.MinValue;
|
||||
|
@ -153,6 +153,8 @@
|
||||
min-width: 8rem;
|
||||
min-height: 8rem;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.profile-shortcode {
|
||||
|
Loading…
Reference in New Issue
Block a user