diff --git a/Application/Misc/MetaService.cs b/Application/Misc/MetaService.cs index 47f0bd1d1..e0578648b 100644 --- a/Application/Misc/MetaService.cs +++ b/Application/Misc/MetaService.cs @@ -207,42 +207,30 @@ namespace IW4MAdmin.Application.Misc public async Task> GetRuntimeMeta(ClientPaginationRequest request) { - var meta = new List(); + var metas = await Task.WhenAll(_metaActions.Where(kvp => kvp.Key != MetaType.Information) + .Select(async kvp => await kvp.Value[0](request))); - foreach (var (type, actions) in _metaActions) - { - // information is not listed chronologically - if (type != MetaType.Information) - { - var metaItems = await actions[0](request); - meta.AddRange(metaItems); - } - } - - return meta.OrderByDescending(_meta => _meta.When) + return metas.SelectMany(m => (IEnumerable)m) + .OrderByDescending(m => m.When) .Take(request.Count) .ToList(); } public async Task> GetRuntimeMeta(ClientPaginationRequest request, MetaType metaType) where T : IClientMeta { - IEnumerable meta; if (metaType == MetaType.Information) { var allMeta = new List(); - foreach (var individualMetaRegistration in _metaActions[metaType]) - { - allMeta.AddRange(await individualMetaRegistration(request)); - } - + var completedMeta = await Task.WhenAll(_metaActions[metaType].Select(async individualMetaRegistration => + (IEnumerable)await individualMetaRegistration(request))); + + allMeta.AddRange(completedMeta.SelectMany(meta => meta)); + return ProcessInformationMeta(allMeta); } - else - { - meta = await _metaActions[metaType][0](request) as IEnumerable; - } + var meta = await _metaActions[metaType][0](request) as IEnumerable; return meta; } diff --git a/Plugins/Stats/Plugin.cs b/Plugins/Stats/Plugin.cs index 2c19ce3a7..e645883f6 100644 --- a/Plugins/Stats/Plugin.cs +++ b/Plugins/Stats/Plugin.cs @@ -191,7 +191,6 @@ namespace IW4MAdmin.Plugins.Stats async Task> getStats(ClientPaginationRequest request) { IList clientStats; - int messageCount = 0; await using var ctx = _databaseContextFactory.CreateContext(enableTracking: false); clientStats = await ctx.Set().Where(c => c.ClientId == request.ClientId).ToListAsync(); diff --git a/SharedLibraryCore/Services/ClientService.cs b/SharedLibraryCore/Services/ClientService.cs index c5eedfade..c920f6b75 100644 --- a/SharedLibraryCore/Services/ClientService.cs +++ b/SharedLibraryCore/Services/ClientService.cs @@ -168,10 +168,9 @@ namespace SharedLibraryCore.Services public async Task Get(int entityId) { - // todo: this needs to be optimized for large linked accounts await using var context = _contextFactory.CreateContext(false); - var client = context.Clients + var client = await context.Clients .Select(_client => new EFClient { ClientId = _client.ClientId, @@ -187,26 +186,28 @@ namespace SharedLibraryCore.Services Name = _client.CurrentAlias.Name, IPAddress = _client.CurrentAlias.IPAddress }, - TotalConnectionTime = _client.TotalConnectionTime + TotalConnectionTime = _client.TotalConnectionTime, + AliasLink = new EFAliasLink + { + AliasLinkId = _client.AliasLinkId, + Children = _client.AliasLink.Children + }, + LinkedAccounts = new Dictionary() + { + {_client.ClientId, _client.NetworkId} + } }) - .FirstOrDefault(_client => _client.ClientId == entityId); + .FirstOrDefaultAsync(_client => _client.ClientId == entityId); if (client == null) { return null; } - client.AliasLink = new EFAliasLink + if (!_appConfig.EnableImplicitAccountLinking) { - AliasLinkId = client.AliasLinkId, - Children = await context.Aliases - .Where(_alias => _alias.LinkId == client.AliasLinkId) - .Select(_alias => new EFAlias - { - Name = _alias.Name, - IPAddress = _alias.IPAddress - }).ToListAsync() - }; + return client; + } var foundClient = new { @@ -220,11 +221,6 @@ namespace SharedLibraryCore.Services .ToListAsync() }; - if (foundClient == null) - { - return null; - } - foundClient.Client.LinkedAccounts = new Dictionary(); // todo: find out the best way to do this // I'm doing this here because I don't know the best way to have multiple awaits in the query diff --git a/SharedLibraryCore/Services/PenaltyService.cs b/SharedLibraryCore/Services/PenaltyService.cs index 5fed597a1..1f4494fac 100644 --- a/SharedLibraryCore/Services/PenaltyService.cs +++ b/SharedLibraryCore/Services/PenaltyService.cs @@ -163,9 +163,6 @@ namespace SharedLibraryCore.Services (p.Expires == null || p.Expires > now); await using var context = _contextFactory.CreateContext(false); - var iqLinkPenalties = context.Penalties - .Where(p => p.LinkId == linkId) - .Where(filter); IQueryable iqIpPenalties; @@ -178,35 +175,6 @@ namespace SharedLibraryCore.Services } else { - /* var aliasIps = await context.Aliases.Where(alias => (alias.LinkId == linkId || alias.AliasId == currentAliasId) && alias.IPAddress != null) - .Select(alias => alias.IPAddress) - .ToListAsync(); - - if (ip != null) - { - aliasIps.Add(ip); - } - - var clientIds = new List(); - - if (aliasIps.Any()) - { - clientIds = await context.Clients.Where(client => aliasIps.Contains(client.CurrentAlias.IPAddress)) - .Select(client => client.ClientId).ToListAsync(); - - } - - if (clientIds.Any()) - { - iqIpPenalties = context.Penalties.Where(penalty => clientIds.Contains(penalty.OffenderId)) - .Where(filter); - } - - else - { - iqIpPenalties = Enumerable.Empty().AsQueryable(); - }*/ - var usedIps = await context.Aliases.AsNoTracking() .Where(alias => (alias.LinkId == linkId || alias.AliasId == currentAliasId) && alias.IPAddress != null) .Select(alias => alias.IPAddress).ToListAsync(); @@ -216,13 +184,12 @@ namespace SharedLibraryCore.Services .ToListAsync(); iqIpPenalties = context.Penalties.AsNoTracking() - .Where(penalty => aliasedIds.Contains(penalty.LinkId)) + .Where(penalty => aliasedIds.Contains(penalty.LinkId) || penalty.LinkId == linkId) .Where(filter); } - var activeLinkPenalties = await iqLinkPenalties.ToListAsync(); var activeIpPenalties = await iqIpPenalties.ToListAsync(); - var activePenalties = activeLinkPenalties.Concat(activeIpPenalties).Distinct(); + var activePenalties = activeIpPenalties.Distinct(); // this is a bit more performant in memory (ordering) return activePenalties.OrderByDescending(p => p.When).ToList(); diff --git a/WebfrontCore/Controllers/Client/ClientController.cs b/WebfrontCore/Controllers/Client/ClientController.cs index fce9ab5e3..56cc39105 100644 --- a/WebfrontCore/Controllers/Client/ClientController.cs +++ b/WebfrontCore/Controllers/Client/ClientController.cs @@ -10,7 +10,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Data.Models; -using IW4MAdmin.Plugins.Stats.Config; using Stats.Config; using WebfrontCore.ViewComponents; @@ -38,7 +37,16 @@ namespace WebfrontCore.Controllers var activePenalties = await Manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId, client.CurrentAliasId, client.IPAddress); - var tag = await _metaService.GetPersistentMeta(EFMeta.ClientTag, client); + var persistentMetaTask = new[] + { + _metaService.GetPersistentMeta(EFMeta.ClientTag, client), + _metaService.GetPersistentMeta("GravatarEmail", client) + }; + + var persistentMeta = await Task.WhenAll(persistentMetaTask); + var tag = persistentMeta[0]; + var gravatar = persistentMeta[1]; + if (tag?.LinkedMeta != null) { client.SetAdditionalProperty(EFMeta.ClientTag, tag.LinkedMeta.Value); @@ -55,7 +63,7 @@ namespace WebfrontCore.Controllers displayLevel = string.IsNullOrEmpty(client.Tag) ? displayLevel : $"{displayLevel} ({client.Tag})"; - var clientDto = new PlayerInfo() + var clientDto = new PlayerInfo { Name = client.Name, Level = displayLevel, @@ -92,7 +100,6 @@ namespace WebfrontCore.Controllers Before = DateTime.UtcNow }, MetaType.Information); - var gravatar = await _metaService.GetPersistentMeta("GravatarEmail", client); if (gravatar != null) { clientDto.Meta.Add(new InformationResponse() @@ -106,7 +113,7 @@ namespace WebfrontCore.Controllers clientDto.ActivePenalty = activePenalties.OrderByDescending(_penalty => _penalty.Type).FirstOrDefault(); clientDto.Meta.AddRange(Authorized ? meta : meta.Where(m => !m.IsSensitive)); - string strippedName = clientDto.Name.StripColors(); + var strippedName = clientDto.Name.StripColors(); ViewBag.Title = strippedName.Substring(strippedName.Length - 1).ToLower()[0] == 's' ? strippedName + "'" : strippedName + "'s";