fix penalty list javascript loading duplicates
make bad GUID parse throw an exception so we don't have a client connect with GUID of 0 no longer print out ac debug messages fix small issue of trying to parse empty chat messages fix issue with set level on accounts with multi guid, same IP
This commit is contained in:
parent
2cceb2f3e7
commit
b51af7ca9a
@ -6,7 +6,7 @@
|
|||||||
<RuntimeFrameworkVersion>2.2.2</RuntimeFrameworkVersion>
|
<RuntimeFrameworkVersion>2.2.2</RuntimeFrameworkVersion>
|
||||||
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
|
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
|
||||||
<PackageId>RaidMax.IW4MAdmin.Application</PackageId>
|
<PackageId>RaidMax.IW4MAdmin.Application</PackageId>
|
||||||
<Version>2.2.7.0</Version>
|
<Version>2.2.7.1</Version>
|
||||||
<Authors>RaidMax</Authors>
|
<Authors>RaidMax</Authors>
|
||||||
<Company>Forever None</Company>
|
<Company>Forever None</Company>
|
||||||
<Product>IW4MAdmin</Product>
|
<Product>IW4MAdmin</Product>
|
||||||
@ -21,6 +21,7 @@
|
|||||||
<Configurations>Debug;Release;Prerelease</Configurations>
|
<Configurations>Debug;Release;Prerelease</Configurations>
|
||||||
<Win32Resource />
|
<Win32Resource />
|
||||||
<RootNamespace>IW4MAdmin.Application</RootNamespace>
|
<RootNamespace>IW4MAdmin.Application</RootNamespace>
|
||||||
|
<PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -31,8 +32,8 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ServerGarbageCollection>true</ServerGarbageCollection>
|
<ServerGarbageCollection>true</ServerGarbageCollection>
|
||||||
<TieredCompilation>true</TieredCompilation>
|
<TieredCompilation>true</TieredCompilation>
|
||||||
<AssemblyVersion>2.2.7.0</AssemblyVersion>
|
<AssemblyVersion>2.2.7.1</AssemblyVersion>
|
||||||
<FileVersion>2.2.7.0</FileVersion>
|
<FileVersion>2.2.7.1</FileVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -28,7 +28,6 @@ namespace IW4MAdmin.Application
|
|||||||
{
|
{
|
||||||
private List<Server> _servers;
|
private List<Server> _servers;
|
||||||
public List<Server> Servers => _servers.OrderByDescending(s => s.ClientNum).ToList();
|
public List<Server> Servers => _servers.OrderByDescending(s => s.ClientNum).ToList();
|
||||||
public Dictionary<int, EFClient> PrivilegedClients { get; set; }
|
|
||||||
public ILogger Logger => GetLogger(0);
|
public ILogger Logger => GetLogger(0);
|
||||||
public bool Running { get; private set; }
|
public bool Running { get; private set; }
|
||||||
public bool IsInitialized { get; private set; }
|
public bool IsInitialized { get; private set; }
|
||||||
@ -41,8 +40,7 @@ namespace IW4MAdmin.Application
|
|||||||
|
|
||||||
public IList<IRConParser> AdditionalRConParsers { get; }
|
public IList<IRConParser> AdditionalRConParsers { get; }
|
||||||
public IList<IEventParser> AdditionalEventParsers { get; }
|
public IList<IEventParser> AdditionalEventParsers { get; }
|
||||||
public ITokenAuthentication TokenAuthenticator => Authenticator;
|
public ITokenAuthentication TokenAuthenticator { get; }
|
||||||
public ITokenAuthentication Authenticator => _authenticator;
|
|
||||||
public string ExternalIPAddress { get; private set; }
|
public string ExternalIPAddress { get; private set; }
|
||||||
|
|
||||||
static ApplicationManager Instance;
|
static ApplicationManager Instance;
|
||||||
@ -58,7 +56,6 @@ namespace IW4MAdmin.Application
|
|||||||
readonly IPageList PageList;
|
readonly IPageList PageList;
|
||||||
readonly SemaphoreSlim ProcessingEvent = new SemaphoreSlim(1, 1);
|
readonly SemaphoreSlim ProcessingEvent = new SemaphoreSlim(1, 1);
|
||||||
readonly Dictionary<long, ILogger> Loggers = new Dictionary<long, ILogger>();
|
readonly Dictionary<long, ILogger> Loggers = new Dictionary<long, ILogger>();
|
||||||
readonly ITokenAuthentication _authenticator;
|
|
||||||
private readonly MetaService _metaService;
|
private readonly MetaService _metaService;
|
||||||
private readonly TimeSpan _throttleTimeout = new TimeSpan(0, 1, 0);
|
private readonly TimeSpan _throttleTimeout = new TimeSpan(0, 1, 0);
|
||||||
|
|
||||||
@ -79,7 +76,7 @@ namespace IW4MAdmin.Application
|
|||||||
AdditionalRConParsers = new List<IRConParser>();
|
AdditionalRConParsers = new List<IRConParser>();
|
||||||
OnServerEvent += OnGameEvent;
|
OnServerEvent += OnGameEvent;
|
||||||
OnServerEvent += EventApi.OnGameEvent;
|
OnServerEvent += EventApi.OnGameEvent;
|
||||||
_authenticator = new TokenAuthentication();
|
TokenAuthenticator = new TokenAuthentication();
|
||||||
_metaService = new MetaService();
|
_metaService = new MetaService();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -734,10 +731,7 @@ namespace IW4MAdmin.Application
|
|||||||
return ConfigHandler;
|
return ConfigHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDictionary<int, EFClient> GetPrivilegedClients()
|
public IDictionary<int, EFClient> PrivilegedClients { get; private set; }
|
||||||
{
|
|
||||||
return PrivilegedClients;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ShutdownRequested()
|
public bool ShutdownRequested()
|
||||||
{
|
{
|
||||||
|
@ -81,10 +81,11 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
string[] lineSplit = logLine.Split(';');
|
string[] lineSplit = logLine.Split(';');
|
||||||
string eventType = lineSplit[0];
|
string eventType = lineSplit[0];
|
||||||
|
|
||||||
|
// this is a "custom callback" event
|
||||||
if (eventType == "JoinTeam")
|
if (eventType == "JoinTeam")
|
||||||
{
|
{
|
||||||
var origin = server.GetClientsAsList()
|
var origin = server.GetClientsAsList()
|
||||||
.FirstOrDefault(c => c.NetworkId == lineSplit[1].ConvertLong());
|
.FirstOrDefault(c => c.NetworkId == lineSplit[1].ConvertGuidToLong());
|
||||||
|
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
@ -107,29 +108,32 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
.Replace("\x15", "")
|
.Replace("\x15", "")
|
||||||
.Trim();
|
.Trim();
|
||||||
|
|
||||||
var origin = server.GetClientsAsList()
|
if (message.Length > 0)
|
||||||
.First(c => c.NetworkId == matchResult.Groups[Configuration.Say.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].ToString().ConvertLong());
|
|
||||||
|
|
||||||
if (message[0] == '!' || message[0] == '@')
|
|
||||||
{
|
{
|
||||||
|
var origin = server.GetClientsAsList()
|
||||||
|
.First(c => c.NetworkId == matchResult.Groups[Configuration.Say.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].ToString().ConvertGuidToLong());
|
||||||
|
|
||||||
|
if (message[0] == '!' || message[0] == '@')
|
||||||
|
{
|
||||||
|
return new GameEvent()
|
||||||
|
{
|
||||||
|
Type = GameEvent.EventType.Command,
|
||||||
|
Data = message,
|
||||||
|
Origin = origin,
|
||||||
|
Owner = server,
|
||||||
|
Message = message
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
Type = GameEvent.EventType.Command,
|
Type = GameEvent.EventType.Say,
|
||||||
Data = message,
|
Data = message,
|
||||||
Origin = origin,
|
Origin = origin,
|
||||||
Owner = server,
|
Owner = server,
|
||||||
Message = message
|
Message = message
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return new GameEvent()
|
|
||||||
{
|
|
||||||
Type = GameEvent.EventType.Say,
|
|
||||||
Data = message,
|
|
||||||
Origin = origin,
|
|
||||||
Owner = server,
|
|
||||||
Message = message
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,11 +149,11 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
string targetId = match.Groups[Configuration.Kill.GroupMapping[ParserRegex.GroupType.TargetNetworkId]].Value.ToString();
|
string targetId = match.Groups[Configuration.Kill.GroupMapping[ParserRegex.GroupType.TargetNetworkId]].Value.ToString();
|
||||||
|
|
||||||
var origin = !string.IsNullOrEmpty(originId) ? server.GetClientsAsList()
|
var origin = !string.IsNullOrEmpty(originId) ? server.GetClientsAsList()
|
||||||
.First(c => c.NetworkId == originId.ConvertLong()) :
|
.First(c => c.NetworkId == originId.ConvertGuidToLong()) :
|
||||||
Utilities.IW4MAdminClient(server);
|
Utilities.IW4MAdminClient(server);
|
||||||
|
|
||||||
var target = !string.IsNullOrEmpty(targetId) ? server.GetClientsAsList()
|
var target = !string.IsNullOrEmpty(targetId) ? server.GetClientsAsList()
|
||||||
.First(c => c.NetworkId == targetId.ConvertLong()) :
|
.First(c => c.NetworkId == targetId.ConvertGuidToLong()) :
|
||||||
Utilities.IW4MAdminClient(server);
|
Utilities.IW4MAdminClient(server);
|
||||||
|
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
@ -166,8 +170,8 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
|
|
||||||
if (eventType == "ScriptKill")
|
if (eventType == "ScriptKill")
|
||||||
{
|
{
|
||||||
long originId = lineSplit[1].ConvertLong();
|
long originId = lineSplit[1].ConvertGuidToLong();
|
||||||
long targetId = lineSplit[2].ConvertLong();
|
long targetId = lineSplit[2].ConvertGuidToLong();
|
||||||
|
|
||||||
var origin = originId == long.MinValue ? Utilities.IW4MAdminClient(server) :
|
var origin = originId == long.MinValue ? Utilities.IW4MAdminClient(server) :
|
||||||
server.GetClientsAsList().First(c => c.NetworkId == originId);
|
server.GetClientsAsList().First(c => c.NetworkId == originId);
|
||||||
@ -186,8 +190,8 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
|
|
||||||
if (eventType == "ScriptDamage")
|
if (eventType == "ScriptDamage")
|
||||||
{
|
{
|
||||||
long originId = lineSplit[1].ConvertLong();
|
long originId = lineSplit[1].ConvertGuidToLong();
|
||||||
long targetId = lineSplit[2].ConvertLong();
|
long targetId = lineSplit[2].ConvertGuidToLong();
|
||||||
|
|
||||||
var origin = originId == long.MinValue ? Utilities.IW4MAdminClient(server) :
|
var origin = originId == long.MinValue ? Utilities.IW4MAdminClient(server) :
|
||||||
server.GetClientsAsList().First(c => c.NetworkId == originId);
|
server.GetClientsAsList().First(c => c.NetworkId == originId);
|
||||||
@ -217,11 +221,11 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
string targetId = regexMatch.Groups[Configuration.Damage.GroupMapping[ParserRegex.GroupType.TargetNetworkId]].ToString();
|
string targetId = regexMatch.Groups[Configuration.Damage.GroupMapping[ParserRegex.GroupType.TargetNetworkId]].ToString();
|
||||||
|
|
||||||
var origin = !string.IsNullOrEmpty(originId) ? server.GetClientsAsList()
|
var origin = !string.IsNullOrEmpty(originId) ? server.GetClientsAsList()
|
||||||
.First(c => c.NetworkId == originId.ConvertLong()) :
|
.First(c => c.NetworkId == originId.ConvertGuidToLong()) :
|
||||||
Utilities.IW4MAdminClient(server);
|
Utilities.IW4MAdminClient(server);
|
||||||
|
|
||||||
var target = !string.IsNullOrEmpty(targetId) ? server.GetClientsAsList()
|
var target = !string.IsNullOrEmpty(targetId) ? server.GetClientsAsList()
|
||||||
.First(c => c.NetworkId == targetId.ConvertLong()) :
|
.First(c => c.NetworkId == targetId.ConvertGuidToLong()) :
|
||||||
Utilities.IW4MAdminClient(server);
|
Utilities.IW4MAdminClient(server);
|
||||||
|
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
@ -255,7 +259,7 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
{
|
{
|
||||||
Name = regexMatch.Groups[Configuration.Join.GroupMapping[ParserRegex.GroupType.OriginName]].ToString().StripColors(),
|
Name = regexMatch.Groups[Configuration.Join.GroupMapping[ParserRegex.GroupType.OriginName]].ToString().StripColors(),
|
||||||
},
|
},
|
||||||
NetworkId = regexMatch.Groups[Configuration.Join.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].ToString().ConvertLong(),
|
NetworkId = regexMatch.Groups[Configuration.Join.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].ToString().ConvertGuidToLong(),
|
||||||
ClientNumber = Convert.ToInt32(regexMatch.Groups[Configuration.Join.GroupMapping[ParserRegex.GroupType.OriginClientNumber]].ToString()),
|
ClientNumber = Convert.ToInt32(regexMatch.Groups[Configuration.Join.GroupMapping[ParserRegex.GroupType.OriginClientNumber]].ToString()),
|
||||||
State = EFClient.ClientState.Connecting,
|
State = EFClient.ClientState.Connecting,
|
||||||
CurrentServer = server,
|
CurrentServer = server,
|
||||||
@ -281,7 +285,7 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
{
|
{
|
||||||
Name = regexMatch.Groups[Configuration.Quit.GroupMapping[ParserRegex.GroupType.OriginName]].ToString().StripColors()
|
Name = regexMatch.Groups[Configuration.Quit.GroupMapping[ParserRegex.GroupType.OriginName]].ToString().StripColors()
|
||||||
},
|
},
|
||||||
NetworkId = regexMatch.Groups[Configuration.Quit.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].ToString().ConvertLong(),
|
NetworkId = regexMatch.Groups[Configuration.Quit.GroupMapping[ParserRegex.GroupType.OriginNetworkId]].ToString().ConvertGuidToLong(),
|
||||||
ClientNumber = Convert.ToInt32(regexMatch.Groups[Configuration.Quit.GroupMapping[ParserRegex.GroupType.OriginClientNumber]].ToString()),
|
ClientNumber = Convert.ToInt32(regexMatch.Groups[Configuration.Quit.GroupMapping[ParserRegex.GroupType.OriginClientNumber]].ToString()),
|
||||||
State = EFClient.ClientState.Disconnecting
|
State = EFClient.ClientState.Disconnecting
|
||||||
}
|
}
|
||||||
|
@ -95,18 +95,18 @@ namespace IW4MAdmin
|
|||||||
if (client.ClientNumber >= 0)
|
if (client.ClientNumber >= 0)
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
Logger.WriteInfo($"Client {client} [{client.State.ToString().ToLower()}] disconnecting...");
|
Logger.WriteInfo($"Client {client} [{client.State.ToString().ToLower()}] disconnecting...");
|
||||||
Clients[client.ClientNumber] = null;
|
Clients[client.ClientNumber] = null;
|
||||||
await client.OnDisconnect();
|
await client.OnDisconnect();
|
||||||
|
|
||||||
var e = new GameEvent()
|
var e = new GameEvent()
|
||||||
{
|
{
|
||||||
Origin = client,
|
Origin = client,
|
||||||
Owner = this,
|
Owner = this,
|
||||||
Type = GameEvent.EventType.Disconnect
|
Type = GameEvent.EventType.Disconnect
|
||||||
};
|
};
|
||||||
|
|
||||||
Manager.GetEventHandler().AddEvent(e);
|
Manager.GetEventHandler().AddEvent(e);
|
||||||
#if DEBUG == true
|
#if DEBUG == true
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -201,22 +201,22 @@ namespace IW4MAdmin
|
|||||||
{
|
{
|
||||||
var newPermission = (Permission)E.Extra;
|
var newPermission = (Permission)E.Extra;
|
||||||
|
|
||||||
if (newPermission < Permission.Moderator)
|
if (newPermission < Permission.Moderator &&
|
||||||
|
!Manager.PrivilegedClients.Remove(E.Target.ClientId, out _))
|
||||||
{
|
{
|
||||||
// remove banned or demoted privileged user
|
Logger.WriteWarning($"Could not remove {E.Target}-{newPermission} from privileged users");
|
||||||
Manager.GetPrivilegedClients().Remove(E.Target.ClientId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Manager.GetPrivilegedClients().ContainsKey(E.Target.ClientId))
|
if (Manager.PrivilegedClients.ContainsKey(E.Target.ClientId))
|
||||||
{
|
{
|
||||||
Manager.GetPrivilegedClients()[E.Target.ClientId] = E.Target;
|
Manager.PrivilegedClients[E.Target.ClientId] = E.Target;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else if (!Manager.PrivilegedClients.TryAdd(E.Target.ClientId, E.Target))
|
||||||
{
|
{
|
||||||
Manager.GetPrivilegedClients().Add(E.Target.ClientId, E.Target);
|
Logger.WriteWarning($"Could not add {E.Target}-{newPermission} to privileged clients");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,17 @@ namespace IW4MAdmin.Application.RconParsers
|
|||||||
ping = int.Parse(regex.Groups[Configuration.Status.GroupMapping[ParserRegex.GroupType.RConPing]].Value);
|
ping = int.Parse(regex.Groups[Configuration.Status.GroupMapping[ParserRegex.GroupType.RConPing]].Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
long networkId = regex.Groups[Configuration.Status.GroupMapping[ParserRegex.GroupType.RConNetworkId]].Value.ConvertLong();
|
long networkId;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
networkId = regex.Groups[Configuration.Status.GroupMapping[ParserRegex.GroupType.RConNetworkId]].Value.ConvertGuidToLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
string name = regex.Groups[Configuration.Status.GroupMapping[ParserRegex.GroupType.RConName]].Value.StripColors().Trim();
|
string name = regex.Groups[Configuration.Status.GroupMapping[ParserRegex.GroupType.RConName]].Value.StripColors().Trim();
|
||||||
int? ip = regex.Groups[Configuration.Status.GroupMapping[ParserRegex.GroupType.RConIpAddress]].Value.Split(':')[0].ConvertToIP();
|
int? ip = regex.Groups[Configuration.Status.GroupMapping[ParserRegex.GroupType.RConIpAddress]].Value.Split(':')[0].ConvertToIP();
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ namespace WebfrontCore.Controllers.API
|
|||||||
public IActionResult ClientInfo(string networkId)
|
public IActionResult ClientInfo(string networkId)
|
||||||
{
|
{
|
||||||
var clientInfo = Manager.GetActiveClients()
|
var clientInfo = Manager.GetActiveClients()
|
||||||
.FirstOrDefault(c => c.NetworkId == networkId.ConvertLong());
|
.FirstOrDefault(c => c.NetworkId == networkId.ConvertGuidToLong());
|
||||||
|
|
||||||
if (clientInfo != null)
|
if (clientInfo != null)
|
||||||
{
|
{
|
||||||
@ -40,7 +40,7 @@ namespace WebfrontCore.Controllers.API
|
|||||||
return Unauthorized();
|
return Unauthorized();
|
||||||
|
|
||||||
var client = Manager.GetActiveClients()
|
var client = Manager.GetActiveClients()
|
||||||
.FirstOrDefault(c => c.NetworkId == networkId.ConvertLong());
|
.FirstOrDefault(c => c.NetworkId == networkId.ConvertGuidToLong());
|
||||||
|
|
||||||
var server = Manager.GetServers().First(c => c.EndPoint == serverId);
|
var server = Manager.GetServers().First(c => c.EndPoint == serverId);
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ namespace IW4MAdmin.Plugins.Login.Commands
|
|||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent E)
|
public override async Task ExecuteAsync(GameEvent E)
|
||||||
{
|
{
|
||||||
var client = E.Owner.Manager.GetPrivilegedClients()[E.Origin.ClientId];
|
var client = E.Owner.Manager.PrivilegedClients[E.Origin.ClientId];
|
||||||
bool success = E.Owner.Manager.TokenAuthenticator.AuthorizeToken(E.Origin.NetworkId, E.Data);
|
bool success = E.Owner.Manager.TokenAuthenticator.AuthorizeToken(E.Origin.NetworkId, E.Data);
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
|
@ -42,7 +42,7 @@ namespace IW4MAdmin.Plugins.Login
|
|||||||
E.Origin.Level == EFClient.Permission.Console)
|
E.Origin.Level == EFClient.Permission.Console)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
E.Owner.Manager.GetPrivilegedClients().TryGetValue(E.Origin.ClientId, out EFClient client);
|
E.Owner.Manager.PrivilegedClients.TryGetValue(E.Origin.ClientId, out EFClient client);
|
||||||
|
|
||||||
if (((Command)E.Extra).Name == new SharedLibraryCore.Commands.CSetPassword().Name &&
|
if (((Command)E.Extra).Name == new SharedLibraryCore.Commands.CSetPassword().Name &&
|
||||||
client?.Password == null)
|
client?.Password == null)
|
||||||
|
@ -201,18 +201,18 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
// ban on headshot
|
// ban on headshot
|
||||||
if (currentHeadshotRatio > maxHeadshotLerpValueForBan)
|
if (currentHeadshotRatio > maxHeadshotLerpValueForBan)
|
||||||
{
|
{
|
||||||
Log.WriteDebug("**Maximum Headshot Ratio Reached For Ban**");
|
//Log.WriteDebug("**Maximum Headshot Ratio Reached For Ban**");
|
||||||
Log.WriteDebug($"ClientId: {hit.AttackerId}");
|
//Log.WriteDebug($"ClientId: {hit.AttackerId}");
|
||||||
Log.WriteDebug($"**HitCount: {HitCount}");
|
//Log.WriteDebug($"**HitCount: {HitCount}");
|
||||||
Log.WriteDebug($"**Ratio {currentHeadshotRatio}");
|
//Log.WriteDebug($"**Ratio {currentHeadshotRatio}");
|
||||||
Log.WriteDebug($"**MaxRatio {maxHeadshotLerpValueForFlag}");
|
//Log.WriteDebug($"**MaxRatio {maxHeadshotLerpValueForFlag}");
|
||||||
var sb = new StringBuilder();
|
//var sb = new StringBuilder();
|
||||||
foreach (var kvp in HitLocationCount)
|
//foreach (var kvp in HitLocationCount)
|
||||||
{
|
//{
|
||||||
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
// sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
||||||
}
|
//}
|
||||||
|
|
||||||
Log.WriteDebug(sb.ToString());
|
//Log.WriteDebug(sb.ToString());
|
||||||
|
|
||||||
result = new DetectionPenaltyResult()
|
result = new DetectionPenaltyResult()
|
||||||
{
|
{
|
||||||
@ -225,18 +225,18 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.WriteDebug("**Maximum Headshot Ratio Reached For Flag**");
|
//Log.WriteDebug("**Maximum Headshot Ratio Reached For Flag**");
|
||||||
Log.WriteDebug($"ClientId: {hit.AttackerId}");
|
//Log.WriteDebug($"ClientId: {hit.AttackerId}");
|
||||||
Log.WriteDebug($"**HitCount: {HitCount}");
|
//Log.WriteDebug($"**HitCount: {HitCount}");
|
||||||
Log.WriteDebug($"**Ratio {currentHeadshotRatio}");
|
//Log.WriteDebug($"**Ratio {currentHeadshotRatio}");
|
||||||
Log.WriteDebug($"**MaxRatio {maxHeadshotLerpValueForFlag}");
|
//Log.WriteDebug($"**MaxRatio {maxHeadshotLerpValueForFlag}");
|
||||||
var sb = new StringBuilder();
|
//var sb = new StringBuilder();
|
||||||
foreach (var kvp in HitLocationCount)
|
//foreach (var kvp in HitLocationCount)
|
||||||
{
|
//{
|
||||||
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
// sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
||||||
}
|
//}
|
||||||
|
|
||||||
Log.WriteDebug(sb.ToString());
|
//Log.WriteDebug(sb.ToString());
|
||||||
|
|
||||||
result = new DetectionPenaltyResult()
|
result = new DetectionPenaltyResult()
|
||||||
{
|
{
|
||||||
|
@ -491,7 +491,7 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private bool ShouldIgnoreEvent(EFClient origin, EFClient target)
|
private bool ShouldIgnoreEvent(EFClient origin, EFClient target)
|
||||||
{
|
{
|
||||||
return ((origin.ClientId <= 1 && target.ClientId <= 1) || (target.IsBot || origin.IsBot) && ServerManager.GetApplicationSettings().Configuration().IgnoreBots);
|
return ((origin.ClientId <= 1 && target.ClientId <= 1) || ((target.IsBot || origin.IsBot) && ServerManager.GetApplicationSettings().Configuration().IgnoreBots));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1119,8 +1119,8 @@ namespace SharedLibraryCore.Commands
|
|||||||
E.Origin.PasswordSalt = hashedPassword[1];
|
E.Origin.PasswordSalt = hashedPassword[1];
|
||||||
|
|
||||||
// update the password for the client in privileged
|
// update the password for the client in privileged
|
||||||
E.Owner.Manager.GetPrivilegedClients()[E.Origin.ClientId].Password = hashedPassword[0];
|
E.Owner.Manager.PrivilegedClients[E.Origin.ClientId].Password = hashedPassword[0];
|
||||||
E.Owner.Manager.GetPrivilegedClients()[E.Origin.ClientId].PasswordSalt = hashedPassword[1];
|
E.Owner.Manager.PrivilegedClients[E.Origin.ClientId].PasswordSalt = hashedPassword[1];
|
||||||
|
|
||||||
await E.Owner.Manager.GetClientService().Update(E.Origin);
|
await E.Owner.Manager.GetClientService().Update(E.Origin);
|
||||||
E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PASSWORD_SUCCESS"]);
|
E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PASSWORD_SUCCESS"]);
|
||||||
|
@ -6,6 +6,7 @@ using SharedLibraryCore.Services;
|
|||||||
using SharedLibraryCore.Configuration;
|
using SharedLibraryCore.Configuration;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using SharedLibraryCore.Database.Models;
|
using SharedLibraryCore.Database.Models;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
namespace SharedLibraryCore.Interfaces
|
namespace SharedLibraryCore.Interfaces
|
||||||
{
|
{
|
||||||
@ -23,7 +24,7 @@ namespace SharedLibraryCore.Interfaces
|
|||||||
ClientService GetClientService();
|
ClientService GetClientService();
|
||||||
AliasService GetAliasService();
|
AliasService GetAliasService();
|
||||||
PenaltyService GetPenaltyService();
|
PenaltyService GetPenaltyService();
|
||||||
IDictionary<int, EFClient> GetPrivilegedClients();
|
IDictionary<int, EFClient> PrivilegedClients { get; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the event handlers
|
/// Get the event handlers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -103,7 +103,7 @@ namespace SharedLibraryCore.Database.Models
|
|||||||
Data = message
|
Data = message
|
||||||
};
|
};
|
||||||
|
|
||||||
this.CurrentServer?.Manager.GetEventHandler().AddEvent(e);
|
CurrentServer?.Manager.GetEventHandler().AddEvent(e);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,14 +125,14 @@ namespace SharedLibraryCore.Database.Models
|
|||||||
};
|
};
|
||||||
|
|
||||||
// enforce level restrictions
|
// enforce level restrictions
|
||||||
if (this.Level > sender.Level)
|
if (Level > sender.Level)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.Warnings++;
|
Warnings++;
|
||||||
}
|
}
|
||||||
|
|
||||||
sender.CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
sender.CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
||||||
@ -156,13 +156,13 @@ namespace SharedLibraryCore.Database.Models
|
|||||||
};
|
};
|
||||||
|
|
||||||
// enforce level restrictions
|
// enforce level restrictions
|
||||||
if (sender.Level <= this.Level)
|
if (sender.Level <= Level)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Warnings = 0;
|
Warnings = 0;
|
||||||
|
|
||||||
sender.CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
sender.CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
||||||
return e;
|
return e;
|
||||||
@ -188,12 +188,12 @@ namespace SharedLibraryCore.Database.Models
|
|||||||
|
|
||||||
int reportCount = sender.GetAdditionalProperty<int>("_reportCount");
|
int reportCount = sender.GetAdditionalProperty<int>("_reportCount");
|
||||||
|
|
||||||
if (this.Level > sender.Level)
|
if (Level > sender.Level)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (this.Equals(sender))
|
else if (Equals(sender))
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Invalid;
|
e.FailReason = GameEvent.EventFailReason.Invalid;
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ namespace SharedLibraryCore.Database.Models
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 == NetworkId)) > 0)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Exception;
|
e.FailReason = GameEvent.EventFailReason.Exception;
|
||||||
}
|
}
|
||||||
@ -232,12 +232,12 @@ namespace SharedLibraryCore.Database.Models
|
|||||||
Owner = sender.CurrentServer
|
Owner = sender.CurrentServer
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.Level >= sender.Level)
|
if (Level >= sender.Level)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (this.Level == Permission.Flagged)
|
else if (Level == Permission.Flagged)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Invalid;
|
e.FailReason = GameEvent.EventFailReason.Invalid;
|
||||||
}
|
}
|
||||||
@ -264,12 +264,12 @@ namespace SharedLibraryCore.Database.Models
|
|||||||
Owner = sender.CurrentServer
|
Owner = sender.CurrentServer
|
||||||
};
|
};
|
||||||
|
|
||||||
if (sender.Level <= this.Level)
|
if (sender.Level <= Level)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (this.Level != Permission.Flagged)
|
else if (Level != Permission.Flagged)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Invalid;
|
e.FailReason = GameEvent.EventFailReason.Invalid;
|
||||||
}
|
}
|
||||||
@ -296,7 +296,7 @@ namespace SharedLibraryCore.Database.Models
|
|||||||
};
|
};
|
||||||
|
|
||||||
// enforce level restrictions
|
// enforce level restrictions
|
||||||
if (this.Level > sender.Level)
|
if (Level > sender.Level)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
}
|
}
|
||||||
@ -325,7 +325,7 @@ namespace SharedLibraryCore.Database.Models
|
|||||||
};
|
};
|
||||||
|
|
||||||
// enforce level restrictions
|
// enforce level restrictions
|
||||||
if (sender.Level <= this.Level)
|
if (sender.Level <= Level)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
}
|
}
|
||||||
@ -353,7 +353,7 @@ namespace SharedLibraryCore.Database.Models
|
|||||||
};
|
};
|
||||||
|
|
||||||
// enforce level restrictions
|
// enforce level restrictions
|
||||||
if (sender.Level <= this.Level)
|
if (sender.Level <= Level)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
}
|
}
|
||||||
@ -381,7 +381,7 @@ namespace SharedLibraryCore.Database.Models
|
|||||||
};
|
};
|
||||||
|
|
||||||
// enforce level restrictions
|
// enforce level restrictions
|
||||||
if (this.Level > sender.Level)
|
if (Level > sender.Level)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
}
|
}
|
||||||
@ -407,7 +407,7 @@ namespace SharedLibraryCore.Database.Models
|
|||||||
Owner = sender.CurrentServer
|
Owner = sender.CurrentServer
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.Level > sender.Level)
|
if (Level > sender.Level)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
}
|
}
|
||||||
@ -675,7 +675,7 @@ namespace SharedLibraryCore.Database.Models
|
|||||||
}
|
}
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
Dictionary<string, object> _additionalProperties;
|
readonly Dictionary<string, object> _additionalProperties;
|
||||||
|
|
||||||
public T GetAdditionalProperty<T>(string name)
|
public T GetAdditionalProperty<T>(string name)
|
||||||
{
|
{
|
||||||
|
@ -217,7 +217,7 @@ namespace SharedLibraryCore.Services
|
|||||||
using (var ctx = new DatabaseContext())
|
using (var ctx = new DatabaseContext())
|
||||||
{
|
{
|
||||||
var entity = await ctx.Clients
|
var entity = await ctx.Clients
|
||||||
.Where(_client => _client.AliasLinkId == temporalClient.AliasLinkId)
|
.Where(_client => _client.ClientId == temporalClient.ClientId)
|
||||||
.FirstAsync();
|
.FirstAsync();
|
||||||
|
|
||||||
var oldPermission = entity.Level;
|
var oldPermission = entity.Level;
|
||||||
@ -451,7 +451,7 @@ namespace SharedLibraryCore.Services
|
|||||||
|
|
||||||
using (var context = new DatabaseContext(disableTracking: true))
|
using (var context = new DatabaseContext(disableTracking: true))
|
||||||
{
|
{
|
||||||
long networkId = identifier.ConvertLong();
|
long networkId = identifier.ConvertGuidToLong();
|
||||||
int? ipAddress = identifier.ConvertToIP();
|
int? ipAddress = identifier.ConvertToIP();
|
||||||
|
|
||||||
IQueryable<EFAlias> iqLinkIds = context.Aliases.Where(_alias => _alias.Active);
|
IQueryable<EFAlias> iqLinkIds = context.Aliases.Where(_alias => _alias.Active);
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
<Authors>RaidMax</Authors>
|
<Authors>RaidMax</Authors>
|
||||||
<Company>Forever None</Company>
|
<Company>Forever None</Company>
|
||||||
<Configurations>Debug;Release;Prerelease</Configurations>
|
<Configurations>Debug;Release;Prerelease</Configurations>
|
||||||
|
<PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -266,33 +266,35 @@ namespace SharedLibraryCore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long ConvertLong(this string str)
|
public static long ConvertGuidToLong(this string str)
|
||||||
{
|
{
|
||||||
str = str.Substring(0, Math.Min(str.Length, 16));
|
str = str.Substring(0, Math.Min(str.Length, 16));
|
||||||
int maxBots = 18;
|
|
||||||
long id;
|
|
||||||
|
|
||||||
if (str.Length <= 11) // 10 numeric characters + signed character
|
|
||||||
{
|
|
||||||
if (long.TryParse(str, NumberStyles.Integer, CultureInfo.InvariantCulture, out id))
|
|
||||||
{
|
|
||||||
return (uint)id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (long.TryParse(str, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out id))
|
|
||||||
{
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bot = Regex.Match(str, @"bot[0-9]+").Value;
|
var bot = Regex.Match(str, @"bot[0-9]+").Value;
|
||||||
if (!string.IsNullOrEmpty(bot))
|
int maxBots = 18;
|
||||||
|
|
||||||
|
// this is a special case for Plutonium T6
|
||||||
|
if (str.Length <= 11 &&
|
||||||
|
long.TryParse(str, NumberStyles.Integer, CultureInfo.InvariantCulture, out long id)) // 10 numeric characters + signed character
|
||||||
|
{
|
||||||
|
id = (uint)id;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (long.TryParse(str, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out id))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (!string.IsNullOrEmpty(bot))
|
||||||
{
|
{
|
||||||
// should set their GUID to the negation of their 1 based index (-1 - -18)
|
// should set their GUID to the negation of their 1 based index (-1 - -18)
|
||||||
return -(Convert.ToInt64(bot.Substring(3)) + 1) % maxBots;
|
id = -(Convert.ToInt64(bot.Substring(3)) + 1) % maxBots;
|
||||||
}
|
}
|
||||||
|
|
||||||
return long.MinValue;
|
if (id == 0)
|
||||||
|
{
|
||||||
|
throw new FormatException($"Could not parse client GUID - {str}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int? ConvertToIP(this string str)
|
public static int? ConvertToIP(this string str)
|
||||||
|
@ -25,14 +25,9 @@ namespace WebfrontCore.Controllers
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//#if DEBUG == true
|
var privilegedClient = Manager.PrivilegedClients[clientId];
|
||||||
// var client = Utilities.IW4MAdminClient();
|
|
||||||
// bool loginSuccess = true;
|
|
||||||
//#else
|
|
||||||
var privilegedClient = Manager.GetPrivilegedClients()[clientId];
|
|
||||||
bool loginSuccess = Manager.TokenAuthenticator.AuthorizeToken(privilegedClient.NetworkId, password) ||
|
bool loginSuccess = Manager.TokenAuthenticator.AuthorizeToken(privilegedClient.NetworkId, password) ||
|
||||||
(await Task.FromResult(SharedLibraryCore.Helpers.Hashing.Hash(password, privilegedClient.PasswordSalt)))[0] == privilegedClient.Password;
|
(await Task.FromResult(SharedLibraryCore.Helpers.Hashing.Hash(password, privilegedClient.PasswordSalt)))[0] == privilegedClient.Password;
|
||||||
//#endif
|
|
||||||
|
|
||||||
if (loginSuccess)
|
if (loginSuccess)
|
||||||
{
|
{
|
||||||
|
@ -71,7 +71,7 @@ namespace WebfrontCore.Controllers
|
|||||||
if (clientId > 0)
|
if (clientId > 0)
|
||||||
{
|
{
|
||||||
Client.ClientId = clientId;
|
Client.ClientId = clientId;
|
||||||
Client.NetworkId = User.Claims.First(_claim => _claim.Type == ClaimTypes.PrimarySid).Value.ConvertLong();
|
Client.NetworkId = User.Claims.First(_claim => _claim.Type == ClaimTypes.PrimarySid).Value.ConvertGuidToLong();
|
||||||
Client.Level = (EFClient.Permission)Enum.Parse(typeof(EFClient.Permission), User.Claims.First(c => c.Type == ClaimTypes.Role).Value);
|
Client.Level = (EFClient.Permission)Enum.Parse(typeof(EFClient.Permission), User.Claims.First(c => c.Type == ClaimTypes.Role).Value);
|
||||||
Client.CurrentAlias = new EFAlias() { Name = User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value };
|
Client.CurrentAlias = new EFAlias() { Name = User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value };
|
||||||
Authorized = Client.ClientId >= 0;
|
Authorized = Client.ClientId >= 0;
|
||||||
|
@ -22,7 +22,7 @@ namespace WebfrontCore.Controllers
|
|||||||
ViewBag.Title = Localization["WEBFRONT_PENALTY_TITLE"];
|
ViewBag.Title = Localization["WEBFRONT_PENALTY_TITLE"];
|
||||||
ViewBag.Keywords = "IW4MAdmin, penalties, ban, kick, warns";
|
ViewBag.Keywords = "IW4MAdmin, penalties, ban, kick, warns";
|
||||||
|
|
||||||
return View((SharedLibraryCore.Objects.Penalty.PenaltyType)showOnly);
|
return View(showOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IActionResult> ListAsync(int offset = 0, PenaltyType showOnly = PenaltyType.Any)
|
public async Task<IActionResult> ListAsync(int offset = 0, PenaltyType showOnly = PenaltyType.Any)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
let offset = 12;
|
let offset = 15;
|
||||||
let isLoading = false;
|
let isLoading = false;
|
||||||
|
|
||||||
function loadMorePenalties() {
|
function loadMorePenalties() {
|
||||||
@ -21,17 +21,15 @@ function loadMorePenalties() {
|
|||||||
errorLoader();
|
errorLoader();
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
});
|
});
|
||||||
offset += 12;
|
offset += 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($('#penalty_table').length === 1) {
|
if ($('#penalty_table').length === 1) {
|
||||||
|
|
||||||
$('#penalty_filter_selection').change(function() {
|
$('#penalty_filter_selection').change(function() {
|
||||||
// if (offset === 0) {
|
|
||||||
location = location.href.split('?')[0] + "?showOnly=" + $('#penalty_filter_selection').val();
|
location = location.href.split('?')[0] + "?showOnly=" + $('#penalty_filter_selection').val();
|
||||||
// }
|
|
||||||
});
|
});
|
||||||
/*
|
/*
|
||||||
https://stackoverflow.com/questions/19731730/jquery-js-detect-users-scroll-attempt-without-any-window-overflow-to-scroll
|
https://stackoverflow.com/questions/19731730/jquery-js-detect-users-scroll-attempt-without-any-window-overflow-to-scroll
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user