implement metaservice v2
This commit is contained in:
parent
b46b1eb5e7
commit
04a4dcf153
64
Application/Commands/ClientTags/AddClientTagCommand.cs
Normal file
64
Application/Commands/ClientTags/AddClientTagCommand.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Data.Models;
|
||||||
|
using Data.Models.Client;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Commands;
|
||||||
|
using SharedLibraryCore.Configuration;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
|
|
||||||
|
namespace IW4MAdmin.Application.Commands.ClientTags
|
||||||
|
{
|
||||||
|
public class AddClientTagCommand : Command
|
||||||
|
{
|
||||||
|
private readonly IMetaServiceV2 _metaService;
|
||||||
|
|
||||||
|
public AddClientTagCommand(ILogger<AddClientTagCommand> commandLogger, CommandConfiguration config,
|
||||||
|
ITranslationLookup layout, IMetaServiceV2 metaService) :
|
||||||
|
base(config, layout)
|
||||||
|
{
|
||||||
|
Name = "addclienttag";
|
||||||
|
Description = layout["COMMANDS_ADD_CLIENT_TAG_DESC"];
|
||||||
|
Alias = "act";
|
||||||
|
Permission = EFClient.Permission.Owner;
|
||||||
|
RequiresTarget = false;
|
||||||
|
Arguments = new[]
|
||||||
|
{
|
||||||
|
new CommandArgument
|
||||||
|
{
|
||||||
|
Name = _translationLookup["COMMANDS_ARGUMENT_TAG"],
|
||||||
|
Required = true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_metaService = metaService;
|
||||||
|
logger = commandLogger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task ExecuteAsync(GameEvent gameEvent)
|
||||||
|
{
|
||||||
|
var existingTags = await _metaService.GetPersistentMetaValue<List<TagMeta>>(EFMeta.ClientTagNameV2) ??
|
||||||
|
new List<TagMeta>();
|
||||||
|
|
||||||
|
var tagName = gameEvent.Data.Trim();
|
||||||
|
|
||||||
|
if (existingTags.Any(tag => tag.TagName == tagName))
|
||||||
|
{
|
||||||
|
logger.LogWarning("Tag with name {TagName} already exists", tagName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
existingTags.Add(new TagMeta
|
||||||
|
{
|
||||||
|
Id = (existingTags.LastOrDefault()?.TagId ?? 0) + 1,
|
||||||
|
Value = tagName
|
||||||
|
});
|
||||||
|
|
||||||
|
await _metaService.SetPersistentMetaValue(EFMeta.ClientTagNameV2, existingTags,
|
||||||
|
gameEvent.Owner.Manager.CancellationToken);
|
||||||
|
gameEvent.Origin.Tell(_translationLookup["COMMANDS_ADD_CLIENT_TAG_SUCCESS"].FormatExt(gameEvent.Data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +1,19 @@
|
|||||||
using System.Linq;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Data.Models;
|
using Data.Models;
|
||||||
using Data.Models.Client;
|
using Data.Models.Client;
|
||||||
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Configuration;
|
using SharedLibraryCore.Configuration;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
|
|
||||||
namespace SharedLibraryCore.Commands
|
namespace IW4MAdmin.Application.Commands.ClientTags
|
||||||
{
|
{
|
||||||
public class ListClientTags : Command
|
public class ListClientTags : Command
|
||||||
{
|
{
|
||||||
private readonly IMetaService _metaService;
|
private readonly IMetaServiceV2 _metaService;
|
||||||
|
|
||||||
public ListClientTags(CommandConfiguration config, ITranslationLookup layout, IMetaService metaService) : base(
|
public ListClientTags(CommandConfiguration config, ITranslationLookup layout, IMetaServiceV2 metaService) : base(
|
||||||
config, layout)
|
config, layout)
|
||||||
{
|
{
|
||||||
Name = "listclienttags";
|
Name = "listclienttags";
|
||||||
@ -19,14 +21,17 @@ namespace SharedLibraryCore.Commands
|
|||||||
Alias = "lct";
|
Alias = "lct";
|
||||||
Permission = EFClient.Permission.Owner;
|
Permission = EFClient.Permission.Owner;
|
||||||
RequiresTarget = false;
|
RequiresTarget = false;
|
||||||
|
|
||||||
_metaService = metaService;
|
_metaService = metaService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent gameEvent)
|
public override async Task ExecuteAsync(GameEvent gameEvent)
|
||||||
{
|
{
|
||||||
var tags = await _metaService.GetPersistentMeta(EFMeta.ClientTagName);
|
var tags = await _metaService.GetPersistentMetaValue<List<TagMeta>>(EFMeta.ClientTagNameV2);
|
||||||
gameEvent.Origin.Tell(tags.Select(tag => tag.Value));
|
|
||||||
|
if (tags is not null)
|
||||||
|
{
|
||||||
|
gameEvent.Origin.Tell(tags.Select(tag => tag.TagName));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,16 +1,20 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Linq;
|
||||||
using Data.Models;
|
using Data.Models;
|
||||||
using Data.Models.Client;
|
using Data.Models.Client;
|
||||||
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Commands;
|
||||||
using SharedLibraryCore.Configuration;
|
using SharedLibraryCore.Configuration;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
|
|
||||||
namespace SharedLibraryCore.Commands
|
namespace IW4MAdmin.Application.Commands.ClientTags
|
||||||
{
|
{
|
||||||
public class RemoveClientTag : Command
|
public class RemoveClientTag : Command
|
||||||
{
|
{
|
||||||
private readonly IMetaService _metaService;
|
private readonly IMetaServiceV2 _metaService;
|
||||||
|
|
||||||
public RemoveClientTag(CommandConfiguration config, ITranslationLookup layout, IMetaService metaService) : base(
|
public RemoveClientTag(CommandConfiguration config, ITranslationLookup layout, IMetaServiceV2 metaService) : base(
|
||||||
config, layout)
|
config, layout)
|
||||||
{
|
{
|
||||||
Name = "removeclienttag";
|
Name = "removeclienttag";
|
||||||
@ -32,8 +36,13 @@ namespace SharedLibraryCore.Commands
|
|||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent gameEvent)
|
public override async Task ExecuteAsync(GameEvent gameEvent)
|
||||||
{
|
{
|
||||||
await _metaService.RemovePersistentMeta(EFMeta.ClientTagName, gameEvent.Data);
|
var existingMeta = await _metaService.GetPersistentMetaValue<List<TagMeta>>(EFMeta.ClientTagNameV2,
|
||||||
|
gameEvent.Owner.Manager.CancellationToken);
|
||||||
|
existingMeta = existingMeta.Where(meta => meta.TagName != gameEvent.Data.Trim()).ToList();
|
||||||
|
await _metaService.SetPersistentMetaValue(EFMeta.ClientTagNameV2, existingMeta,
|
||||||
|
gameEvent.Owner.Manager.CancellationToken);
|
||||||
|
|
||||||
gameEvent.Origin.Tell(_translationLookup["COMMANDS_REMOVE_CLIENT_TAG_SUCCESS"].FormatExt(gameEvent.Data));
|
gameEvent.Origin.Tell(_translationLookup["COMMANDS_REMOVE_CLIENT_TAG_SUCCESS"].FormatExt(gameEvent.Data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,18 +1,22 @@
|
|||||||
using System.Linq;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Data.Models;
|
using Data.Models;
|
||||||
using Data.Models.Client;
|
using Data.Models.Client;
|
||||||
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Commands;
|
||||||
using SharedLibraryCore.Configuration;
|
using SharedLibraryCore.Configuration;
|
||||||
|
using SharedLibraryCore.Dtos;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
|
|
||||||
namespace SharedLibraryCore.Commands
|
namespace IW4MAdmin.Application.Commands.ClientTags
|
||||||
{
|
{
|
||||||
public class SetClientTagCommand : Command
|
public class SetClientTagCommand : Command
|
||||||
{
|
{
|
||||||
private readonly IMetaService _metaService;
|
private readonly IMetaServiceV2 _metaService;
|
||||||
|
|
||||||
|
|
||||||
public SetClientTagCommand(CommandConfiguration config, ITranslationLookup layout, IMetaService metaService) :
|
public SetClientTagCommand(CommandConfiguration config, ITranslationLookup layout, IMetaServiceV2 metaService) :
|
||||||
base(config, layout)
|
base(config, layout)
|
||||||
{
|
{
|
||||||
Name = "setclienttag";
|
Name = "setclienttag";
|
||||||
@ -34,8 +38,10 @@ namespace SharedLibraryCore.Commands
|
|||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent gameEvent)
|
public override async Task ExecuteAsync(GameEvent gameEvent)
|
||||||
{
|
{
|
||||||
var availableTags = await _metaService.GetPersistentMeta(EFMeta.ClientTagName);
|
var token = gameEvent.Owner.Manager.CancellationToken;
|
||||||
var matchingTag = availableTags.FirstOrDefault(tag => tag.Value == gameEvent.Data);
|
|
||||||
|
var availableTags = await _metaService.GetPersistentMetaValue<List<LookupValue<string>>>(EFMeta.ClientTagNameV2, token);
|
||||||
|
var matchingTag = availableTags.FirstOrDefault(tag => tag.Value == gameEvent.Data.Trim());
|
||||||
|
|
||||||
if (matchingTag == null)
|
if (matchingTag == null)
|
||||||
{
|
{
|
||||||
@ -44,8 +50,9 @@ namespace SharedLibraryCore.Commands
|
|||||||
}
|
}
|
||||||
|
|
||||||
gameEvent.Target.Tag = matchingTag.Value;
|
gameEvent.Target.Tag = matchingTag.Value;
|
||||||
await _metaService.AddPersistentMeta(EFMeta.ClientTag, string.Empty, gameEvent.Target, matchingTag);
|
await _metaService.SetPersistentMetaForLookupKey(EFMeta.ClientTagV2, EFMeta.ClientTagNameV2, matchingTag.Id,
|
||||||
|
gameEvent.Target.ClientId, token);
|
||||||
gameEvent.Origin.Tell(_translationLookup["COMMANDS_SET_CLIENT_TAG_SUCCESS"].FormatExt(matchingTag.Value));
|
gameEvent.Origin.Tell(_translationLookup["COMMANDS_SET_CLIENT_TAG_SUCCESS"].FormatExt(matchingTag.Value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
13
Application/Commands/ClientTags/TagMeta.cs
Normal file
13
Application/Commands/ClientTags/TagMeta.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
|
|
||||||
|
namespace IW4MAdmin.Application.Commands.ClientTags;
|
||||||
|
|
||||||
|
public class TagMeta : ILookupValue<string>
|
||||||
|
{
|
||||||
|
[JsonIgnore] public int TagId => Id;
|
||||||
|
[JsonIgnore] public string TagName => Value;
|
||||||
|
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Value { get; set; }
|
||||||
|
}
|
@ -1,17 +1,18 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Data.Models;
|
using Data.Models;
|
||||||
using Data.Models.Client;
|
using Data.Models.Client;
|
||||||
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Commands;
|
||||||
using SharedLibraryCore.Configuration;
|
using SharedLibraryCore.Configuration;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
|
|
||||||
namespace SharedLibraryCore.Commands
|
namespace IW4MAdmin.Application.Commands.ClientTags
|
||||||
{
|
{
|
||||||
public class UnsetClientTagCommand : Command
|
public class UnsetClientTagCommand : Command
|
||||||
{
|
{
|
||||||
private readonly IMetaService _metaService;
|
private readonly IMetaServiceV2 _metaService;
|
||||||
|
|
||||||
|
public UnsetClientTagCommand(CommandConfiguration config, ITranslationLookup layout, IMetaServiceV2 metaService) :
|
||||||
public UnsetClientTagCommand(CommandConfiguration config, ITranslationLookup layout, IMetaService metaService) :
|
|
||||||
base(config, layout)
|
base(config, layout)
|
||||||
{
|
{
|
||||||
Name = "unsetclienttag";
|
Name = "unsetclienttag";
|
||||||
@ -34,8 +35,9 @@ namespace SharedLibraryCore.Commands
|
|||||||
public override async Task ExecuteAsync(GameEvent gameEvent)
|
public override async Task ExecuteAsync(GameEvent gameEvent)
|
||||||
{
|
{
|
||||||
gameEvent.Target.Tag = null;
|
gameEvent.Target.Tag = null;
|
||||||
await _metaService.RemovePersistentMeta(EFMeta.ClientTag, gameEvent.Target);
|
await _metaService.RemovePersistentMeta(EFMeta.ClientTagV2, gameEvent.Target.ClientId,
|
||||||
|
gameEvent.Owner.Manager.CancellationToken);
|
||||||
gameEvent.Origin.Tell(_translationLookup["COMMANDS_UNSET_CLIENT_TAG_SUCCESS"]);
|
gameEvent.Origin.Tell(_translationLookup["COMMANDS_UNSET_CLIENT_TAG_SUCCESS"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,7 +14,7 @@ namespace IW4MAdmin.Application.Factories
|
|||||||
internal class GameServerInstanceFactory : IGameServerInstanceFactory
|
internal class GameServerInstanceFactory : IGameServerInstanceFactory
|
||||||
{
|
{
|
||||||
private readonly ITranslationLookup _translationLookup;
|
private readonly ITranslationLookup _translationLookup;
|
||||||
private readonly IMetaService _metaService;
|
private readonly IMetaServiceV2 _metaService;
|
||||||
private readonly IServiceProvider _serviceProvider;
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -23,7 +23,7 @@ namespace IW4MAdmin.Application.Factories
|
|||||||
/// <param name="translationLookup"></param>
|
/// <param name="translationLookup"></param>
|
||||||
/// <param name="rconConnectionFactory"></param>
|
/// <param name="rconConnectionFactory"></param>
|
||||||
public GameServerInstanceFactory(ITranslationLookup translationLookup,
|
public GameServerInstanceFactory(ITranslationLookup translationLookup,
|
||||||
IMetaService metaService,
|
IMetaServiceV2 metaService,
|
||||||
IServiceProvider serviceProvider)
|
IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
_translationLookup = translationLookup;
|
_translationLookup = translationLookup;
|
||||||
@ -45,4 +45,4 @@ namespace IW4MAdmin.Application.Factories
|
|||||||
_serviceProvider.GetRequiredService<ILookupCache<EFServer>>());
|
_serviceProvider.GetRequiredService<ILookupCache<EFServer>>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ namespace IW4MAdmin
|
|||||||
private static readonly SharedLibraryCore.Localization.TranslationLookup loc = Utilities.CurrentLocalization.LocalizationIndex;
|
private static readonly SharedLibraryCore.Localization.TranslationLookup loc = Utilities.CurrentLocalization.LocalizationIndex;
|
||||||
public GameLogEventDetection LogEvent;
|
public GameLogEventDetection LogEvent;
|
||||||
private readonly ITranslationLookup _translationLookup;
|
private readonly ITranslationLookup _translationLookup;
|
||||||
private readonly IMetaService _metaService;
|
private readonly IMetaServiceV2 _metaService;
|
||||||
private const int REPORT_FLAG_COUNT = 4;
|
private const int REPORT_FLAG_COUNT = 4;
|
||||||
private long lastGameTime = 0;
|
private long lastGameTime = 0;
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ namespace IW4MAdmin
|
|||||||
ServerConfiguration serverConfiguration,
|
ServerConfiguration serverConfiguration,
|
||||||
CommandConfiguration commandConfiguration,
|
CommandConfiguration commandConfiguration,
|
||||||
ITranslationLookup lookup,
|
ITranslationLookup lookup,
|
||||||
IMetaService metaService,
|
IMetaServiceV2 metaService,
|
||||||
IServiceProvider serviceProvider,
|
IServiceProvider serviceProvider,
|
||||||
IClientNoticeMessageFormatter messageFormatter,
|
IClientNoticeMessageFormatter messageFormatter,
|
||||||
ILookupCache<EFServer> serverCache) : base(serviceProvider.GetRequiredService<ILogger<Server>>(),
|
ILookupCache<EFServer> serverCache) : base(serviceProvider.GetRequiredService<ILogger<Server>>(),
|
||||||
@ -350,7 +350,8 @@ namespace IW4MAdmin
|
|||||||
Time = DateTime.UtcNow
|
Time = DateTime.UtcNow
|
||||||
});
|
});
|
||||||
|
|
||||||
var clientTag = await _metaService.GetPersistentMeta(EFMeta.ClientTag, E.Origin);
|
var clientTag = await _metaService.GetPersistentMetaByLookup(EFMeta.ClientTagV2,
|
||||||
|
EFMeta.ClientTagNameV2, E.Origin.ClientId, Manager.CancellationToken);
|
||||||
|
|
||||||
if (clientTag?.LinkedMeta != null)
|
if (clientTag?.LinkedMeta != null)
|
||||||
{
|
{
|
||||||
@ -568,8 +569,10 @@ namespace IW4MAdmin
|
|||||||
Time = DateTime.UtcNow
|
Time = DateTime.UtcNow
|
||||||
});
|
});
|
||||||
|
|
||||||
await _metaService.AddPersistentMeta("LastMapPlayed", CurrentMap.Alias, E.Origin);
|
await _metaService.SetPersistentMeta("LastMapPlayed", CurrentMap.Alias, E.Origin.ClientId,
|
||||||
await _metaService.AddPersistentMeta("LastServerPlayed", E.Owner.Hostname, E.Origin);
|
Manager.CancellationToken);
|
||||||
|
await _metaService.SetPersistentMeta("LastServerPlayed", E.Owner.Hostname, E.Origin.ClientId,
|
||||||
|
Manager.CancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (E.Type == GameEvent.EventType.PreDisconnect)
|
else if (E.Type == GameEvent.EventType.PreDisconnect)
|
||||||
|
@ -278,7 +278,7 @@ namespace IW4MAdmin.Application
|
|||||||
|
|
||||||
// register the native commands
|
// register the native commands
|
||||||
foreach (var commandType in typeof(SharedLibraryCore.Commands.QuitCommand).Assembly.GetTypes()
|
foreach (var commandType in typeof(SharedLibraryCore.Commands.QuitCommand).Assembly.GetTypes()
|
||||||
.Concat(typeof(Program).Assembly.GetTypes().Where(type => type.Namespace == "IW4MAdmin.Application.Commands"))
|
.Concat(typeof(Program).Assembly.GetTypes().Where(type => type.Namespace?.StartsWith("IW4MAdmin.Application.Commands") ?? false))
|
||||||
.Where(command => command.BaseType == typeof(Command)))
|
.Where(command => command.BaseType == typeof(Command)))
|
||||||
{
|
{
|
||||||
defaultLogger.LogDebug("Registered native command type {Name}", commandType.Name);
|
defaultLogger.LogDebug("Registered native command type {Name}", commandType.Name);
|
||||||
@ -406,6 +406,7 @@ namespace IW4MAdmin.Application
|
|||||||
.AddSingleton<IAuditInformationRepository, AuditInformationRepository>()
|
.AddSingleton<IAuditInformationRepository, AuditInformationRepository>()
|
||||||
.AddSingleton<IEntityService<EFClient>, ClientService>()
|
.AddSingleton<IEntityService<EFClient>, ClientService>()
|
||||||
.AddSingleton<IMetaService, MetaService>()
|
.AddSingleton<IMetaService, MetaService>()
|
||||||
|
.AddSingleton<IMetaServiceV2, MetaServiceV2>()
|
||||||
.AddSingleton<ClientService>()
|
.AddSingleton<ClientService>()
|
||||||
.AddSingleton<PenaltyService>()
|
.AddSingleton<PenaltyService>()
|
||||||
.AddSingleton<ChangeHistoryService>()
|
.AddSingleton<ChangeHistoryService>()
|
||||||
|
@ -5,6 +5,7 @@ using SharedLibraryCore.Interfaces;
|
|||||||
using SharedLibraryCore.QueryHelper;
|
using SharedLibraryCore.QueryHelper;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using ILogger = Microsoft.Extensions.Logging.ILogger;
|
using ILogger = Microsoft.Extensions.Logging.ILogger;
|
||||||
@ -15,17 +16,22 @@ namespace IW4MAdmin.Application.Meta
|
|||||||
{
|
{
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private ITranslationLookup _transLookup;
|
private ITranslationLookup _transLookup;
|
||||||
private readonly IMetaService _metaService;
|
private readonly IMetaServiceV2 _metaService;
|
||||||
private readonly IEntityService<EFClient> _clientEntityService;
|
private readonly IEntityService<EFClient> _clientEntityService;
|
||||||
private readonly IResourceQueryHelper<ClientPaginationRequest, ReceivedPenaltyResponse> _receivedPenaltyHelper;
|
private readonly IResourceQueryHelper<ClientPaginationRequest, ReceivedPenaltyResponse> _receivedPenaltyHelper;
|
||||||
private readonly IResourceQueryHelper<ClientPaginationRequest, AdministeredPenaltyResponse> _administeredPenaltyHelper;
|
|
||||||
|
private readonly IResourceQueryHelper<ClientPaginationRequest, AdministeredPenaltyResponse>
|
||||||
|
_administeredPenaltyHelper;
|
||||||
|
|
||||||
private readonly IResourceQueryHelper<ClientPaginationRequest, UpdatedAliasResponse> _updatedAliasHelper;
|
private readonly IResourceQueryHelper<ClientPaginationRequest, UpdatedAliasResponse> _updatedAliasHelper;
|
||||||
|
|
||||||
private readonly IResourceQueryHelper<ClientPaginationRequest, ConnectionHistoryResponse>
|
private readonly IResourceQueryHelper<ClientPaginationRequest, ConnectionHistoryResponse>
|
||||||
_connectionHistoryHelper;
|
_connectionHistoryHelper;
|
||||||
|
|
||||||
private readonly IResourceQueryHelper<ClientPaginationRequest, PermissionLevelChangedResponse>
|
private readonly IResourceQueryHelper<ClientPaginationRequest, PermissionLevelChangedResponse>
|
||||||
_permissionLevelHelper;
|
_permissionLevelHelper;
|
||||||
|
|
||||||
public MetaRegistration(ILogger<MetaRegistration> logger, IMetaService metaService,
|
public MetaRegistration(ILogger<MetaRegistration> logger, IMetaServiceV2 metaService,
|
||||||
ITranslationLookup transLookup, IEntityService<EFClient> clientEntityService,
|
ITranslationLookup transLookup, IEntityService<EFClient> clientEntityService,
|
||||||
IResourceQueryHelper<ClientPaginationRequest, ReceivedPenaltyResponse> receivedPenaltyHelper,
|
IResourceQueryHelper<ClientPaginationRequest, ReceivedPenaltyResponse> receivedPenaltyHelper,
|
||||||
IResourceQueryHelper<ClientPaginationRequest, AdministeredPenaltyResponse> administeredPenaltyHelper,
|
IResourceQueryHelper<ClientPaginationRequest, AdministeredPenaltyResponse> administeredPenaltyHelper,
|
||||||
@ -46,19 +52,26 @@ namespace IW4MAdmin.Application.Meta
|
|||||||
|
|
||||||
public void Register()
|
public void Register()
|
||||||
{
|
{
|
||||||
_metaService.AddRuntimeMeta<ClientPaginationRequest, InformationResponse>(MetaType.Information, GetProfileMeta);
|
_metaService.AddRuntimeMeta<ClientPaginationRequest, InformationResponse>(MetaType.Information,
|
||||||
_metaService.AddRuntimeMeta<ClientPaginationRequest, ReceivedPenaltyResponse>(MetaType.ReceivedPenalty, GetReceivedPenaltiesMeta);
|
GetProfileMeta);
|
||||||
_metaService.AddRuntimeMeta<ClientPaginationRequest, AdministeredPenaltyResponse>(MetaType.Penalized, GetAdministeredPenaltiesMeta);
|
_metaService.AddRuntimeMeta<ClientPaginationRequest, ReceivedPenaltyResponse>(MetaType.ReceivedPenalty,
|
||||||
_metaService.AddRuntimeMeta<ClientPaginationRequest, UpdatedAliasResponse>(MetaType.AliasUpdate, GetUpdatedAliasMeta);
|
GetReceivedPenaltiesMeta);
|
||||||
_metaService.AddRuntimeMeta<ClientPaginationRequest, ConnectionHistoryResponse>(MetaType.ConnectionHistory, GetConnectionHistoryMeta);
|
_metaService.AddRuntimeMeta<ClientPaginationRequest, AdministeredPenaltyResponse>(MetaType.Penalized,
|
||||||
|
GetAdministeredPenaltiesMeta);
|
||||||
|
_metaService.AddRuntimeMeta<ClientPaginationRequest, UpdatedAliasResponse>(MetaType.AliasUpdate,
|
||||||
|
GetUpdatedAliasMeta);
|
||||||
|
_metaService.AddRuntimeMeta<ClientPaginationRequest, ConnectionHistoryResponse>(MetaType.ConnectionHistory,
|
||||||
|
GetConnectionHistoryMeta);
|
||||||
_metaService.AddRuntimeMeta<ClientPaginationRequest, PermissionLevelChangedResponse>(
|
_metaService.AddRuntimeMeta<ClientPaginationRequest, PermissionLevelChangedResponse>(
|
||||||
MetaType.PermissionLevel, GetPermissionLevelMeta);
|
MetaType.PermissionLevel, GetPermissionLevelMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IEnumerable<InformationResponse>> GetProfileMeta(ClientPaginationRequest request)
|
private async Task<IEnumerable<InformationResponse>> GetProfileMeta(ClientPaginationRequest request,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var metaList = new List<InformationResponse>();
|
var metaList = new List<InformationResponse>();
|
||||||
var lastMapMeta = await _metaService.GetPersistentMeta("LastMapPlayed", new EFClient() { ClientId = request.ClientId });
|
var lastMapMeta =
|
||||||
|
await _metaService.GetPersistentMeta("LastMapPlayed", request.ClientId, cancellationToken);
|
||||||
|
|
||||||
if (lastMapMeta != null)
|
if (lastMapMeta != null)
|
||||||
{
|
{
|
||||||
@ -75,7 +88,8 @@ namespace IW4MAdmin.Application.Meta
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var lastServerMeta = await _metaService.GetPersistentMeta("LastServerPlayed", new EFClient() { ClientId = request.ClientId });
|
var lastServerMeta =
|
||||||
|
await _metaService.GetPersistentMeta("LastServerPlayed", request.ClientId, cancellationToken);
|
||||||
|
|
||||||
if (lastServerMeta != null)
|
if (lastServerMeta != null)
|
||||||
{
|
{
|
||||||
@ -96,7 +110,7 @@ namespace IW4MAdmin.Application.Meta
|
|||||||
|
|
||||||
if (client == null)
|
if (client == null)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("No client found with id {clientId} when generating profile meta", request.ClientId);
|
_logger.LogWarning("No client found with id {ClientId} when generating profile meta", request.ClientId);
|
||||||
return metaList;
|
return metaList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +151,8 @@ namespace IW4MAdmin.Application.Meta
|
|||||||
{
|
{
|
||||||
ClientId = client.ClientId,
|
ClientId = client.ClientId,
|
||||||
Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_CONNECTIONS"],
|
Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_CONNECTIONS"],
|
||||||
Value = client.Connections.ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)),
|
Value = client.Connections.ToString("#,##0",
|
||||||
|
new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)),
|
||||||
ShouldDisplay = true,
|
ShouldDisplay = true,
|
||||||
Column = 1,
|
Column = 1,
|
||||||
Order = 3,
|
Order = 3,
|
||||||
@ -148,7 +163,9 @@ namespace IW4MAdmin.Application.Meta
|
|||||||
{
|
{
|
||||||
ClientId = client.ClientId,
|
ClientId = client.ClientId,
|
||||||
Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_MASKED"],
|
Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_MASKED"],
|
||||||
Value = client.Masked ? Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_TRUE"] : Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_FALSE"],
|
Value = client.Masked
|
||||||
|
? Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_TRUE"]
|
||||||
|
: Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_FALSE"],
|
||||||
IsSensitive = true,
|
IsSensitive = true,
|
||||||
Column = 1,
|
Column = 1,
|
||||||
Order = 4,
|
Order = 4,
|
||||||
@ -158,32 +175,36 @@ namespace IW4MAdmin.Application.Meta
|
|||||||
return metaList;
|
return metaList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IEnumerable<ReceivedPenaltyResponse>> GetReceivedPenaltiesMeta(ClientPaginationRequest request)
|
private async Task<IEnumerable<ReceivedPenaltyResponse>> GetReceivedPenaltiesMeta(
|
||||||
|
ClientPaginationRequest request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var penalties = await _receivedPenaltyHelper.QueryResource(request);
|
var penalties = await _receivedPenaltyHelper.QueryResource(request);
|
||||||
return penalties.Results;
|
return penalties.Results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IEnumerable<AdministeredPenaltyResponse>> GetAdministeredPenaltiesMeta(ClientPaginationRequest request)
|
private async Task<IEnumerable<AdministeredPenaltyResponse>> GetAdministeredPenaltiesMeta(
|
||||||
|
ClientPaginationRequest request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var penalties = await _administeredPenaltyHelper.QueryResource(request);
|
var penalties = await _administeredPenaltyHelper.QueryResource(request);
|
||||||
return penalties.Results;
|
return penalties.Results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IEnumerable<UpdatedAliasResponse>> GetUpdatedAliasMeta(ClientPaginationRequest request)
|
private async Task<IEnumerable<UpdatedAliasResponse>> GetUpdatedAliasMeta(ClientPaginationRequest request,
|
||||||
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var aliases = await _updatedAliasHelper.QueryResource(request);
|
var aliases = await _updatedAliasHelper.QueryResource(request);
|
||||||
return aliases.Results;
|
return aliases.Results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IEnumerable<ConnectionHistoryResponse>> GetConnectionHistoryMeta(ClientPaginationRequest request)
|
private async Task<IEnumerable<ConnectionHistoryResponse>> GetConnectionHistoryMeta(
|
||||||
|
ClientPaginationRequest request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var connections = await _connectionHistoryHelper.QueryResource(request);
|
var connections = await _connectionHistoryHelper.QueryResource(request);
|
||||||
return connections.Results;
|
return connections.Results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IEnumerable<PermissionLevelChangedResponse>> GetPermissionLevelMeta(
|
private async Task<IEnumerable<PermissionLevelChangedResponse>> GetPermissionLevelMeta(
|
||||||
ClientPaginationRequest request)
|
ClientPaginationRequest request, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var permissionChanges = await _permissionLevelHelper.QueryResource(request);
|
var permissionChanges = await _permissionLevelHelper.QueryResource(request);
|
||||||
return permissionChanges.Results;
|
return permissionChanges.Results;
|
||||||
|
500
Application/Misc/MetaServiceV2.cs
Normal file
500
Application/Misc/MetaServiceV2.cs
Normal file
@ -0,0 +1,500 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Data.Abstractions;
|
||||||
|
using Data.Models;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using SharedLibraryCore.Dtos;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
|
using SharedLibraryCore.QueryHelper;
|
||||||
|
using ILogger = Microsoft.Extensions.Logging.ILogger;
|
||||||
|
|
||||||
|
namespace IW4MAdmin.Application.Misc;
|
||||||
|
|
||||||
|
public class MetaServiceV2 : IMetaServiceV2
|
||||||
|
{
|
||||||
|
private readonly IDictionary<MetaType, List<dynamic>> _metaActions;
|
||||||
|
private readonly IDatabaseContextFactory _contextFactory;
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
public MetaServiceV2(ILogger<MetaServiceV2> logger, IDatabaseContextFactory contextFactory)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_metaActions = new Dictionary<MetaType, List<dynamic>>();
|
||||||
|
_contextFactory = contextFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SetPersistentMeta(string metaKey, string metaValue, int clientId,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (!ValidArgs(metaKey, clientId))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await using var context = _contextFactory.CreateContext();
|
||||||
|
|
||||||
|
var existingMeta = await context.EFMeta
|
||||||
|
.Where(meta => meta.Key == metaKey)
|
||||||
|
.Where(meta => meta.ClientId == clientId)
|
||||||
|
.FirstOrDefaultAsync(token);
|
||||||
|
|
||||||
|
if (existingMeta != null)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Updating existing meta with key {Key} and id {Id}", existingMeta.Key,
|
||||||
|
existingMeta.MetaId);
|
||||||
|
existingMeta.Value = metaValue;
|
||||||
|
existingMeta.Updated = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Adding new meta with key {Key}", metaKey);
|
||||||
|
context.EFMeta.Add(new EFMeta
|
||||||
|
{
|
||||||
|
ClientId = clientId,
|
||||||
|
Created = DateTime.UtcNow,
|
||||||
|
Key = metaKey,
|
||||||
|
Value = metaValue,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await context.SaveChangesAsync(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SetPersistentMetaValue<T>(string metaKey, T metaValue, int clientId,
|
||||||
|
CancellationToken token = default) where T : class
|
||||||
|
{
|
||||||
|
if (!ValidArgs(metaKey, clientId))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string serializedValue;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
serializedValue = JsonSerializer.Serialize(metaValue);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Could not serialize meta with key {Key}", metaKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await SetPersistentMeta(metaKey, serializedValue, clientId, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SetPersistentMetaForLookupKey(string metaKey, string lookupKey, int lookupId, int clientId,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (!ValidArgs(metaKey, clientId))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await using var context = _contextFactory.CreateContext();
|
||||||
|
|
||||||
|
var lookupMeta = await context.EFMeta.FirstOrDefaultAsync(meta => meta.Key == lookupKey, token);
|
||||||
|
|
||||||
|
if (lookupMeta is null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("No lookup meta exists for metaKey {MetaKey} and lookupKey {LookupKey}", metaKey,
|
||||||
|
lookupKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lookupValues = JsonSerializer.Deserialize<List<LookupValue<string>>>(lookupMeta.Value);
|
||||||
|
|
||||||
|
if (lookupValues is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var foundLookup = lookupValues.FirstOrDefault(value => value.Id == lookupId);
|
||||||
|
|
||||||
|
if (foundLookup is null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("No lookup meta found for provided lookup id {MetaKey}, {LookupKey}, {LookupId}",
|
||||||
|
metaKey, lookupKey, lookupId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogDebug("Setting meta for lookup {MetaKey}, {LookupKey}, {LookupId}",
|
||||||
|
metaKey, lookupKey, lookupId);
|
||||||
|
|
||||||
|
await SetPersistentMeta(metaKey, lookupId.ToString(), clientId, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task IncrementPersistentMeta(string metaKey, int incrementAmount, int clientId,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (!ValidArgs(metaKey, clientId))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var existingMeta = await GetPersistentMeta(metaKey, clientId, token);
|
||||||
|
|
||||||
|
if (!long.TryParse(existingMeta?.Value ?? "0", out var existingValue))
|
||||||
|
{
|
||||||
|
existingValue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var newValue = existingValue + incrementAmount;
|
||||||
|
await SetPersistentMeta(metaKey, newValue.ToString(), clientId, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DecrementPersistentMeta(string metaKey, int decrementAmount, int clientId,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
await IncrementPersistentMeta(metaKey, -decrementAmount, clientId, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<EFMeta> GetPersistentMeta(string metaKey, int clientId, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (!ValidArgs(metaKey, clientId))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
await using var ctx = _contextFactory.CreateContext(enableTracking: false);
|
||||||
|
|
||||||
|
return await ctx.EFMeta
|
||||||
|
.Where(meta => meta.Key == metaKey)
|
||||||
|
.Where(meta => meta.ClientId == clientId)
|
||||||
|
.Select(meta => new EFMeta
|
||||||
|
{
|
||||||
|
MetaId = meta.MetaId,
|
||||||
|
Key = meta.Key,
|
||||||
|
ClientId = meta.ClientId,
|
||||||
|
Value = meta.Value,
|
||||||
|
})
|
||||||
|
.FirstOrDefaultAsync(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<T> GetPersistentMetaValue<T>(string metaKey, int clientId, CancellationToken token = default)
|
||||||
|
where T : class
|
||||||
|
{
|
||||||
|
var meta = await GetPersistentMeta(metaKey, clientId, token);
|
||||||
|
|
||||||
|
if (meta is null)
|
||||||
|
{
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return JsonSerializer.Deserialize<T>(meta.Value);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Could not deserialize meta with key {Key} and value {Value}", metaKey, meta.Value);
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<EFMeta> GetPersistentMetaByLookup(string metaKey, string lookupKey, int clientId,
|
||||||
|
CancellationToken token = default)
|
||||||
|
{
|
||||||
|
await using var context = _contextFactory.CreateContext();
|
||||||
|
|
||||||
|
var metaValue = await GetPersistentMeta(metaKey, clientId, token);
|
||||||
|
|
||||||
|
if (metaValue is null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("No meta exists for key {Key}, clientId {ClientId}", metaKey, clientId);
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lookupMeta = await context.EFMeta.FirstOrDefaultAsync(meta => meta.Key == lookupKey, token);
|
||||||
|
|
||||||
|
if (lookupMeta is null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("No lookup meta exists for metaKey {MetaKey} and lookupKey {LookupKey}", metaKey,
|
||||||
|
lookupKey);
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lookupId = int.Parse(metaValue.Value);
|
||||||
|
var lookupValues = JsonSerializer.Deserialize<List<LookupValue<string>>>(lookupMeta.Value);
|
||||||
|
|
||||||
|
if (lookupValues is null)
|
||||||
|
{
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
var foundLookup = lookupValues.FirstOrDefault(value => value.Id == lookupId);
|
||||||
|
|
||||||
|
if (foundLookup is not null)
|
||||||
|
{
|
||||||
|
return new EFMeta
|
||||||
|
{
|
||||||
|
Created = metaValue.Created,
|
||||||
|
Updated = metaValue.Updated,
|
||||||
|
Extra = metaValue.Extra,
|
||||||
|
MetaId = metaValue.MetaId,
|
||||||
|
Value = foundLookup.Value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogWarning("No lookup meta found for provided lookup id {MetaKey}, {LookupKey}, {LookupId}",
|
||||||
|
metaKey, lookupKey, lookupId);
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task RemovePersistentMeta(string metaKey, int clientId, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (!ValidArgs(metaKey, clientId))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await using var context = _contextFactory.CreateContext();
|
||||||
|
|
||||||
|
var existingMeta = await context.EFMeta
|
||||||
|
.FirstOrDefaultAsync(meta => meta.Key == metaKey && meta.ClientId == clientId, token);
|
||||||
|
|
||||||
|
if (existingMeta == null)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("No meta with key {Key} found for client id {Id}", metaKey, clientId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogDebug("Removing meta for key {Key} with id {Id}", metaKey, existingMeta.MetaId);
|
||||||
|
context.EFMeta.Remove(existingMeta);
|
||||||
|
await context.SaveChangesAsync(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SetPersistentMeta(string metaKey, string metaValue, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(metaKey))
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Cannot save meta with no key");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await using var ctx = _contextFactory.CreateContext();
|
||||||
|
|
||||||
|
var existingMeta = await ctx.EFMeta
|
||||||
|
.Where(meta => meta.Key == metaKey)
|
||||||
|
.Where(meta => meta.ClientId == null)
|
||||||
|
.FirstOrDefaultAsync(token);
|
||||||
|
|
||||||
|
if (existingMeta is not null)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Updating existing meta with key {Key} and id {Id}", existingMeta.Key,
|
||||||
|
existingMeta.MetaId);
|
||||||
|
|
||||||
|
existingMeta.Value = metaValue;
|
||||||
|
existingMeta.Updated = DateTime.UtcNow;
|
||||||
|
|
||||||
|
await ctx.SaveChangesAsync(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Adding new meta with key {Key}", metaKey);
|
||||||
|
|
||||||
|
ctx.EFMeta.Add(new EFMeta
|
||||||
|
{
|
||||||
|
Created = DateTime.UtcNow,
|
||||||
|
Key = metaKey,
|
||||||
|
Value = metaValue
|
||||||
|
});
|
||||||
|
|
||||||
|
await ctx.SaveChangesAsync(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SetPersistentMetaValue<T>(string metaKey, T metaValue, CancellationToken token = default)
|
||||||
|
where T : class
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(metaKey))
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Meta key is null, not setting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (metaValue is null)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Meta value is null, not setting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string serializedMeta;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
serializedMeta = JsonSerializer.Serialize(metaValue);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Could not serialize meta with {Key} and value {Value}", metaKey, metaValue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await SetPersistentMeta(metaKey, serializedMeta, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<EFMeta> GetPersistentMeta(string metaKey, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(metaKey))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
await using var context = _contextFactory.CreateContext(false);
|
||||||
|
return await context.EFMeta.FirstOrDefaultAsync(meta => meta.Key == metaKey, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<T> GetPersistentMetaValue<T>(string metaKey, CancellationToken token = default) where T : class
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(metaKey))
|
||||||
|
{
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
var meta = await GetPersistentMeta(metaKey, token);
|
||||||
|
|
||||||
|
if (meta is null)
|
||||||
|
{
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return JsonSerializer.Deserialize<T>(meta.Value);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Could not serialize meta with key {Key} and value {Value}", metaKey, meta.Value);
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task RemovePersistentMeta(string metaKey, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(metaKey))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await using var context = _contextFactory.CreateContext(enableTracking: false);
|
||||||
|
|
||||||
|
var existingMeta = await context.EFMeta
|
||||||
|
.Where(meta => meta.Key == metaKey)
|
||||||
|
.Where(meta => meta.ClientId == null)
|
||||||
|
.FirstOrDefaultAsync(token);
|
||||||
|
|
||||||
|
if (existingMeta != null)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Removing meta for key {Key} with id {Id}", metaKey, existingMeta.MetaId);
|
||||||
|
context.Remove(existingMeta);
|
||||||
|
await context.SaveChangesAsync(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRuntimeMeta<T, TReturnType>(MetaType metaKey,
|
||||||
|
Func<T, CancellationToken, Task<IEnumerable<TReturnType>>> metaAction)
|
||||||
|
where T : PaginationRequest where TReturnType : IClientMeta
|
||||||
|
{
|
||||||
|
if (!_metaActions.ContainsKey(metaKey))
|
||||||
|
{
|
||||||
|
_metaActions.Add(metaKey, new List<dynamic> { metaAction });
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_metaActions[metaKey].Add(metaAction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<IClientMeta>> GetRuntimeMeta(ClientPaginationRequest request, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var metas = await Task.WhenAll(_metaActions.Where(kvp => kvp.Key != MetaType.Information)
|
||||||
|
.Select(async kvp => await kvp.Value[0](request, token)));
|
||||||
|
|
||||||
|
return metas.SelectMany(m => (IEnumerable<IClientMeta>)m)
|
||||||
|
.OrderByDescending(m => m.When)
|
||||||
|
.Take(request.Count)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<T>> GetRuntimeMeta<T>(ClientPaginationRequest request, MetaType metaType, CancellationToken token = default)
|
||||||
|
where T : IClientMeta
|
||||||
|
{
|
||||||
|
if (metaType == MetaType.Information)
|
||||||
|
{
|
||||||
|
var allMeta = new List<T>();
|
||||||
|
|
||||||
|
var completedMeta = await Task.WhenAll(_metaActions[metaType].Select(async individualMetaRegistration =>
|
||||||
|
(IEnumerable<T>)await individualMetaRegistration(request, token)));
|
||||||
|
|
||||||
|
allMeta.AddRange(completedMeta.SelectMany(meta => meta));
|
||||||
|
|
||||||
|
return ProcessInformationMeta(allMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
var meta = await _metaActions[metaType][0](request) as IEnumerable<T>;
|
||||||
|
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<T> ProcessInformationMeta<T>(IEnumerable<T> meta) where T : IClientMeta
|
||||||
|
{
|
||||||
|
var metaList = meta.ToList();
|
||||||
|
var metaWithColumn = metaList
|
||||||
|
.Where(m => m.Column != null)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var columnGrouping = metaWithColumn
|
||||||
|
.GroupBy(m => m.Column)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var metaToSort = metaList.Except(metaWithColumn).ToList();
|
||||||
|
|
||||||
|
var table = columnGrouping.Select(metaItem => new List<T>(metaItem)).ToList();
|
||||||
|
|
||||||
|
while (metaToSort.Count > 0)
|
||||||
|
{
|
||||||
|
var sortingMeta = metaToSort.First();
|
||||||
|
|
||||||
|
int IndexOfSmallestColumn()
|
||||||
|
{
|
||||||
|
var index = 0;
|
||||||
|
var smallestColumnSize = int.MaxValue;
|
||||||
|
for (var i = 0; i < table.Count; i++)
|
||||||
|
{
|
||||||
|
if (table[i].Count >= smallestColumnSize)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
smallestColumnSize = table[i].Count;
|
||||||
|
index = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
var columnIndex = IndexOfSmallestColumn();
|
||||||
|
|
||||||
|
sortingMeta.Column = columnIndex;
|
||||||
|
sortingMeta.Order = columnGrouping
|
||||||
|
.First(group => group.Key == columnIndex)
|
||||||
|
.Count();
|
||||||
|
|
||||||
|
table[columnIndex].Add(sortingMeta);
|
||||||
|
|
||||||
|
metaToSort.Remove(sortingMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
return metaList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool ValidArgs(string key, int clientId) => !string.IsNullOrWhiteSpace(key) && clientId > 0;
|
||||||
|
}
|
@ -10,8 +10,8 @@ namespace Data.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class EFMeta : SharedEntity
|
public class EFMeta : SharedEntity
|
||||||
{
|
{
|
||||||
public const string ClientTagName = nameof(ClientTagName);
|
public const string ClientTagNameV2 = nameof(ClientTagNameV2);
|
||||||
public const string ClientTag = nameof(ClientTag);
|
public const string ClientTagV2 = nameof(ClientTagV2);
|
||||||
|
|
||||||
[Key]
|
[Key]
|
||||||
public int MetaId { get; set; }
|
public int MetaId { get; set; }
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Data.Models;
|
|
||||||
using Data.Models.Client;
|
|
||||||
using SharedLibraryCore.Configuration;
|
|
||||||
using SharedLibraryCore.Interfaces;
|
|
||||||
|
|
||||||
namespace SharedLibraryCore.Commands
|
|
||||||
{
|
|
||||||
public class AddClientTagCommand : Command
|
|
||||||
{
|
|
||||||
private readonly IMetaService _metaService;
|
|
||||||
|
|
||||||
public AddClientTagCommand(CommandConfiguration config, ITranslationLookup layout, IMetaService metaService) :
|
|
||||||
base(config, layout)
|
|
||||||
{
|
|
||||||
Name = "addclienttag";
|
|
||||||
Description = layout["COMMANDS_ADD_CLIENT_TAG_DESC"];
|
|
||||||
Alias = "act";
|
|
||||||
Permission = EFClient.Permission.Owner;
|
|
||||||
RequiresTarget = false;
|
|
||||||
Arguments = new[]
|
|
||||||
{
|
|
||||||
new CommandArgument
|
|
||||||
{
|
|
||||||
Name = _translationLookup["COMMANDS_ARGUMENT_TAG"],
|
|
||||||
Required = true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
_metaService = metaService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent gameEvent)
|
|
||||||
{
|
|
||||||
await _metaService.AddPersistentMeta(EFMeta.ClientTagName, gameEvent.Data);
|
|
||||||
gameEvent.Origin.Tell(_translationLookup["COMMANDS_ADD_CLIENT_TAG_SUCCESS"].FormatExt(gameEvent.Data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1137,10 +1137,10 @@ namespace SharedLibraryCore.Commands
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class SetGravatarCommand : Command
|
public class SetGravatarCommand : Command
|
||||||
{
|
{
|
||||||
private readonly IMetaService _metaService;
|
private readonly IMetaServiceV2 _metaService;
|
||||||
|
|
||||||
public SetGravatarCommand(CommandConfiguration config, ITranslationLookup translationLookup,
|
public SetGravatarCommand(CommandConfiguration config, ITranslationLookup translationLookup,
|
||||||
IMetaService metaService) : base(config, translationLookup)
|
IMetaServiceV2 metaService) : base(config, translationLookup)
|
||||||
{
|
{
|
||||||
Name = "setgravatar";
|
Name = "setgravatar";
|
||||||
Description = _translationLookup["COMMANDS_GRAVATAR_DESC"];
|
Description = _translationLookup["COMMANDS_GRAVATAR_DESC"];
|
||||||
@ -1166,7 +1166,8 @@ namespace SharedLibraryCore.Commands
|
|||||||
var gravatarEmail = string.Concat(md5
|
var gravatarEmail = string.Concat(md5
|
||||||
.ComputeHash(E.Data.ToLower().Select(d => Convert.ToByte(d)).ToArray())
|
.ComputeHash(E.Data.ToLower().Select(d => Convert.ToByte(d)).ToArray())
|
||||||
.Select(h => h.ToString("x2")));
|
.Select(h => h.ToString("x2")));
|
||||||
await _metaService.AddPersistentMeta("GravatarEmail", gravatarEmail, E.Origin);
|
await _metaService.SetPersistentMeta("GravatarEmail", gravatarEmail, E.Origin.ClientId,
|
||||||
|
E.Owner.Manager.CancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
E.Origin.Tell(_translationLookup["COMMANDS_GRAVATAR_SUCCESS_NEW"]);
|
E.Origin.Tell(_translationLookup["COMMANDS_GRAVATAR_SUCCESS_NEW"]);
|
||||||
|
9
SharedLibraryCore/Dtos/LookupValue.cs
Normal file
9
SharedLibraryCore/Dtos/LookupValue.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
|
|
||||||
|
namespace SharedLibraryCore.Dtos;
|
||||||
|
|
||||||
|
public class LookupValue<TObject> : ILookupValue<TObject>
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public TObject Value { get; set; }
|
||||||
|
}
|
7
SharedLibraryCore/Interfaces/ILookupValue.cs
Normal file
7
SharedLibraryCore/Interfaces/ILookupValue.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace SharedLibraryCore.Interfaces;
|
||||||
|
|
||||||
|
public interface ILookupValue<TObject>
|
||||||
|
{
|
||||||
|
int Id { get; }
|
||||||
|
TObject Value { get; }
|
||||||
|
}
|
194
SharedLibraryCore/Interfaces/IMetaServiceV2.cs
Normal file
194
SharedLibraryCore/Interfaces/IMetaServiceV2.cs
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Data.Models;
|
||||||
|
using SharedLibraryCore.Dtos;
|
||||||
|
using SharedLibraryCore.QueryHelper;
|
||||||
|
|
||||||
|
namespace SharedLibraryCore.Interfaces;
|
||||||
|
|
||||||
|
public interface IMetaServiceV2
|
||||||
|
{
|
||||||
|
#region PER_CLIENT
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// adds or updates meta key and value to the database as simple string
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="metaKey">key of meta data</param>
|
||||||
|
/// <param name="metaValue">value of the meta data</param>
|
||||||
|
/// <param name="clientId">id of the client to save the meta for</param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task SetPersistentMeta(string metaKey, string metaValue, int clientId, CancellationToken token = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// add or update meta key and value to the database as serialized object type
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="metaKey"></param>
|
||||||
|
/// <param name="metaValue"></param>
|
||||||
|
/// <param name="clientId"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <typeparam name="T">type of object being serialized</typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task SetPersistentMetaValue<T>(string metaKey, T metaValue, int clientId, CancellationToken token = default)
|
||||||
|
where T : class;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets meta key to a linked lookup key and id
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="metaKey">Key for the client meta</param>
|
||||||
|
/// <param name="lookupKey">Key of the global lookup meta</param>
|
||||||
|
/// <param name="lookupId">Id in the list of lookup values</param>
|
||||||
|
/// <param name="clientId">id of the client</param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task SetPersistentMetaForLookupKey(string metaKey, string lookupKey, int lookupId, int clientId,
|
||||||
|
CancellationToken token = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// increments meta value and persists to the database
|
||||||
|
/// <remarks>if the meta value does not already exist it will be set to the increment amount</remarks>
|
||||||
|
/// <remarks>the assumption is made that the existing value is <see cref="int"/></remarks>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="metaKey">key of meta data</param>
|
||||||
|
/// <param name="incrementAmount">value to increment by</param>
|
||||||
|
/// <param name="clientId">id of the client to save the meta for</param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task IncrementPersistentMeta(string metaKey, int incrementAmount, int clientId,
|
||||||
|
CancellationToken token = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// decrements meta value and persists to the database
|
||||||
|
/// <remarks>if the meta value does not already exist it will be set to the decrement amount</remarks>
|
||||||
|
/// <remarks>the assumption is made that the existing value is <see cref="int"/></remarks>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="metaKey">key of meta data</param>
|
||||||
|
/// <param name="decrementAmount">value to increment by</param>
|
||||||
|
/// <param name="clientId">id of the client to save the meta for</param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task DecrementPersistentMeta(string metaKey, int decrementAmount, int clientId,
|
||||||
|
CancellationToken token = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// retrieves meta entry
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="metaKey"></param>
|
||||||
|
/// <param name="clientId"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<EFMeta> GetPersistentMeta(string metaKey, int clientId, CancellationToken token = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// retrieves meta value as deserialized object
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="metaKey"></param>
|
||||||
|
/// <param name="clientId"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <typeparam name="T">object type to deserialize into</typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<T> GetPersistentMetaValue<T>(string metaKey, int clientId, CancellationToken token = default)
|
||||||
|
where T : class;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// retrieves meta entry by with associated lookup value as string
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="metaKey"></param>
|
||||||
|
/// <param name="lookupKey"></param>
|
||||||
|
/// <param name="clientId"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<EFMeta> GetPersistentMetaByLookup(string metaKey, string lookupKey, int clientId,
|
||||||
|
CancellationToken token = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// removes meta key with given value
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="metaKey">key of meta data</param>
|
||||||
|
/// <param name="clientId">client to delete the meta for</param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task RemovePersistentMeta(string metaKey, int clientId, CancellationToken token = default);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region GLOBAL
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// adds or updates meta key and value to the database
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="metaKey">key of meta data</param>
|
||||||
|
/// <param name="metaValue">value of the meta data</param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task SetPersistentMeta(string metaKey, string metaValue, CancellationToken token = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// serializes and sets (create or update) meta key and value
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="metaKey"></param>
|
||||||
|
/// <param name="metaValue"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task SetPersistentMetaValue<T>(string metaKey, T metaValue, CancellationToken token = default) where T : class;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// removes meta key with given value
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="metaKey">key of the meta data</param>
|
||||||
|
/// <param name="metaValue">value of the meta data</param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task RemovePersistentMeta(string metaKey, CancellationToken token = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// retrieves collection of meta for given key
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="metaKey">key to retrieve values for</param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<EFMeta> GetPersistentMeta(string metaKey, CancellationToken token = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// returns value of meta key if it exists
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="metaKey"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<T> GetPersistentMetaValue<T>(string metaKey, CancellationToken token = default) where T : class;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// adds a meta task to the runtime meta list
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="metaKey">type of meta</param>
|
||||||
|
/// <param name="metaAction">action to perform</param>
|
||||||
|
void AddRuntimeMeta<T, TReturn>(MetaType metaKey,
|
||||||
|
Func<T, CancellationToken, Task<IEnumerable<TReturn>>> metaAction)
|
||||||
|
where TReturn : IClientMeta where T : PaginationRequest;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// retrieves all the runtime meta information for given client idea
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">request information</param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<IClientMeta>> GetRuntimeMeta(ClientPaginationRequest request, CancellationToken token = default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// retrieves all the runtime of provided type
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">>request information</param>
|
||||||
|
/// <param name="metaType">type of meta to retreive</param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<T>> GetRuntimeMeta<T>(ClientPaginationRequest request, MetaType metaType, CancellationToken token = default)
|
||||||
|
where T : IClientMeta;
|
||||||
|
}
|
@ -124,8 +124,8 @@ namespace SharedLibraryCore.Database.Models
|
|||||||
[NotMapped]
|
[NotMapped]
|
||||||
public string Tag
|
public string Tag
|
||||||
{
|
{
|
||||||
get => GetAdditionalProperty<string>(EFMeta.ClientTag);
|
get => GetAdditionalProperty<string>(EFMeta.ClientTagV2);
|
||||||
set => SetAdditionalProperty(EFMeta.ClientTag, value);
|
set => SetAdditionalProperty(EFMeta.ClientTagV2, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
|
@ -8,6 +8,7 @@ using SharedLibraryCore.QueryHelper;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Data.Models;
|
using Data.Models;
|
||||||
using Stats.Config;
|
using Stats.Config;
|
||||||
@ -17,16 +18,16 @@ namespace WebfrontCore.Controllers
|
|||||||
{
|
{
|
||||||
public class ClientController : BaseController
|
public class ClientController : BaseController
|
||||||
{
|
{
|
||||||
private readonly IMetaService _metaService;
|
private readonly IMetaServiceV2 _metaService;
|
||||||
private readonly StatsConfiguration _config;
|
private readonly StatsConfiguration _config;
|
||||||
|
|
||||||
public ClientController(IManager manager, IMetaService metaService, StatsConfiguration config) : base(manager)
|
public ClientController(IManager manager, IMetaServiceV2 metaService, StatsConfiguration config) : base(manager)
|
||||||
{
|
{
|
||||||
_metaService = metaService;
|
_metaService = metaService;
|
||||||
_config = config;
|
_config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IActionResult> ProfileAsync(int id, MetaType? metaFilterType)
|
public async Task<IActionResult> ProfileAsync(int id, MetaType? metaFilterType, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var client = await Manager.GetClientService().Get(id);
|
var client = await Manager.GetClientService().Get(id);
|
||||||
|
|
||||||
@ -40,17 +41,17 @@ namespace WebfrontCore.Controllers
|
|||||||
|
|
||||||
var persistentMetaTask = new[]
|
var persistentMetaTask = new[]
|
||||||
{
|
{
|
||||||
_metaService.GetPersistentMeta(EFMeta.ClientTag, client),
|
_metaService.GetPersistentMetaByLookup(EFMeta.ClientTagV2, EFMeta.ClientTagNameV2, client.ClientId, token),
|
||||||
_metaService.GetPersistentMeta("GravatarEmail", client)
|
_metaService.GetPersistentMeta("GravatarEmail", client.ClientId, token)
|
||||||
};
|
};
|
||||||
|
|
||||||
var persistentMeta = await Task.WhenAll(persistentMetaTask);
|
var persistentMeta = await Task.WhenAll(persistentMetaTask);
|
||||||
var tag = persistentMeta[0];
|
var tag = persistentMeta[0];
|
||||||
var gravatar = persistentMeta[1];
|
var gravatar = persistentMeta[1];
|
||||||
|
|
||||||
if (tag?.LinkedMeta != null)
|
if (tag?.Value != null)
|
||||||
{
|
{
|
||||||
client.SetAdditionalProperty(EFMeta.ClientTag, tag.LinkedMeta.Value);
|
client.SetAdditionalProperty(EFMeta.ClientTagV2, tag.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// even though we haven't set their level to "banned" yet
|
// even though we haven't set their level to "banned" yet
|
||||||
|
@ -116,13 +116,14 @@ namespace WebfrontCore
|
|||||||
// todo: this needs to be handled more gracefully
|
// todo: this needs to be handled more gracefully
|
||||||
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<DefaultSettings>());
|
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<DefaultSettings>());
|
||||||
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<ILoggerFactory>());
|
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<ILoggerFactory>());
|
||||||
services.AddSingleton(Program.ApplicationServiceProvider.GetService<IConfigurationHandlerFactory>());
|
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<IConfigurationHandlerFactory>());
|
||||||
services.AddSingleton(Program.ApplicationServiceProvider.GetService<IDatabaseContextFactory>());
|
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<IDatabaseContextFactory>());
|
||||||
services.AddSingleton(Program.ApplicationServiceProvider.GetService<IAuditInformationRepository>());
|
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<IAuditInformationRepository>());
|
||||||
services.AddSingleton(Program.ApplicationServiceProvider.GetService<ITranslationLookup>());
|
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<ITranslationLookup>());
|
||||||
services.AddSingleton(Program.ApplicationServiceProvider.GetService<IEnumerable<IManagerCommand>>());
|
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<IEnumerable<IManagerCommand>>());
|
||||||
services.AddSingleton(Program.ApplicationServiceProvider.GetService<IMetaService>());
|
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<IMetaService>());
|
||||||
services.AddSingleton(Program.ApplicationServiceProvider.GetService<ApplicationConfiguration>());
|
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<IMetaServiceV2>());
|
||||||
|
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<ApplicationConfiguration>());
|
||||||
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<ClientService>());
|
services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService<ClientService>());
|
||||||
services.AddSingleton(
|
services.AddSingleton(
|
||||||
Program.ApplicationServiceProvider.GetRequiredService<IServerDistributionCalculator>());
|
Program.ApplicationServiceProvider.GetRequiredService<IServerDistributionCalculator>());
|
||||||
|
@ -13,9 +13,9 @@ namespace WebfrontCore.ViewComponents
|
|||||||
{
|
{
|
||||||
public class ProfileMetaListViewComponent : ViewComponent
|
public class ProfileMetaListViewComponent : ViewComponent
|
||||||
{
|
{
|
||||||
private readonly IMetaService _metaService;
|
private readonly IMetaServiceV2 _metaService;
|
||||||
|
|
||||||
public ProfileMetaListViewComponent(IMetaService metaService)
|
public ProfileMetaListViewComponent(IMetaServiceV2 metaService)
|
||||||
{
|
{
|
||||||
_metaService = metaService;
|
_metaService = metaService;
|
||||||
}
|
}
|
||||||
@ -38,7 +38,7 @@ namespace WebfrontCore.ViewComponents
|
|||||||
return View("_List", meta);
|
return View("_List", meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<IEnumerable<IClientMeta>> GetClientMeta(IMetaService metaService, MetaType? metaType,
|
public static async Task<IEnumerable<IClientMeta>> GetClientMeta(IMetaServiceV2 metaService, MetaType? metaType,
|
||||||
EFClient.Permission level, ClientPaginationRequest request)
|
EFClient.Permission level, ClientPaginationRequest request)
|
||||||
{
|
{
|
||||||
IEnumerable<IClientMeta> meta = null;
|
IEnumerable<IClientMeta> meta = null;
|
||||||
|
Loading…
Reference in New Issue
Block a user