mirror of
https://github.com/RaidMax/IW4M-Admin.git
synced 2025-06-10 15:20:48 -05:00
add ban management page
This commit is contained in:
@ -1,6 +1,10 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Data.Abstractions;
|
||||
using Data.Models;
|
||||
using Data.Models.Client;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SharedLibraryCore;
|
||||
@ -21,16 +25,26 @@ public class BanInfoResourceQueryHelper : IResourceQueryHelper<BanInfoRequest, B
|
||||
|
||||
public async Task<ResourceQueryHelperResult<BanInfo>> QueryResource(BanInfoRequest query)
|
||||
{
|
||||
if (query.Count > 30)
|
||||
if (query.Count > 10)
|
||||
{
|
||||
query.Count = 30;
|
||||
query.Count = 10;
|
||||
}
|
||||
|
||||
await using var context = _contextFactory.CreateContext(false);
|
||||
|
||||
var matchingClients = await context.Clients.Where(client =>
|
||||
EF.Functions.ILike(client.CurrentAlias.SearchableName ?? client.CurrentAlias.Name, $"%{query.ClientName.Trim()}%"))
|
||||
.Where(client => client.Level == EFClient.Permission.Banned)
|
||||
await using var context = _contextFactory.CreateContext(false);
|
||||
|
||||
var iqMatchingClients = context.Clients.Where(client => client.Level == EFClient.Permission.Banned);
|
||||
iqMatchingClients = SetupSearchArgs(query, iqMatchingClients);
|
||||
|
||||
if (string.IsNullOrEmpty(query.ClientName) && string.IsNullOrEmpty(query.ClientGuid) &&
|
||||
query.ClientId is null && string.IsNullOrEmpty(query.ClientIP))
|
||||
{
|
||||
return new ResourceQueryHelperResult<BanInfo>
|
||||
{
|
||||
Results = Enumerable.Empty<BanInfo>()
|
||||
};
|
||||
}
|
||||
|
||||
var matchingClients = await iqMatchingClients
|
||||
.OrderByDescending(client => client.LastConnection)
|
||||
.Skip(query.Offset)
|
||||
.Take(query.Count)
|
||||
@ -39,52 +53,117 @@ public class BanInfoResourceQueryHelper : IResourceQueryHelper<BanInfoRequest, B
|
||||
client.CurrentAlias.Name,
|
||||
client.NetworkId,
|
||||
client.AliasLinkId,
|
||||
client.ClientId
|
||||
client.ClientId,
|
||||
client.CurrentAlias.IPAddress
|
||||
}).ToListAsync();
|
||||
|
||||
var usedIps = await context.Aliases
|
||||
.Where(alias => matchingClients.Select(client => client.AliasLinkId).Contains(alias.LinkId))
|
||||
.Where(alias => alias.IPAddress != null)
|
||||
.Select(alias => new { alias.IPAddress, alias.LinkId })
|
||||
.ToListAsync();
|
||||
var results = new List<BanInfo>();
|
||||
var matchedClientIds = new List<int?>();
|
||||
var lateDateTime = DateTime.Now.AddYears(100);
|
||||
|
||||
var usedIpsGrouped = usedIps
|
||||
.GroupBy(alias => alias.LinkId)
|
||||
.ToDictionary(key => key.Key, value => value.Select(alias => alias.IPAddress).Distinct());
|
||||
|
||||
var searchingNetworkIds = matchingClients.Select(client => client.NetworkId);
|
||||
var searchingIps = usedIpsGrouped.SelectMany(group => group.Value);
|
||||
|
||||
var matchedPenalties = await context.PenaltyIdentifiers.Where(identifier =>
|
||||
searchingNetworkIds.Contains(identifier.NetworkId) ||
|
||||
searchingIps.Contains(identifier.IPv4Address))
|
||||
.Select(penalty => new
|
||||
{
|
||||
penalty.CreatedDateTime,
|
||||
PunisherName = penalty.Penalty.Punisher.CurrentAlias.Name,
|
||||
Offense = string.IsNullOrEmpty(penalty.Penalty.AutomatedOffense) ? penalty.Penalty.Offense : "Anticheat Detection",
|
||||
LinkId = penalty.Penalty.Offender.AliasLinkId,
|
||||
penalty.Penalty.PunisherId
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
var groupedPenalties = matchedPenalties.GroupBy(penalty => penalty.LinkId)
|
||||
.ToDictionary(key => key.Key, value => value.FirstOrDefault());
|
||||
|
||||
var results = matchingClients.Select(client =>
|
||||
// would prefer not to loop this, but unfortunately due to the data design
|
||||
// we can't properly group on ip and alias link
|
||||
foreach (var matchingClient in matchingClients)
|
||||
{
|
||||
var matchedPenalty =
|
||||
groupedPenalties.ContainsKey(client.AliasLinkId) ? groupedPenalties[client.AliasLinkId] : null;
|
||||
return new BanInfo
|
||||
var usedIps = await context.Aliases
|
||||
.Where(alias => matchingClient.AliasLinkId == alias.LinkId)
|
||||
.Where(alias => alias.IPAddress != null)
|
||||
.Select(alias => new { alias.IPAddress, alias.LinkId })
|
||||
.ToListAsync();
|
||||
|
||||
var searchingNetworkId = matchingClient.NetworkId;
|
||||
var searchingIps = usedIps.Select(ip => ip.IPAddress).Distinct();
|
||||
|
||||
var matchedPenalties = await context.PenaltyIdentifiers.Where(identifier =>
|
||||
identifier.NetworkId == searchingNetworkId ||
|
||||
searchingIps.Contains(identifier.IPv4Address))
|
||||
.Where(identifier => identifier.Penalty.Expires == null || identifier.Penalty.Expires > lateDateTime)
|
||||
.Select(penalty => new
|
||||
{
|
||||
penalty.CreatedDateTime,
|
||||
PunisherName = penalty.Penalty.Punisher.CurrentAlias.Name,
|
||||
OffenderName = penalty.Penalty.Offender.CurrentAlias.Name,
|
||||
Offense = string.IsNullOrEmpty(penalty.Penalty.AutomatedOffense)
|
||||
? penalty.Penalty.Offense
|
||||
: "Anticheat Detection",
|
||||
LinkId = penalty.Penalty.Offender.AliasLinkId,
|
||||
penalty.Penalty.OffenderId,
|
||||
penalty.Penalty.PunisherId,
|
||||
penalty.IPv4Address,
|
||||
penalty.Penalty.Offender.NetworkId
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
if (!matchedPenalties.Any())
|
||||
{
|
||||
DateTime = matchedPenalty?.CreatedDateTime,
|
||||
OffenderName = client.Name.StripColors(),
|
||||
OffenderId = client.ClientId,
|
||||
PunisherName = matchedPenalty?.PunisherName.StripColors(),
|
||||
PunisherId = matchedPenalty?.PunisherId,
|
||||
Offense = matchedPenalty?.Offense
|
||||
};
|
||||
}).ToList();
|
||||
var linkIds = (await context.Aliases
|
||||
.Where(alias => alias.IPAddress != null && searchingIps.Contains(alias.IPAddress))
|
||||
.Select(alias => alias.LinkId)
|
||||
.ToListAsync()).Distinct();
|
||||
|
||||
|
||||
matchedPenalties = await context.Penalties.Where(penalty => penalty.Type == EFPenalty.PenaltyType.Ban)
|
||||
.Where(penalty => penalty.Expires == null || penalty.Expires > lateDateTime)
|
||||
.Where(penalty => penalty.LinkId != null && linkIds.Contains(penalty.LinkId.Value))
|
||||
.OrderByDescending(penalty => penalty.When)
|
||||
.Select(penalty => new
|
||||
{
|
||||
CreatedDateTime = penalty.When,
|
||||
PunisherName = penalty.Punisher.CurrentAlias.Name,
|
||||
OffenderName = penalty.Offender.CurrentAlias.Name,
|
||||
Offense = string.IsNullOrEmpty(penalty.AutomatedOffense)
|
||||
? penalty.Offense
|
||||
: "Anticheat Detection",
|
||||
LinkId = penalty.Offender.AliasLinkId,
|
||||
penalty.OffenderId,
|
||||
penalty.PunisherId,
|
||||
IPv4Address = penalty.Offender.CurrentAlias.IPAddress,
|
||||
penalty.Offender.NetworkId
|
||||
}).ToListAsync();
|
||||
}
|
||||
|
||||
var allPenalties = matchedPenalties.Select(penalty => new PenaltyInfo
|
||||
{
|
||||
DateTime = penalty.CreatedDateTime,
|
||||
Offense = penalty.Offense,
|
||||
PunisherInfo = new RelatedClientInfo
|
||||
{
|
||||
ClientName = penalty.PunisherName.StripColors(),
|
||||
ClientId = penalty.PunisherId,
|
||||
},
|
||||
OffenderInfo = new RelatedClientInfo
|
||||
{
|
||||
ClientName = penalty.OffenderName.StripColors(),
|
||||
ClientId = penalty.OffenderId,
|
||||
IPAddress = penalty.IPv4Address,
|
||||
NetworkId = penalty.NetworkId
|
||||
}
|
||||
}).ToList();
|
||||
|
||||
|
||||
if (matchedClientIds.Contains(matchingClient.ClientId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
matchedClientIds.Add(matchingClient.ClientId);
|
||||
var relatedEntities =
|
||||
allPenalties.Where(penalty => penalty.OffenderInfo.ClientId != matchingClient.ClientId);
|
||||
|
||||
matchedClientIds.AddRange(relatedEntities.Select(client => client.OffenderInfo.ClientId));
|
||||
|
||||
results.Add(new BanInfo
|
||||
{
|
||||
ClientName = matchingClient.Name.StripColors(),
|
||||
ClientId = matchingClient.ClientId,
|
||||
NetworkId = matchingClient.NetworkId,
|
||||
IPAddress = matchingClient.IPAddress,
|
||||
|
||||
AssociatedPenalties = relatedEntities,
|
||||
AttachedPenalty = allPenalties.FirstOrDefault(penalty =>
|
||||
penalty.OffenderInfo.ClientId == matchingClient.ClientId)
|
||||
});
|
||||
}
|
||||
|
||||
return new ResourceQueryHelperResult<BanInfo>
|
||||
{
|
||||
@ -93,4 +172,61 @@ public class BanInfoResourceQueryHelper : IResourceQueryHelper<BanInfoRequest, B
|
||||
Results = results
|
||||
};
|
||||
}
|
||||
|
||||
private IQueryable<EFClient> SetupSearchArgs(BanInfoRequest query, IQueryable<EFClient> source)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(query.ClientName))
|
||||
{
|
||||
var nameToSearch = query.ClientName.Trim().ToLower();
|
||||
source = source.Where(client =>
|
||||
EF.Functions.Like(client.CurrentAlias.SearchableName ?? client.CurrentAlias.Name.ToLower(),
|
||||
$"%{nameToSearch}%"));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(query.ClientGuid))
|
||||
{
|
||||
long? parsedGuid = null;
|
||||
if (!long.TryParse(query.ClientGuid, NumberStyles.HexNumber, null, out var guid))
|
||||
{
|
||||
if (!long.TryParse(query.ClientGuid, out var guid2))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
parsedGuid = guid2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
parsedGuid = guid;
|
||||
}
|
||||
|
||||
if (parsedGuid is not null)
|
||||
{
|
||||
source = source.Where(client => client.NetworkId == parsedGuid);
|
||||
}
|
||||
}
|
||||
|
||||
if (query.ClientId is not null)
|
||||
{
|
||||
source = source.Where(client => client.ClientId == query.ClientId);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(query.ClientIP))
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
var parsedIp = query.ClientIP.ConvertToIP();
|
||||
if (parsedIp is not null)
|
||||
{
|
||||
source = source.Where(client => client.CurrentAlias.IPAddress == parsedIp);
|
||||
}
|
||||
else
|
||||
{
|
||||
query.ClientIP = null;
|
||||
}
|
||||
|
||||
return source;
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WebfrontCore.QueryHelpers.Models;
|
||||
|
||||
public class BanInfo
|
||||
{
|
||||
public string OffenderName { get; set; }
|
||||
public int OffenderId { get; set; }
|
||||
public string PunisherName { get; set; }
|
||||
public int? PunisherId { get; set; }
|
||||
public string ClientName { get; set; }
|
||||
public int ClientId { get; set; }
|
||||
public int? IPAddress { get; set; }
|
||||
public long NetworkId { get; set; }
|
||||
public PenaltyInfo AttachedPenalty { get; set; }
|
||||
public IEnumerable<PenaltyInfo> AssociatedPenalties { get; set; }
|
||||
}
|
||||
|
||||
public class PenaltyInfo
|
||||
{
|
||||
public RelatedClientInfo OffenderInfo { get; set; }
|
||||
public RelatedClientInfo PunisherInfo { get; set; }
|
||||
public string Offense { get; set; }
|
||||
public DateTime? DateTime { get; set; }
|
||||
public long? TimeStamp => DateTime.HasValue ? new DateTimeOffset(DateTime.Value, TimeSpan.Zero).ToUnixTimeSeconds() : null;
|
||||
|
||||
public long? TimeStamp =>
|
||||
DateTime.HasValue ? new DateTimeOffset(DateTime.Value, TimeSpan.Zero).ToUnixTimeSeconds() : null;
|
||||
}
|
||||
|
||||
public class RelatedClientInfo
|
||||
{
|
||||
public string ClientName { get; set; }
|
||||
public int? ClientId { get; set; }
|
||||
public int? IPAddress { get; set; }
|
||||
public long? NetworkId { get; set; }
|
||||
}
|
||||
|
@ -5,4 +5,7 @@ namespace WebfrontCore.QueryHelpers.Models;
|
||||
public class BanInfoRequest : PaginationRequest
|
||||
{
|
||||
public string ClientName { get; set; }
|
||||
public string ClientGuid { get; set; }
|
||||
public int? ClientId { get; set; }
|
||||
public string ClientIP { get; set; }
|
||||
}
|
||||
|
Reference in New Issue
Block a user