optimize the find client query

This commit is contained in:
RaidMax 2019-04-25 21:05:35 -05:00
parent 02622ea7de
commit 599a14b646
5 changed files with 58 additions and 35 deletions

View File

@ -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.6.5</Version> <Version>2.2.7.0</Version>
<Authors>RaidMax</Authors> <Authors>RaidMax</Authors>
<Company>Forever None</Company> <Company>Forever None</Company>
<Product>IW4MAdmin</Product> <Product>IW4MAdmin</Product>
@ -31,8 +31,8 @@
<PropertyGroup> <PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection> <ServerGarbageCollection>true</ServerGarbageCollection>
<TieredCompilation>true</TieredCompilation> <TieredCompilation>true</TieredCompilation>
<AssemblyVersion>2.2.6.5</AssemblyVersion> <AssemblyVersion>2.2.7.0</AssemblyVersion>
<FileVersion>2.2.6.5</FileVersion> <FileVersion>2.2.7.0</FileVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,6 +1,6 @@
# IW4MAdmin # IW4MAdmin
### Quick Start Guide ### Quick Start Guide
### Version 2.2 ### Version 2.3
_______ _______
### About ### About
**IW4MAdmin** is an administration tool for [IW4x](https://iw4xcachep26muba.onion.link/), [Pluto T6](https://forum.plutonium.pw/category/33/plutonium-t6), ~~[Pluto IW5](https://forum.plutonium.pw/category/5/plutonium-iw5)~~, and most Call of Duty® dedicated servers. It allows complete control of your server; from changing maps, to banning players, **IW4MAdmin** monitors and records activity on your server(s). With plugin support, extending its functionality is a breeze. **IW4MAdmin** is an administration tool for [IW4x](https://iw4xcachep26muba.onion.link/), [Pluto T6](https://forum.plutonium.pw/category/33/plutonium-t6), ~~[Pluto IW5](https://forum.plutonium.pw/category/5/plutonium-iw5)~~, and most Call of Duty® dedicated servers. It allows complete control of your server; from changing maps, to banning players, **IW4MAdmin** monitors and records activity on your server(s). With plugin support, extending its functionality is a breeze.

View File

@ -11,6 +11,7 @@ using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using static SharedLibraryCore.Database.Models.EFClient;
namespace SharedLibraryCore.Commands namespace SharedLibraryCore.Commands
{ {
@ -619,10 +620,7 @@ namespace SharedLibraryCore.Commands
return; return;
} }
IList<EFClient> db_players = (await (E.Owner.Manager.GetClientService() as ClientService) var db_players = (await (E.Owner.Manager.GetClientService() as ClientService).FindClientsByIdentifier(E.Data));
.FindClientsByIdentifier(E.Data))
.OrderByDescending(p => p.LastConnection)
.ToList();
if (db_players.Count == 0) if (db_players.Count == 0)
{ {
@ -632,11 +630,11 @@ namespace SharedLibraryCore.Commands
foreach (var P in db_players) foreach (var P in db_players)
{ {
string localizedLevel = Utilities.CurrentLocalization.LocalizationIndex[$"GLOBAL_PERMISSION_{P.Level.ToString().ToUpper()}"];
// they're not going by another alias // they're not going by another alias
// /*P.AliasLink.Children.FirstOrDefault(a => a.Name.ToLower().Contains(E.Data.ToLower()))?.Name*/
string msg = P.Name.ToLower().Contains(E.Data.ToLower()) ? string msg = P.Name.ToLower().Contains(E.Data.ToLower()) ?
$"[^3{P.Name}^7] [^3@{P.ClientId}^7] - [{ Utilities.ConvertLevelToColor(P.Level, localizedLevel)}^7] - {P.IPAddressString} | last seen {Utilities.GetTimePassed(P.LastConnection)}" : $"[^3{P.Name}^7] [^3@{P.ClientId}^7] - [{ Utilities.ConvertLevelToColor((Permission)P.LevelInt, P.Level)}^7] - {P.IPAddress} | last seen {Utilities.GetTimePassed(P.LastConnection)}" :
$"({P.AliasLink.Children.FirstOrDefault(a => a.Name.ToLower().Contains(E.Data.ToLower()))?.Name})->[^3{P.Name}^7] [^3@{P.ClientId}^7] - [{ Utilities.ConvertLevelToColor(P.Level, localizedLevel)}^7] - {P.IPAddressString} | last seen {Utilities.GetTimePassed(P.LastConnection)}"; $"()->[^3{P.Name}^7] [^3@{P.ClientId}^7] - [{ Utilities.ConvertLevelToColor((Permission)P.LevelInt, P.Level)}^7] - {P.IPAddress} | last seen {Utilities.GetTimePassed(P.LastConnection)}";
E.Origin.Tell(msg); E.Origin.Tell(msg);
} }
} }

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using SharedLibraryCore.Database; using SharedLibraryCore.Database;
using SharedLibraryCore.Database.Models; using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Dtos;
using SharedLibraryCore.Objects; using SharedLibraryCore.Objects;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -439,11 +440,11 @@ namespace SharedLibraryCore.Services
} }
} }
public async Task<IList<EFClient>> FindClientsByIdentifier(string identifier) public async Task<IList<PlayerInfo>> FindClientsByIdentifier(string identifier)
{ {
if (identifier?.Length < 3) if (identifier?.Length < 3)
{ {
return new List<EFClient>(); return new List<PlayerInfo>();
} }
identifier = identifier.ToLower(); identifier = identifier.ToLower();
@ -453,24 +454,59 @@ namespace SharedLibraryCore.Services
long networkId = identifier.ConvertLong(); long networkId = identifier.ConvertLong();
int? ipAddress = identifier.ConvertToIP(); int? ipAddress = identifier.ConvertToIP();
var iqLinkIds = (from alias in context.Aliases IQueryable<EFAlias> iqLinkIds = context.Aliases.Where(_alias => _alias.Active);
where (alias.IPAddress != null && alias.IPAddress == ipAddress) ||
alias.Name.ToLower().Contains(identifier)
select alias.LinkId).Distinct();
var linkIds = await iqLinkIds.ToListAsync(); // we want to query for the IP ADdress
if (ipAddress != null)
{
iqLinkIds = iqLinkIds.Where(_alias => _alias.IPAddress == ipAddress);
}
// want to find them by name (wildcard)
// todo maybe not make it start with wildcard?
else
{
iqLinkIds = iqLinkIds.Where(_alias => EF.Functions.Like(_alias.Name, $"%{identifier}%"));
}
var linkIds = await iqLinkIds
.Select(_alias => _alias.LinkId)
.ToListAsync();
// get all the clients that match the alias link or the network id
var iqClients = context.Clients var iqClients = context.Clients
.Where(c => linkIds.Contains(c.AliasLinkId) || .Where(_client => _client.Active);
networkId == c.NetworkId)
.Include(c => c.CurrentAlias)
.Include(c => c.AliasLink.Children);
if (networkId != long.MinValue)
{
iqClients = iqClients.Where(_client => networkId == _client.NetworkId);
}
else
{
iqClients = iqClients.Where(_client => linkIds.Contains(_client.AliasLinkId));
}
// we want to project our results
var iqClientProjection = iqClients.OrderByDescending(_client => _client.LastConnection)
.Select(_client => new PlayerInfo()
{
Name = _client.CurrentAlias.Name,
LevelInt = (int)_client.Level,
LastConnection = _client.LastConnection,
ClientId = _client.ClientId,
});
#if DEBUG == true #if DEBUG == true
var iqClientsSql = iqClients.ToSql(); var iqClientsSql = iqClients.ToSql();
#endif #endif
var clients = await iqClientProjection.ToListAsync();
return await iqClients.ToListAsync(); // this is so we don't try to evaluate this in the linq to entities query
foreach (var client in clients)
{
client.Level = ((Permission)client.LevelInt).ToLocalizedLevelName();
}
return clients;
} }
} }

View File

@ -121,18 +121,7 @@ namespace WebfrontCore.Controllers
public async Task<IActionResult> FindAsync(string clientName) public async Task<IActionResult> FindAsync(string clientName)
{ {
var clients = (await Manager.GetClientService().FindClientsByIdentifier(clientName)) var clientsDto = await Manager.GetClientService().FindClientsByIdentifier(clientName);
.OrderByDescending(c => c.LastConnection);
var clientsDto = clients.Select(c => new PlayerInfo()
{
Name = c.Name,
Level = c.Level.ToLocalizedLevelName(),
LevelInt = (int)c.Level,
LastConnection = c.LastConnection,
ClientId = c.ClientId
})
.ToList();
ViewBag.Title = $"{clientsDto.Count} {Localization["WEBFRONT_CLIENT_SEARCH_MATCHING"]} \"{clientName}\""; ViewBag.Title = $"{clientsDto.Count} {Localization["WEBFRONT_CLIENT_SEARCH_MATCHING"]} \"{clientName}\"";
return View("Find/Index", clientsDto); return View("Find/Index", clientsDto);