diff --git a/Application/Application.csproj b/Application/Application.csproj index 00b23616..8e83b788 100644 --- a/Application/Application.csproj +++ b/Application/Application.csproj @@ -56,7 +56,7 @@ - Always + PreserveNewest PreserveNewest diff --git a/Application/ApplicationManager.cs b/Application/ApplicationManager.cs index 7ecafa7b..35ff09ba 100644 --- a/Application/ApplicationManager.cs +++ b/Application/ApplicationManager.cs @@ -6,7 +6,6 @@ using SharedLibraryCore; using SharedLibraryCore.Commands; using SharedLibraryCore.Configuration; using SharedLibraryCore.Configuration.Validation; -using SharedLibraryCore.Database; using SharedLibraryCore.Database.Models; using SharedLibraryCore.Exceptions; using SharedLibraryCore.Helpers; @@ -21,6 +20,8 @@ using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; +using Data.Abstractions; +using Data.Context; using IW4MAdmin.Application.Migration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -291,6 +292,15 @@ namespace IW4MAdmin.Application IsRunning = true; ExternalIPAddress = await Utilities.GetExternalIP(); + #region DATABASE + _logger.LogInformation("Beginning database migration sync"); + Console.WriteLine(_translationLookup["MANAGER_MIGRATION_START"]); + await ContextSeed.Seed(_serviceProvider.GetRequiredService(), _tokenSource.Token); + await DatabaseHousekeeping.RemoveOldRatings(_serviceProvider.GetRequiredService(), _tokenSource.Token); + _logger.LogInformation("Finished database migration sync"); + Console.WriteLine(_translationLookup["MANAGER_MIGRATION_END"]); + #endregion + #region PLUGINS foreach (var plugin in Plugins) { @@ -331,7 +341,7 @@ namespace IW4MAdmin.Application // copy over default config if it doesn't exist if (!_appConfig.Servers?.Any() ?? true) { - var defaultConfig = new BaseConfigurationHandler("DefaultSettings").Configuration(); + var defaultConfig = new BaseConfigurationHandler("DefaultSettings").Configuration(); //ConfigHandler.Set((ApplicationConfiguration)new ApplicationConfiguration().Generate()); //var newConfig = ConfigHandler.Configuration(); @@ -424,15 +434,6 @@ namespace IW4MAdmin.Application #endregion - #region DATABASE - _logger.LogInformation("Beginning database migration sync"); - Console.WriteLine(_translationLookup["MANAGER_MIGRATION_START"]); - await ContextSeed.Seed(_serviceProvider.GetRequiredService(), _tokenSource.Token); - await DatabaseHousekeeping.RemoveOldRatings(_serviceProvider.GetRequiredService(), _tokenSource.Token); - _logger.LogInformation("Finished database migration sync"); - Console.WriteLine(_translationLookup["MANAGER_MIGRATION_END"]); - #endregion - #region COMMANDS if (await ClientSvc.HasOwnerAsync(_tokenSource.Token)) { @@ -517,7 +518,7 @@ namespace IW4MAdmin.Application // add the start event for this server var e = new GameEvent() { - Type = GameEvent.EventType.Start, + Type = EventType.Start, Data = $"{ServerInstance.GameName} started", Owner = ServerInstance }; diff --git a/Application/DefaultSettings.json b/Application/DefaultSettings.json index 811565d1..eeff723d 100644 --- a/Application/DefaultSettings.json +++ b/Application/DefaultSettings.json @@ -16,7 +16,13 @@ "Keep grenade launcher use to a minimum", "Balance teams at ALL times" ], - "DisallowedClientNames": [ "Unknown Soldier", "VickNet", "UnknownSoldier", "CHEATER", "Play77" ], + "DisallowedClientNames": [ + "Unknown Soldier", + "VickNet", + "UnknownSoldier", + "CHEATER", + "Play77" + ], "QuickMessages": [ { "Game": "IW4", @@ -248,222 +254,178 @@ "Alias": "Rust", "Name": "mp_rust" }, - { "Alias": "Terminal", "Name": "mp_terminal" }, - { "Alias": "Crash", "Name": "mp_crash" }, - { "Alias": "Afghan", "Name": "mp_afghan" }, - { "Alias": "Derail", "Name": "mp_derail" }, - { "Alias": "Estate", "Name": "mp_estate" }, - { "Alias": "Favela", "Name": "mp_favela" }, - { "Alias": "Highrise", "Name": "mp_highrise" }, - { "Alias": "Invasion", "Name": "mp_invasion" }, - { "Alias": "Karachi", "Name": "mp_checkpoint" }, - { "Alias": "Quarry", "Name": "mp_quarry" }, - { "Alias": "Rundown", "Name": "mp_rundown" }, - { "Alias": "Scrapyard", "Name": "mp_boneyard" }, - { "Alias": "Skidrow", "Name": "mp_nightshift" }, - { "Alias": "Sub Base", "Name": "mp_subbase" }, - { "Alias": "Underpass", "Name": "mp_underpass" }, - { "Alias": "Wasteland", "Name": "mp_brecourt" }, - { "Alias": "Overgrown", "Name": "mp_overgrown" }, - { "Alias": "Strike", "Name": "mp_strike" }, - { "Alias": "Vacant", "Name": "mp_vacant" }, - { "Alias": "Carnival", "Name": "mp_abandon" }, - { "Alias": "Trailer Park", "Name": "mp_trailerpark" }, - { "Alias": "Fuel", "Name": "mp_fuel2" }, - { "Alias": "Storm", "Name": "mp_storm" }, - { "Alias": "Bailout", "Name": "mp_complex" }, - { "Alias": "Salvage", "Name": "mp_compact" }, - { "Alias": "Nuketown", "Name": "mp_nuked" }, - { "Alias": "Test map", "Name": "iw4_credits" }, - { "Alias": "Killhouse", "Name": "mp_killhouse" }, - { "Alias": "Bog", "Name": "mp_bog_sh" }, - { "Alias": "Freighter", "Name": "mp_cargoship_sh" }, - { "Alias": "Cargoship", "Name": "mp_cargoship" }, - { "Alias": "Shipment", "Name": "mp_shipment" }, - { "Alias": "Shipment - Long", "Name": "mp_shipment_long" }, - { "Alias": "Rust - Long", "Name": "mp_rust_long" }, - { "Alias": "Firing Range", "Name": "mp_firingrange" }, - { "Alias": "Chemical Plant", "Name": "mp_storm_spring" }, - { "Alias": "Tropical Favela", "Name": "mp_fav_tropical" }, - { "Alias": "Tropical Estate", "Name": "mp_estate_tropical" }, - { "Alias": "Tropical Crash", "Name": "mp_crash_tropical" }, - { "Alias": "Forgotten City", "Name": "mp_bloc_sh" }, - { "Alias": "Crossfire", "Name": "mp_cross_fire" }, - { "Alias": "Bloc", "Name": "mp_bloc" }, - { "Alias": "Oilrig", "Name": "oilrig" }, - { "Name": "Village", "Alias": "co_hunted" @@ -519,7 +481,7 @@ }, { "Alias": "Havana", - "Name": "mp_cairo" + "Name": "mp_cairo" }, { "Alias": "Hazard", @@ -885,5 +847,79 @@ } ] } - ] + ], + "GameStrings": { + "IW4": { + "torso_upper": "Upper Torso", + "torso_lower": "Lower Torso", + "right_leg_upper": "Upper Right Leg", + "right_leg_lower": "Lower Right Leg", + "right_hand": "Right Hand", + "right_foot": "Right Foot", + "right_arm_upper": "Upper Right Arm", + "right_arm_lower": "Lower Right Arm", + "left_leg_upper": "Upper Left Leg", + "left_leg_lower": "Lower Left Leg", + "left_hand": "Left Hand", + "left_foot": "Left Foot", + "left_arm_upper": "Upper Left Arm", + "left_arm_lower": "Lower Left Arm", + "acog": "ACOG Sight", + "eotech": "Holographic Sight", + "fmj": "FMJ", + "gl": "Grenade Launcher", + "heartbeat": "Heartbeat Sensor", + "reflex": "Red Dot Sight", + "rof": "Rapid Fire", + "thermal": "Thermal", + "xmags": "Extended Mags", + "m4": "M4A1", + "m40a3": "M40A3", + "ak47": "AK-47", + "ak47classic": "AK-47 Classic", + "fn2000": "F2000", + "masada": "ACR", + "famas": "FAMAS", + "fal": "FAL", + "scar": "SCAR-H", + "tavor": "TAR-21", + "m16": "M16A4", + "mp5k": "MP5K", + "ump45": "UMP45", + "kriss": "Vector", + "uzi": "Mini-Uzi", + "rpd": "RPD", + "sa80": "L86 LSW", + "mg4": "MG4", + "aug": "AUG HBAR", + "cheytac": "Intervention", + "barrett": "Barrett .50cal", + "wa2000": "WA2000", + "m21": "M21 EBR", + "pp2000": "PP2000", + "glock": "G18", + "beretta": "M93 Raffica", + "tmp": "TMP", + "spas12": "SPAS-12", + "aa12": "AA-12", + "model1887": "Model 1887", + "usp": "USP .45", + "coltanaconda": ".44 Magnum", + "deserteagle": "Desert Eagle", + "deserteaglegold": "Desert Eagle Gold", + "at4": "AT4-HS", + "m79": "Thumper", + "rpg": "RPG-7", + "concussion": "Stun", + "throwingknife": "Throwing Knife", + "ffar": "Airstrike", + "pavelow": "Pave Low", + "cobra": "Attack Helicopter", + "ac130": "AC-130", + "remotemissile": "Predator Missile", + "artillery": "Precision Airstrike", + "player": "", + "attach": "" + } + } } diff --git a/Application/EventParsers/BaseEventParser.cs b/Application/EventParsers/BaseEventParser.cs index 2bb40fbb..ddb3578c 100644 --- a/Application/EventParsers/BaseEventParser.cs +++ b/Application/EventParsers/BaseEventParser.cs @@ -5,6 +5,7 @@ using SharedLibraryCore.Interfaces; using System; using System.Collections.Generic; using System.Linq; +using Data.Models; using Microsoft.Extensions.Logging; using static SharedLibraryCore.Server; using ILogger = Microsoft.Extensions.Logging.ILogger; @@ -310,7 +311,7 @@ namespace IW4MAdmin.Application.EventParsers } } - if (eventType.Contains("ExitLevel")) + if (eventType.Contains("ExitLevel") || eventType.Contains("ShutdownGame")) { return new GameEvent() { diff --git a/Application/Extensions/StartupExtensions.cs b/Application/Extensions/StartupExtensions.cs index b59a4b0b..4e0e2242 100644 --- a/Application/Extensions/StartupExtensions.cs +++ b/Application/Extensions/StartupExtensions.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Runtime.InteropServices; +using Data.MigrationContext; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; @@ -10,7 +11,6 @@ using Serilog; using Serilog.Events; using SharedLibraryCore; using SharedLibraryCore.Configuration; -using SharedLibraryCore.Database.MigrationContext; using ILogger = Serilog.ILogger; namespace IW4MAdmin.Application.Extensions @@ -32,13 +32,12 @@ namespace IW4MAdmin.Application.Extensions .ReadFrom.Configuration(configuration) .MinimumLevel.Override("Microsoft", LogEventLevel.Warning); - if (Utilities.IsDevelopment) { loggerConfig = loggerConfig.WriteTo.Console( outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Server} {Level:u3}] {Message:lj}{NewLine}{Exception}") - .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .MinimumLevel.Debug(); } @@ -67,10 +66,10 @@ namespace IW4MAdmin.Application.Extensions {DataSource = Path.Join(currentPath, "Database", "Database.db")}; var connectionString = connectionStringBuilder.ToString(); - var builder = new DbContextOptionsBuilder() - .UseSqlite(connectionString); - - services.AddSingleton((DbContextOptions) builder.Options); + services.AddSingleton(sp => (DbContextOptions) new DbContextOptionsBuilder() + .UseSqlite(connectionString) + .UseLoggerFactory(sp.GetRequiredService()) + .EnableSensitiveDataLogging().Options); return services; } @@ -90,7 +89,11 @@ namespace IW4MAdmin.Application.Extensions services.AddSingleton(sp => (DbContextOptions) new DbContextOptionsBuilder() .UseNpgsql(appConfig.ConnectionString + (appendTimeout ? ";Command Timeout=0" : ""), - postgresqlOptions => postgresqlOptions.EnableRetryOnFailure()) + postgresqlOptions => + { + postgresqlOptions.EnableRetryOnFailure(); + postgresqlOptions.SetPostgresVersion(new Version("9.4")); + }) .UseLoggerFactory(sp.GetRequiredService()).Options); return services; default: diff --git a/Application/Factories/DatabaseContextFactory.cs b/Application/Factories/DatabaseContextFactory.cs index 87b33f8f..604d8e6c 100644 --- a/Application/Factories/DatabaseContextFactory.cs +++ b/Application/Factories/DatabaseContextFactory.cs @@ -1,9 +1,9 @@ using System; +using Data.Abstractions; +using Data.Context; +using Data.MigrationContext; using Microsoft.EntityFrameworkCore; using SharedLibraryCore.Configuration; -using SharedLibraryCore.Database; -using SharedLibraryCore.Database.MigrationContext; -using SharedLibraryCore.Interfaces; namespace IW4MAdmin.Application.Factories { diff --git a/Application/Factories/GameServerInstanceFactory.cs b/Application/Factories/GameServerInstanceFactory.cs index 8cadbc73..dbf4b82b 100644 --- a/Application/Factories/GameServerInstanceFactory.cs +++ b/Application/Factories/GameServerInstanceFactory.cs @@ -1,4 +1,6 @@ using System; +using Data.Abstractions; +using Data.Models.Server; using Microsoft.Extensions.DependencyInjection; using SharedLibraryCore; using SharedLibraryCore.Configuration; @@ -37,7 +39,7 @@ namespace IW4MAdmin.Application.Factories /// public Server CreateServer(ServerConfiguration config, IManager manager) { - return new IW4MServer(config, _translationLookup, _metaService, _serviceProvider, _serviceProvider.GetRequiredService()); + return new IW4MServer(config, _translationLookup, _metaService, _serviceProvider, _serviceProvider.GetRequiredService(), _serviceProvider.GetRequiredService>()); } } } diff --git a/Application/Factories/ScriptCommandFactory.cs b/Application/Factories/ScriptCommandFactory.cs index d2e3a38b..ce6ea26e 100644 --- a/Application/Factories/ScriptCommandFactory.cs +++ b/Application/Factories/ScriptCommandFactory.cs @@ -6,9 +6,9 @@ using SharedLibraryCore.Interfaces; using System; using System.Collections.Generic; using System.Linq; +using Data.Models.Client; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using static SharedLibraryCore.Database.Models.EFClient; namespace IW4MAdmin.Application.Factories { @@ -32,7 +32,7 @@ namespace IW4MAdmin.Application.Factories public IManagerCommand CreateScriptCommand(string name, string alias, string description, string permission, bool isTargetRequired, IEnumerable<(string, bool)> args, Action executeAction) { - var permissionEnum = Enum.Parse(permission); + var permissionEnum = Enum.Parse(permission); var argsArray = args.Select(_arg => new CommandArgument { Name = _arg.Item1, diff --git a/Application/IW4MServer.cs b/Application/IW4MServer.cs index a58f026f..c3d103be 100644 --- a/Application/IW4MServer.cs +++ b/Application/IW4MServer.cs @@ -15,10 +15,14 @@ using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; +using Data.Abstractions; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Serilog.Context; using static SharedLibraryCore.Database.Models.EFClient; +using Data.Models; +using Data.Models.Server; +using static Data.Models.Client.EFClient; namespace IW4MAdmin { @@ -34,13 +38,15 @@ namespace IW4MAdmin public int Id { get; private set; } private readonly IServiceProvider _serviceProvider; private readonly IClientNoticeMessageFormatter _messageFormatter; + private readonly ILookupCache _serverCache; public IW4MServer( ServerConfiguration serverConfiguration, ITranslationLookup lookup, IMetaService metaService, IServiceProvider serviceProvider, - IClientNoticeMessageFormatter messageFormatter) : base(serviceProvider.GetRequiredService>(), + IClientNoticeMessageFormatter messageFormatter, + ILookupCache serverCache) : base(serviceProvider.GetRequiredService>(), serviceProvider.GetRequiredService(), serverConfiguration, serviceProvider.GetRequiredService(), @@ -51,6 +57,7 @@ namespace IW4MAdmin _metaService = metaService; _serviceProvider = serviceProvider; _messageFormatter = messageFormatter; + _serverCache = serverCache; } public override async Task OnClientConnected(EFClient clientFromLog) @@ -250,6 +257,28 @@ namespace IW4MAdmin { ServerLogger.LogDebug("processing event of type {type}", E.Type); + if (E.Type == GameEvent.EventType.Start) + { + var existingServer = (await _serverCache + .FirstAsync(server => server.Id == EndPoint)); + + var serverId = await GetIdForServer(E.Owner); + + if (existingServer == null) + { + var server = new EFServer() + { + Port = Port, + EndPoint = ToString(), + ServerId = serverId, + GameName = (Reference.Game?)GameName, + HostName = Hostname + }; + + await _serverCache.AddAsync(server); + } + } + if (E.Type == GameEvent.EventType.ConnectionLost) { var exception = E.Extra as Exception; @@ -734,6 +763,25 @@ namespace IW4MAdmin updatedClients.ToList() }; } + + private async Task GetIdForServer(Server server) + { + if ($"{server.IP}:{server.Port.ToString()}" == "66.150.121.184:28965") + { + return 886229536; + } + + // todo: this is not stable and will need to be migrated again... + long id = HashCode.Combine(server.IP, server.Port); + id = id < 0 ? Math.Abs(id) : id; + + var serverId = (await _serverCache + .FirstAsync(_server => _server.ServerId == server.EndPoint || + _server.EndPoint == server.ToString() || + _server.ServerId == id))?.ServerId; + + return !serverId.HasValue ? id : serverId.Value; + } private void UpdateMap(string mapname) { @@ -1113,6 +1161,7 @@ namespace IW4MAdmin this, GenerateUriForLog(LogPath, ServerConfig.GameLogServerUrl?.AbsoluteUri), gameLogReaderFactory); + await _serverCache.InitializeAsync(); _ = Task.Run(() => LogEvent.PollForChanges()); if (!Utilities.IsDevelopment) diff --git a/Application/Main.cs b/Application/Main.cs index c09159ad..8bd61a37 100644 --- a/Application/Main.cs +++ b/Application/Main.cs @@ -23,10 +23,18 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using Data.Abstractions; +using Data.Helpers; using IW4MAdmin.Application.Extensions; using IW4MAdmin.Application.Localization; using Microsoft.Extensions.Logging; using ILogger = Microsoft.Extensions.Logging.ILogger; +using IW4MAdmin.Plugins.Stats.Client.Abstractions; +using IW4MAdmin.Plugins.Stats.Client; +using IW4MAdmin.Plugins.Stats.Client.Game; +using Stats.Client.Abstractions; +using Stats.Client; +using Stats.Helpers; namespace IW4MAdmin.Application { @@ -80,13 +88,13 @@ namespace IW4MAdmin.Application /// private static async Task LaunchAsync(string[] args) { - restart: + restart: ITranslationLookup translationLookup = null; var logger = BuildDefaultLogger(new ApplicationConfiguration()); Utilities.DefaultLogger = logger; IServiceCollection services = null; logger.LogInformation("Begin IW4MAdmin startup. Version is {version} {@args}", Version, args); - + try { // do any needed housekeeping file/folder migrations @@ -96,7 +104,7 @@ namespace IW4MAdmin.Application services = ConfigureServices(args); serviceProvider = services.BuildServiceProvider(); var versionChecker = serviceProvider.GetRequiredService(); - ServerManager = (ApplicationManager)serviceProvider.GetRequiredService(); + ServerManager = (ApplicationManager) serviceProvider.GetRequiredService(); translationLookup = serviceProvider.GetRequiredService(); await versionChecker.CheckVersion(); @@ -105,8 +113,12 @@ namespace IW4MAdmin.Application catch (Exception e) { - string failMessage = translationLookup == null ? "Failed to initialize IW4MAdmin" : translationLookup["MANAGER_INIT_FAIL"]; - string exitMessage = translationLookup == null ? "Press enter to exit..." : translationLookup["MANAGER_EXIT"]; + string failMessage = translationLookup == null + ? "Failed to initialize IW4MAdmin" + : translationLookup["MANAGER_INIT_FAIL"]; + string exitMessage = translationLookup == null + ? "Press enter to exit..." + : translationLookup["MANAGER_EXIT"]; logger.LogCritical(e, "Failed to initialize IW4MAdmin"); Console.WriteLine(failMessage); @@ -120,7 +132,8 @@ namespace IW4MAdmin.Application { if (translationLookup != null) { - Console.WriteLine(translationLookup[configException.Message].FormatExt(configException.ConfigurationFileName)); + Console.WriteLine(translationLookup[configException.Message] + .FormatExt(configException.ConfigurationFileName)); } foreach (string error in configException.Errors) @@ -148,7 +161,9 @@ namespace IW4MAdmin.Application catch (Exception e) { logger.LogCritical(e, "Failed to launch IW4MAdmin"); - string failMessage = translationLookup == null ? "Failed to launch IW4MAdmin" : translationLookup["MANAGER_INIT_FAIL"]; + string failMessage = translationLookup == null + ? "Failed to launch IW4MAdmin" + : translationLookup["MANAGER_INIT_FAIL"]; Console.WriteLine($"{failMessage}: {e.GetExceptionInfo()}"); } @@ -166,9 +181,9 @@ namespace IW4MAdmin.Application /// private static async Task RunApplicationTasksAsync(ILogger logger, IServiceCollection services) { - var webfrontTask = ServerManager.GetApplicationSettings().Configuration().EnableWebFront ? - WebfrontCore.Program.Init(ServerManager, serviceProvider, services, ServerManager.CancellationToken) : - Task.CompletedTask; + var webfrontTask = ServerManager.GetApplicationSettings().Configuration().EnableWebFront + ? WebfrontCore.Program.Init(ServerManager, serviceProvider, services, ServerManager.CancellationToken) + : Task.CompletedTask; // we want to run this one on a manual thread instead of letting the thread pool handle it, // because we can't exit early from waiting on console input, and it prevents us from restarting @@ -179,7 +194,8 @@ namespace IW4MAdmin.Application { ServerManager.Start(), webfrontTask, - serviceProvider.GetRequiredService().RunUploadStatus(ServerManager.CancellationToken) + serviceProvider.GetRequiredService() + .RunUploadStatus(ServerManager.CancellationToken) }; logger.LogDebug("Starting webfront and input tasks"); @@ -231,11 +247,12 @@ namespace IW4MAdmin.Application } } catch (OperationCanceledException) - { } + { + } } - private static IServiceCollection HandlePluginRegistration(ApplicationConfiguration appConfig, - IServiceCollection serviceCollection, + private static IServiceCollection HandlePluginRegistration(ApplicationConfiguration appConfig, + IServiceCollection serviceCollection, IMasterApi masterApi) { var defaultLogger = BuildDefaultLogger(appConfig); @@ -248,33 +265,44 @@ namespace IW4MAdmin.Application .BuildServiceProvider(); var pluginImporter = pluginServiceProvider.GetRequiredService(); - + // we need to register the rest client with regular collection serviceCollection.AddSingleton(masterApi); - + // register the native commands foreach (var commandType in typeof(SharedLibraryCore.Commands.QuitCommand).Assembly.GetTypes() - .Where(_command => _command.BaseType == typeof(Command))) + .Where(_command => _command.BaseType == typeof(Command))) { defaultLogger.LogDebug("Registered native command type {name}", commandType.Name); serviceCollection.AddSingleton(typeof(IManagerCommand), commandType); } // register the plugin implementations - var pluginImplementations = pluginImporter.DiscoverAssemblyPluginImplementations(); - foreach (var pluginType in pluginImplementations.Item1) + var (plugins, commands, configurations) = pluginImporter.DiscoverAssemblyPluginImplementations(); + foreach (var pluginType in plugins) { defaultLogger.LogDebug("Registered plugin type {name}", pluginType.FullName); serviceCollection.AddSingleton(typeof(IPlugin), pluginType); } // register the plugin commands - foreach (var commandType in pluginImplementations.Item2) + foreach (var commandType in commands) { defaultLogger.LogDebug("Registered plugin command type {name}", commandType.FullName); serviceCollection.AddSingleton(typeof(IManagerCommand), commandType); } + foreach (var configurationType in configurations) + { + defaultLogger.LogDebug("Registered plugin config type {name}", configurationType.Name); + var configInstance = (IBaseConfiguration) Activator.CreateInstance(configurationType); + var handlerType = typeof(BaseConfigurationHandler<>).MakeGenericType(configurationType); + var handlerInstance = Activator.CreateInstance(handlerType, new[] {configInstance.Name()}); + var genericInterfaceType = typeof(IConfigurationHandler<>).MakeGenericType(configurationType); + + serviceCollection.AddSingleton(genericInterfaceType, handlerInstance); + } + // register any script plugins foreach (var scriptPlugin in pluginImporter.DiscoverScriptPlugins()) { @@ -284,10 +312,9 @@ namespace IW4MAdmin.Application // register any eventable types foreach (var assemblyType in typeof(Program).Assembly.GetTypes() .Where(_asmType => typeof(IRegisterEvent).IsAssignableFrom(_asmType)) - .Union(pluginImplementations - .Item1.SelectMany(_asm => _asm.Assembly.GetTypes()) - .Distinct() - .Where(_asmType => typeof(IRegisterEvent).IsAssignableFrom(_asmType)))) + .Union(plugins.SelectMany(_asm => _asm.Assembly.GetTypes()) + .Distinct() + .Where(_asmType => typeof(IRegisterEvent).IsAssignableFrom(_asmType)))) { var instance = Activator.CreateInstance(assemblyType) as IRegisterEvent; serviceCollection.AddSingleton(instance); @@ -295,7 +322,7 @@ namespace IW4MAdmin.Application return serviceCollection; } - + /// /// Configures the dependency injection services @@ -310,7 +337,7 @@ namespace IW4MAdmin.Application ? new Uri("http://127.0.0.1:8080") : appConfig?.MasterUrl ?? new ApplicationConfiguration().MasterUrl; var masterRestClient = RestClient.For(masterUri); - var translationLookup = Configure.Initialize(Utilities.DefaultLogger, masterRestClient, appConfig); + var translationLookup = Configure.Initialize(Utilities.DefaultLogger, masterRestClient, appConfig); if (appConfig == null) { @@ -327,13 +354,14 @@ namespace IW4MAdmin.Application Utilities.PermissionLevelOverrides.Add(key, value); } } - + // build the dependency list HandlePluginRegistration(appConfig, serviceCollection, masterRestClient); serviceCollection .AddBaseLogger(appConfig) .AddSingleton(_serviceProvider => serviceCollection) + .AddSingleton, BaseConfigurationHandler>() .AddSingleton((IConfigurationHandler) appConfigHandler) .AddSingleton( new BaseConfigurationHandler("CommandConfiguration") as @@ -372,6 +400,12 @@ namespace IW4MAdmin.Application .AddSingleton() .AddSingleton() .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton(typeof(ILookupCache<>), typeof(LookupCache<>)) + .AddSingleton(typeof(IDataValueCache<,>), typeof(DataValueCache<,>)) .AddSingleton(translationLookup) .AddDatabaseContextOptions(appConfig); @@ -386,7 +420,7 @@ namespace IW4MAdmin.Application return serviceCollection; } - + private static ILogger BuildDefaultLogger(ApplicationConfiguration appConfig) { var collection = new ServiceCollection() @@ -396,4 +430,4 @@ namespace IW4MAdmin.Application return collection.GetRequiredService>(); } } -} +} \ No newline at end of file diff --git a/Application/Meta/AdministeredPenaltyResourceQueryHelper.cs b/Application/Meta/AdministeredPenaltyResourceQueryHelper.cs index 616e19de..da9f8015 100644 --- a/Application/Meta/AdministeredPenaltyResourceQueryHelper.cs +++ b/Application/Meta/AdministeredPenaltyResourceQueryHelper.cs @@ -1,8 +1,9 @@ using System.Linq; using System.Threading.Tasks; +using Data.Abstractions; +using Data.Models; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; -using SharedLibraryCore.Database.Models; using SharedLibraryCore.Dtos.Meta.Responses; using SharedLibraryCore.Helpers; using SharedLibraryCore.Interfaces; diff --git a/Application/Meta/ReceivedPenaltyResourceQueryHelper.cs b/Application/Meta/ReceivedPenaltyResourceQueryHelper.cs index f63ad068..d9c8bbdd 100644 --- a/Application/Meta/ReceivedPenaltyResourceQueryHelper.cs +++ b/Application/Meta/ReceivedPenaltyResourceQueryHelper.cs @@ -1,10 +1,10 @@ -using System; -using System.Linq; +using System.Linq; using System.Threading.Tasks; +using Data.Abstractions; +using Data.Models; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using SharedLibraryCore; -using SharedLibraryCore.Database.Models; using SharedLibraryCore.Dtos.Meta.Responses; using SharedLibraryCore.Helpers; using SharedLibraryCore.Interfaces; diff --git a/Application/Meta/UpdatedAliasResourceQueryHelper.cs b/Application/Meta/UpdatedAliasResourceQueryHelper.cs index 4765cbf0..8dbce96e 100644 --- a/Application/Meta/UpdatedAliasResourceQueryHelper.cs +++ b/Application/Meta/UpdatedAliasResourceQueryHelper.cs @@ -6,6 +6,7 @@ using SharedLibraryCore.Interfaces; using SharedLibraryCore.QueryHelper; using System.Linq; using System.Threading.Tasks; +using Data.Abstractions; using Microsoft.Extensions.Logging; using ILogger = Microsoft.Extensions.Logging.ILogger; diff --git a/Application/Migration/DatabaseHousekeeping.cs b/Application/Migration/DatabaseHousekeeping.cs index eec18006..d4331dd9 100644 --- a/Application/Migration/DatabaseHousekeeping.cs +++ b/Application/Migration/DatabaseHousekeeping.cs @@ -2,7 +2,8 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using IW4MAdmin.Plugins.Stats.Models; +using Data.Abstractions; +using Data.Models.Client.Stats; using SharedLibraryCore.Database; using SharedLibraryCore.Interfaces; diff --git a/Application/Misc/BaseConfigurationHandler.cs b/Application/Misc/BaseConfigurationHandler.cs index 23d8295b..9aaedb06 100644 --- a/Application/Misc/BaseConfigurationHandler.cs +++ b/Application/Misc/BaseConfigurationHandler.cs @@ -22,6 +22,11 @@ namespace IW4MAdmin.Application.Misc Build(); } + public BaseConfigurationHandler() : this(typeof(T).Name) + { + + } + public string FileName { get; } public void Build() diff --git a/Application/Misc/ClientNoticeMessageFormatter.cs b/Application/Misc/ClientNoticeMessageFormatter.cs index d4885c6d..3ab5c120 100644 --- a/Application/Misc/ClientNoticeMessageFormatter.cs +++ b/Application/Misc/ClientNoticeMessageFormatter.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using Data.Models; using SharedLibraryCore; using SharedLibraryCore.Configuration; -using SharedLibraryCore.Database.Models; using SharedLibraryCore.Interfaces; namespace IW4MAdmin.Application.Misc diff --git a/Application/Misc/MetaService.cs b/Application/Misc/MetaService.cs index 7de83bf2..47f0bd1d 100644 --- a/Application/Misc/MetaService.cs +++ b/Application/Misc/MetaService.cs @@ -7,8 +7,10 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Data.Abstractions; using Microsoft.Extensions.Logging; using ILogger = Microsoft.Extensions.Logging.ILogger; +using Data.Models; namespace IW4MAdmin.Application.Misc { diff --git a/Application/Misc/PluginImporter.cs b/Application/Misc/PluginImporter.cs index 79318b40..453b6b98 100644 --- a/Application/Misc/PluginImporter.cs +++ b/Application/Misc/PluginImporter.cs @@ -63,11 +63,12 @@ namespace IW4MAdmin.Application.Misc /// discovers all the C# assembly plugins and commands /// /// - public (IEnumerable, IEnumerable) DiscoverAssemblyPluginImplementations() + public (IEnumerable, IEnumerable, IEnumerable) DiscoverAssemblyPluginImplementations() { - string pluginDir = $"{Utilities.OperatingDirectory}{PLUGIN_DIR}{Path.DirectorySeparatorChar}"; + var pluginDir = $"{Utilities.OperatingDirectory}{PLUGIN_DIR}{Path.DirectorySeparatorChar}"; var pluginTypes = Enumerable.Empty(); var commandTypes = Enumerable.Empty(); + var configurationTypes = Enumerable.Empty(); if (Directory.Exists(pluginDir)) { @@ -92,10 +93,17 @@ namespace IW4MAdmin.Application.Misc .Where(_assemblyType => _assemblyType.IsClass && _assemblyType.BaseType == typeof(Command)); _logger.LogDebug("Discovered {count} plugin commands", commandTypes.Count()); + + configurationTypes = assemblies + .SelectMany(asm => asm.GetTypes()) + .Where(asmType => + asmType.IsClass && asmType.GetInterface(nameof(IBaseConfiguration), false) != null); + + _logger.LogDebug("Discovered {count} configuration implementations", configurationTypes.Count()); } } - return (pluginTypes, commandTypes); + return (pluginTypes, commandTypes, configurationTypes); } private IEnumerable GetRemoteAssemblies() diff --git a/Application/Misc/ScriptCommand.cs b/Application/Misc/ScriptCommand.cs index b4fe43a1..26d756e0 100644 --- a/Application/Misc/ScriptCommand.cs +++ b/Application/Misc/ScriptCommand.cs @@ -4,6 +4,7 @@ using SharedLibraryCore.Configuration; using SharedLibraryCore.Interfaces; using System; using System.Threading.Tasks; +using Data.Models.Client; using Microsoft.Extensions.Logging; using static SharedLibraryCore.Database.Models.EFClient; using ILogger = Microsoft.Extensions.Logging.ILogger; @@ -18,7 +19,7 @@ namespace IW4MAdmin.Application.Misc private readonly Action _executeAction; private readonly ILogger _logger; - public ScriptCommand(string name, string alias, string description, bool isTargetRequired, Permission permission, + public ScriptCommand(string name, string alias, string description, bool isTargetRequired, EFClient.Permission permission, CommandArgument[] args, Action executeAction, CommandConfiguration config, ITranslationLookup layout, ILogger logger) : base(config, layout) { diff --git a/Application/Misc/SerializationHelpers.cs b/Application/Misc/SerializationHelpers.cs index d2753daf..bfb7e0b9 100644 --- a/Application/Misc/SerializationHelpers.cs +++ b/Application/Misc/SerializationHelpers.cs @@ -4,6 +4,7 @@ using SharedLibraryCore; using SharedLibraryCore.Database.Models; using System; using System.Net; +using Data.Models; using static SharedLibraryCore.Database.Models.EFClient; using static SharedLibraryCore.GameEvent; diff --git a/Application/RconParsers/BaseRConParser.cs b/Application/RconParsers/BaseRConParser.cs index 45b763c9..da5c3bad 100644 --- a/Application/RconParsers/BaseRConParser.cs +++ b/Application/RconParsers/BaseRConParser.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; +using Data.Models; using Microsoft.Extensions.Logging; using static SharedLibraryCore.Server; using ILogger = Microsoft.Extensions.Logging.ILogger; diff --git a/Data/Abstractions/IDataValueCache.cs b/Data/Abstractions/IDataValueCache.cs new file mode 100644 index 00000000..a76bd28f --- /dev/null +++ b/Data/Abstractions/IDataValueCache.cs @@ -0,0 +1,12 @@ +using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; + +namespace Data.Abstractions +{ + public interface IDataValueCache where T : class + { + void SetCacheItem(Func, Task> itemGetter, string keyName, TimeSpan? expirationTime = null); + Task GetCacheItem(string keyName); + } +} \ No newline at end of file diff --git a/SharedLibraryCore/Interfaces/IDatabaseContextFactory.cs b/Data/Abstractions/IDatabaseContextFactory.cs similarity index 86% rename from SharedLibraryCore/Interfaces/IDatabaseContextFactory.cs rename to Data/Abstractions/IDatabaseContextFactory.cs index 179f4afb..cd455c14 100644 --- a/SharedLibraryCore/Interfaces/IDatabaseContextFactory.cs +++ b/Data/Abstractions/IDatabaseContextFactory.cs @@ -1,6 +1,6 @@ -using SharedLibraryCore.Database; +using Data.Context; -namespace SharedLibraryCore.Interfaces +namespace Data.Abstractions { /// /// describes the capabilities of the database context factory diff --git a/Data/Abstractions/ILookupCache.cs b/Data/Abstractions/ILookupCache.cs new file mode 100644 index 00000000..70b27572 --- /dev/null +++ b/Data/Abstractions/ILookupCache.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Data.Abstractions +{ + public interface ILookupCache where T : class + { + Task InitializeAsync(); + Task AddAsync(T item); + Task FirstAsync(Func query); + IEnumerable GetAll(); + } +} diff --git a/SharedLibraryCore/Interfaces/IPropertyExtender.cs b/Data/Abstractions/IPropertyExtender.cs similarity index 94% rename from SharedLibraryCore/Interfaces/IPropertyExtender.cs rename to Data/Abstractions/IPropertyExtender.cs index 7ca1df8c..33275498 100644 --- a/SharedLibraryCore/Interfaces/IPropertyExtender.cs +++ b/Data/Abstractions/IPropertyExtender.cs @@ -1,4 +1,4 @@ -namespace SharedLibraryCore.Interfaces +namespace Data.Abstractions { /// /// describes the capability of extending properties by name diff --git a/Data/Abstractions/IUniqueId.cs b/Data/Abstractions/IUniqueId.cs new file mode 100644 index 00000000..65b73fb6 --- /dev/null +++ b/Data/Abstractions/IUniqueId.cs @@ -0,0 +1,13 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace Data.Abstractions +{ + public interface IUniqueId + { + [NotMapped] + long Id { get; } + + [NotMapped] + string Value { get; } + } +} diff --git a/SharedLibraryCore/Database/ContextSeed.cs b/Data/Context/ContextSeed.cs similarity index 82% rename from SharedLibraryCore/Database/ContextSeed.cs rename to Data/Context/ContextSeed.cs index 770230fb..c9acf06f 100644 --- a/SharedLibraryCore/Database/ContextSeed.cs +++ b/Data/Context/ContextSeed.cs @@ -1,13 +1,12 @@ -using Microsoft.EntityFrameworkCore; -using SharedLibraryCore.Database.Models; -using System; -using System.Linq; +using System; using System.Threading; using System.Threading.Tasks; -using SharedLibraryCore.Interfaces; -using static SharedLibraryCore.Database.Models.EFClient; +using Data.Abstractions; +using Data.Models; +using Data.Models.Client; +using Microsoft.EntityFrameworkCore; -namespace SharedLibraryCore.Database +namespace Data.Context { public static class ContextSeed { @@ -30,7 +29,7 @@ namespace SharedLibraryCore.Database Connections = 0, FirstConnection = DateTime.UtcNow, LastConnection = DateTime.UtcNow, - Level = Permission.Console, + Level = EFClient.Permission.Console, Masked = true, NetworkId = 0, AliasLink = link, diff --git a/Data/Context/DatabaseContext.cs b/Data/Context/DatabaseContext.cs new file mode 100644 index 00000000..041912ed --- /dev/null +++ b/Data/Context/DatabaseContext.cs @@ -0,0 +1,135 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Threading; +using System.Threading.Tasks; +using Data.Extensions; +using Data.Models; +using Data.Models.Client; +using Data.Models.Client.Stats; +using Data.Models.Client.Stats.Reference; +using Data.Models.Server; + +namespace Data.Context +{ + public abstract class DatabaseContext : DbContext + { + public DbSet Clients { get; set; } + public DbSet Aliases { get; set; } + public DbSet AliasLinks { get; set; } + public DbSet Penalties { get; set; } + public DbSet EFMeta { get; set; } + public DbSet EFChangeHistory { get; set; } + + #region STATS + + public DbSet Vector3s { get; set; } + public DbSet SnapshotVector3s { get; set; } + public DbSet ACSnapshots { get; set; } + public DbSet Servers { get; set; } + public DbSet ClientKills { get; set; } + public DbSet ClientMessages { get; set; } + + public DbSet ServerStatistics { get; set; } + public DbSet HitLocations { get; set; } + public DbSet HitStatistics { get; set; } + public DbSet Weapons { get; set; } + public DbSet WeaponAttachments { get; set; } + public DbSet Maps { get; set; } + + #endregion + + private void SetAuditColumns() + { + return; + } + + public DatabaseContext() + { + if (!MigrationExtensions.IsMigration) + { + throw new InvalidOperationException(); + } + } + + public DatabaseContext(DbContextOptions options) : base(options) + { + } + + protected DatabaseContext(DbContextOptions options) : base(options) + { + } + + public override Task SaveChangesAsync(bool acceptAllChangesOnSuccess, + CancellationToken cancellationToken = default) + { + SetAuditColumns(); + return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken); + } + + public override int SaveChanges() + { + SetAuditColumns(); + return base.SaveChanges(); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + // make network id unique + modelBuilder.Entity(entity => { entity.HasIndex(e => e.NetworkId).IsUnique(); }); + + modelBuilder.Entity(entity => + { + entity.HasOne(p => p.Offender) + .WithMany(c => c.ReceivedPenalties) + .HasForeignKey(c => c.OffenderId) + .OnDelete(DeleteBehavior.Restrict); + + entity.HasOne(p => p.Punisher) + .WithMany(p => p.AdministeredPenalties) + .HasForeignKey(c => c.PunisherId) + .OnDelete(DeleteBehavior.Restrict); + + entity.Property(p => p.Expires) + .IsRequired(false); + }); + + modelBuilder.Entity(entity => + { + entity.HasMany(e => e.Children) + .WithOne(a => a.Link) + .HasForeignKey(k => k.LinkId) + .OnDelete(DeleteBehavior.Restrict); + }); + + modelBuilder.Entity(ent => + { + ent.Property(a => a.IPAddress).IsRequired(false); + ent.HasIndex(a => a.IPAddress); + ent.Property(a => a.Name).HasMaxLength(24); + ent.HasIndex(a => a.Name); + ent.Property(_alias => _alias.SearchableName).HasMaxLength(24); + ent.HasIndex(_alias => _alias.SearchableName); + ent.HasIndex(_alias => new {_alias.Name, _alias.IPAddress}).IsUnique(); + }); + + modelBuilder.Entity(ent => + { + ent.HasIndex(_meta => _meta.Key); + ent.HasIndex(_meta => _meta.LinkedMetaId); + ent.HasOne(_meta => _meta.LinkedMeta) + .WithMany() + .OnDelete(DeleteBehavior.SetNull); + }); + + // force full name for database conversion + modelBuilder.Entity().ToTable("EFClients"); + modelBuilder.Entity().ToTable("EFAlias"); + modelBuilder.Entity().ToTable("EFAliasLinks"); + modelBuilder.Entity().ToTable("EFPenalties"); + + Models.Configuration.StatsModelConfiguration.Configure(modelBuilder); + + base.OnModelCreating(modelBuilder); + } + } +} \ No newline at end of file diff --git a/Data/Data.csproj b/Data/Data.csproj new file mode 100644 index 00000000..671d685a --- /dev/null +++ b/Data/Data.csproj @@ -0,0 +1,82 @@ + + + + netcoreapp3.1 + Debug;Release;Prerelease + AnyCPU + true + RaidMax.IW4MAdmin.Data + RaidMax.IW4MAdmin.Data + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles + + + + + + + + + + + + diff --git a/Data/Extensions/Extensions.cs b/Data/Extensions/Extensions.cs new file mode 100644 index 00000000..0ca9d9fd --- /dev/null +++ b/Data/Extensions/Extensions.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; + +namespace Data.Extensions +{ + public static class MigrationExtensions + { + public static bool IsMigration => Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Migration"; + } +} \ No newline at end of file diff --git a/Data/Helpers/DataValueCache.cs b/Data/Helpers/DataValueCache.cs new file mode 100644 index 00000000..f6ac8937 --- /dev/null +++ b/Data/Helpers/DataValueCache.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Data.Abstractions; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; + +namespace Data.Helpers +{ + public class DataValueCache : IDataValueCache where T : class + { + private readonly ILogger _logger; + private readonly IDatabaseContextFactory _contextFactory; + private readonly Dictionary _cacheStates = new Dictionary(); + private const int DefaultExpireMinutes = 15; + + private class CacheState + { + public string Key { get; set; } + public DateTime LastRetrieval { get; set; } + public TimeSpan ExpirationTime { get; set; } + public Func, Task> Getter { get; set; } + public V Value { get; set; } + public bool IsExpired => (DateTime.Now - LastRetrieval.Add(ExpirationTime)).TotalSeconds > 0; + } + + public DataValueCache(ILogger> logger, IDatabaseContextFactory contextFactory) + { + _logger = logger; + _contextFactory = contextFactory; + } + + public void SetCacheItem(Func, Task> getter, string key, TimeSpan? expirationTime = null) + { + if (_cacheStates.ContainsKey(key)) + { + _logger.LogDebug("Cache key {key} is already added", key); + return; + } + + var state = new CacheState() + { + Key = key, + Getter = getter, + ExpirationTime = expirationTime ?? TimeSpan.FromMinutes(DefaultExpireMinutes) + }; + + _cacheStates.Add(key, state); + } + + public async Task GetCacheItem(string keyName) + { + if (!_cacheStates.ContainsKey(keyName)) + { + throw new ArgumentException("No cache found for key {key}", keyName); + } + + var state = _cacheStates[keyName]; + + if (state.IsExpired) + { + await RunCacheUpdate(state); + } + + return state.Value; + } + + private async Task RunCacheUpdate(CacheState state) + { + try + { + await using var context = _contextFactory.CreateContext(false); + var set = context.Set(); + var value = await state.Getter(set); + state.Value = value; + state.LastRetrieval = DateTime.Now; + } + catch (Exception ex) + { + _logger.LogError(ex, "Could not get cached value for {key}", state.Key); + } + } + } +} \ No newline at end of file diff --git a/Data/Helpers/LookupCache.cs b/Data/Helpers/LookupCache.cs new file mode 100644 index 00000000..fd45b8bc --- /dev/null +++ b/Data/Helpers/LookupCache.cs @@ -0,0 +1,114 @@ +using Data.Abstractions; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using ILogger = Microsoft.Extensions.Logging.ILogger; + +namespace Data.Helpers +{ + public class LookupCache : ILookupCache where T : class, IUniqueId + { + private readonly ILogger _logger; + private readonly IDatabaseContextFactory _contextFactory; + private Dictionary _cachedItems; + private readonly SemaphoreSlim _onOperation = new SemaphoreSlim(1, 1); + + public LookupCache(ILogger> logger, IDatabaseContextFactory contextFactory) + { + _logger = logger; + _contextFactory = contextFactory; + } + + public async Task AddAsync(T item) + { + await _onOperation.WaitAsync(); + T existingItem = null; + + if (_cachedItems.ContainsKey(item.Id)) + { + existingItem = _cachedItems[item.Id]; + } + + if (existingItem != null) + { + _logger.LogDebug("Cached item already added for {type} {id} {value}", typeof(T).Name, item.Id, + item.Value); + _onOperation.Release(); + return existingItem; + } + + try + { + _logger.LogDebug("Adding new {type} with {id} {value}", typeof(T).Name, item.Id, item.Value); + await using var context = _contextFactory.CreateContext(); + context.Set().Add(item); + await context.SaveChangesAsync(); + _cachedItems.Add(item.Id, item); + return item; + } + catch (Exception ex) + { + _logger.LogError(ex, "Could not add item to cache for {type}", typeof(T).Name); + throw new Exception("Could not add item to cache"); + } + finally + { + if (_onOperation.CurrentCount == 0) + { + _onOperation.Release(); + } + } + } + + public async Task FirstAsync(Func query) + { + await _onOperation.WaitAsync(); + + try + { + var cachedResult = _cachedItems.Values.Where(query); + + if (cachedResult.Any()) + { + return cachedResult.FirstOrDefault(); + } + } + + catch + { + } + + finally + { + if (_onOperation.CurrentCount == 0) + { + _onOperation.Release(1); + } + } + + return null; + } + + public IEnumerable GetAll() + { + return _cachedItems.Values; + } + + public async Task InitializeAsync() + { + try + { + await using var context = _contextFactory.CreateContext(); + _cachedItems = await context.Set().ToDictionaryAsync(item => item.Id); + } + catch (Exception ex) + { + _logger.LogError(ex, "Could not initialize caching for {cacheType}", typeof(T).Name); + } + } + } +} \ No newline at end of file diff --git a/SharedLibraryCore/Database/MigrationContext/MySqlDatabaseContext.cs b/Data/MigrationContext/MySqlDatabaseContext.cs similarity index 80% rename from SharedLibraryCore/Database/MigrationContext/MySqlDatabaseContext.cs rename to Data/MigrationContext/MySqlDatabaseContext.cs index 88fd9cef..785869c8 100644 --- a/SharedLibraryCore/Database/MigrationContext/MySqlDatabaseContext.cs +++ b/Data/MigrationContext/MySqlDatabaseContext.cs @@ -1,13 +1,15 @@ using System; +using Data.Context; +using Data.Extensions; using Microsoft.EntityFrameworkCore; -namespace SharedLibraryCore.Database.MigrationContext +namespace Data.MigrationContext { public class MySqlDatabaseContext : DatabaseContext { public MySqlDatabaseContext() { - if (!Utilities.IsMigration) + if (!MigrationExtensions.IsMigration) { throw new InvalidOperationException(); } @@ -20,7 +22,7 @@ namespace SharedLibraryCore.Database.MigrationContext protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - if (Utilities.IsMigration) + if (MigrationExtensions.IsMigration) { optionsBuilder.UseMySql("Server=127.0.0.1;Database=IW4MAdmin_Migration;Uid=root;Pwd=password;") .EnableDetailedErrors(true) diff --git a/SharedLibraryCore/Database/MigrationContext/PostgresqlDatabaseContext.cs b/Data/MigrationContext/PostgresqlDatabaseContext.cs similarity index 70% rename from SharedLibraryCore/Database/MigrationContext/PostgresqlDatabaseContext.cs rename to Data/MigrationContext/PostgresqlDatabaseContext.cs index cf6c57b8..d3df902e 100644 --- a/SharedLibraryCore/Database/MigrationContext/PostgresqlDatabaseContext.cs +++ b/Data/MigrationContext/PostgresqlDatabaseContext.cs @@ -1,33 +1,34 @@ using System; +using Data.Context; +using Data.Extensions; using Microsoft.EntityFrameworkCore; -namespace SharedLibraryCore.Database.MigrationContext +namespace Data.MigrationContext { public class PostgresqlDatabaseContext : DatabaseContext { public PostgresqlDatabaseContext() { - if (!Utilities.IsMigration) + if (!MigrationExtensions.IsMigration) { throw new InvalidOperationException(); } } - + public PostgresqlDatabaseContext(DbContextOptions options) : base(options) { - } - + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - if (Utilities.IsMigration) + if (MigrationExtensions.IsMigration) { optionsBuilder.UseNpgsql( - "Host=127.0.0.1;Database=IW4MAdmin_Migration;Username=postgres;Password=password;") + "Host=127.0.0.1;Database=IW4MAdmin_Migration;Username=postgres;Password=password;", + options => options.SetPostgresVersion(new Version("9.4"))) .EnableDetailedErrors(true) .EnableSensitiveDataLogging(true); } } - } } \ No newline at end of file diff --git a/SharedLibraryCore/Database/MigrationContext/SqliteDatabaseContext.cs b/Data/MigrationContext/SqliteDatabaseContext.cs similarity index 80% rename from SharedLibraryCore/Database/MigrationContext/SqliteDatabaseContext.cs rename to Data/MigrationContext/SqliteDatabaseContext.cs index 89a8274c..22421a7e 100644 --- a/SharedLibraryCore/Database/MigrationContext/SqliteDatabaseContext.cs +++ b/Data/MigrationContext/SqliteDatabaseContext.cs @@ -1,13 +1,15 @@ using System; +using Data.Context; +using Data.Extensions; using Microsoft.EntityFrameworkCore; -namespace SharedLibraryCore.Database.MigrationContext +namespace Data.MigrationContext { public class SqliteDatabaseContext : DatabaseContext { public SqliteDatabaseContext() { - if (!Utilities.IsMigration) + if (!MigrationExtensions.IsMigration) { throw new InvalidOperationException(); } @@ -20,7 +22,7 @@ namespace SharedLibraryCore.Database.MigrationContext protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - if (Utilities.IsMigration) + if (MigrationExtensions.IsMigration) { optionsBuilder.UseSqlite("Data Source=IW4MAdmin_Migration.db") .EnableDetailedErrors(true) diff --git a/SharedLibraryCore/Migrations/MySql/20180409183408_InitialCreate.Designer.cs b/Data/Migrations/MySql/20180409183408_InitialCreate.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180409183408_InitialCreate.Designer.cs rename to Data/Migrations/MySql/20180409183408_InitialCreate.Designer.cs index 686e0fb5..72836bff 100644 --- a/SharedLibraryCore/Migrations/MySql/20180409183408_InitialCreate.Designer.cs +++ b/Data/Migrations/MySql/20180409183408_InitialCreate.Designer.cs @@ -5,11 +5,11 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database; -using SharedLibraryCore.Database.MigrationContext; +using Data; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180409183408_InitialCreate")] diff --git a/SharedLibraryCore/Migrations/MySql/20180409183408_InitialCreate.cs b/Data/Migrations/MySql/20180409183408_InitialCreate.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180409183408_InitialCreate.cs rename to Data/Migrations/MySql/20180409183408_InitialCreate.cs index 32e488c7..4e4ec530 100644 --- a/SharedLibraryCore/Migrations/MySql/20180409183408_InitialCreate.cs +++ b/Data/Migrations/MySql/20180409183408_InitialCreate.cs @@ -4,7 +4,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class InitialCreate : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180502195450_Update.Designer.cs b/Data/Migrations/MySql/20180502195450_Update.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180502195450_Update.Designer.cs rename to Data/Migrations/MySql/20180502195450_Update.Designer.cs index 576eeed1..200a84a1 100644 --- a/SharedLibraryCore/Migrations/MySql/20180502195450_Update.Designer.cs +++ b/Data/Migrations/MySql/20180502195450_Update.Designer.cs @@ -5,11 +5,11 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database; -using SharedLibraryCore.Database.MigrationContext; +using Data; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180502195450_Update")] diff --git a/SharedLibraryCore/Migrations/MySql/20180502195450_Update.cs b/Data/Migrations/MySql/20180502195450_Update.cs similarity index 95% rename from SharedLibraryCore/Migrations/MySql/20180502195450_Update.cs rename to Data/Migrations/MySql/20180502195450_Update.cs index fc7795f5..f331a64d 100644 --- a/SharedLibraryCore/Migrations/MySql/20180502195450_Update.cs +++ b/Data/Migrations/MySql/20180502195450_Update.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class Update : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180516023249_AddEloField.Designer.cs b/Data/Migrations/MySql/20180516023249_AddEloField.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180516023249_AddEloField.Designer.cs rename to Data/Migrations/MySql/20180516023249_AddEloField.Designer.cs index 7cda630b..95b08e7b 100644 --- a/SharedLibraryCore/Migrations/MySql/20180516023249_AddEloField.Designer.cs +++ b/Data/Migrations/MySql/20180516023249_AddEloField.Designer.cs @@ -5,11 +5,11 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database; -using SharedLibraryCore.Database.MigrationContext; +using Data; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180516023249_AddEloField")] diff --git a/SharedLibraryCore/Migrations/MySql/20180516023249_AddEloField.cs b/Data/Migrations/MySql/20180516023249_AddEloField.cs similarity index 93% rename from SharedLibraryCore/Migrations/MySql/20180516023249_AddEloField.cs rename to Data/Migrations/MySql/20180516023249_AddEloField.cs index ccf1b51e..0412f35d 100644 --- a/SharedLibraryCore/Migrations/MySql/20180516023249_AddEloField.cs +++ b/Data/Migrations/MySql/20180516023249_AddEloField.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddEloField : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180517223349_AddRollingKDR.Designer.cs b/Data/Migrations/MySql/20180517223349_AddRollingKDR.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180517223349_AddRollingKDR.Designer.cs rename to Data/Migrations/MySql/20180517223349_AddRollingKDR.Designer.cs index 0e6991cf..ac6e8758 100644 --- a/SharedLibraryCore/Migrations/MySql/20180517223349_AddRollingKDR.Designer.cs +++ b/Data/Migrations/MySql/20180517223349_AddRollingKDR.Designer.cs @@ -5,11 +5,11 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database; -using SharedLibraryCore.Database.MigrationContext; +using Data; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180517223349_AddRollingKDR")] diff --git a/SharedLibraryCore/Migrations/MySql/20180517223349_AddRollingKDR.cs b/Data/Migrations/MySql/20180517223349_AddRollingKDR.cs similarity index 93% rename from SharedLibraryCore/Migrations/MySql/20180517223349_AddRollingKDR.cs rename to Data/Migrations/MySql/20180517223349_AddRollingKDR.cs index 638a2743..5fe056cd 100644 --- a/SharedLibraryCore/Migrations/MySql/20180517223349_AddRollingKDR.cs +++ b/Data/Migrations/MySql/20180517223349_AddRollingKDR.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddRollingKDR : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs b/Data/Migrations/MySql/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs rename to Data/Migrations/MySql/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs index 442b7098..61813c53 100644 --- a/SharedLibraryCore/Migrations/MySql/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs +++ b/Data/Migrations/MySql/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs @@ -5,10 +5,10 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180531212903_AddAutomatedOffenseAndRatingHistory")] diff --git a/SharedLibraryCore/Migrations/MySql/20180531212903_AddAutomatedOffenseAndRatingHistory.cs b/Data/Migrations/MySql/20180531212903_AddAutomatedOffenseAndRatingHistory.cs similarity index 98% rename from SharedLibraryCore/Migrations/MySql/20180531212903_AddAutomatedOffenseAndRatingHistory.cs rename to Data/Migrations/MySql/20180531212903_AddAutomatedOffenseAndRatingHistory.cs index b497989a..d83629a3 100644 --- a/SharedLibraryCore/Migrations/MySql/20180531212903_AddAutomatedOffenseAndRatingHistory.cs +++ b/Data/Migrations/MySql/20180531212903_AddAutomatedOffenseAndRatingHistory.cs @@ -4,7 +4,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddAutomatedOffenseAndRatingHistory : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180601172317_AddActivityAmount.Designer.cs b/Data/Migrations/MySql/20180601172317_AddActivityAmount.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180601172317_AddActivityAmount.Designer.cs rename to Data/Migrations/MySql/20180601172317_AddActivityAmount.Designer.cs index 0e4bdd5b..103fa6b6 100644 --- a/SharedLibraryCore/Migrations/MySql/20180601172317_AddActivityAmount.Designer.cs +++ b/Data/Migrations/MySql/20180601172317_AddActivityAmount.Designer.cs @@ -5,10 +5,10 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180601172317_AddActivityAmount")] diff --git a/SharedLibraryCore/Migrations/MySql/20180601172317_AddActivityAmount.cs b/Data/Migrations/MySql/20180601172317_AddActivityAmount.cs similarity index 93% rename from SharedLibraryCore/Migrations/MySql/20180601172317_AddActivityAmount.cs rename to Data/Migrations/MySql/20180601172317_AddActivityAmount.cs index a8ff56ff..82dade0a 100644 --- a/SharedLibraryCore/Migrations/MySql/20180601172317_AddActivityAmount.cs +++ b/Data/Migrations/MySql/20180601172317_AddActivityAmount.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddActivityAmount : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180602041758_AddClientMeta.Designer.cs b/Data/Migrations/MySql/20180602041758_AddClientMeta.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180602041758_AddClientMeta.Designer.cs rename to Data/Migrations/MySql/20180602041758_AddClientMeta.Designer.cs index 66dc5702..13a91e90 100644 --- a/SharedLibraryCore/Migrations/MySql/20180602041758_AddClientMeta.Designer.cs +++ b/Data/Migrations/MySql/20180602041758_AddClientMeta.Designer.cs @@ -5,10 +5,10 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180602041758_AddClientMeta")] diff --git a/SharedLibraryCore/Migrations/MySql/20180602041758_AddClientMeta.cs b/Data/Migrations/MySql/20180602041758_AddClientMeta.cs similarity index 97% rename from SharedLibraryCore/Migrations/MySql/20180602041758_AddClientMeta.cs rename to Data/Migrations/MySql/20180602041758_AddClientMeta.cs index 9566c210..54e510e2 100644 --- a/SharedLibraryCore/Migrations/MySql/20180602041758_AddClientMeta.cs +++ b/Data/Migrations/MySql/20180602041758_AddClientMeta.cs @@ -4,7 +4,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddClientMeta : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180605191706_AddEFACSnapshots.Designer.cs b/Data/Migrations/MySql/20180605191706_AddEFACSnapshots.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180605191706_AddEFACSnapshots.Designer.cs rename to Data/Migrations/MySql/20180605191706_AddEFACSnapshots.Designer.cs index 7d586f1b..ac4de91f 100644 --- a/SharedLibraryCore/Migrations/MySql/20180605191706_AddEFACSnapshots.Designer.cs +++ b/Data/Migrations/MySql/20180605191706_AddEFACSnapshots.Designer.cs @@ -5,10 +5,10 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180605191706_AddEFACSnapshots")] diff --git a/SharedLibraryCore/Migrations/MySql/20180605191706_AddEFACSnapshots.cs b/Data/Migrations/MySql/20180605191706_AddEFACSnapshots.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180605191706_AddEFACSnapshots.cs rename to Data/Migrations/MySql/20180605191706_AddEFACSnapshots.cs index e6c7e721..6011345d 100644 --- a/SharedLibraryCore/Migrations/MySql/20180605191706_AddEFACSnapshots.cs +++ b/Data/Migrations/MySql/20180605191706_AddEFACSnapshots.cs @@ -4,7 +4,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddEFACSnapshots : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180614014303_IndexForEFAlias.Designer.cs b/Data/Migrations/MySql/20180614014303_IndexForEFAlias.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180614014303_IndexForEFAlias.Designer.cs rename to Data/Migrations/MySql/20180614014303_IndexForEFAlias.Designer.cs index 24cee69e..cfbd70c5 100644 --- a/SharedLibraryCore/Migrations/MySql/20180614014303_IndexForEFAlias.Designer.cs +++ b/Data/Migrations/MySql/20180614014303_IndexForEFAlias.Designer.cs @@ -5,10 +5,10 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180614014303_IndexForEFAlias")] diff --git a/SharedLibraryCore/Migrations/MySql/20180614014303_IndexForEFAlias.cs b/Data/Migrations/MySql/20180614014303_IndexForEFAlias.cs similarity index 93% rename from SharedLibraryCore/Migrations/MySql/20180614014303_IndexForEFAlias.cs rename to Data/Migrations/MySql/20180614014303_IndexForEFAlias.cs index 4137b988..95fe7acd 100644 --- a/SharedLibraryCore/Migrations/MySql/20180614014303_IndexForEFAlias.cs +++ b/Data/Migrations/MySql/20180614014303_IndexForEFAlias.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class IndexForEFAlias : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180902035612_AddFractionAndIsKill.Designer.cs b/Data/Migrations/MySql/20180902035612_AddFractionAndIsKill.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180902035612_AddFractionAndIsKill.Designer.cs rename to Data/Migrations/MySql/20180902035612_AddFractionAndIsKill.Designer.cs index 76646c90..cb2f8150 100644 --- a/SharedLibraryCore/Migrations/MySql/20180902035612_AddFractionAndIsKill.Designer.cs +++ b/Data/Migrations/MySql/20180902035612_AddFractionAndIsKill.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180902035612_AddFractionAndIsKill")] diff --git a/SharedLibraryCore/Migrations/MySql/20180902035612_AddFractionAndIsKill.cs b/Data/Migrations/MySql/20180902035612_AddFractionAndIsKill.cs similarity index 98% rename from SharedLibraryCore/Migrations/MySql/20180902035612_AddFractionAndIsKill.cs rename to Data/Migrations/MySql/20180902035612_AddFractionAndIsKill.cs index 529a79c4..7c3e2034 100644 --- a/SharedLibraryCore/Migrations/MySql/20180902035612_AddFractionAndIsKill.cs +++ b/Data/Migrations/MySql/20180902035612_AddFractionAndIsKill.cs @@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddFractionAndIsKill : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180904154622_AddVisibilityPercentage.Designer.cs b/Data/Migrations/MySql/20180904154622_AddVisibilityPercentage.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180904154622_AddVisibilityPercentage.Designer.cs rename to Data/Migrations/MySql/20180904154622_AddVisibilityPercentage.Designer.cs index b9ec66ff..94bd439c 100644 --- a/SharedLibraryCore/Migrations/MySql/20180904154622_AddVisibilityPercentage.Designer.cs +++ b/Data/Migrations/MySql/20180904154622_AddVisibilityPercentage.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180904154622_AddVisibilityPercentage")] diff --git a/SharedLibraryCore/Migrations/MySql/20180904154622_AddVisibilityPercentage.cs b/Data/Migrations/MySql/20180904154622_AddVisibilityPercentage.cs similarity index 93% rename from SharedLibraryCore/Migrations/MySql/20180904154622_AddVisibilityPercentage.cs rename to Data/Migrations/MySql/20180904154622_AddVisibilityPercentage.cs index d4a8132e..0cb44ec8 100644 --- a/SharedLibraryCore/Migrations/MySql/20180904154622_AddVisibilityPercentage.cs +++ b/Data/Migrations/MySql/20180904154622_AddVisibilityPercentage.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddVisibilityPercentage : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180907020706_AddVision.Designer.cs b/Data/Migrations/MySql/20180907020706_AddVision.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180907020706_AddVision.Designer.cs rename to Data/Migrations/MySql/20180907020706_AddVision.Designer.cs index ade98e4e..f8658f5a 100644 --- a/SharedLibraryCore/Migrations/MySql/20180907020706_AddVision.Designer.cs +++ b/Data/Migrations/MySql/20180907020706_AddVision.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180907020706_AddVision")] diff --git a/SharedLibraryCore/Migrations/MySql/20180907020706_AddVision.cs b/Data/Migrations/MySql/20180907020706_AddVision.cs similarity index 93% rename from SharedLibraryCore/Migrations/MySql/20180907020706_AddVision.cs rename to Data/Migrations/MySql/20180907020706_AddVision.cs index 8085963a..19bc5e3f 100644 --- a/SharedLibraryCore/Migrations/MySql/20180907020706_AddVision.cs +++ b/Data/Migrations/MySql/20180907020706_AddVision.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddVision : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180908004053_AddWhenToRating.Designer.cs b/Data/Migrations/MySql/20180908004053_AddWhenToRating.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180908004053_AddWhenToRating.Designer.cs rename to Data/Migrations/MySql/20180908004053_AddWhenToRating.Designer.cs index 2d700dce..6a4c0bb9 100644 --- a/SharedLibraryCore/Migrations/MySql/20180908004053_AddWhenToRating.Designer.cs +++ b/Data/Migrations/MySql/20180908004053_AddWhenToRating.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180908004053_AddWhenToRating")] diff --git a/SharedLibraryCore/Migrations/MySql/20180908004053_AddWhenToRating.cs b/Data/Migrations/MySql/20180908004053_AddWhenToRating.cs similarity index 93% rename from SharedLibraryCore/Migrations/MySql/20180908004053_AddWhenToRating.cs rename to Data/Migrations/MySql/20180908004053_AddWhenToRating.cs index 63e84cc3..59a98152 100644 --- a/SharedLibraryCore/Migrations/MySql/20180908004053_AddWhenToRating.cs +++ b/Data/Migrations/MySql/20180908004053_AddWhenToRating.cs @@ -1,7 +1,7 @@ using System; using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddWhenToRating : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180910221749_AddRatingIndexes.Designer.cs b/Data/Migrations/MySql/20180910221749_AddRatingIndexes.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180910221749_AddRatingIndexes.Designer.cs rename to Data/Migrations/MySql/20180910221749_AddRatingIndexes.Designer.cs index 15b4bd6d..f37f1321 100644 --- a/SharedLibraryCore/Migrations/MySql/20180910221749_AddRatingIndexes.Designer.cs +++ b/Data/Migrations/MySql/20180910221749_AddRatingIndexes.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180910221749_AddRatingIndexes")] diff --git a/SharedLibraryCore/Migrations/MySql/20180910221749_AddRatingIndexes.cs b/Data/Migrations/MySql/20180910221749_AddRatingIndexes.cs similarity index 96% rename from SharedLibraryCore/Migrations/MySql/20180910221749_AddRatingIndexes.cs rename to Data/Migrations/MySql/20180910221749_AddRatingIndexes.cs index fc26e0d7..f81d83dc 100644 --- a/SharedLibraryCore/Migrations/MySql/20180910221749_AddRatingIndexes.cs +++ b/Data/Migrations/MySql/20180910221749_AddRatingIndexes.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddRatingIndexes : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180911184224_AddEFAliasNameIndex.Designer.cs b/Data/Migrations/MySql/20180911184224_AddEFAliasNameIndex.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180911184224_AddEFAliasNameIndex.Designer.cs rename to Data/Migrations/MySql/20180911184224_AddEFAliasNameIndex.Designer.cs index e740317a..0d74c86a 100644 --- a/SharedLibraryCore/Migrations/MySql/20180911184224_AddEFAliasNameIndex.Designer.cs +++ b/Data/Migrations/MySql/20180911184224_AddEFAliasNameIndex.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180911184224_AddEFAliasNameIndex")] diff --git a/SharedLibraryCore/Migrations/MySql/20180911184224_AddEFAliasNameIndex.cs b/Data/Migrations/MySql/20180911184224_AddEFAliasNameIndex.cs similarity index 92% rename from SharedLibraryCore/Migrations/MySql/20180911184224_AddEFAliasNameIndex.cs rename to Data/Migrations/MySql/20180911184224_AddEFAliasNameIndex.cs index f810fc9f..7e62a4f0 100644 --- a/SharedLibraryCore/Migrations/MySql/20180911184224_AddEFAliasNameIndex.cs +++ b/Data/Migrations/MySql/20180911184224_AddEFAliasNameIndex.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddEFAliasNameIndex : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180911190823_AddEFAliasNameMaxLength24.Designer.cs b/Data/Migrations/MySql/20180911190823_AddEFAliasNameMaxLength24.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180911190823_AddEFAliasNameMaxLength24.Designer.cs rename to Data/Migrations/MySql/20180911190823_AddEFAliasNameMaxLength24.Designer.cs index 2c099c6e..6580d156 100644 --- a/SharedLibraryCore/Migrations/MySql/20180911190823_AddEFAliasNameMaxLength24.Designer.cs +++ b/Data/Migrations/MySql/20180911190823_AddEFAliasNameMaxLength24.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180911190823_AddEFAliasNameMaxLength24")] diff --git a/SharedLibraryCore/Migrations/MySql/20180911190823_AddEFAliasNameMaxLength24.cs b/Data/Migrations/MySql/20180911190823_AddEFAliasNameMaxLength24.cs similarity index 94% rename from SharedLibraryCore/Migrations/MySql/20180911190823_AddEFAliasNameMaxLength24.cs rename to Data/Migrations/MySql/20180911190823_AddEFAliasNameMaxLength24.cs index 7e03a909..0b281c63 100644 --- a/SharedLibraryCore/Migrations/MySql/20180911190823_AddEFAliasNameMaxLength24.cs +++ b/Data/Migrations/MySql/20180911190823_AddEFAliasNameMaxLength24.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddEFAliasNameMaxLength24 : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs b/Data/Migrations/MySql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs rename to Data/Migrations/MySql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs index 68be3dbe..5cc66330 100644 --- a/SharedLibraryCore/Migrations/MySql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs +++ b/Data/Migrations/MySql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180912015012_AddPreviousCurrentValueToEFChangeHistory")] diff --git a/SharedLibraryCore/Migrations/MySql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs b/Data/Migrations/MySql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs similarity index 95% rename from SharedLibraryCore/Migrations/MySql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs rename to Data/Migrations/MySql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs index a910959c..ee1aa976 100644 --- a/SharedLibraryCore/Migrations/MySql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs +++ b/Data/Migrations/MySql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddPreviousCurrentValueToEFChangeHistory : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180915163111_AddIndexToMessageTimeSent.Designer.cs b/Data/Migrations/MySql/20180915163111_AddIndexToMessageTimeSent.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180915163111_AddIndexToMessageTimeSent.Designer.cs rename to Data/Migrations/MySql/20180915163111_AddIndexToMessageTimeSent.Designer.cs index 27b20cb9..a4847787 100644 --- a/SharedLibraryCore/Migrations/MySql/20180915163111_AddIndexToMessageTimeSent.Designer.cs +++ b/Data/Migrations/MySql/20180915163111_AddIndexToMessageTimeSent.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180915163111_AddIndexToMessageTimeSent")] diff --git a/SharedLibraryCore/Migrations/MySql/20180915163111_AddIndexToMessageTimeSent.cs b/Data/Migrations/MySql/20180915163111_AddIndexToMessageTimeSent.cs similarity index 93% rename from SharedLibraryCore/Migrations/MySql/20180915163111_AddIndexToMessageTimeSent.cs rename to Data/Migrations/MySql/20180915163111_AddIndexToMessageTimeSent.cs index 18e39938..4baf71ce 100644 --- a/SharedLibraryCore/Migrations/MySql/20180915163111_AddIndexToMessageTimeSent.cs +++ b/Data/Migrations/MySql/20180915163111_AddIndexToMessageTimeSent.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddIndexToMessageTimeSent : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180922231310_RemoveACSnapShot.Designer.cs b/Data/Migrations/MySql/20180922231310_RemoveACSnapShot.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180922231310_RemoveACSnapShot.Designer.cs rename to Data/Migrations/MySql/20180922231310_RemoveACSnapShot.Designer.cs index f0cc690b..64f28ed5 100644 --- a/SharedLibraryCore/Migrations/MySql/20180922231310_RemoveACSnapShot.Designer.cs +++ b/Data/Migrations/MySql/20180922231310_RemoveACSnapShot.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180922231310_RemoveACSnapShot")] diff --git a/SharedLibraryCore/Migrations/MySql/20180922231310_RemoveACSnapShot.cs b/Data/Migrations/MySql/20180922231310_RemoveACSnapShot.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180922231310_RemoveACSnapShot.cs rename to Data/Migrations/MySql/20180922231310_RemoveACSnapShot.cs index d1804ad0..5e85477a 100644 --- a/SharedLibraryCore/Migrations/MySql/20180922231310_RemoveACSnapShot.cs +++ b/Data/Migrations/MySql/20180922231310_RemoveACSnapShot.cs @@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class RemoveACSnapShot : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20180922231600_ReaddACSnapshot.Designer.cs b/Data/Migrations/MySql/20180922231600_ReaddACSnapshot.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180922231600_ReaddACSnapshot.Designer.cs rename to Data/Migrations/MySql/20180922231600_ReaddACSnapshot.Designer.cs index acb00ec6..3dbc6574 100644 --- a/SharedLibraryCore/Migrations/MySql/20180922231600_ReaddACSnapshot.Designer.cs +++ b/Data/Migrations/MySql/20180922231600_ReaddACSnapshot.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20180922231600_ReaddACSnapshot")] diff --git a/SharedLibraryCore/Migrations/MySql/20180922231600_ReaddACSnapshot.cs b/Data/Migrations/MySql/20180922231600_ReaddACSnapshot.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20180922231600_ReaddACSnapshot.cs rename to Data/Migrations/MySql/20180922231600_ReaddACSnapshot.cs index da730312..ff9797dd 100644 --- a/SharedLibraryCore/Migrations/MySql/20180922231600_ReaddACSnapshot.cs +++ b/Data/Migrations/MySql/20180922231600_ReaddACSnapshot.cs @@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class ReaddACSnapshot : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20181014171848_MakePenaltyExpirationNullable.Designer.cs b/Data/Migrations/MySql/20181014171848_MakePenaltyExpirationNullable.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20181014171848_MakePenaltyExpirationNullable.Designer.cs rename to Data/Migrations/MySql/20181014171848_MakePenaltyExpirationNullable.Designer.cs index 387e3e69..eb274592 100644 --- a/SharedLibraryCore/Migrations/MySql/20181014171848_MakePenaltyExpirationNullable.Designer.cs +++ b/Data/Migrations/MySql/20181014171848_MakePenaltyExpirationNullable.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20181014171848_MakePenaltyExpirationNullable")] diff --git a/SharedLibraryCore/Migrations/MySql/20181014171848_MakePenaltyExpirationNullable.cs b/Data/Migrations/MySql/20181014171848_MakePenaltyExpirationNullable.cs similarity index 98% rename from SharedLibraryCore/Migrations/MySql/20181014171848_MakePenaltyExpirationNullable.cs rename to Data/Migrations/MySql/20181014171848_MakePenaltyExpirationNullable.cs index d1ab3570..8b007788 100644 --- a/SharedLibraryCore/Migrations/MySql/20181014171848_MakePenaltyExpirationNullable.cs +++ b/Data/Migrations/MySql/20181014171848_MakePenaltyExpirationNullable.cs @@ -1,7 +1,7 @@ using System; using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class MakePenaltyExpirationNullable : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20181125193243_MakeClientIPNullable.Designer.cs b/Data/Migrations/MySql/20181125193243_MakeClientIPNullable.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20181125193243_MakeClientIPNullable.Designer.cs rename to Data/Migrations/MySql/20181125193243_MakeClientIPNullable.Designer.cs index 62ca0ffb..5afe44ec 100644 --- a/SharedLibraryCore/Migrations/MySql/20181125193243_MakeClientIPNullable.Designer.cs +++ b/Data/Migrations/MySql/20181125193243_MakeClientIPNullable.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20181125193243_MakeClientIPNullable")] diff --git a/SharedLibraryCore/Migrations/MySql/20181125193243_MakeClientIPNullable.cs b/Data/Migrations/MySql/20181125193243_MakeClientIPNullable.cs similarity index 98% rename from SharedLibraryCore/Migrations/MySql/20181125193243_MakeClientIPNullable.cs rename to Data/Migrations/MySql/20181125193243_MakeClientIPNullable.cs index 8e858b04..60a3221b 100644 --- a/SharedLibraryCore/Migrations/MySql/20181125193243_MakeClientIPNullable.cs +++ b/Data/Migrations/MySql/20181125193243_MakeClientIPNullable.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class MakeClientIPNullable : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs b/Data/Migrations/MySql/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs rename to Data/Migrations/MySql/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs index f6a21ff9..d6b4d6ed 100644 --- a/SharedLibraryCore/Migrations/MySql/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs +++ b/Data/Migrations/MySql/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20181127144417_AddEndpointToEFServerUpdateServerIdType")] diff --git a/SharedLibraryCore/Migrations/MySql/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs b/Data/Migrations/MySql/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs similarity index 92% rename from SharedLibraryCore/Migrations/MySql/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs rename to Data/Migrations/MySql/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs index 52d1d831..a41c8a2d 100644 --- a/SharedLibraryCore/Migrations/MySql/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs +++ b/Data/Migrations/MySql/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddEndpointToEFServerUpdateServerIdType : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20181216214513_AddEvadePenaltyFlag.Designer.cs b/Data/Migrations/MySql/20181216214513_AddEvadePenaltyFlag.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20181216214513_AddEvadePenaltyFlag.Designer.cs rename to Data/Migrations/MySql/20181216214513_AddEvadePenaltyFlag.Designer.cs index 2f6186b8..44e2f1b7 100644 --- a/SharedLibraryCore/Migrations/MySql/20181216214513_AddEvadePenaltyFlag.Designer.cs +++ b/Data/Migrations/MySql/20181216214513_AddEvadePenaltyFlag.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20181216214513_AddEvadePenaltyFlag")] diff --git a/SharedLibraryCore/Migrations/MySql/20181216214513_AddEvadePenaltyFlag.cs b/Data/Migrations/MySql/20181216214513_AddEvadePenaltyFlag.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20181216214513_AddEvadePenaltyFlag.cs rename to Data/Migrations/MySql/20181216214513_AddEvadePenaltyFlag.cs index 0037aae5..a5913a04 100644 --- a/SharedLibraryCore/Migrations/MySql/20181216214513_AddEvadePenaltyFlag.cs +++ b/Data/Migrations/MySql/20181216214513_AddEvadePenaltyFlag.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddEvadePenaltyFlag : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs b/Data/Migrations/MySql/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs rename to Data/Migrations/MySql/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs index a114d3a9..06b12894 100644 --- a/SharedLibraryCore/Migrations/MySql/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs +++ b/Data/Migrations/MySql/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20190222234742_AddIndexToEFMeta-KeyAndClientId")] diff --git a/SharedLibraryCore/Migrations/MySql/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs b/Data/Migrations/MySql/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs similarity index 94% rename from SharedLibraryCore/Migrations/MySql/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs rename to Data/Migrations/MySql/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs index 3b9621cd..e5d1e9a9 100644 --- a/SharedLibraryCore/Migrations/MySql/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs +++ b/Data/Migrations/MySql/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddIndexToEFMetaKeyAndClientId : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20190423142128_AddGameNameToEFServer.Designer.cs b/Data/Migrations/MySql/20190423142128_AddGameNameToEFServer.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20190423142128_AddGameNameToEFServer.Designer.cs rename to Data/Migrations/MySql/20190423142128_AddGameNameToEFServer.Designer.cs index 0ff15914..eb142757 100644 --- a/SharedLibraryCore/Migrations/MySql/20190423142128_AddGameNameToEFServer.Designer.cs +++ b/Data/Migrations/MySql/20190423142128_AddGameNameToEFServer.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20190423142128_AddGameNameToEFServer")] diff --git a/SharedLibraryCore/Migrations/MySql/20190423142128_AddGameNameToEFServer.cs b/Data/Migrations/MySql/20190423142128_AddGameNameToEFServer.cs similarity index 92% rename from SharedLibraryCore/Migrations/MySql/20190423142128_AddGameNameToEFServer.cs rename to Data/Migrations/MySql/20190423142128_AddGameNameToEFServer.cs index 45b6a189..b5e1fe02 100644 --- a/SharedLibraryCore/Migrations/MySql/20190423142128_AddGameNameToEFServer.cs +++ b/Data/Migrations/MySql/20190423142128_AddGameNameToEFServer.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddGameNameToEFServer : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20190615145212_AddAvgRecoilOffset.Designer.cs b/Data/Migrations/MySql/20190615145212_AddAvgRecoilOffset.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20190615145212_AddAvgRecoilOffset.Designer.cs rename to Data/Migrations/MySql/20190615145212_AddAvgRecoilOffset.Designer.cs index 2023a061..a2af60ed 100644 --- a/SharedLibraryCore/Migrations/MySql/20190615145212_AddAvgRecoilOffset.Designer.cs +++ b/Data/Migrations/MySql/20190615145212_AddAvgRecoilOffset.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20190615145212_AddAvgRecoilOffset")] diff --git a/SharedLibraryCore/Migrations/MySql/20190615145212_AddAvgRecoilOffset.cs b/Data/Migrations/MySql/20190615145212_AddAvgRecoilOffset.cs similarity index 91% rename from SharedLibraryCore/Migrations/MySql/20190615145212_AddAvgRecoilOffset.cs rename to Data/Migrations/MySql/20190615145212_AddAvgRecoilOffset.cs index d74bfd95..7ddea78f 100644 --- a/SharedLibraryCore/Migrations/MySql/20190615145212_AddAvgRecoilOffset.cs +++ b/Data/Migrations/MySql/20190615145212_AddAvgRecoilOffset.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddAvgRecoilOffset : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs b/Data/Migrations/MySql/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs rename to Data/Migrations/MySql/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs index 25f0f3f3..694e823e 100644 --- a/SharedLibraryCore/Migrations/MySql/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs +++ b/Data/Migrations/MySql/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20190615214055_AddRecoilOffsetToSnapshot")] diff --git a/SharedLibraryCore/Migrations/MySql/20190615214055_AddRecoilOffsetToSnapshot.cs b/Data/Migrations/MySql/20190615214055_AddRecoilOffsetToSnapshot.cs similarity index 93% rename from SharedLibraryCore/Migrations/MySql/20190615214055_AddRecoilOffsetToSnapshot.cs rename to Data/Migrations/MySql/20190615214055_AddRecoilOffsetToSnapshot.cs index 481e74bd..44aa0fbd 100644 --- a/SharedLibraryCore/Migrations/MySql/20190615214055_AddRecoilOffsetToSnapshot.cs +++ b/Data/Migrations/MySql/20190615214055_AddRecoilOffsetToSnapshot.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddRecoilOffsetToSnapshot : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20190725000309_AlterEFRatingIndex.Designer.cs b/Data/Migrations/MySql/20190725000309_AlterEFRatingIndex.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20190725000309_AlterEFRatingIndex.Designer.cs rename to Data/Migrations/MySql/20190725000309_AlterEFRatingIndex.Designer.cs index d26ad7cf..4b1a6f97 100644 --- a/SharedLibraryCore/Migrations/MySql/20190725000309_AlterEFRatingIndex.Designer.cs +++ b/Data/Migrations/MySql/20190725000309_AlterEFRatingIndex.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20190725000309_AlterEFRatingIndex")] diff --git a/SharedLibraryCore/Migrations/MySql/20190725000309_AlterEFRatingIndex.cs b/Data/Migrations/MySql/20190725000309_AlterEFRatingIndex.cs similarity index 97% rename from SharedLibraryCore/Migrations/MySql/20190725000309_AlterEFRatingIndex.cs rename to Data/Migrations/MySql/20190725000309_AlterEFRatingIndex.cs index d198ee2d..994bcfc5 100644 --- a/SharedLibraryCore/Migrations/MySql/20190725000309_AlterEFRatingIndex.cs +++ b/Data/Migrations/MySql/20190725000309_AlterEFRatingIndex.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AlterEFRatingIndex : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20190802174908_AddSearchNameToEFAlias.Designer.cs b/Data/Migrations/MySql/20190802174908_AddSearchNameToEFAlias.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20190802174908_AddSearchNameToEFAlias.Designer.cs rename to Data/Migrations/MySql/20190802174908_AddSearchNameToEFAlias.Designer.cs index 2498fc41..55550d32 100644 --- a/SharedLibraryCore/Migrations/MySql/20190802174908_AddSearchNameToEFAlias.Designer.cs +++ b/Data/Migrations/MySql/20190802174908_AddSearchNameToEFAlias.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20190802174908_AddSearchNameToEFAlias")] diff --git a/SharedLibraryCore/Migrations/MySql/20190802174908_AddSearchNameToEFAlias.cs b/Data/Migrations/MySql/20190802174908_AddSearchNameToEFAlias.cs similarity index 95% rename from SharedLibraryCore/Migrations/MySql/20190802174908_AddSearchNameToEFAlias.cs rename to Data/Migrations/MySql/20190802174908_AddSearchNameToEFAlias.cs index 249713b6..6a2650cc 100644 --- a/SharedLibraryCore/Migrations/MySql/20190802174908_AddSearchNameToEFAlias.cs +++ b/Data/Migrations/MySql/20190802174908_AddSearchNameToEFAlias.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddSearchNameToEFAlias : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20190831210503_AvgSnapValueToClientStatistics.Designer.cs b/Data/Migrations/MySql/20190831210503_AvgSnapValueToClientStatistics.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20190831210503_AvgSnapValueToClientStatistics.Designer.cs rename to Data/Migrations/MySql/20190831210503_AvgSnapValueToClientStatistics.Designer.cs index ca976673..ad2c5382 100644 --- a/SharedLibraryCore/Migrations/MySql/20190831210503_AvgSnapValueToClientStatistics.Designer.cs +++ b/Data/Migrations/MySql/20190831210503_AvgSnapValueToClientStatistics.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20190831210503_AvgSnapValueToClientStatistics")] diff --git a/SharedLibraryCore/Migrations/MySql/20190831210503_AvgSnapValueToClientStatistics.cs b/Data/Migrations/MySql/20190831210503_AvgSnapValueToClientStatistics.cs similarity index 93% rename from SharedLibraryCore/Migrations/MySql/20190831210503_AvgSnapValueToClientStatistics.cs rename to Data/Migrations/MySql/20190831210503_AvgSnapValueToClientStatistics.cs index ddd0278a..0ac58e12 100644 --- a/SharedLibraryCore/Migrations/MySql/20190831210503_AvgSnapValueToClientStatistics.cs +++ b/Data/Migrations/MySql/20190831210503_AvgSnapValueToClientStatistics.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AvgSnapValueToClientStatistics : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs b/Data/Migrations/MySql/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs rename to Data/Migrations/MySql/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs index 46ca9d25..16cb66b7 100644 --- a/SharedLibraryCore/Migrations/MySql/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs +++ b/Data/Migrations/MySql/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20190901180209_AddSnapHitCountToClientStatistics")] diff --git a/SharedLibraryCore/Migrations/MySql/20190901180209_AddSnapHitCountToClientStatistics.cs b/Data/Migrations/MySql/20190901180209_AddSnapHitCountToClientStatistics.cs similarity index 93% rename from SharedLibraryCore/Migrations/MySql/20190901180209_AddSnapHitCountToClientStatistics.cs rename to Data/Migrations/MySql/20190901180209_AddSnapHitCountToClientStatistics.cs index 0b102af3..fd6258da 100644 --- a/SharedLibraryCore/Migrations/MySql/20190901180209_AddSnapHitCountToClientStatistics.cs +++ b/Data/Migrations/MySql/20190901180209_AddSnapHitCountToClientStatistics.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddSnapHitCountToClientStatistics : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs b/Data/Migrations/MySql/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs rename to Data/Migrations/MySql/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs index a16f5ed5..435383a4 100644 --- a/SharedLibraryCore/Migrations/MySql/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs +++ b/Data/Migrations/MySql/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20190901223620_UseJunctionTableForSnapshotVector3")] diff --git a/SharedLibraryCore/Migrations/MySql/20190901223620_UseJunctionTableForSnapshotVector3.cs b/Data/Migrations/MySql/20190901223620_UseJunctionTableForSnapshotVector3.cs similarity index 98% rename from SharedLibraryCore/Migrations/MySql/20190901223620_UseJunctionTableForSnapshotVector3.cs rename to Data/Migrations/MySql/20190901223620_UseJunctionTableForSnapshotVector3.cs index 82d20240..e256200b 100644 --- a/SharedLibraryCore/Migrations/MySql/20190901223620_UseJunctionTableForSnapshotVector3.cs +++ b/Data/Migrations/MySql/20190901223620_UseJunctionTableForSnapshotVector3.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class UseJunctionTableForSnapshotVector3 : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs b/Data/Migrations/MySql/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs rename to Data/Migrations/MySql/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs index 4f4d44ab..0c9a6fd9 100644 --- a/SharedLibraryCore/Migrations/MySql/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs +++ b/Data/Migrations/MySql/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20190914011524_AddCurrentSnapValueToSnapshot")] diff --git a/SharedLibraryCore/Migrations/MySql/20190914011524_AddCurrentSnapValueToSnapshot.cs b/Data/Migrations/MySql/20190914011524_AddCurrentSnapValueToSnapshot.cs similarity index 93% rename from SharedLibraryCore/Migrations/MySql/20190914011524_AddCurrentSnapValueToSnapshot.cs rename to Data/Migrations/MySql/20190914011524_AddCurrentSnapValueToSnapshot.cs index 9b225d5d..cd9755a8 100644 --- a/SharedLibraryCore/Migrations/MySql/20190914011524_AddCurrentSnapValueToSnapshot.cs +++ b/Data/Migrations/MySql/20190914011524_AddCurrentSnapValueToSnapshot.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddCurrentSnapValueToSnapshot : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs b/Data/Migrations/MySql/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs rename to Data/Migrations/MySql/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs index 97118961..3bbec379 100644 --- a/SharedLibraryCore/Migrations/MySql/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs +++ b/Data/Migrations/MySql/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20190914012015_AddSessionSnapHitsToSnapshot")] diff --git a/SharedLibraryCore/Migrations/MySql/20190914012015_AddSessionSnapHitsToSnapshot.cs b/Data/Migrations/MySql/20190914012015_AddSessionSnapHitsToSnapshot.cs similarity index 93% rename from SharedLibraryCore/Migrations/MySql/20190914012015_AddSessionSnapHitsToSnapshot.cs rename to Data/Migrations/MySql/20190914012015_AddSessionSnapHitsToSnapshot.cs index e4b2340b..45cbc9b7 100644 --- a/SharedLibraryCore/Migrations/MySql/20190914012015_AddSessionSnapHitsToSnapshot.cs +++ b/Data/Migrations/MySql/20190914012015_AddSessionSnapHitsToSnapshot.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddSessionSnapHitsToSnapshot : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20191004172550_RenameClientHitLocationCountColumns.Designer.cs b/Data/Migrations/MySql/20191004172550_RenameClientHitLocationCountColumns.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20191004172550_RenameClientHitLocationCountColumns.Designer.cs rename to Data/Migrations/MySql/20191004172550_RenameClientHitLocationCountColumns.Designer.cs index 91727ea7..a56222c6 100644 --- a/SharedLibraryCore/Migrations/MySql/20191004172550_RenameClientHitLocationCountColumns.Designer.cs +++ b/Data/Migrations/MySql/20191004172550_RenameClientHitLocationCountColumns.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20191004172550_RenameClientHitLocationCountColumns")] diff --git a/SharedLibraryCore/Migrations/MySql/20191004172550_RenameClientHitLocationCountColumns.cs b/Data/Migrations/MySql/20191004172550_RenameClientHitLocationCountColumns.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20191004172550_RenameClientHitLocationCountColumns.cs rename to Data/Migrations/MySql/20191004172550_RenameClientHitLocationCountColumns.cs index 4ebe4ccd..cec9d7cf 100644 --- a/SharedLibraryCore/Migrations/MySql/20191004172550_RenameClientHitLocationCountColumns.cs +++ b/Data/Migrations/MySql/20191004172550_RenameClientHitLocationCountColumns.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class RenameClientHitLocationCountColumns : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs b/Data/Migrations/MySql/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs rename to Data/Migrations/MySql/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs index d156f99b..a36575e9 100644 --- a/SharedLibraryCore/Migrations/MySql/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs +++ b/Data/Migrations/MySql/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20191030000713_EnforceUniqueIndexForEFAliasIPName")] diff --git a/SharedLibraryCore/Migrations/MySql/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs b/Data/Migrations/MySql/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs similarity index 98% rename from SharedLibraryCore/Migrations/MySql/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs rename to Data/Migrations/MySql/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs index bd5c6a82..e5e781c5 100644 --- a/SharedLibraryCore/Migrations/MySql/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs +++ b/Data/Migrations/MySql/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class EnforceUniqueIndexForEFAliasIPName : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs b/Data/Migrations/MySql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs rename to Data/Migrations/MySql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs index 59ca1e24..0f86740a 100644 --- a/SharedLibraryCore/Migrations/MySql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs +++ b/Data/Migrations/MySql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL")] diff --git a/SharedLibraryCore/Migrations/MySql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs b/Data/Migrations/MySql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs similarity index 94% rename from SharedLibraryCore/Migrations/MySql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs rename to Data/Migrations/MySql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs index e91b3f53..0fad88fe 100644 --- a/SharedLibraryCore/Migrations/MySql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs +++ b/Data/Migrations/MySql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class SetCaseSensitiveCoallationForAliasNameMySQL : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20191230140947_AddMissingActiveColumns.Designer.cs b/Data/Migrations/MySql/20191230140947_AddMissingActiveColumns.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20191230140947_AddMissingActiveColumns.Designer.cs rename to Data/Migrations/MySql/20191230140947_AddMissingActiveColumns.Designer.cs index 01a9b9f2..de6cd57d 100644 --- a/SharedLibraryCore/Migrations/MySql/20191230140947_AddMissingActiveColumns.Designer.cs +++ b/Data/Migrations/MySql/20191230140947_AddMissingActiveColumns.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20191230140947_AddMissingActiveColumns")] diff --git a/SharedLibraryCore/Migrations/MySql/20191230140947_AddMissingActiveColumns.cs b/Data/Migrations/MySql/20191230140947_AddMissingActiveColumns.cs similarity index 93% rename from SharedLibraryCore/Migrations/MySql/20191230140947_AddMissingActiveColumns.cs rename to Data/Migrations/MySql/20191230140947_AddMissingActiveColumns.cs index 13afb77f..0b7eb0c7 100644 --- a/SharedLibraryCore/Migrations/MySql/20191230140947_AddMissingActiveColumns.cs +++ b/Data/Migrations/MySql/20191230140947_AddMissingActiveColumns.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddMissingActiveColumns : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs b/Data/Migrations/MySql/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs rename to Data/Migrations/MySql/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs index b3cf9f08..54d7c9a0 100644 --- a/SharedLibraryCore/Migrations/MySql/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs +++ b/Data/Migrations/MySql/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20200423225137_AddImpersonationIdToEFChangeHistory")] diff --git a/SharedLibraryCore/Migrations/MySql/20200423225137_AddImpersonationIdToEFChangeHistory.cs b/Data/Migrations/MySql/20200423225137_AddImpersonationIdToEFChangeHistory.cs similarity index 93% rename from SharedLibraryCore/Migrations/MySql/20200423225137_AddImpersonationIdToEFChangeHistory.cs rename to Data/Migrations/MySql/20200423225137_AddImpersonationIdToEFChangeHistory.cs index b1d337d9..1fa955a2 100644 --- a/SharedLibraryCore/Migrations/MySql/20200423225137_AddImpersonationIdToEFChangeHistory.cs +++ b/Data/Migrations/MySql/20200423225137_AddImpersonationIdToEFChangeHistory.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddImpersonationIdToEFChangeHistory : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20200521203304_AddHostnameToEFServer.Designer.cs b/Data/Migrations/MySql/20200521203304_AddHostnameToEFServer.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20200521203304_AddHostnameToEFServer.Designer.cs rename to Data/Migrations/MySql/20200521203304_AddHostnameToEFServer.Designer.cs index 0de748a5..cadc4929 100644 --- a/SharedLibraryCore/Migrations/MySql/20200521203304_AddHostnameToEFServer.Designer.cs +++ b/Data/Migrations/MySql/20200521203304_AddHostnameToEFServer.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20200521203304_AddHostnameToEFServer")] diff --git a/SharedLibraryCore/Migrations/MySql/20200521203304_AddHostnameToEFServer.cs b/Data/Migrations/MySql/20200521203304_AddHostnameToEFServer.cs similarity index 92% rename from SharedLibraryCore/Migrations/MySql/20200521203304_AddHostnameToEFServer.cs rename to Data/Migrations/MySql/20200521203304_AddHostnameToEFServer.cs index 7f0e8657..88e94533 100644 --- a/SharedLibraryCore/Migrations/MySql/20200521203304_AddHostnameToEFServer.cs +++ b/Data/Migrations/MySql/20200521203304_AddHostnameToEFServer.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddHostnameToEFServer : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20200819224119_AddIsPasswordProtectedColumn.Designer.cs b/Data/Migrations/MySql/20200819224119_AddIsPasswordProtectedColumn.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20200819224119_AddIsPasswordProtectedColumn.Designer.cs rename to Data/Migrations/MySql/20200819224119_AddIsPasswordProtectedColumn.Designer.cs index 2dbf60c8..8e777ea4 100644 --- a/SharedLibraryCore/Migrations/MySql/20200819224119_AddIsPasswordProtectedColumn.Designer.cs +++ b/Data/Migrations/MySql/20200819224119_AddIsPasswordProtectedColumn.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20200819224119_AddIsPasswordProtectedColumn")] diff --git a/SharedLibraryCore/Migrations/MySql/20200819224119_AddIsPasswordProtectedColumn.cs b/Data/Migrations/MySql/20200819224119_AddIsPasswordProtectedColumn.cs similarity index 95% rename from SharedLibraryCore/Migrations/MySql/20200819224119_AddIsPasswordProtectedColumn.cs rename to Data/Migrations/MySql/20200819224119_AddIsPasswordProtectedColumn.cs index 410ad8ff..7db2d353 100644 --- a/SharedLibraryCore/Migrations/MySql/20200819224119_AddIsPasswordProtectedColumn.cs +++ b/Data/Migrations/MySql/20200819224119_AddIsPasswordProtectedColumn.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddIsPasswordProtectedColumn : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20201114232340_UpdateEFRatingIndex.Designer.cs b/Data/Migrations/MySql/20201114232340_UpdateEFRatingIndex.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20201114232340_UpdateEFRatingIndex.Designer.cs rename to Data/Migrations/MySql/20201114232340_UpdateEFRatingIndex.Designer.cs index 72108831..6cb95a41 100644 --- a/SharedLibraryCore/Migrations/MySql/20201114232340_UpdateEFRatingIndex.Designer.cs +++ b/Data/Migrations/MySql/20201114232340_UpdateEFRatingIndex.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20201114232340_UpdateEFRatingIndex")] diff --git a/SharedLibraryCore/Migrations/MySql/20201114232340_UpdateEFRatingIndex.cs b/Data/Migrations/MySql/20201114232340_UpdateEFRatingIndex.cs similarity index 94% rename from SharedLibraryCore/Migrations/MySql/20201114232340_UpdateEFRatingIndex.cs rename to Data/Migrations/MySql/20201114232340_UpdateEFRatingIndex.cs index 510663d0..34b82fcd 100644 --- a/SharedLibraryCore/Migrations/MySql/20201114232340_UpdateEFRatingIndex.cs +++ b/Data/Migrations/MySql/20201114232340_UpdateEFRatingIndex.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class UpdateEFRatingIndex : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs b/Data/Migrations/MySql/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs rename to Data/Migrations/MySql/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs index d807ea9b..67be6ad1 100644 --- a/SharedLibraryCore/Migrations/MySql/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs +++ b/Data/Migrations/MySql/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20201118023106_AddSentIngameFlagToClientMessage")] diff --git a/SharedLibraryCore/Migrations/MySql/20201118023106_AddSentIngameFlagToClientMessage.cs b/Data/Migrations/MySql/20201118023106_AddSentIngameFlagToClientMessage.cs similarity index 93% rename from SharedLibraryCore/Migrations/MySql/20201118023106_AddSentIngameFlagToClientMessage.cs rename to Data/Migrations/MySql/20201118023106_AddSentIngameFlagToClientMessage.cs index 56a27833..3493dc75 100644 --- a/SharedLibraryCore/Migrations/MySql/20201118023106_AddSentIngameFlagToClientMessage.cs +++ b/Data/Migrations/MySql/20201118023106_AddSentIngameFlagToClientMessage.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class AddSentIngameFlagToClientMessage : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20201124024731_UpdateMigrationsToMySql.Designer.cs b/Data/Migrations/MySql/20201124024731_UpdateMigrationsToMySql.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20201124024731_UpdateMigrationsToMySql.Designer.cs rename to Data/Migrations/MySql/20201124024731_UpdateMigrationsToMySql.Designer.cs index ae78d67b..c1664272 100644 --- a/SharedLibraryCore/Migrations/MySql/20201124024731_UpdateMigrationsToMySql.Designer.cs +++ b/Data/Migrations/MySql/20201124024731_UpdateMigrationsToMySql.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20201124024731_UpdateMigrationsToMySql")] diff --git a/SharedLibraryCore/Migrations/MySql/20201124024731_UpdateMigrationsToMySql.cs b/Data/Migrations/MySql/20201124024731_UpdateMigrationsToMySql.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20201124024731_UpdateMigrationsToMySql.cs rename to Data/Migrations/MySql/20201124024731_UpdateMigrationsToMySql.cs index 83b7e2a2..64815bff 100644 --- a/SharedLibraryCore/Migrations/MySql/20201124024731_UpdateMigrationsToMySql.cs +++ b/Data/Migrations/MySql/20201124024731_UpdateMigrationsToMySql.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class UpdateMigrationsToMySql : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20210123023921_UpdateEFMetaToSupportNonClientMeta.Designer.cs b/Data/Migrations/MySql/20210123023921_UpdateEFMetaToSupportNonClientMeta.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20210123023921_UpdateEFMetaToSupportNonClientMeta.Designer.cs rename to Data/Migrations/MySql/20210123023921_UpdateEFMetaToSupportNonClientMeta.Designer.cs index 933e6398..a38ded01 100644 --- a/SharedLibraryCore/Migrations/MySql/20210123023921_UpdateEFMetaToSupportNonClientMeta.Designer.cs +++ b/Data/Migrations/MySql/20210123023921_UpdateEFMetaToSupportNonClientMeta.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20210123023921_UpdateEFMetaToSupportNonClientMeta")] diff --git a/SharedLibraryCore/Migrations/MySql/20210123023921_UpdateEFMetaToSupportNonClientMeta.cs b/Data/Migrations/MySql/20210123023921_UpdateEFMetaToSupportNonClientMeta.cs similarity index 97% rename from SharedLibraryCore/Migrations/MySql/20210123023921_UpdateEFMetaToSupportNonClientMeta.cs rename to Data/Migrations/MySql/20210123023921_UpdateEFMetaToSupportNonClientMeta.cs index 1a748afd..80289108 100644 --- a/SharedLibraryCore/Migrations/MySql/20210123023921_UpdateEFMetaToSupportNonClientMeta.cs +++ b/Data/Migrations/MySql/20210123023921_UpdateEFMetaToSupportNonClientMeta.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class UpdateEFMetaToSupportNonClientMeta : Migration { diff --git a/SharedLibraryCore/Migrations/MySql/20210124170830_UpdateEFMetaToSupportLinkedMeta.Designer.cs b/Data/Migrations/MySql/20210124170830_UpdateEFMetaToSupportLinkedMeta.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/MySql/20210124170830_UpdateEFMetaToSupportLinkedMeta.Designer.cs rename to Data/Migrations/MySql/20210124170830_UpdateEFMetaToSupportLinkedMeta.Designer.cs index 745b1b34..bf502a4d 100644 --- a/SharedLibraryCore/Migrations/MySql/20210124170830_UpdateEFMetaToSupportLinkedMeta.Designer.cs +++ b/Data/Migrations/MySql/20210124170830_UpdateEFMetaToSupportLinkedMeta.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] [Migration("20210124170830_UpdateEFMetaToSupportLinkedMeta")] diff --git a/SharedLibraryCore/Migrations/MySql/20210124170830_UpdateEFMetaToSupportLinkedMeta.cs b/Data/Migrations/MySql/20210124170830_UpdateEFMetaToSupportLinkedMeta.cs similarity index 96% rename from SharedLibraryCore/Migrations/MySql/20210124170830_UpdateEFMetaToSupportLinkedMeta.cs rename to Data/Migrations/MySql/20210124170830_UpdateEFMetaToSupportLinkedMeta.cs index 30e37b9b..2794932d 100644 --- a/SharedLibraryCore/Migrations/MySql/20210124170830_UpdateEFMetaToSupportLinkedMeta.cs +++ b/Data/Migrations/MySql/20210124170830_UpdateEFMetaToSupportLinkedMeta.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { public partial class UpdateEFMetaToSupportLinkedMeta : Migration { diff --git a/Data/Migrations/MySql/20210315222843_AddAdvancedStats.Designer.cs b/Data/Migrations/MySql/20210315222843_AddAdvancedStats.Designer.cs new file mode 100644 index 00000000..2af10efa --- /dev/null +++ b/Data/Migrations/MySql/20210315222843_AddAdvancedStats.Designer.cs @@ -0,0 +1,1280 @@ +// +using System; +using Data.MigrationContext; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Data.Migrations.MySql +{ + [DbContext(typeof(MySqlDatabaseContext))] + [Migration("20210315222843_AddAdvancedStats")] + partial class AddAdvancedStats + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.10") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Data.Models.Client.EFACSnapshotVector3", b => + { + b.Property("ACSnapshotVector3Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("SnapshotId") + .HasColumnType("int"); + + b.Property("Vector3Id") + .HasColumnType("int"); + + b.HasKey("ACSnapshotVector3Id"); + + b.HasIndex("SnapshotId"); + + b.HasIndex("Vector3Id"); + + b.ToTable("EFACSnapshotVector3"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClient", b => + { + b.Property("ClientId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("AliasLinkId") + .HasColumnType("int"); + + b.Property("Connections") + .HasColumnType("int"); + + b.Property("CurrentAliasId") + .HasColumnType("int"); + + b.Property("FirstConnection") + .HasColumnType("datetime(6)"); + + b.Property("LastConnection") + .HasColumnType("datetime(6)"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Masked") + .HasColumnType("tinyint(1)"); + + b.Property("NetworkId") + .HasColumnType("bigint"); + + b.Property("Password") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("PasswordSalt") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("TotalConnectionTime") + .HasColumnType("int"); + + b.HasKey("ClientId"); + + b.HasIndex("AliasLinkId"); + + b.HasIndex("CurrentAliasId"); + + b.HasIndex("NetworkId") + .IsUnique(); + + b.ToTable("EFClients"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientKill", b => + { + b.Property("KillId") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("AttackerId") + .HasColumnType("int"); + + b.Property("Damage") + .HasColumnType("int"); + + b.Property("DeathOriginVector3Id") + .HasColumnType("int"); + + b.Property("DeathType") + .HasColumnType("int"); + + b.Property("Fraction") + .HasColumnType("double"); + + b.Property("HitLoc") + .HasColumnType("int"); + + b.Property("IsKill") + .HasColumnType("tinyint(1)"); + + b.Property("KillOriginVector3Id") + .HasColumnType("int"); + + b.Property("Map") + .HasColumnType("int"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("VictimId") + .HasColumnType("int"); + + b.Property("ViewAnglesVector3Id") + .HasColumnType("int"); + + b.Property("VisibilityPercentage") + .HasColumnType("double"); + + b.Property("Weapon") + .HasColumnType("int"); + + b.Property("When") + .HasColumnType("datetime(6)"); + + b.HasKey("KillId"); + + b.HasIndex("AttackerId"); + + b.HasIndex("DeathOriginVector3Id"); + + b.HasIndex("KillOriginVector3Id"); + + b.HasIndex("ServerId"); + + b.HasIndex("VictimId"); + + b.HasIndex("ViewAnglesVector3Id"); + + b.ToTable("EFClientKills"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientMessage", b => + { + b.Property("MessageId") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Message") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("SentIngame") + .HasColumnType("tinyint(1)"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("TimeSent") + .HasColumnType("datetime(6)"); + + b.HasKey("MessageId"); + + b.HasIndex("ClientId"); + + b.HasIndex("ServerId"); + + b.HasIndex("TimeSent"); + + b.ToTable("EFClientMessages"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFACSnapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("CurrentSessionLength") + .HasColumnType("int"); + + b.Property("CurrentStrain") + .HasColumnType("double"); + + b.Property("CurrentViewAngleId") + .HasColumnType("int"); + + b.Property("Deaths") + .HasColumnType("int"); + + b.Property("Distance") + .HasColumnType("double"); + + b.Property("EloRating") + .HasColumnType("double"); + + b.Property("HitDestinationId") + .HasColumnType("int"); + + b.Property("HitLocation") + .HasColumnType("int"); + + b.Property("HitOriginId") + .HasColumnType("int"); + + b.Property("HitType") + .HasColumnType("int"); + + b.Property("Hits") + .HasColumnType("int"); + + b.Property("Kills") + .HasColumnType("int"); + + b.Property("LastStrainAngleId") + .HasColumnType("int"); + + b.Property("RecoilOffset") + .HasColumnType("double"); + + b.Property("SessionAngleOffset") + .HasColumnType("double"); + + b.Property("SessionAverageSnapValue") + .HasColumnType("double"); + + b.Property("SessionSPM") + .HasColumnType("double"); + + b.Property("SessionScore") + .HasColumnType("int"); + + b.Property("SessionSnapHits") + .HasColumnType("int"); + + b.Property("StrainAngleBetween") + .HasColumnType("double"); + + b.Property("TimeSinceLastEvent") + .HasColumnType("int"); + + b.Property("WeaponId") + .HasColumnType("int"); + + b.Property("When") + .HasColumnType("datetime(6)"); + + b.HasKey("SnapshotId"); + + b.HasIndex("ClientId"); + + b.HasIndex("CurrentViewAngleId"); + + b.HasIndex("HitDestinationId"); + + b.HasIndex("HitOriginId"); + + b.HasIndex("LastStrainAngleId"); + + b.ToTable("EFACSnapshot"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientHitStatistic", b => + { + b.Property("ClientHitStatisticId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("DamageInflicted") + .HasColumnType("int"); + + b.Property("DamageReceived") + .HasColumnType("int"); + + b.Property("DeathCount") + .HasColumnType("int"); + + b.Property("HitCount") + .HasColumnType("int"); + + b.Property("HitLocationId") + .HasColumnType("int"); + + b.Property("KillCount") + .HasColumnType("int"); + + b.Property("MeansOfDeathId") + .HasColumnType("int"); + + b.Property("ReceivedHitCount") + .HasColumnType("int"); + + b.Property("Score") + .HasColumnType("int"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("SuicideCount") + .HasColumnType("int"); + + b.Property("UpdatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("UsageSeconds") + .HasColumnType("int"); + + b.Property("WeaponAttachmentComboId") + .HasColumnType("int"); + + b.Property("WeaponId") + .HasColumnType("int"); + + b.HasKey("ClientHitStatisticId"); + + b.HasIndex("ClientId"); + + b.HasIndex("HitLocationId"); + + b.HasIndex("MeansOfDeathId"); + + b.HasIndex("ServerId"); + + b.HasIndex("WeaponAttachmentComboId"); + + b.HasIndex("WeaponId"); + + b.ToTable("EFClientHitStatistics"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRankingHistory", b => + { + b.Property("ClientRankingHistoryId") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("Newest") + .HasColumnType("tinyint(1)"); + + b.Property("PerformanceMetric") + .HasColumnType("double"); + + b.Property("Ranking") + .HasColumnType("int"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("UpdatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("ZScore") + .HasColumnType("double"); + + b.HasKey("ClientRankingHistoryId"); + + b.HasIndex("ClientId"); + + b.HasIndex("Ranking"); + + b.HasIndex("ServerId"); + + b.HasIndex("UpdatedDateTime"); + + b.HasIndex("ZScore"); + + b.ToTable("EFClientRankingHistory"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRatingHistory", b => + { + b.Property("RatingHistoryId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.HasKey("RatingHistoryId"); + + b.HasIndex("ClientId"); + + b.ToTable("EFClientRatingHistory"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientStatistics", b => + { + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("AverageSnapValue") + .HasColumnType("double"); + + b.Property("Deaths") + .HasColumnType("int"); + + b.Property("EloRating") + .HasColumnType("double"); + + b.Property("Kills") + .HasColumnType("int"); + + b.Property("MaxStrain") + .HasColumnType("double"); + + b.Property("RollingWeightedKDR") + .HasColumnType("double"); + + b.Property("SPM") + .HasColumnType("double"); + + b.Property("Skill") + .HasColumnType("double"); + + b.Property("SnapHitCount") + .HasColumnType("int"); + + b.Property("TimePlayed") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("ZScore") + .HasColumnType("double"); + + b.HasKey("ClientId", "ServerId"); + + b.HasIndex("ServerId"); + + b.HasIndex("ZScore"); + + b.HasIndex("ClientId", "TimePlayed", "ZScore"); + + b.ToTable("EFClientStatistics"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFHitLocationCount", b => + { + b.Property("HitLocationCountId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("EFClientStatisticsClientId") + .HasColumnName("EFClientStatisticsClientId") + .HasColumnType("int"); + + b.Property("EFClientStatisticsServerId") + .HasColumnName("EFClientStatisticsServerId") + .HasColumnType("bigint"); + + b.Property("HitCount") + .HasColumnType("int"); + + b.Property("HitOffsetAverage") + .HasColumnType("float"); + + b.Property("Location") + .HasColumnType("int"); + + b.Property("MaxAngleDistance") + .HasColumnType("float"); + + b.HasKey("HitLocationCountId"); + + b.HasIndex("EFClientStatisticsServerId"); + + b.HasIndex("EFClientStatisticsClientId", "EFClientStatisticsServerId"); + + b.ToTable("EFHitLocationCounts"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFRating", b => + { + b.Property("RatingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ActivityAmount") + .HasColumnType("int"); + + b.Property("Newest") + .HasColumnType("tinyint(1)"); + + b.Property("Performance") + .HasColumnType("double"); + + b.Property("Ranking") + .HasColumnType("int"); + + b.Property("RatingHistoryId") + .HasColumnType("int"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("When") + .HasColumnType("datetime(6)"); + + b.HasKey("RatingId"); + + b.HasIndex("RatingHistoryId"); + + b.HasIndex("ServerId"); + + b.HasIndex("Performance", "Ranking", "When"); + + b.HasIndex("When", "ServerId", "Performance", "ActivityAmount"); + + b.ToTable("EFRating"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFHitLocation", b => + { + b.Property("HitLocationId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("Game") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("UpdatedDateTime") + .HasColumnType("datetime(6)"); + + b.HasKey("HitLocationId"); + + b.HasIndex("Name"); + + b.ToTable("EFHitLocations"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFMap", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("Game") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UpdatedDateTime") + .HasColumnType("datetime(6)"); + + b.HasKey("MapId"); + + b.ToTable("EFMaps"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFMeansOfDeath", b => + { + b.Property("MeansOfDeathId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("Game") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UpdatedDateTime") + .HasColumnType("datetime(6)"); + + b.HasKey("MeansOfDeathId"); + + b.ToTable("EFMeansOfDeath"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeapon", b => + { + b.Property("WeaponId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("Game") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("UpdatedDateTime") + .HasColumnType("datetime(6)"); + + b.HasKey("WeaponId"); + + b.HasIndex("Name"); + + b.ToTable("EFWeapons"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachment", b => + { + b.Property("WeaponAttachmentId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("Game") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UpdatedDateTime") + .HasColumnType("datetime(6)"); + + b.HasKey("WeaponAttachmentId"); + + b.ToTable("EFWeaponAttachments"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", b => + { + b.Property("WeaponAttachmentComboId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Attachment1Id") + .HasColumnType("int"); + + b.Property("Attachment2Id") + .HasColumnType("int"); + + b.Property("Attachment3Id") + .HasColumnType("int"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("Game") + .HasColumnType("int"); + + b.Property("UpdatedDateTime") + .HasColumnType("datetime(6)"); + + b.HasKey("WeaponAttachmentComboId"); + + b.HasIndex("Attachment1Id"); + + b.HasIndex("Attachment2Id"); + + b.HasIndex("Attachment3Id"); + + b.ToTable("EFWeaponAttachmentCombos"); + }); + + modelBuilder.Entity("Data.Models.EFAlias", b => + { + b.Property("AliasId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("IPAddress") + .HasColumnType("int"); + + b.Property("LinkId") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(24) CHARACTER SET utf8mb4") + .HasMaxLength(24); + + b.Property("SearchableName") + .HasColumnType("varchar(24) CHARACTER SET utf8mb4") + .HasMaxLength(24); + + b.HasKey("AliasId"); + + b.HasIndex("IPAddress"); + + b.HasIndex("LinkId"); + + b.HasIndex("Name"); + + b.HasIndex("SearchableName"); + + b.HasIndex("Name", "IPAddress") + .IsUnique(); + + b.ToTable("EFAlias"); + }); + + modelBuilder.Entity("Data.Models.EFAliasLink", b => + { + b.Property("AliasLinkId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.HasKey("AliasLinkId"); + + b.ToTable("EFAliasLinks"); + }); + + modelBuilder.Entity("Data.Models.EFChangeHistory", b => + { + b.Property("ChangeHistoryId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("Comment") + .HasColumnType("varchar(128) CHARACTER SET utf8mb4") + .HasMaxLength(128); + + b.Property("CurrentValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("ImpersonationEntityId") + .HasColumnType("int"); + + b.Property("OriginEntityId") + .HasColumnType("int"); + + b.Property("PreviousValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("TargetEntityId") + .HasColumnType("int"); + + b.Property("TimeChanged") + .HasColumnType("datetime(6)"); + + b.Property("TypeOfChange") + .HasColumnType("int"); + + b.HasKey("ChangeHistoryId"); + + b.ToTable("EFChangeHistory"); + }); + + modelBuilder.Entity("Data.Models.EFMeta", b => + { + b.Property("MetaId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime(6)"); + + b.Property("Extra") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Key") + .IsRequired() + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("LinkedMetaId") + .HasColumnType("int"); + + b.Property("Updated") + .HasColumnType("datetime(6)"); + + b.Property("Value") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("MetaId"); + + b.HasIndex("ClientId"); + + b.HasIndex("Key"); + + b.HasIndex("LinkedMetaId"); + + b.ToTable("EFMeta"); + }); + + modelBuilder.Entity("Data.Models.EFPenalty", b => + { + b.Property("PenaltyId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("AutomatedOffense") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Expires") + .HasColumnType("datetime(6)"); + + b.Property("IsEvadedOffense") + .HasColumnType("tinyint(1)"); + + b.Property("LinkId") + .HasColumnType("int"); + + b.Property("OffenderId") + .HasColumnType("int"); + + b.Property("Offense") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("PunisherId") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("When") + .HasColumnType("datetime(6)"); + + b.HasKey("PenaltyId"); + + b.HasIndex("LinkId"); + + b.HasIndex("OffenderId"); + + b.HasIndex("PunisherId"); + + b.ToTable("EFPenalties"); + }); + + modelBuilder.Entity("Data.Models.Server.EFServer", b => + { + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("EndPoint") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("GameName") + .HasColumnType("int"); + + b.Property("HostName") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("IsPasswordProtected") + .HasColumnType("tinyint(1)"); + + b.Property("Port") + .HasColumnType("int"); + + b.HasKey("ServerId"); + + b.ToTable("EFServers"); + }); + + modelBuilder.Entity("Data.Models.Server.EFServerStatistics", b => + { + b.Property("StatisticId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("TotalKills") + .HasColumnType("bigint"); + + b.Property("TotalPlayTime") + .HasColumnType("bigint"); + + b.HasKey("StatisticId"); + + b.HasIndex("ServerId"); + + b.ToTable("EFServerStatistics"); + }); + + modelBuilder.Entity("Data.Models.Vector3", b => + { + b.Property("Vector3Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("X") + .HasColumnType("float"); + + b.Property("Y") + .HasColumnType("float"); + + b.Property("Z") + .HasColumnType("float"); + + b.HasKey("Vector3Id"); + + b.ToTable("Vector3"); + }); + + modelBuilder.Entity("Data.Models.Client.EFACSnapshotVector3", b => + { + b.HasOne("Data.Models.Client.Stats.EFACSnapshot", "Snapshot") + .WithMany("PredictedViewAngles") + .HasForeignKey("SnapshotId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "Vector") + .WithMany() + .HasForeignKey("Vector3Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.EFClient", b => + { + b.HasOne("Data.Models.EFAliasLink", "AliasLink") + .WithMany() + .HasForeignKey("AliasLinkId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.EFAlias", "CurrentAlias") + .WithMany() + .HasForeignKey("CurrentAliasId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientKill", b => + { + b.HasOne("Data.Models.Client.EFClient", "Attacker") + .WithMany() + .HasForeignKey("AttackerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "DeathOrigin") + .WithMany() + .HasForeignKey("DeathOriginVector3Id"); + + b.HasOne("Data.Models.Vector3", "KillOrigin") + .WithMany() + .HasForeignKey("KillOriginVector3Id"); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.EFClient", "Victim") + .WithMany() + .HasForeignKey("VictimId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "ViewAngles") + .WithMany() + .HasForeignKey("ViewAnglesVector3Id"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientMessage", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFACSnapshot", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "CurrentViewAngle") + .WithMany() + .HasForeignKey("CurrentViewAngleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "HitDestination") + .WithMany() + .HasForeignKey("HitDestinationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "HitOrigin") + .WithMany() + .HasForeignKey("HitOriginId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "LastStrainAngle") + .WithMany() + .HasForeignKey("LastStrainAngleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientHitStatistic", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.Reference.EFHitLocation", "HitLocation") + .WithMany() + .HasForeignKey("HitLocationId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFMeansOfDeath", "MeansOfDeath") + .WithMany() + .HasForeignKey("MeansOfDeathId"); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", "WeaponAttachmentCombo") + .WithMany() + .HasForeignKey("WeaponAttachmentComboId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeapon", "Weapon") + .WithMany() + .HasForeignKey("WeaponId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRankingHistory", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRatingHistory", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientStatistics", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFHitLocationCount", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("EFClientStatisticsClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("EFClientStatisticsServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.EFClientStatistics", null) + .WithMany("HitLocations") + .HasForeignKey("EFClientStatisticsClientId", "EFClientStatisticsServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFRating", b => + { + b.HasOne("Data.Models.Client.Stats.EFClientRatingHistory", "RatingHistory") + .WithMany("Ratings") + .HasForeignKey("RatingHistoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", b => + { + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment1") + .WithMany() + .HasForeignKey("Attachment1Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment2") + .WithMany() + .HasForeignKey("Attachment2Id"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment3") + .WithMany() + .HasForeignKey("Attachment3Id"); + }); + + modelBuilder.Entity("Data.Models.EFAlias", b => + { + b.HasOne("Data.Models.EFAliasLink", "Link") + .WithMany("Children") + .HasForeignKey("LinkId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.EFMeta", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany("Meta") + .HasForeignKey("ClientId"); + + b.HasOne("Data.Models.EFMeta", "LinkedMeta") + .WithMany() + .HasForeignKey("LinkedMetaId") + .OnDelete(DeleteBehavior.SetNull); + }); + + modelBuilder.Entity("Data.Models.EFPenalty", b => + { + b.HasOne("Data.Models.EFAliasLink", "Link") + .WithMany("ReceivedPenalties") + .HasForeignKey("LinkId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.EFClient", "Offender") + .WithMany("ReceivedPenalties") + .HasForeignKey("OffenderId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Data.Models.Client.EFClient", "Punisher") + .WithMany("AdministeredPenalties") + .HasForeignKey("PunisherId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Server.EFServerStatistics", b => + { + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Data/Migrations/MySql/20210315222843_AddAdvancedStats.cs b/Data/Migrations/MySql/20210315222843_AddAdvancedStats.cs new file mode 100644 index 00000000..f9bcc9f5 --- /dev/null +++ b/Data/Migrations/MySql/20210315222843_AddAdvancedStats.cs @@ -0,0 +1,391 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Data.Migrations.MySql +{ + public partial class AddAdvancedStats : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "AverageRecoilOffset", + table: "EFClientStatistics"); + + migrationBuilder.DropColumn( + name: "VisionAverage", + table: "EFClientStatistics"); + + migrationBuilder.AddColumn( + name: "UpdatedAt", + table: "EFClientStatistics", + nullable: true); + + migrationBuilder.AddColumn( + name: "ZScore", + table: "EFClientStatistics", + nullable: false, + defaultValue: 0.0); + + migrationBuilder.CreateTable( + name: "EFClientRankingHistory", + columns: table => new + { + ClientRankingHistoryId = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + ClientId = table.Column(nullable: false), + ServerId = table.Column(nullable: true), + Newest = table.Column(nullable: false), + Ranking = table.Column(nullable: true), + ZScore = table.Column(nullable: true), + PerformanceMetric = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EFClientRankingHistory", x => x.ClientRankingHistoryId); + table.ForeignKey( + name: "FK_EFClientRankingHistory_EFClients_ClientId", + column: x => x.ClientId, + principalTable: "EFClients", + principalColumn: "ClientId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_EFClientRankingHistory_EFServers_ServerId", + column: x => x.ServerId, + principalTable: "EFServers", + principalColumn: "ServerId", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "EFHitLocations", + columns: table => new + { + HitLocationId = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Name = table.Column(nullable: false), + Game = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EFHitLocations", x => x.HitLocationId); + }); + + migrationBuilder.CreateTable( + name: "EFMaps", + columns: table => new + { + MapId = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Name = table.Column(nullable: false), + Game = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EFMaps", x => x.MapId); + }); + + migrationBuilder.CreateTable( + name: "EFMeansOfDeath", + columns: table => new + { + MeansOfDeathId = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Name = table.Column(nullable: false), + Game = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EFMeansOfDeath", x => x.MeansOfDeathId); + }); + + migrationBuilder.CreateTable( + name: "EFWeaponAttachments", + columns: table => new + { + WeaponAttachmentId = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Name = table.Column(nullable: false), + Game = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EFWeaponAttachments", x => x.WeaponAttachmentId); + }); + + migrationBuilder.CreateTable( + name: "EFWeapons", + columns: table => new + { + WeaponId = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Name = table.Column(nullable: false), + Game = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EFWeapons", x => x.WeaponId); + }); + + migrationBuilder.CreateTable( + name: "EFWeaponAttachmentCombos", + columns: table => new + { + WeaponAttachmentComboId = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Game = table.Column(nullable: false), + Attachment1Id = table.Column(nullable: false), + Attachment2Id = table.Column(nullable: true), + Attachment3Id = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EFWeaponAttachmentCombos", x => x.WeaponAttachmentComboId); + table.ForeignKey( + name: "FK_EFWeaponAttachmentCombos_EFWeaponAttachments_Attachment1Id", + column: x => x.Attachment1Id, + principalTable: "EFWeaponAttachments", + principalColumn: "WeaponAttachmentId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_EFWeaponAttachmentCombos_EFWeaponAttachments_Attachment2Id", + column: x => x.Attachment2Id, + principalTable: "EFWeaponAttachments", + principalColumn: "WeaponAttachmentId", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_EFWeaponAttachmentCombos_EFWeaponAttachments_Attachment3Id", + column: x => x.Attachment3Id, + principalTable: "EFWeaponAttachments", + principalColumn: "WeaponAttachmentId", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "EFClientHitStatistics", + columns: table => new + { + ClientHitStatisticId = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + ClientId = table.Column(nullable: false), + ServerId = table.Column(nullable: true), + HitLocationId = table.Column(nullable: true), + MeansOfDeathId = table.Column(nullable: true), + WeaponId = table.Column(nullable: true), + WeaponAttachmentComboId = table.Column(nullable: true), + HitCount = table.Column(nullable: false), + KillCount = table.Column(nullable: false), + DamageInflicted = table.Column(nullable: false), + ReceivedHitCount = table.Column(nullable: false), + DeathCount = table.Column(nullable: false), + DamageReceived = table.Column(nullable: false), + SuicideCount = table.Column(nullable: false), + UsageSeconds = table.Column(nullable: true), + Score = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EFClientHitStatistics", x => x.ClientHitStatisticId); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFClients_ClientId", + column: x => x.ClientId, + principalTable: "EFClients", + principalColumn: "ClientId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFHitLocations_HitLocationId", + column: x => x.HitLocationId, + principalTable: "EFHitLocations", + principalColumn: "HitLocationId", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFMeansOfDeath_MeansOfDeathId", + column: x => x.MeansOfDeathId, + principalTable: "EFMeansOfDeath", + principalColumn: "MeansOfDeathId", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFServers_ServerId", + column: x => x.ServerId, + principalTable: "EFServers", + principalColumn: "ServerId", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFWeaponAttachmentCombos_WeaponAttachm~", + column: x => x.WeaponAttachmentComboId, + principalTable: "EFWeaponAttachmentCombos", + principalColumn: "WeaponAttachmentComboId", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFWeapons_WeaponId", + column: x => x.WeaponId, + principalTable: "EFWeapons", + principalColumn: "WeaponId", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_EFClientStatistics_ZScore", + table: "EFClientStatistics", + column: "ZScore"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientStatistics_ClientId_TimePlayed_ZScore", + table: "EFClientStatistics", + columns: new[] { "ClientId", "TimePlayed", "ZScore" }); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_ClientId", + table: "EFClientHitStatistics", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_HitLocationId", + table: "EFClientHitStatistics", + column: "HitLocationId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_MeansOfDeathId", + table: "EFClientHitStatistics", + column: "MeansOfDeathId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_ServerId", + table: "EFClientHitStatistics", + column: "ServerId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_WeaponAttachmentComboId", + table: "EFClientHitStatistics", + column: "WeaponAttachmentComboId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_WeaponId", + table: "EFClientHitStatistics", + column: "WeaponId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientRankingHistory_ClientId", + table: "EFClientRankingHistory", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientRankingHistory_Ranking", + table: "EFClientRankingHistory", + column: "Ranking"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientRankingHistory_ServerId", + table: "EFClientRankingHistory", + column: "ServerId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientRankingHistory_UpdatedDateTime", + table: "EFClientRankingHistory", + column: "UpdatedDateTime"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientRankingHistory_ZScore", + table: "EFClientRankingHistory", + column: "ZScore"); + + migrationBuilder.CreateIndex( + name: "IX_EFHitLocations_Name", + table: "EFHitLocations", + column: "Name"); + + migrationBuilder.CreateIndex( + name: "IX_EFWeaponAttachmentCombos_Attachment1Id", + table: "EFWeaponAttachmentCombos", + column: "Attachment1Id"); + + migrationBuilder.CreateIndex( + name: "IX_EFWeaponAttachmentCombos_Attachment2Id", + table: "EFWeaponAttachmentCombos", + column: "Attachment2Id"); + + migrationBuilder.CreateIndex( + name: "IX_EFWeaponAttachmentCombos_Attachment3Id", + table: "EFWeaponAttachmentCombos", + column: "Attachment3Id"); + + migrationBuilder.CreateIndex( + name: "IX_EFWeapons_Name", + table: "EFWeapons", + column: "Name"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "EFClientHitStatistics"); + + migrationBuilder.DropTable( + name: "EFClientRankingHistory"); + + migrationBuilder.DropTable( + name: "EFMaps"); + + migrationBuilder.DropTable( + name: "EFHitLocations"); + + migrationBuilder.DropTable( + name: "EFMeansOfDeath"); + + migrationBuilder.DropTable( + name: "EFWeaponAttachmentCombos"); + + migrationBuilder.DropTable( + name: "EFWeapons"); + + migrationBuilder.DropTable( + name: "EFWeaponAttachments"); + + migrationBuilder.DropIndex( + name: "IX_EFClientStatistics_ZScore", + table: "EFClientStatistics"); + + migrationBuilder.DropIndex( + name: "IX_EFClientStatistics_ClientId_TimePlayed_ZScore", + table: "EFClientStatistics"); + + migrationBuilder.DropColumn( + name: "UpdatedAt", + table: "EFClientStatistics"); + + migrationBuilder.DropColumn( + name: "ZScore", + table: "EFClientStatistics"); + + migrationBuilder.AddColumn( + name: "AverageRecoilOffset", + table: "EFClientStatistics", + type: "double", + nullable: false, + defaultValue: 0.0); + + migrationBuilder.AddColumn( + name: "VisionAverage", + table: "EFClientStatistics", + type: "double", + nullable: false, + defaultValue: 0.0); + } + } +} diff --git a/SharedLibraryCore/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs b/Data/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs similarity index 62% rename from SharedLibraryCore/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs rename to Data/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs index 933b9b72..39862696 100644 --- a/SharedLibraryCore/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs +++ b/Data/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs @@ -1,11 +1,11 @@ // using System; +using Data.MigrationContext; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; -namespace SharedLibraryCore.Migrations.MySql +namespace Data.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] partial class MySqlDatabaseContextModelSnapshot : ModelSnapshot @@ -17,7 +17,191 @@ namespace SharedLibraryCore.Migrations.MySql .HasAnnotation("ProductVersion", "3.1.10") .HasAnnotation("Relational:MaxIdentifierLength", 64); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b => + modelBuilder.Entity("Data.Models.Client.EFACSnapshotVector3", b => + { + b.Property("ACSnapshotVector3Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("SnapshotId") + .HasColumnType("int"); + + b.Property("Vector3Id") + .HasColumnType("int"); + + b.HasKey("ACSnapshotVector3Id"); + + b.HasIndex("SnapshotId"); + + b.HasIndex("Vector3Id"); + + b.ToTable("EFACSnapshotVector3"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClient", b => + { + b.Property("ClientId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("AliasLinkId") + .HasColumnType("int"); + + b.Property("Connections") + .HasColumnType("int"); + + b.Property("CurrentAliasId") + .HasColumnType("int"); + + b.Property("FirstConnection") + .HasColumnType("datetime(6)"); + + b.Property("LastConnection") + .HasColumnType("datetime(6)"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Masked") + .HasColumnType("tinyint(1)"); + + b.Property("NetworkId") + .HasColumnType("bigint"); + + b.Property("Password") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("PasswordSalt") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("TotalConnectionTime") + .HasColumnType("int"); + + b.HasKey("ClientId"); + + b.HasIndex("AliasLinkId"); + + b.HasIndex("CurrentAliasId"); + + b.HasIndex("NetworkId") + .IsUnique(); + + b.ToTable("EFClients"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientKill", b => + { + b.Property("KillId") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("AttackerId") + .HasColumnType("int"); + + b.Property("Damage") + .HasColumnType("int"); + + b.Property("DeathOriginVector3Id") + .HasColumnType("int"); + + b.Property("DeathType") + .HasColumnType("int"); + + b.Property("Fraction") + .HasColumnType("double"); + + b.Property("HitLoc") + .HasColumnType("int"); + + b.Property("IsKill") + .HasColumnType("tinyint(1)"); + + b.Property("KillOriginVector3Id") + .HasColumnType("int"); + + b.Property("Map") + .HasColumnType("int"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("VictimId") + .HasColumnType("int"); + + b.Property("ViewAnglesVector3Id") + .HasColumnType("int"); + + b.Property("VisibilityPercentage") + .HasColumnType("double"); + + b.Property("Weapon") + .HasColumnType("int"); + + b.Property("When") + .HasColumnType("datetime(6)"); + + b.HasKey("KillId"); + + b.HasIndex("AttackerId"); + + b.HasIndex("DeathOriginVector3Id"); + + b.HasIndex("KillOriginVector3Id"); + + b.HasIndex("ServerId"); + + b.HasIndex("VictimId"); + + b.HasIndex("ViewAnglesVector3Id"); + + b.ToTable("EFClientKills"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientMessage", b => + { + b.Property("MessageId") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("Message") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("SentIngame") + .HasColumnType("tinyint(1)"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("TimeSent") + .HasColumnType("datetime(6)"); + + b.HasKey("MessageId"); + + b.HasIndex("ClientId"); + + b.HasIndex("ServerId"); + + b.HasIndex("TimeSent"); + + b.ToTable("EFClientMessages"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFACSnapshot", b => { b.Property("SnapshotId") .ValueGeneratedOnAdd() @@ -113,137 +297,126 @@ namespace SharedLibraryCore.Migrations.MySql b.ToTable("EFACSnapshot"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshotVector3", b => + modelBuilder.Entity("Data.Models.Client.Stats.EFClientHitStatistic", b => { - b.Property("ACSnapshotVector3Id") + b.Property("ClientHitStatisticId") .ValueGeneratedOnAdd() .HasColumnType("int"); - b.Property("Active") - .HasColumnType("tinyint(1)"); - - b.Property("SnapshotId") - .HasColumnType("int"); - - b.Property("Vector3Id") - .HasColumnType("int"); - - b.HasKey("ACSnapshotVector3Id"); - - b.HasIndex("SnapshotId"); - - b.HasIndex("Vector3Id"); - - b.ToTable("EFACSnapshotVector3"); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b => - { - b.Property("KillId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Active") - .HasColumnType("tinyint(1)"); - - b.Property("AttackerId") - .HasColumnType("int"); - - b.Property("Damage") - .HasColumnType("int"); - - b.Property("DeathOriginVector3Id") - .HasColumnType("int"); - - b.Property("DeathType") - .HasColumnType("int"); - - b.Property("Fraction") - .HasColumnType("double"); - - b.Property("HitLoc") - .HasColumnType("int"); - - b.Property("IsKill") - .HasColumnType("tinyint(1)"); - - b.Property("KillOriginVector3Id") - .HasColumnType("int"); - - b.Property("Map") - .HasColumnType("int"); - - b.Property("ServerId") - .HasColumnType("bigint"); - - b.Property("VictimId") - .HasColumnType("int"); - - b.Property("ViewAnglesVector3Id") - .HasColumnType("int"); - - b.Property("VisibilityPercentage") - .HasColumnType("double"); - - b.Property("Weapon") - .HasColumnType("int"); - - b.Property("When") - .HasColumnType("datetime(6)"); - - b.HasKey("KillId"); - - b.HasIndex("AttackerId"); - - b.HasIndex("DeathOriginVector3Id"); - - b.HasIndex("KillOriginVector3Id"); - - b.HasIndex("ServerId"); - - b.HasIndex("VictimId"); - - b.HasIndex("ViewAnglesVector3Id"); - - b.ToTable("EFClientKills"); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientMessage", b => - { - b.Property("MessageId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Active") - .HasColumnType("tinyint(1)"); - b.Property("ClientId") .HasColumnType("int"); - b.Property("Message") - .HasColumnType("longtext CHARACTER SET utf8mb4"); - - b.Property("SentIngame") - .HasColumnType("tinyint(1)"); - - b.Property("ServerId") - .HasColumnType("bigint"); - - b.Property("TimeSent") + b.Property("CreatedDateTime") .HasColumnType("datetime(6)"); - b.HasKey("MessageId"); + b.Property("DamageInflicted") + .HasColumnType("int"); + + b.Property("DamageReceived") + .HasColumnType("int"); + + b.Property("DeathCount") + .HasColumnType("int"); + + b.Property("HitCount") + .HasColumnType("int"); + + b.Property("HitLocationId") + .HasColumnType("int"); + + b.Property("KillCount") + .HasColumnType("int"); + + b.Property("MeansOfDeathId") + .HasColumnType("int"); + + b.Property("ReceivedHitCount") + .HasColumnType("int"); + + b.Property("Score") + .HasColumnType("int"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("SuicideCount") + .HasColumnType("int"); + + b.Property("UpdatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("UsageSeconds") + .HasColumnType("int"); + + b.Property("WeaponAttachmentComboId") + .HasColumnType("int"); + + b.Property("WeaponId") + .HasColumnType("int"); + + b.HasKey("ClientHitStatisticId"); b.HasIndex("ClientId"); + b.HasIndex("HitLocationId"); + + b.HasIndex("MeansOfDeathId"); + b.HasIndex("ServerId"); - b.HasIndex("TimeSent"); + b.HasIndex("WeaponAttachmentComboId"); - b.ToTable("EFClientMessages"); + b.HasIndex("WeaponId"); + + b.ToTable("EFClientHitStatistics"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b => + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRankingHistory", b => + { + b.Property("ClientRankingHistoryId") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("ClientId") + .HasColumnType("int"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("Newest") + .HasColumnType("tinyint(1)"); + + b.Property("PerformanceMetric") + .HasColumnType("double"); + + b.Property("Ranking") + .HasColumnType("int"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("UpdatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("ZScore") + .HasColumnType("double"); + + b.HasKey("ClientRankingHistoryId"); + + b.HasIndex("ClientId"); + + b.HasIndex("Ranking"); + + b.HasIndex("ServerId"); + + b.HasIndex("UpdatedDateTime"); + + b.HasIndex("ZScore"); + + b.ToTable("EFClientRankingHistory"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRatingHistory", b => { b.Property("RatingHistoryId") .ValueGeneratedOnAdd() @@ -262,7 +435,7 @@ namespace SharedLibraryCore.Migrations.MySql b.ToTable("EFClientRatingHistory"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b => + modelBuilder.Entity("Data.Models.Client.Stats.EFClientStatistics", b => { b.Property("ClientId") .HasColumnType("int"); @@ -273,9 +446,6 @@ namespace SharedLibraryCore.Migrations.MySql b.Property("Active") .HasColumnType("tinyint(1)"); - b.Property("AverageRecoilOffset") - .HasColumnType("double"); - b.Property("AverageSnapValue") .HasColumnType("double"); @@ -306,17 +476,24 @@ namespace SharedLibraryCore.Migrations.MySql b.Property("TimePlayed") .HasColumnType("int"); - b.Property("VisionAverage") + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("ZScore") .HasColumnType("double"); b.HasKey("ClientId", "ServerId"); b.HasIndex("ServerId"); + b.HasIndex("ZScore"); + + b.HasIndex("ClientId", "TimePlayed", "ZScore"); + b.ToTable("EFClientStatistics"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b => + modelBuilder.Entity("Data.Models.Client.Stats.EFHitLocationCount", b => { b.Property("HitLocationCountId") .ValueGeneratedOnAdd() @@ -354,7 +531,7 @@ namespace SharedLibraryCore.Migrations.MySql b.ToTable("EFHitLocationCounts"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b => + modelBuilder.Entity("Data.Models.Client.Stats.EFRating", b => { b.Property("RatingId") .ValueGeneratedOnAdd() @@ -397,60 +574,166 @@ namespace SharedLibraryCore.Migrations.MySql b.ToTable("EFRating"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServer", b => + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFHitLocation", b => { - b.Property("ServerId") - .HasColumnType("bigint"); - - b.Property("Active") - .HasColumnType("tinyint(1)"); - - b.Property("EndPoint") - .HasColumnType("longtext CHARACTER SET utf8mb4"); - - b.Property("GameName") - .HasColumnType("int"); - - b.Property("HostName") - .HasColumnType("longtext CHARACTER SET utf8mb4"); - - b.Property("IsPasswordProtected") - .HasColumnType("tinyint(1)"); - - b.Property("Port") - .HasColumnType("int"); - - b.HasKey("ServerId"); - - b.ToTable("EFServers"); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b => - { - b.Property("StatisticId") + b.Property("HitLocationId") .ValueGeneratedOnAdd() .HasColumnType("int"); - b.Property("Active") - .HasColumnType("tinyint(1)"); + b.Property("CreatedDateTime") + .HasColumnType("datetime(6)"); - b.Property("ServerId") - .HasColumnType("bigint"); + b.Property("Game") + .HasColumnType("int"); - b.Property("TotalKills") - .HasColumnType("bigint"); + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); - b.Property("TotalPlayTime") - .HasColumnType("bigint"); + b.Property("UpdatedDateTime") + .HasColumnType("datetime(6)"); - b.HasKey("StatisticId"); + b.HasKey("HitLocationId"); - b.HasIndex("ServerId"); + b.HasIndex("Name"); - b.ToTable("EFServerStatistics"); + b.ToTable("EFHitLocations"); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b => + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFMap", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("Game") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UpdatedDateTime") + .HasColumnType("datetime(6)"); + + b.HasKey("MapId"); + + b.ToTable("EFMaps"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFMeansOfDeath", b => + { + b.Property("MeansOfDeathId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("Game") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UpdatedDateTime") + .HasColumnType("datetime(6)"); + + b.HasKey("MeansOfDeathId"); + + b.ToTable("EFMeansOfDeath"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeapon", b => + { + b.Property("WeaponId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("Game") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("UpdatedDateTime") + .HasColumnType("datetime(6)"); + + b.HasKey("WeaponId"); + + b.HasIndex("Name"); + + b.ToTable("EFWeapons"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachment", b => + { + b.Property("WeaponAttachmentId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("Game") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UpdatedDateTime") + .HasColumnType("datetime(6)"); + + b.HasKey("WeaponAttachmentId"); + + b.ToTable("EFWeaponAttachments"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", b => + { + b.Property("WeaponAttachmentComboId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Attachment1Id") + .HasColumnType("int"); + + b.Property("Attachment2Id") + .HasColumnType("int"); + + b.Property("Attachment3Id") + .HasColumnType("int"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("Game") + .HasColumnType("int"); + + b.Property("UpdatedDateTime") + .HasColumnType("datetime(6)"); + + b.HasKey("WeaponAttachmentComboId"); + + b.HasIndex("Attachment1Id"); + + b.HasIndex("Attachment2Id"); + + b.HasIndex("Attachment3Id"); + + b.ToTable("EFWeaponAttachmentCombos"); + }); + + modelBuilder.Entity("Data.Models.EFAlias", b => { b.Property("AliasId") .ValueGeneratedOnAdd() @@ -493,7 +776,7 @@ namespace SharedLibraryCore.Migrations.MySql b.ToTable("EFAlias"); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAliasLink", b => + modelBuilder.Entity("Data.Models.EFAliasLink", b => { b.Property("AliasLinkId") .ValueGeneratedOnAdd() @@ -507,7 +790,7 @@ namespace SharedLibraryCore.Migrations.MySql b.ToTable("EFAliasLinks"); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFChangeHistory", b => + modelBuilder.Entity("Data.Models.EFChangeHistory", b => { b.Property("ChangeHistoryId") .ValueGeneratedOnAdd() @@ -546,61 +829,7 @@ namespace SharedLibraryCore.Migrations.MySql b.ToTable("EFChangeHistory"); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b => - { - b.Property("ClientId") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("Active") - .HasColumnType("tinyint(1)"); - - b.Property("AliasLinkId") - .HasColumnType("int"); - - b.Property("Connections") - .HasColumnType("int"); - - b.Property("CurrentAliasId") - .HasColumnType("int"); - - b.Property("FirstConnection") - .HasColumnType("datetime(6)"); - - b.Property("LastConnection") - .HasColumnType("datetime(6)"); - - b.Property("Level") - .HasColumnType("int"); - - b.Property("Masked") - .HasColumnType("tinyint(1)"); - - b.Property("NetworkId") - .HasColumnType("bigint"); - - b.Property("Password") - .HasColumnType("longtext CHARACTER SET utf8mb4"); - - b.Property("PasswordSalt") - .HasColumnType("longtext CHARACTER SET utf8mb4"); - - b.Property("TotalConnectionTime") - .HasColumnType("int"); - - b.HasKey("ClientId"); - - b.HasIndex("AliasLinkId"); - - b.HasIndex("CurrentAliasId"); - - b.HasIndex("NetworkId") - .IsUnique(); - - b.ToTable("EFClients"); - }); - - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFMeta", b => + modelBuilder.Entity("Data.Models.EFMeta", b => { b.Property("MetaId") .ValueGeneratedOnAdd() @@ -644,7 +873,7 @@ namespace SharedLibraryCore.Migrations.MySql b.ToTable("EFMeta"); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b => + modelBuilder.Entity("Data.Models.EFPenalty", b => { b.Property("PenaltyId") .ValueGeneratedOnAdd() @@ -692,7 +921,60 @@ namespace SharedLibraryCore.Migrations.MySql b.ToTable("EFPenalties"); }); - modelBuilder.Entity("SharedLibraryCore.Helpers.Vector3", b => + modelBuilder.Entity("Data.Models.Server.EFServer", b => + { + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("EndPoint") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("GameName") + .HasColumnType("int"); + + b.Property("HostName") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("IsPasswordProtected") + .HasColumnType("tinyint(1)"); + + b.Property("Port") + .HasColumnType("int"); + + b.HasKey("ServerId"); + + b.ToTable("EFServers"); + }); + + modelBuilder.Entity("Data.Models.Server.EFServerStatistics", b => + { + b.Property("StatisticId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("TotalKills") + .HasColumnType("bigint"); + + b.Property("TotalPlayTime") + .HasColumnType("bigint"); + + b.HasKey("StatisticId"); + + b.HasIndex("ServerId"); + + b.ToTable("EFServerStatistics"); + }); + + modelBuilder.Entity("Data.Models.Vector3", b => { b.Property("Vector3Id") .ValueGeneratedOnAdd() @@ -712,225 +994,284 @@ namespace SharedLibraryCore.Migrations.MySql b.ToTable("Vector3"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b => + modelBuilder.Entity("Data.Models.Client.EFACSnapshotVector3", b => { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "CurrentViewAngle") - .WithMany() - .HasForeignKey("CurrentViewAngleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "HitDestination") - .WithMany() - .HasForeignKey("HitDestinationId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "HitOrigin") - .WithMany() - .HasForeignKey("HitOriginId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "LastStrainAngle") - .WithMany() - .HasForeignKey("LastStrainAngleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshotVector3", b => - { - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", "Snapshot") + b.HasOne("Data.Models.Client.Stats.EFACSnapshot", "Snapshot") .WithMany("PredictedViewAngles") .HasForeignKey("SnapshotId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("SharedLibraryCore.Helpers.Vector3", "Vector") + b.HasOne("Data.Models.Vector3", "Vector") .WithMany() .HasForeignKey("Vector3Id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b => + modelBuilder.Entity("Data.Models.Client.EFClient", b => { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Attacker") - .WithMany() - .HasForeignKey("AttackerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "DeathOrigin") - .WithMany() - .HasForeignKey("DeathOriginVector3Id"); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "KillOrigin") - .WithMany() - .HasForeignKey("KillOriginVector3Id"); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Victim") - .WithMany() - .HasForeignKey("VictimId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "ViewAngles") - .WithMany() - .HasForeignKey("ViewAnglesVector3Id"); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientMessage", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") - .WithMany() - .HasForeignKey("EFClientStatisticsClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("EFClientStatisticsServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", null) - .WithMany("HitLocations") - .HasForeignKey("EFClientStatisticsClientId", "EFClientStatisticsServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b => - { - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", "RatingHistory") - .WithMany("Ratings") - .HasForeignKey("RatingHistoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId"); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b => - { - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link") - .WithMany("Children") - .HasForeignKey("LinkId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - }); - - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "AliasLink") + b.HasOne("Data.Models.EFAliasLink", "AliasLink") .WithMany() .HasForeignKey("AliasLinkId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("SharedLibraryCore.Database.Models.EFAlias", "CurrentAlias") + b.HasOne("Data.Models.EFAlias", "CurrentAlias") .WithMany() .HasForeignKey("CurrentAliasId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFMeta", b => + modelBuilder.Entity("Data.Models.Client.EFClientKill", b => { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") + b.HasOne("Data.Models.Client.EFClient", "Attacker") + .WithMany() + .HasForeignKey("AttackerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "DeathOrigin") + .WithMany() + .HasForeignKey("DeathOriginVector3Id"); + + b.HasOne("Data.Models.Vector3", "KillOrigin") + .WithMany() + .HasForeignKey("KillOriginVector3Id"); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.EFClient", "Victim") + .WithMany() + .HasForeignKey("VictimId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "ViewAngles") + .WithMany() + .HasForeignKey("ViewAnglesVector3Id"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientMessage", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFACSnapshot", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "CurrentViewAngle") + .WithMany() + .HasForeignKey("CurrentViewAngleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "HitDestination") + .WithMany() + .HasForeignKey("HitDestinationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "HitOrigin") + .WithMany() + .HasForeignKey("HitOriginId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "LastStrainAngle") + .WithMany() + .HasForeignKey("LastStrainAngleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientHitStatistic", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.Reference.EFHitLocation", "HitLocation") + .WithMany() + .HasForeignKey("HitLocationId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFMeansOfDeath", "MeansOfDeath") + .WithMany() + .HasForeignKey("MeansOfDeathId"); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", "WeaponAttachmentCombo") + .WithMany() + .HasForeignKey("WeaponAttachmentComboId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeapon", "Weapon") + .WithMany() + .HasForeignKey("WeaponId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRankingHistory", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRatingHistory", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientStatistics", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFHitLocationCount", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("EFClientStatisticsClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("EFClientStatisticsServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.EFClientStatistics", null) + .WithMany("HitLocations") + .HasForeignKey("EFClientStatisticsClientId", "EFClientStatisticsServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFRating", b => + { + b.HasOne("Data.Models.Client.Stats.EFClientRatingHistory", "RatingHistory") + .WithMany("Ratings") + .HasForeignKey("RatingHistoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", b => + { + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment1") + .WithMany() + .HasForeignKey("Attachment1Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment2") + .WithMany() + .HasForeignKey("Attachment2Id"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment3") + .WithMany() + .HasForeignKey("Attachment3Id"); + }); + + modelBuilder.Entity("Data.Models.EFAlias", b => + { + b.HasOne("Data.Models.EFAliasLink", "Link") + .WithMany("Children") + .HasForeignKey("LinkId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.EFMeta", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") .WithMany("Meta") .HasForeignKey("ClientId"); - b.HasOne("SharedLibraryCore.Database.Models.EFMeta", "LinkedMeta") + b.HasOne("Data.Models.EFMeta", "LinkedMeta") .WithMany() .HasForeignKey("LinkedMetaId") .OnDelete(DeleteBehavior.SetNull); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b => + modelBuilder.Entity("Data.Models.EFPenalty", b => { - b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link") + b.HasOne("Data.Models.EFAliasLink", "Link") .WithMany("ReceivedPenalties") .HasForeignKey("LinkId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Offender") + b.HasOne("Data.Models.Client.EFClient", "Offender") .WithMany("ReceivedPenalties") .HasForeignKey("OffenderId") .OnDelete(DeleteBehavior.Restrict) .IsRequired(); - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Punisher") + b.HasOne("Data.Models.Client.EFClient", "Punisher") .WithMany("AdministeredPenalties") .HasForeignKey("PunisherId") .OnDelete(DeleteBehavior.Restrict) .IsRequired(); }); + + modelBuilder.Entity("Data.Models.Server.EFServerStatistics", b => + { + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); #pragma warning restore 612, 618 } } diff --git a/SharedLibraryCore/Migrations/Postgresql/20180409183408_InitialCreate.Designer.cs b/Data/Migrations/Postgresql/20180409183408_InitialCreate.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180409183408_InitialCreate.Designer.cs rename to Data/Migrations/Postgresql/20180409183408_InitialCreate.Designer.cs index 8bbe0b2e..3451fa60 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180409183408_InitialCreate.Designer.cs +++ b/Data/Migrations/Postgresql/20180409183408_InitialCreate.Designer.cs @@ -5,11 +5,11 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database; -using SharedLibraryCore.Database.MigrationContext; +using Data; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180409183408_InitialCreate")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180409183408_InitialCreate.cs b/Data/Migrations/Postgresql/20180409183408_InitialCreate.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180409183408_InitialCreate.cs rename to Data/Migrations/Postgresql/20180409183408_InitialCreate.cs index 4727c927..875817e6 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180409183408_InitialCreate.cs +++ b/Data/Migrations/Postgresql/20180409183408_InitialCreate.cs @@ -4,7 +4,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class InitialCreate : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180502195450_Update.Designer.cs b/Data/Migrations/Postgresql/20180502195450_Update.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180502195450_Update.Designer.cs rename to Data/Migrations/Postgresql/20180502195450_Update.Designer.cs index 7650eb20..8e824e9b 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180502195450_Update.Designer.cs +++ b/Data/Migrations/Postgresql/20180502195450_Update.Designer.cs @@ -5,11 +5,11 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database; -using SharedLibraryCore.Database.MigrationContext; +using Data; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180502195450_Update")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180502195450_Update.cs b/Data/Migrations/Postgresql/20180502195450_Update.cs similarity index 95% rename from SharedLibraryCore/Migrations/Sqlite/20180502195450_Update.cs rename to Data/Migrations/Postgresql/20180502195450_Update.cs index eebdb16d..7bb8993e 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180502195450_Update.cs +++ b/Data/Migrations/Postgresql/20180502195450_Update.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class Update : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180516023249_AddEloField.Designer.cs b/Data/Migrations/Postgresql/20180516023249_AddEloField.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180516023249_AddEloField.Designer.cs rename to Data/Migrations/Postgresql/20180516023249_AddEloField.Designer.cs index f887c6f4..a26a6fa5 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180516023249_AddEloField.Designer.cs +++ b/Data/Migrations/Postgresql/20180516023249_AddEloField.Designer.cs @@ -5,11 +5,11 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database; -using SharedLibraryCore.Database.MigrationContext; +using Data; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180516023249_AddEloField")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180516023249_AddEloField.cs b/Data/Migrations/Postgresql/20180516023249_AddEloField.cs similarity index 93% rename from SharedLibraryCore/Migrations/Sqlite/20180516023249_AddEloField.cs rename to Data/Migrations/Postgresql/20180516023249_AddEloField.cs index 0b6eb37a..c9717454 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180516023249_AddEloField.cs +++ b/Data/Migrations/Postgresql/20180516023249_AddEloField.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddEloField : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180517223349_AddRollingKDR.Designer.cs b/Data/Migrations/Postgresql/20180517223349_AddRollingKDR.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180517223349_AddRollingKDR.Designer.cs rename to Data/Migrations/Postgresql/20180517223349_AddRollingKDR.Designer.cs index 96739576..b8d9eff9 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180517223349_AddRollingKDR.Designer.cs +++ b/Data/Migrations/Postgresql/20180517223349_AddRollingKDR.Designer.cs @@ -5,11 +5,11 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database; -using SharedLibraryCore.Database.MigrationContext; +using Data; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180517223349_AddRollingKDR")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180517223349_AddRollingKDR.cs b/Data/Migrations/Postgresql/20180517223349_AddRollingKDR.cs similarity index 93% rename from SharedLibraryCore/Migrations/Sqlite/20180517223349_AddRollingKDR.cs rename to Data/Migrations/Postgresql/20180517223349_AddRollingKDR.cs index 83b39456..61f513f0 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180517223349_AddRollingKDR.cs +++ b/Data/Migrations/Postgresql/20180517223349_AddRollingKDR.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddRollingKDR : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs b/Data/Migrations/Postgresql/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs rename to Data/Migrations/Postgresql/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs index fcf2a27e..4c8f1831 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs +++ b/Data/Migrations/Postgresql/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs @@ -5,10 +5,10 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180531212903_AddAutomatedOffenseAndRatingHistory")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180531212903_AddAutomatedOffenseAndRatingHistory.cs b/Data/Migrations/Postgresql/20180531212903_AddAutomatedOffenseAndRatingHistory.cs similarity index 98% rename from SharedLibraryCore/Migrations/Sqlite/20180531212903_AddAutomatedOffenseAndRatingHistory.cs rename to Data/Migrations/Postgresql/20180531212903_AddAutomatedOffenseAndRatingHistory.cs index 1b597008..7f09e127 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180531212903_AddAutomatedOffenseAndRatingHistory.cs +++ b/Data/Migrations/Postgresql/20180531212903_AddAutomatedOffenseAndRatingHistory.cs @@ -4,7 +4,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddAutomatedOffenseAndRatingHistory : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180601172317_AddActivityAmount.Designer.cs b/Data/Migrations/Postgresql/20180601172317_AddActivityAmount.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180601172317_AddActivityAmount.Designer.cs rename to Data/Migrations/Postgresql/20180601172317_AddActivityAmount.Designer.cs index a2baa449..345efb90 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180601172317_AddActivityAmount.Designer.cs +++ b/Data/Migrations/Postgresql/20180601172317_AddActivityAmount.Designer.cs @@ -5,10 +5,10 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180601172317_AddActivityAmount")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180601172317_AddActivityAmount.cs b/Data/Migrations/Postgresql/20180601172317_AddActivityAmount.cs similarity index 93% rename from SharedLibraryCore/Migrations/Sqlite/20180601172317_AddActivityAmount.cs rename to Data/Migrations/Postgresql/20180601172317_AddActivityAmount.cs index 61ab0518..91462a0c 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180601172317_AddActivityAmount.cs +++ b/Data/Migrations/Postgresql/20180601172317_AddActivityAmount.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddActivityAmount : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180602041758_AddClientMeta.Designer.cs b/Data/Migrations/Postgresql/20180602041758_AddClientMeta.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180602041758_AddClientMeta.Designer.cs rename to Data/Migrations/Postgresql/20180602041758_AddClientMeta.Designer.cs index 7d17e01e..0ed37dd2 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180602041758_AddClientMeta.Designer.cs +++ b/Data/Migrations/Postgresql/20180602041758_AddClientMeta.Designer.cs @@ -5,10 +5,10 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180602041758_AddClientMeta")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180602041758_AddClientMeta.cs b/Data/Migrations/Postgresql/20180602041758_AddClientMeta.cs similarity index 97% rename from SharedLibraryCore/Migrations/Sqlite/20180602041758_AddClientMeta.cs rename to Data/Migrations/Postgresql/20180602041758_AddClientMeta.cs index 5fff4b5c..0a0e5336 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180602041758_AddClientMeta.cs +++ b/Data/Migrations/Postgresql/20180602041758_AddClientMeta.cs @@ -4,7 +4,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddClientMeta : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180605191706_AddEFACSnapshots.Designer.cs b/Data/Migrations/Postgresql/20180605191706_AddEFACSnapshots.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180605191706_AddEFACSnapshots.Designer.cs rename to Data/Migrations/Postgresql/20180605191706_AddEFACSnapshots.Designer.cs index dde715ca..7638414c 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180605191706_AddEFACSnapshots.Designer.cs +++ b/Data/Migrations/Postgresql/20180605191706_AddEFACSnapshots.Designer.cs @@ -5,10 +5,10 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180605191706_AddEFACSnapshots")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180605191706_AddEFACSnapshots.cs b/Data/Migrations/Postgresql/20180605191706_AddEFACSnapshots.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180605191706_AddEFACSnapshots.cs rename to Data/Migrations/Postgresql/20180605191706_AddEFACSnapshots.cs index bdf00e1c..39295860 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180605191706_AddEFACSnapshots.cs +++ b/Data/Migrations/Postgresql/20180605191706_AddEFACSnapshots.cs @@ -4,7 +4,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddEFACSnapshots : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180614014303_IndexForEFAlias.Designer.cs b/Data/Migrations/Postgresql/20180614014303_IndexForEFAlias.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180614014303_IndexForEFAlias.Designer.cs rename to Data/Migrations/Postgresql/20180614014303_IndexForEFAlias.Designer.cs index b55a67c9..350e0907 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180614014303_IndexForEFAlias.Designer.cs +++ b/Data/Migrations/Postgresql/20180614014303_IndexForEFAlias.Designer.cs @@ -5,10 +5,10 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180614014303_IndexForEFAlias")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180614014303_IndexForEFAlias.cs b/Data/Migrations/Postgresql/20180614014303_IndexForEFAlias.cs similarity index 93% rename from SharedLibraryCore/Migrations/Sqlite/20180614014303_IndexForEFAlias.cs rename to Data/Migrations/Postgresql/20180614014303_IndexForEFAlias.cs index de188ae2..023cbc32 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180614014303_IndexForEFAlias.cs +++ b/Data/Migrations/Postgresql/20180614014303_IndexForEFAlias.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class IndexForEFAlias : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180902035612_AddFractionAndIsKill.Designer.cs b/Data/Migrations/Postgresql/20180902035612_AddFractionAndIsKill.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180902035612_AddFractionAndIsKill.Designer.cs rename to Data/Migrations/Postgresql/20180902035612_AddFractionAndIsKill.Designer.cs index 454d1a42..ae0d6e45 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180902035612_AddFractionAndIsKill.Designer.cs +++ b/Data/Migrations/Postgresql/20180902035612_AddFractionAndIsKill.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180902035612_AddFractionAndIsKill")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180902035612_AddFractionAndIsKill.cs b/Data/Migrations/Postgresql/20180902035612_AddFractionAndIsKill.cs similarity index 98% rename from SharedLibraryCore/Migrations/Sqlite/20180902035612_AddFractionAndIsKill.cs rename to Data/Migrations/Postgresql/20180902035612_AddFractionAndIsKill.cs index be6423b4..078e7ed7 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180902035612_AddFractionAndIsKill.cs +++ b/Data/Migrations/Postgresql/20180902035612_AddFractionAndIsKill.cs @@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddFractionAndIsKill : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180904154622_AddVisibilityPercentage.Designer.cs b/Data/Migrations/Postgresql/20180904154622_AddVisibilityPercentage.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180904154622_AddVisibilityPercentage.Designer.cs rename to Data/Migrations/Postgresql/20180904154622_AddVisibilityPercentage.Designer.cs index afba0742..8399d5c5 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180904154622_AddVisibilityPercentage.Designer.cs +++ b/Data/Migrations/Postgresql/20180904154622_AddVisibilityPercentage.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180904154622_AddVisibilityPercentage")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180904154622_AddVisibilityPercentage.cs b/Data/Migrations/Postgresql/20180904154622_AddVisibilityPercentage.cs similarity index 93% rename from SharedLibraryCore/Migrations/Sqlite/20180904154622_AddVisibilityPercentage.cs rename to Data/Migrations/Postgresql/20180904154622_AddVisibilityPercentage.cs index 01407acc..edf762e2 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180904154622_AddVisibilityPercentage.cs +++ b/Data/Migrations/Postgresql/20180904154622_AddVisibilityPercentage.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddVisibilityPercentage : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180907020706_AddVision.Designer.cs b/Data/Migrations/Postgresql/20180907020706_AddVision.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180907020706_AddVision.Designer.cs rename to Data/Migrations/Postgresql/20180907020706_AddVision.Designer.cs index eb6d0fcb..1c27a829 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180907020706_AddVision.Designer.cs +++ b/Data/Migrations/Postgresql/20180907020706_AddVision.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180907020706_AddVision")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180907020706_AddVision.cs b/Data/Migrations/Postgresql/20180907020706_AddVision.cs similarity index 93% rename from SharedLibraryCore/Migrations/Sqlite/20180907020706_AddVision.cs rename to Data/Migrations/Postgresql/20180907020706_AddVision.cs index 80ac8fe6..e8ad8ca9 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180907020706_AddVision.cs +++ b/Data/Migrations/Postgresql/20180907020706_AddVision.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddVision : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180908004053_AddWhenToRating.Designer.cs b/Data/Migrations/Postgresql/20180908004053_AddWhenToRating.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180908004053_AddWhenToRating.Designer.cs rename to Data/Migrations/Postgresql/20180908004053_AddWhenToRating.Designer.cs index 9411e8d1..83dfcb77 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180908004053_AddWhenToRating.Designer.cs +++ b/Data/Migrations/Postgresql/20180908004053_AddWhenToRating.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180908004053_AddWhenToRating")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180908004053_AddWhenToRating.cs b/Data/Migrations/Postgresql/20180908004053_AddWhenToRating.cs similarity index 93% rename from SharedLibraryCore/Migrations/Sqlite/20180908004053_AddWhenToRating.cs rename to Data/Migrations/Postgresql/20180908004053_AddWhenToRating.cs index 1af6caa4..2a1ee398 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180908004053_AddWhenToRating.cs +++ b/Data/Migrations/Postgresql/20180908004053_AddWhenToRating.cs @@ -1,7 +1,7 @@ using System; using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddWhenToRating : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180910221749_AddRatingIndexes.Designer.cs b/Data/Migrations/Postgresql/20180910221749_AddRatingIndexes.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180910221749_AddRatingIndexes.Designer.cs rename to Data/Migrations/Postgresql/20180910221749_AddRatingIndexes.Designer.cs index 06dfdf36..60b19bf8 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180910221749_AddRatingIndexes.Designer.cs +++ b/Data/Migrations/Postgresql/20180910221749_AddRatingIndexes.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180910221749_AddRatingIndexes")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180910221749_AddRatingIndexes.cs b/Data/Migrations/Postgresql/20180910221749_AddRatingIndexes.cs similarity index 96% rename from SharedLibraryCore/Migrations/Sqlite/20180910221749_AddRatingIndexes.cs rename to Data/Migrations/Postgresql/20180910221749_AddRatingIndexes.cs index 5f634a08..0bf904ba 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180910221749_AddRatingIndexes.cs +++ b/Data/Migrations/Postgresql/20180910221749_AddRatingIndexes.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddRatingIndexes : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180911184224_AddEFAliasNameIndex.Designer.cs b/Data/Migrations/Postgresql/20180911184224_AddEFAliasNameIndex.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180911184224_AddEFAliasNameIndex.Designer.cs rename to Data/Migrations/Postgresql/20180911184224_AddEFAliasNameIndex.Designer.cs index e8acef8c..368de2c2 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180911184224_AddEFAliasNameIndex.Designer.cs +++ b/Data/Migrations/Postgresql/20180911184224_AddEFAliasNameIndex.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180911184224_AddEFAliasNameIndex")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180911184224_AddEFAliasNameIndex.cs b/Data/Migrations/Postgresql/20180911184224_AddEFAliasNameIndex.cs similarity index 92% rename from SharedLibraryCore/Migrations/Sqlite/20180911184224_AddEFAliasNameIndex.cs rename to Data/Migrations/Postgresql/20180911184224_AddEFAliasNameIndex.cs index ab34699e..9eacd55e 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180911184224_AddEFAliasNameIndex.cs +++ b/Data/Migrations/Postgresql/20180911184224_AddEFAliasNameIndex.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddEFAliasNameIndex : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180911190823_AddEFAliasNameMaxLength24.Designer.cs b/Data/Migrations/Postgresql/20180911190823_AddEFAliasNameMaxLength24.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180911190823_AddEFAliasNameMaxLength24.Designer.cs rename to Data/Migrations/Postgresql/20180911190823_AddEFAliasNameMaxLength24.Designer.cs index 8aabb7cc..dc157f40 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180911190823_AddEFAliasNameMaxLength24.Designer.cs +++ b/Data/Migrations/Postgresql/20180911190823_AddEFAliasNameMaxLength24.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180911190823_AddEFAliasNameMaxLength24")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180911190823_AddEFAliasNameMaxLength24.cs b/Data/Migrations/Postgresql/20180911190823_AddEFAliasNameMaxLength24.cs similarity index 94% rename from SharedLibraryCore/Migrations/Sqlite/20180911190823_AddEFAliasNameMaxLength24.cs rename to Data/Migrations/Postgresql/20180911190823_AddEFAliasNameMaxLength24.cs index 6389196c..6b7dedc9 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180911190823_AddEFAliasNameMaxLength24.cs +++ b/Data/Migrations/Postgresql/20180911190823_AddEFAliasNameMaxLength24.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddEFAliasNameMaxLength24 : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs b/Data/Migrations/Postgresql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs rename to Data/Migrations/Postgresql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs index cb9cc3c0..86563a50 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs +++ b/Data/Migrations/Postgresql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180912015012_AddPreviousCurrentValueToEFChangeHistory")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs b/Data/Migrations/Postgresql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs similarity index 95% rename from SharedLibraryCore/Migrations/Sqlite/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs rename to Data/Migrations/Postgresql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs index 195bbda0..a73b27f9 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs +++ b/Data/Migrations/Postgresql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddPreviousCurrentValueToEFChangeHistory : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180915163111_AddIndexToMessageTimeSent.Designer.cs b/Data/Migrations/Postgresql/20180915163111_AddIndexToMessageTimeSent.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180915163111_AddIndexToMessageTimeSent.Designer.cs rename to Data/Migrations/Postgresql/20180915163111_AddIndexToMessageTimeSent.Designer.cs index 30151d62..2148bbbd 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180915163111_AddIndexToMessageTimeSent.Designer.cs +++ b/Data/Migrations/Postgresql/20180915163111_AddIndexToMessageTimeSent.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180915163111_AddIndexToMessageTimeSent")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180915163111_AddIndexToMessageTimeSent.cs b/Data/Migrations/Postgresql/20180915163111_AddIndexToMessageTimeSent.cs similarity index 93% rename from SharedLibraryCore/Migrations/Sqlite/20180915163111_AddIndexToMessageTimeSent.cs rename to Data/Migrations/Postgresql/20180915163111_AddIndexToMessageTimeSent.cs index 9e82c11d..befe3b6f 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180915163111_AddIndexToMessageTimeSent.cs +++ b/Data/Migrations/Postgresql/20180915163111_AddIndexToMessageTimeSent.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddIndexToMessageTimeSent : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180922231310_RemoveACSnapShot.Designer.cs b/Data/Migrations/Postgresql/20180922231310_RemoveACSnapShot.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180922231310_RemoveACSnapShot.Designer.cs rename to Data/Migrations/Postgresql/20180922231310_RemoveACSnapShot.Designer.cs index d8731227..e4abed3e 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180922231310_RemoveACSnapShot.Designer.cs +++ b/Data/Migrations/Postgresql/20180922231310_RemoveACSnapShot.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180922231310_RemoveACSnapShot")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180922231310_RemoveACSnapShot.cs b/Data/Migrations/Postgresql/20180922231310_RemoveACSnapShot.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180922231310_RemoveACSnapShot.cs rename to Data/Migrations/Postgresql/20180922231310_RemoveACSnapShot.cs index 60d4622a..d323c010 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180922231310_RemoveACSnapShot.cs +++ b/Data/Migrations/Postgresql/20180922231310_RemoveACSnapShot.cs @@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class RemoveACSnapShot : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20180922231600_ReaddACSnapshot.Designer.cs b/Data/Migrations/Postgresql/20180922231600_ReaddACSnapshot.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180922231600_ReaddACSnapshot.Designer.cs rename to Data/Migrations/Postgresql/20180922231600_ReaddACSnapshot.Designer.cs index e7917a40..ee70ee2a 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180922231600_ReaddACSnapshot.Designer.cs +++ b/Data/Migrations/Postgresql/20180922231600_ReaddACSnapshot.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20180922231600_ReaddACSnapshot")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20180922231600_ReaddACSnapshot.cs b/Data/Migrations/Postgresql/20180922231600_ReaddACSnapshot.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180922231600_ReaddACSnapshot.cs rename to Data/Migrations/Postgresql/20180922231600_ReaddACSnapshot.cs index 849f683d..692464b1 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180922231600_ReaddACSnapshot.cs +++ b/Data/Migrations/Postgresql/20180922231600_ReaddACSnapshot.cs @@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class ReaddACSnapshot : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20181014171848_MakePenaltyExpirationNullable.Designer.cs b/Data/Migrations/Postgresql/20181014171848_MakePenaltyExpirationNullable.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20181014171848_MakePenaltyExpirationNullable.Designer.cs rename to Data/Migrations/Postgresql/20181014171848_MakePenaltyExpirationNullable.Designer.cs index 97e85323..7074cdb4 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20181014171848_MakePenaltyExpirationNullable.Designer.cs +++ b/Data/Migrations/Postgresql/20181014171848_MakePenaltyExpirationNullable.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20181014171848_MakePenaltyExpirationNullable")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20181014171848_MakePenaltyExpirationNullable.cs b/Data/Migrations/Postgresql/20181014171848_MakePenaltyExpirationNullable.cs similarity index 98% rename from SharedLibraryCore/Migrations/Sqlite/20181014171848_MakePenaltyExpirationNullable.cs rename to Data/Migrations/Postgresql/20181014171848_MakePenaltyExpirationNullable.cs index 7a1815e5..7e8b135e 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20181014171848_MakePenaltyExpirationNullable.cs +++ b/Data/Migrations/Postgresql/20181014171848_MakePenaltyExpirationNullable.cs @@ -1,7 +1,7 @@ using System; using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class MakePenaltyExpirationNullable : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20181125193243_MakeClientIPNullable.Designer.cs b/Data/Migrations/Postgresql/20181125193243_MakeClientIPNullable.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20181125193243_MakeClientIPNullable.Designer.cs rename to Data/Migrations/Postgresql/20181125193243_MakeClientIPNullable.Designer.cs index 9ce5daa4..87d84283 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20181125193243_MakeClientIPNullable.Designer.cs +++ b/Data/Migrations/Postgresql/20181125193243_MakeClientIPNullable.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20181125193243_MakeClientIPNullable")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20181125193243_MakeClientIPNullable.cs b/Data/Migrations/Postgresql/20181125193243_MakeClientIPNullable.cs similarity index 98% rename from SharedLibraryCore/Migrations/Sqlite/20181125193243_MakeClientIPNullable.cs rename to Data/Migrations/Postgresql/20181125193243_MakeClientIPNullable.cs index 0d201fe5..d42d43bc 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20181125193243_MakeClientIPNullable.cs +++ b/Data/Migrations/Postgresql/20181125193243_MakeClientIPNullable.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class MakeClientIPNullable : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs b/Data/Migrations/Postgresql/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs rename to Data/Migrations/Postgresql/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs index df4a6f0e..df8769fa 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs +++ b/Data/Migrations/Postgresql/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20181127144417_AddEndpointToEFServerUpdateServerIdType")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs b/Data/Migrations/Postgresql/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs similarity index 92% rename from SharedLibraryCore/Migrations/Sqlite/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs rename to Data/Migrations/Postgresql/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs index 284d5fa3..4316ea65 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs +++ b/Data/Migrations/Postgresql/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddEndpointToEFServerUpdateServerIdType : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20181216214513_AddEvadePenaltyFlag.Designer.cs b/Data/Migrations/Postgresql/20181216214513_AddEvadePenaltyFlag.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20181216214513_AddEvadePenaltyFlag.Designer.cs rename to Data/Migrations/Postgresql/20181216214513_AddEvadePenaltyFlag.Designer.cs index f006af9e..57ec2be7 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20181216214513_AddEvadePenaltyFlag.Designer.cs +++ b/Data/Migrations/Postgresql/20181216214513_AddEvadePenaltyFlag.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20181216214513_AddEvadePenaltyFlag")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20181216214513_AddEvadePenaltyFlag.cs b/Data/Migrations/Postgresql/20181216214513_AddEvadePenaltyFlag.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20181216214513_AddEvadePenaltyFlag.cs rename to Data/Migrations/Postgresql/20181216214513_AddEvadePenaltyFlag.cs index 0d49cc07..e28d3e18 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20181216214513_AddEvadePenaltyFlag.cs +++ b/Data/Migrations/Postgresql/20181216214513_AddEvadePenaltyFlag.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddEvadePenaltyFlag : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs b/Data/Migrations/Postgresql/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs rename to Data/Migrations/Postgresql/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs index 81f02781..c6201e32 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs +++ b/Data/Migrations/Postgresql/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20190222234742_AddIndexToEFMeta-KeyAndClientId")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs b/Data/Migrations/Postgresql/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs similarity index 94% rename from SharedLibraryCore/Migrations/Sqlite/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs rename to Data/Migrations/Postgresql/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs index 10b7fbd9..7020b88b 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs +++ b/Data/Migrations/Postgresql/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddIndexToEFMetaKeyAndClientId : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20190423142128_AddGameNameToEFServer.Designer.cs b/Data/Migrations/Postgresql/20190423142128_AddGameNameToEFServer.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20190423142128_AddGameNameToEFServer.Designer.cs rename to Data/Migrations/Postgresql/20190423142128_AddGameNameToEFServer.Designer.cs index f57d2e45..7bc3148f 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190423142128_AddGameNameToEFServer.Designer.cs +++ b/Data/Migrations/Postgresql/20190423142128_AddGameNameToEFServer.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20190423142128_AddGameNameToEFServer")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20190423142128_AddGameNameToEFServer.cs b/Data/Migrations/Postgresql/20190423142128_AddGameNameToEFServer.cs similarity index 92% rename from SharedLibraryCore/Migrations/Sqlite/20190423142128_AddGameNameToEFServer.cs rename to Data/Migrations/Postgresql/20190423142128_AddGameNameToEFServer.cs index ded914a9..a1213ae4 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190423142128_AddGameNameToEFServer.cs +++ b/Data/Migrations/Postgresql/20190423142128_AddGameNameToEFServer.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddGameNameToEFServer : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20190615145212_AddAvgRecoilOffset.Designer.cs b/Data/Migrations/Postgresql/20190615145212_AddAvgRecoilOffset.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20190615145212_AddAvgRecoilOffset.Designer.cs rename to Data/Migrations/Postgresql/20190615145212_AddAvgRecoilOffset.Designer.cs index 789c7b13..7dd07039 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190615145212_AddAvgRecoilOffset.Designer.cs +++ b/Data/Migrations/Postgresql/20190615145212_AddAvgRecoilOffset.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20190615145212_AddAvgRecoilOffset")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20190615145212_AddAvgRecoilOffset.cs b/Data/Migrations/Postgresql/20190615145212_AddAvgRecoilOffset.cs similarity index 91% rename from SharedLibraryCore/Migrations/Sqlite/20190615145212_AddAvgRecoilOffset.cs rename to Data/Migrations/Postgresql/20190615145212_AddAvgRecoilOffset.cs index ccd978c6..b773ce7a 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190615145212_AddAvgRecoilOffset.cs +++ b/Data/Migrations/Postgresql/20190615145212_AddAvgRecoilOffset.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddAvgRecoilOffset : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs b/Data/Migrations/Postgresql/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs rename to Data/Migrations/Postgresql/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs index 54190afc..3ba79fe2 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs +++ b/Data/Migrations/Postgresql/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20190615214055_AddRecoilOffsetToSnapshot")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20190615214055_AddRecoilOffsetToSnapshot.cs b/Data/Migrations/Postgresql/20190615214055_AddRecoilOffsetToSnapshot.cs similarity index 93% rename from SharedLibraryCore/Migrations/Sqlite/20190615214055_AddRecoilOffsetToSnapshot.cs rename to Data/Migrations/Postgresql/20190615214055_AddRecoilOffsetToSnapshot.cs index 5256281c..b795ec0a 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190615214055_AddRecoilOffsetToSnapshot.cs +++ b/Data/Migrations/Postgresql/20190615214055_AddRecoilOffsetToSnapshot.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddRecoilOffsetToSnapshot : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20190725000309_AlterEFRatingIndex.Designer.cs b/Data/Migrations/Postgresql/20190725000309_AlterEFRatingIndex.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20190725000309_AlterEFRatingIndex.Designer.cs rename to Data/Migrations/Postgresql/20190725000309_AlterEFRatingIndex.Designer.cs index 52a49551..12e9502e 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190725000309_AlterEFRatingIndex.Designer.cs +++ b/Data/Migrations/Postgresql/20190725000309_AlterEFRatingIndex.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20190725000309_AlterEFRatingIndex")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20190725000309_AlterEFRatingIndex.cs b/Data/Migrations/Postgresql/20190725000309_AlterEFRatingIndex.cs similarity index 97% rename from SharedLibraryCore/Migrations/Sqlite/20190725000309_AlterEFRatingIndex.cs rename to Data/Migrations/Postgresql/20190725000309_AlterEFRatingIndex.cs index 74d61590..35227abd 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190725000309_AlterEFRatingIndex.cs +++ b/Data/Migrations/Postgresql/20190725000309_AlterEFRatingIndex.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AlterEFRatingIndex : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20190802174908_AddSearchNameToEFAlias.Designer.cs b/Data/Migrations/Postgresql/20190802174908_AddSearchNameToEFAlias.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20190802174908_AddSearchNameToEFAlias.Designer.cs rename to Data/Migrations/Postgresql/20190802174908_AddSearchNameToEFAlias.Designer.cs index 02226b02..8c2ecafa 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190802174908_AddSearchNameToEFAlias.Designer.cs +++ b/Data/Migrations/Postgresql/20190802174908_AddSearchNameToEFAlias.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20190802174908_AddSearchNameToEFAlias")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20190802174908_AddSearchNameToEFAlias.cs b/Data/Migrations/Postgresql/20190802174908_AddSearchNameToEFAlias.cs similarity index 95% rename from SharedLibraryCore/Migrations/Sqlite/20190802174908_AddSearchNameToEFAlias.cs rename to Data/Migrations/Postgresql/20190802174908_AddSearchNameToEFAlias.cs index c9dc245b..ea9518eb 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190802174908_AddSearchNameToEFAlias.cs +++ b/Data/Migrations/Postgresql/20190802174908_AddSearchNameToEFAlias.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddSearchNameToEFAlias : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20190831210503_AvgSnapValueToClientStatistics.Designer.cs b/Data/Migrations/Postgresql/20190831210503_AvgSnapValueToClientStatistics.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20190831210503_AvgSnapValueToClientStatistics.Designer.cs rename to Data/Migrations/Postgresql/20190831210503_AvgSnapValueToClientStatistics.Designer.cs index b0c541ff..db84c9cd 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190831210503_AvgSnapValueToClientStatistics.Designer.cs +++ b/Data/Migrations/Postgresql/20190831210503_AvgSnapValueToClientStatistics.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20190831210503_AvgSnapValueToClientStatistics")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20190831210503_AvgSnapValueToClientStatistics.cs b/Data/Migrations/Postgresql/20190831210503_AvgSnapValueToClientStatistics.cs similarity index 93% rename from SharedLibraryCore/Migrations/Sqlite/20190831210503_AvgSnapValueToClientStatistics.cs rename to Data/Migrations/Postgresql/20190831210503_AvgSnapValueToClientStatistics.cs index 944173d5..63bc2285 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190831210503_AvgSnapValueToClientStatistics.cs +++ b/Data/Migrations/Postgresql/20190831210503_AvgSnapValueToClientStatistics.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AvgSnapValueToClientStatistics : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs b/Data/Migrations/Postgresql/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs rename to Data/Migrations/Postgresql/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs index c4100f24..9073923b 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs +++ b/Data/Migrations/Postgresql/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20190901180209_AddSnapHitCountToClientStatistics")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20190901180209_AddSnapHitCountToClientStatistics.cs b/Data/Migrations/Postgresql/20190901180209_AddSnapHitCountToClientStatistics.cs similarity index 93% rename from SharedLibraryCore/Migrations/Sqlite/20190901180209_AddSnapHitCountToClientStatistics.cs rename to Data/Migrations/Postgresql/20190901180209_AddSnapHitCountToClientStatistics.cs index 96c9161d..68c7a0bc 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190901180209_AddSnapHitCountToClientStatistics.cs +++ b/Data/Migrations/Postgresql/20190901180209_AddSnapHitCountToClientStatistics.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddSnapHitCountToClientStatistics : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs b/Data/Migrations/Postgresql/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs rename to Data/Migrations/Postgresql/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs index 631b0a20..457053ea 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs +++ b/Data/Migrations/Postgresql/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20190901223620_UseJunctionTableForSnapshotVector3")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20190901223620_UseJunctionTableForSnapshotVector3.cs b/Data/Migrations/Postgresql/20190901223620_UseJunctionTableForSnapshotVector3.cs similarity index 98% rename from SharedLibraryCore/Migrations/Sqlite/20190901223620_UseJunctionTableForSnapshotVector3.cs rename to Data/Migrations/Postgresql/20190901223620_UseJunctionTableForSnapshotVector3.cs index b4a816b8..5ba63045 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190901223620_UseJunctionTableForSnapshotVector3.cs +++ b/Data/Migrations/Postgresql/20190901223620_UseJunctionTableForSnapshotVector3.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class UseJunctionTableForSnapshotVector3 : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs b/Data/Migrations/Postgresql/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs rename to Data/Migrations/Postgresql/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs index 9ffe59a6..662afbc4 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs +++ b/Data/Migrations/Postgresql/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20190914011524_AddCurrentSnapValueToSnapshot")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20190914011524_AddCurrentSnapValueToSnapshot.cs b/Data/Migrations/Postgresql/20190914011524_AddCurrentSnapValueToSnapshot.cs similarity index 93% rename from SharedLibraryCore/Migrations/Sqlite/20190914011524_AddCurrentSnapValueToSnapshot.cs rename to Data/Migrations/Postgresql/20190914011524_AddCurrentSnapValueToSnapshot.cs index 3dc2405b..5a67832e 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190914011524_AddCurrentSnapValueToSnapshot.cs +++ b/Data/Migrations/Postgresql/20190914011524_AddCurrentSnapValueToSnapshot.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddCurrentSnapValueToSnapshot : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs b/Data/Migrations/Postgresql/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs rename to Data/Migrations/Postgresql/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs index 8bcd882a..6ee298ee 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs +++ b/Data/Migrations/Postgresql/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20190914012015_AddSessionSnapHitsToSnapshot")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20190914012015_AddSessionSnapHitsToSnapshot.cs b/Data/Migrations/Postgresql/20190914012015_AddSessionSnapHitsToSnapshot.cs similarity index 93% rename from SharedLibraryCore/Migrations/Sqlite/20190914012015_AddSessionSnapHitsToSnapshot.cs rename to Data/Migrations/Postgresql/20190914012015_AddSessionSnapHitsToSnapshot.cs index 4f233b2f..c867a1e1 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190914012015_AddSessionSnapHitsToSnapshot.cs +++ b/Data/Migrations/Postgresql/20190914012015_AddSessionSnapHitsToSnapshot.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddSessionSnapHitsToSnapshot : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20191004172550_RenameClientHitLocationCountColumns.Designer.cs b/Data/Migrations/Postgresql/20191004172550_RenameClientHitLocationCountColumns.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20191004172550_RenameClientHitLocationCountColumns.Designer.cs rename to Data/Migrations/Postgresql/20191004172550_RenameClientHitLocationCountColumns.Designer.cs index fe2cc55a..da6301d6 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20191004172550_RenameClientHitLocationCountColumns.Designer.cs +++ b/Data/Migrations/Postgresql/20191004172550_RenameClientHitLocationCountColumns.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20191004172550_RenameClientHitLocationCountColumns")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20191004172550_RenameClientHitLocationCountColumns.cs b/Data/Migrations/Postgresql/20191004172550_RenameClientHitLocationCountColumns.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20191004172550_RenameClientHitLocationCountColumns.cs rename to Data/Migrations/Postgresql/20191004172550_RenameClientHitLocationCountColumns.cs index 92c6fe9b..acb9222d 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20191004172550_RenameClientHitLocationCountColumns.cs +++ b/Data/Migrations/Postgresql/20191004172550_RenameClientHitLocationCountColumns.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class RenameClientHitLocationCountColumns : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs b/Data/Migrations/Postgresql/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs rename to Data/Migrations/Postgresql/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs index 84f64a95..8eec0d3f 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs +++ b/Data/Migrations/Postgresql/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20191030000713_EnforceUniqueIndexForEFAliasIPName")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs b/Data/Migrations/Postgresql/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs similarity index 98% rename from SharedLibraryCore/Migrations/Sqlite/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs rename to Data/Migrations/Postgresql/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs index 5e713f81..38e762ff 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs +++ b/Data/Migrations/Postgresql/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class EnforceUniqueIndexForEFAliasIPName : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs b/Data/Migrations/Postgresql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs rename to Data/Migrations/Postgresql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs index 525481e7..190001b9 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs +++ b/Data/Migrations/Postgresql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs b/Data/Migrations/Postgresql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs similarity index 94% rename from SharedLibraryCore/Migrations/Sqlite/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs rename to Data/Migrations/Postgresql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs index 38b6b619..c276533a 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs +++ b/Data/Migrations/Postgresql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class SetCaseSensitiveCoallationForAliasNameMySQL : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20191230140947_AddMissingActiveColumns.Designer.cs b/Data/Migrations/Postgresql/20191230140947_AddMissingActiveColumns.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20191230140947_AddMissingActiveColumns.Designer.cs rename to Data/Migrations/Postgresql/20191230140947_AddMissingActiveColumns.Designer.cs index c6bf3eee..3eb09d83 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20191230140947_AddMissingActiveColumns.Designer.cs +++ b/Data/Migrations/Postgresql/20191230140947_AddMissingActiveColumns.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20191230140947_AddMissingActiveColumns")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20191230140947_AddMissingActiveColumns.cs b/Data/Migrations/Postgresql/20191230140947_AddMissingActiveColumns.cs similarity index 93% rename from SharedLibraryCore/Migrations/Sqlite/20191230140947_AddMissingActiveColumns.cs rename to Data/Migrations/Postgresql/20191230140947_AddMissingActiveColumns.cs index 58ee70ea..6e6262bc 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20191230140947_AddMissingActiveColumns.cs +++ b/Data/Migrations/Postgresql/20191230140947_AddMissingActiveColumns.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddMissingActiveColumns : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs b/Data/Migrations/Postgresql/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs rename to Data/Migrations/Postgresql/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs index 5497e0c8..b268d8f4 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs +++ b/Data/Migrations/Postgresql/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20200423225137_AddImpersonationIdToEFChangeHistory")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20200423225137_AddImpersonationIdToEFChangeHistory.cs b/Data/Migrations/Postgresql/20200423225137_AddImpersonationIdToEFChangeHistory.cs similarity index 93% rename from SharedLibraryCore/Migrations/Sqlite/20200423225137_AddImpersonationIdToEFChangeHistory.cs rename to Data/Migrations/Postgresql/20200423225137_AddImpersonationIdToEFChangeHistory.cs index cadd981f..9fde7662 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20200423225137_AddImpersonationIdToEFChangeHistory.cs +++ b/Data/Migrations/Postgresql/20200423225137_AddImpersonationIdToEFChangeHistory.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddImpersonationIdToEFChangeHistory : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20200521203304_AddHostnameToEFServer.Designer.cs b/Data/Migrations/Postgresql/20200521203304_AddHostnameToEFServer.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20200521203304_AddHostnameToEFServer.Designer.cs rename to Data/Migrations/Postgresql/20200521203304_AddHostnameToEFServer.Designer.cs index c25872e6..62ee61ca 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20200521203304_AddHostnameToEFServer.Designer.cs +++ b/Data/Migrations/Postgresql/20200521203304_AddHostnameToEFServer.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20200521203304_AddHostnameToEFServer")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20200521203304_AddHostnameToEFServer.cs b/Data/Migrations/Postgresql/20200521203304_AddHostnameToEFServer.cs similarity index 92% rename from SharedLibraryCore/Migrations/Sqlite/20200521203304_AddHostnameToEFServer.cs rename to Data/Migrations/Postgresql/20200521203304_AddHostnameToEFServer.cs index 79c48c9b..db12b317 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20200521203304_AddHostnameToEFServer.cs +++ b/Data/Migrations/Postgresql/20200521203304_AddHostnameToEFServer.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddHostnameToEFServer : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20200819224119_AddIsPasswordProtectedColumn.Designer.cs b/Data/Migrations/Postgresql/20200819224119_AddIsPasswordProtectedColumn.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20200819224119_AddIsPasswordProtectedColumn.Designer.cs rename to Data/Migrations/Postgresql/20200819224119_AddIsPasswordProtectedColumn.Designer.cs index ac88256b..ac804832 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20200819224119_AddIsPasswordProtectedColumn.Designer.cs +++ b/Data/Migrations/Postgresql/20200819224119_AddIsPasswordProtectedColumn.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20200819224119_AddIsPasswordProtectedColumn")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20200819224119_AddIsPasswordProtectedColumn.cs b/Data/Migrations/Postgresql/20200819224119_AddIsPasswordProtectedColumn.cs similarity index 95% rename from SharedLibraryCore/Migrations/Sqlite/20200819224119_AddIsPasswordProtectedColumn.cs rename to Data/Migrations/Postgresql/20200819224119_AddIsPasswordProtectedColumn.cs index 506be9b7..a4d42d66 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20200819224119_AddIsPasswordProtectedColumn.cs +++ b/Data/Migrations/Postgresql/20200819224119_AddIsPasswordProtectedColumn.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddIsPasswordProtectedColumn : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20201114232340_UpdateEFRatingIndex.Designer.cs b/Data/Migrations/Postgresql/20201114232340_UpdateEFRatingIndex.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20201114232340_UpdateEFRatingIndex.Designer.cs rename to Data/Migrations/Postgresql/20201114232340_UpdateEFRatingIndex.Designer.cs index 9c968e9a..7f584512 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20201114232340_UpdateEFRatingIndex.Designer.cs +++ b/Data/Migrations/Postgresql/20201114232340_UpdateEFRatingIndex.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20201114232340_UpdateEFRatingIndex")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20201114232340_UpdateEFRatingIndex.cs b/Data/Migrations/Postgresql/20201114232340_UpdateEFRatingIndex.cs similarity index 93% rename from SharedLibraryCore/Migrations/Sqlite/20201114232340_UpdateEFRatingIndex.cs rename to Data/Migrations/Postgresql/20201114232340_UpdateEFRatingIndex.cs index 2f476b00..b6bdeb85 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20201114232340_UpdateEFRatingIndex.cs +++ b/Data/Migrations/Postgresql/20201114232340_UpdateEFRatingIndex.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class UpdateEFRatingIndex : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs b/Data/Migrations/Postgresql/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs rename to Data/Migrations/Postgresql/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs index 1aa80f9b..f1cb660c 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs +++ b/Data/Migrations/Postgresql/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20201118023106_AddSentIngameFlagToClientMessage")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20201118023106_AddSentIngameFlagToClientMessage.cs b/Data/Migrations/Postgresql/20201118023106_AddSentIngameFlagToClientMessage.cs similarity index 93% rename from SharedLibraryCore/Migrations/Sqlite/20201118023106_AddSentIngameFlagToClientMessage.cs rename to Data/Migrations/Postgresql/20201118023106_AddSentIngameFlagToClientMessage.cs index 48300e72..df056f48 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20201118023106_AddSentIngameFlagToClientMessage.cs +++ b/Data/Migrations/Postgresql/20201118023106_AddSentIngameFlagToClientMessage.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Postgresql { public partial class AddSentIngameFlagToClientMessage : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20201125160058_UpdateMigrationsForPostgresql.Designer.cs b/Data/Migrations/Postgresql/20201125160058_UpdateMigrationsForPostgresql.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20201125160058_UpdateMigrationsForPostgresql.Designer.cs rename to Data/Migrations/Postgresql/20201125160058_UpdateMigrationsForPostgresql.Designer.cs index 7f27b9c0..63d5b10f 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20201125160058_UpdateMigrationsForPostgresql.Designer.cs +++ b/Data/Migrations/Postgresql/20201125160058_UpdateMigrationsForPostgresql.Designer.cs @@ -5,9 +5,9 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20201125160058_UpdateMigrationsForPostgresql")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20201125160058_UpdateMigrationsForPostgresql.cs b/Data/Migrations/Postgresql/20201125160058_UpdateMigrationsForPostgresql.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20201125160058_UpdateMigrationsForPostgresql.cs rename to Data/Migrations/Postgresql/20201125160058_UpdateMigrationsForPostgresql.cs index c44a5008..fb0cacfe 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20201125160058_UpdateMigrationsForPostgresql.cs +++ b/Data/Migrations/Postgresql/20201125160058_UpdateMigrationsForPostgresql.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { public partial class UpdateMigrationsForPostgresql : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20210123024304_UpdateEFMetaToSupportNonClientMeta.Designer.cs b/Data/Migrations/Postgresql/20210123024304_UpdateEFMetaToSupportNonClientMeta.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20210123024304_UpdateEFMetaToSupportNonClientMeta.Designer.cs rename to Data/Migrations/Postgresql/20210123024304_UpdateEFMetaToSupportNonClientMeta.Designer.cs index cfb4d9e8..bc582025 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20210123024304_UpdateEFMetaToSupportNonClientMeta.Designer.cs +++ b/Data/Migrations/Postgresql/20210123024304_UpdateEFMetaToSupportNonClientMeta.Designer.cs @@ -5,9 +5,9 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20210123024304_UpdateEFMetaToSupportNonClientMeta")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20210123024304_UpdateEFMetaToSupportNonClientMeta.cs b/Data/Migrations/Postgresql/20210123024304_UpdateEFMetaToSupportNonClientMeta.cs similarity index 97% rename from SharedLibraryCore/Migrations/Postgresql/20210123024304_UpdateEFMetaToSupportNonClientMeta.cs rename to Data/Migrations/Postgresql/20210123024304_UpdateEFMetaToSupportNonClientMeta.cs index fc4f4aa3..67b80f10 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20210123024304_UpdateEFMetaToSupportNonClientMeta.cs +++ b/Data/Migrations/Postgresql/20210123024304_UpdateEFMetaToSupportNonClientMeta.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { public partial class UpdateEFMetaToSupportNonClientMeta : Migration { diff --git a/SharedLibraryCore/Migrations/Postgresql/20210124170956_UpdateEFMetaToSupportLinkedMeta.Designer.cs b/Data/Migrations/Postgresql/20210124170956_UpdateEFMetaToSupportLinkedMeta.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20210124170956_UpdateEFMetaToSupportLinkedMeta.Designer.cs rename to Data/Migrations/Postgresql/20210124170956_UpdateEFMetaToSupportLinkedMeta.Designer.cs index cd28418d..f8357d9e 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20210124170956_UpdateEFMetaToSupportLinkedMeta.Designer.cs +++ b/Data/Migrations/Postgresql/20210124170956_UpdateEFMetaToSupportLinkedMeta.Designer.cs @@ -5,9 +5,9 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] [Migration("20210124170956_UpdateEFMetaToSupportLinkedMeta")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20210124170956_UpdateEFMetaToSupportLinkedMeta.cs b/Data/Migrations/Postgresql/20210124170956_UpdateEFMetaToSupportLinkedMeta.cs similarity index 96% rename from SharedLibraryCore/Migrations/Postgresql/20210124170956_UpdateEFMetaToSupportLinkedMeta.cs rename to Data/Migrations/Postgresql/20210124170956_UpdateEFMetaToSupportLinkedMeta.cs index 55927c72..c05e87f3 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20210124170956_UpdateEFMetaToSupportLinkedMeta.cs +++ b/Data/Migrations/Postgresql/20210124170956_UpdateEFMetaToSupportLinkedMeta.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { public partial class UpdateEFMetaToSupportLinkedMeta : Migration { diff --git a/Data/Migrations/Postgresql/20210316004759_AddAdvancedStats.Designer.cs b/Data/Migrations/Postgresql/20210316004759_AddAdvancedStats.Designer.cs new file mode 100644 index 00000000..4bbe438a --- /dev/null +++ b/Data/Migrations/Postgresql/20210316004759_AddAdvancedStats.Designer.cs @@ -0,0 +1,1305 @@ +// +using System; +using Data.MigrationContext; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Data.Migrations.Postgresql +{ + [DbContext(typeof(PostgresqlDatabaseContext))] + [Migration("20210316004759_AddAdvancedStats")] + partial class AddAdvancedStats + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) + .HasAnnotation("ProductVersion", "3.1.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("Data.Models.Client.EFACSnapshotVector3", b => + { + b.Property("ACSnapshotVector3Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("SnapshotId") + .HasColumnType("integer"); + + b.Property("Vector3Id") + .HasColumnType("integer"); + + b.HasKey("ACSnapshotVector3Id"); + + b.HasIndex("SnapshotId"); + + b.HasIndex("Vector3Id"); + + b.ToTable("EFACSnapshotVector3"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClient", b => + { + b.Property("ClientId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("AliasLinkId") + .HasColumnType("integer"); + + b.Property("Connections") + .HasColumnType("integer"); + + b.Property("CurrentAliasId") + .HasColumnType("integer"); + + b.Property("FirstConnection") + .HasColumnType("timestamp without time zone"); + + b.Property("LastConnection") + .HasColumnType("timestamp without time zone"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Masked") + .HasColumnType("boolean"); + + b.Property("NetworkId") + .HasColumnType("bigint"); + + b.Property("Password") + .HasColumnType("text"); + + b.Property("PasswordSalt") + .HasColumnType("text"); + + b.Property("TotalConnectionTime") + .HasColumnType("integer"); + + b.HasKey("ClientId"); + + b.HasIndex("AliasLinkId"); + + b.HasIndex("CurrentAliasId"); + + b.HasIndex("NetworkId") + .IsUnique(); + + b.ToTable("EFClients"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientKill", b => + { + b.Property("KillId") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("AttackerId") + .HasColumnType("integer"); + + b.Property("Damage") + .HasColumnType("integer"); + + b.Property("DeathOriginVector3Id") + .HasColumnType("integer"); + + b.Property("DeathType") + .HasColumnType("integer"); + + b.Property("Fraction") + .HasColumnType("double precision"); + + b.Property("HitLoc") + .HasColumnType("integer"); + + b.Property("IsKill") + .HasColumnType("boolean"); + + b.Property("KillOriginVector3Id") + .HasColumnType("integer"); + + b.Property("Map") + .HasColumnType("integer"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("VictimId") + .HasColumnType("integer"); + + b.Property("ViewAnglesVector3Id") + .HasColumnType("integer"); + + b.Property("VisibilityPercentage") + .HasColumnType("double precision"); + + b.Property("Weapon") + .HasColumnType("integer"); + + b.Property("When") + .HasColumnType("timestamp without time zone"); + + b.HasKey("KillId"); + + b.HasIndex("AttackerId"); + + b.HasIndex("DeathOriginVector3Id"); + + b.HasIndex("KillOriginVector3Id"); + + b.HasIndex("ServerId"); + + b.HasIndex("VictimId"); + + b.HasIndex("ViewAnglesVector3Id"); + + b.ToTable("EFClientKills"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientMessage", b => + { + b.Property("MessageId") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Message") + .HasColumnType("text"); + + b.Property("SentIngame") + .HasColumnType("boolean"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("TimeSent") + .HasColumnType("timestamp without time zone"); + + b.HasKey("MessageId"); + + b.HasIndex("ClientId"); + + b.HasIndex("ServerId"); + + b.HasIndex("TimeSent"); + + b.ToTable("EFClientMessages"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFACSnapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("CurrentSessionLength") + .HasColumnType("integer"); + + b.Property("CurrentStrain") + .HasColumnType("double precision"); + + b.Property("CurrentViewAngleId") + .HasColumnType("integer"); + + b.Property("Deaths") + .HasColumnType("integer"); + + b.Property("Distance") + .HasColumnType("double precision"); + + b.Property("EloRating") + .HasColumnType("double precision"); + + b.Property("HitDestinationId") + .HasColumnType("integer"); + + b.Property("HitLocation") + .HasColumnType("integer"); + + b.Property("HitOriginId") + .HasColumnType("integer"); + + b.Property("HitType") + .HasColumnType("integer"); + + b.Property("Hits") + .HasColumnType("integer"); + + b.Property("Kills") + .HasColumnType("integer"); + + b.Property("LastStrainAngleId") + .HasColumnType("integer"); + + b.Property("RecoilOffset") + .HasColumnType("double precision"); + + b.Property("SessionAngleOffset") + .HasColumnType("double precision"); + + b.Property("SessionAverageSnapValue") + .HasColumnType("double precision"); + + b.Property("SessionSPM") + .HasColumnType("double precision"); + + b.Property("SessionScore") + .HasColumnType("integer"); + + b.Property("SessionSnapHits") + .HasColumnType("integer"); + + b.Property("StrainAngleBetween") + .HasColumnType("double precision"); + + b.Property("TimeSinceLastEvent") + .HasColumnType("integer"); + + b.Property("WeaponId") + .HasColumnType("integer"); + + b.Property("When") + .HasColumnType("timestamp without time zone"); + + b.HasKey("SnapshotId"); + + b.HasIndex("ClientId"); + + b.HasIndex("CurrentViewAngleId"); + + b.HasIndex("HitDestinationId"); + + b.HasIndex("HitOriginId"); + + b.HasIndex("LastStrainAngleId"); + + b.ToTable("EFACSnapshot"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientHitStatistic", b => + { + b.Property("ClientHitStatisticId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("CreatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("DamageInflicted") + .HasColumnType("integer"); + + b.Property("DamageReceived") + .HasColumnType("integer"); + + b.Property("DeathCount") + .HasColumnType("integer"); + + b.Property("HitCount") + .HasColumnType("integer"); + + b.Property("HitLocationId") + .HasColumnType("integer"); + + b.Property("KillCount") + .HasColumnType("integer"); + + b.Property("MeansOfDeathId") + .HasColumnType("integer"); + + b.Property("ReceivedHitCount") + .HasColumnType("integer"); + + b.Property("Score") + .HasColumnType("integer"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("SuicideCount") + .HasColumnType("integer"); + + b.Property("UpdatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("UsageSeconds") + .HasColumnType("integer"); + + b.Property("WeaponAttachmentComboId") + .HasColumnType("integer"); + + b.Property("WeaponId") + .HasColumnType("integer"); + + b.HasKey("ClientHitStatisticId"); + + b.HasIndex("ClientId"); + + b.HasIndex("HitLocationId"); + + b.HasIndex("MeansOfDeathId"); + + b.HasIndex("ServerId"); + + b.HasIndex("WeaponAttachmentComboId"); + + b.HasIndex("WeaponId"); + + b.ToTable("EFClientHitStatistics"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRankingHistory", b => + { + b.Property("ClientRankingHistoryId") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("CreatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Newest") + .HasColumnType("boolean"); + + b.Property("PerformanceMetric") + .HasColumnType("double precision"); + + b.Property("Ranking") + .HasColumnType("integer"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("UpdatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("ZScore") + .HasColumnType("double precision"); + + b.HasKey("ClientRankingHistoryId"); + + b.HasIndex("ClientId"); + + b.HasIndex("Ranking"); + + b.HasIndex("ServerId"); + + b.HasIndex("UpdatedDateTime"); + + b.HasIndex("ZScore"); + + b.ToTable("EFClientRankingHistory"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRatingHistory", b => + { + b.Property("RatingHistoryId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.HasKey("RatingHistoryId"); + + b.HasIndex("ClientId"); + + b.ToTable("EFClientRatingHistory"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientStatistics", b => + { + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("AverageSnapValue") + .HasColumnType("double precision"); + + b.Property("Deaths") + .HasColumnType("integer"); + + b.Property("EloRating") + .HasColumnType("double precision"); + + b.Property("Kills") + .HasColumnType("integer"); + + b.Property("MaxStrain") + .HasColumnType("double precision"); + + b.Property("RollingWeightedKDR") + .HasColumnType("double precision"); + + b.Property("SPM") + .HasColumnType("double precision"); + + b.Property("Skill") + .HasColumnType("double precision"); + + b.Property("SnapHitCount") + .HasColumnType("integer"); + + b.Property("TimePlayed") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp without time zone"); + + b.Property("ZScore") + .HasColumnType("double precision"); + + b.HasKey("ClientId", "ServerId"); + + b.HasIndex("ServerId"); + + b.HasIndex("ZScore"); + + b.HasIndex("ClientId", "TimePlayed", "ZScore"); + + b.ToTable("EFClientStatistics"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFHitLocationCount", b => + { + b.Property("HitLocationCountId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("EFClientStatisticsClientId") + .HasColumnName("EFClientStatisticsClientId") + .HasColumnType("integer"); + + b.Property("EFClientStatisticsServerId") + .HasColumnName("EFClientStatisticsServerId") + .HasColumnType("bigint"); + + b.Property("HitCount") + .HasColumnType("integer"); + + b.Property("HitOffsetAverage") + .HasColumnType("real"); + + b.Property("Location") + .HasColumnType("integer"); + + b.Property("MaxAngleDistance") + .HasColumnType("real"); + + b.HasKey("HitLocationCountId"); + + b.HasIndex("EFClientStatisticsServerId"); + + b.HasIndex("EFClientStatisticsClientId", "EFClientStatisticsServerId"); + + b.ToTable("EFHitLocationCounts"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFRating", b => + { + b.Property("RatingId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("ActivityAmount") + .HasColumnType("integer"); + + b.Property("Newest") + .HasColumnType("boolean"); + + b.Property("Performance") + .HasColumnType("double precision"); + + b.Property("Ranking") + .HasColumnType("integer"); + + b.Property("RatingHistoryId") + .HasColumnType("integer"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("When") + .HasColumnType("timestamp without time zone"); + + b.HasKey("RatingId"); + + b.HasIndex("RatingHistoryId"); + + b.HasIndex("ServerId"); + + b.HasIndex("Performance", "Ranking", "When"); + + b.HasIndex("When", "ServerId", "Performance", "ActivityAmount"); + + b.ToTable("EFRating"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFHitLocation", b => + { + b.Property("HitLocationId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("CreatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Game") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.HasKey("HitLocationId"); + + b.HasIndex("Name"); + + b.ToTable("EFHitLocations"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFMap", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("CreatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Game") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.HasKey("MapId"); + + b.ToTable("EFMaps"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFMeansOfDeath", b => + { + b.Property("MeansOfDeathId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("CreatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Game") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.HasKey("MeansOfDeathId"); + + b.ToTable("EFMeansOfDeath"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeapon", b => + { + b.Property("WeaponId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("CreatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Game") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.HasKey("WeaponId"); + + b.HasIndex("Name"); + + b.ToTable("EFWeapons"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachment", b => + { + b.Property("WeaponAttachmentId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("CreatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Game") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.HasKey("WeaponAttachmentId"); + + b.ToTable("EFWeaponAttachments"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", b => + { + b.Property("WeaponAttachmentComboId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Attachment1Id") + .HasColumnType("integer"); + + b.Property("Attachment2Id") + .HasColumnType("integer"); + + b.Property("Attachment3Id") + .HasColumnType("integer"); + + b.Property("CreatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Game") + .HasColumnType("integer"); + + b.Property("UpdatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.HasKey("WeaponAttachmentComboId"); + + b.HasIndex("Attachment1Id"); + + b.HasIndex("Attachment2Id"); + + b.HasIndex("Attachment3Id"); + + b.ToTable("EFWeaponAttachmentCombos"); + }); + + modelBuilder.Entity("Data.Models.EFAlias", b => + { + b.Property("AliasId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("DateAdded") + .HasColumnType("timestamp without time zone"); + + b.Property("IPAddress") + .HasColumnType("integer"); + + b.Property("LinkId") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("character varying(24)") + .HasMaxLength(24); + + b.Property("SearchableName") + .HasColumnType("character varying(24)") + .HasMaxLength(24); + + b.HasKey("AliasId"); + + b.HasIndex("IPAddress"); + + b.HasIndex("LinkId"); + + b.HasIndex("Name"); + + b.HasIndex("SearchableName"); + + b.HasIndex("Name", "IPAddress") + .IsUnique(); + + b.ToTable("EFAlias"); + }); + + modelBuilder.Entity("Data.Models.EFAliasLink", b => + { + b.Property("AliasLinkId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.HasKey("AliasLinkId"); + + b.ToTable("EFAliasLinks"); + }); + + modelBuilder.Entity("Data.Models.EFChangeHistory", b => + { + b.Property("ChangeHistoryId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("Comment") + .HasColumnType("character varying(128)") + .HasMaxLength(128); + + b.Property("CurrentValue") + .HasColumnType("text"); + + b.Property("ImpersonationEntityId") + .HasColumnType("integer"); + + b.Property("OriginEntityId") + .HasColumnType("integer"); + + b.Property("PreviousValue") + .HasColumnType("text"); + + b.Property("TargetEntityId") + .HasColumnType("integer"); + + b.Property("TimeChanged") + .HasColumnType("timestamp without time zone"); + + b.Property("TypeOfChange") + .HasColumnType("integer"); + + b.HasKey("ChangeHistoryId"); + + b.ToTable("EFChangeHistory"); + }); + + modelBuilder.Entity("Data.Models.EFMeta", b => + { + b.Property("MetaId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Created") + .HasColumnType("timestamp without time zone"); + + b.Property("Extra") + .HasColumnType("text"); + + b.Property("Key") + .IsRequired() + .HasColumnType("character varying(32)") + .HasMaxLength(32); + + b.Property("LinkedMetaId") + .HasColumnType("integer"); + + b.Property("Updated") + .HasColumnType("timestamp without time zone"); + + b.Property("Value") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("MetaId"); + + b.HasIndex("ClientId"); + + b.HasIndex("Key"); + + b.HasIndex("LinkedMetaId"); + + b.ToTable("EFMeta"); + }); + + modelBuilder.Entity("Data.Models.EFPenalty", b => + { + b.Property("PenaltyId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("AutomatedOffense") + .HasColumnType("text"); + + b.Property("Expires") + .HasColumnType("timestamp without time zone"); + + b.Property("IsEvadedOffense") + .HasColumnType("boolean"); + + b.Property("LinkId") + .HasColumnType("integer"); + + b.Property("OffenderId") + .HasColumnType("integer"); + + b.Property("Offense") + .IsRequired() + .HasColumnType("text"); + + b.Property("PunisherId") + .HasColumnType("integer"); + + b.Property("Type") + .HasColumnType("integer"); + + b.Property("When") + .HasColumnType("timestamp without time zone"); + + b.HasKey("PenaltyId"); + + b.HasIndex("LinkId"); + + b.HasIndex("OffenderId"); + + b.HasIndex("PunisherId"); + + b.ToTable("EFPenalties"); + }); + + modelBuilder.Entity("Data.Models.Server.EFServer", b => + { + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("EndPoint") + .HasColumnType("text"); + + b.Property("GameName") + .HasColumnType("integer"); + + b.Property("HostName") + .HasColumnType("text"); + + b.Property("IsPasswordProtected") + .HasColumnType("boolean"); + + b.Property("Port") + .HasColumnType("integer"); + + b.HasKey("ServerId"); + + b.ToTable("EFServers"); + }); + + modelBuilder.Entity("Data.Models.Server.EFServerStatistics", b => + { + b.Property("StatisticId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("TotalKills") + .HasColumnType("bigint"); + + b.Property("TotalPlayTime") + .HasColumnType("bigint"); + + b.HasKey("StatisticId"); + + b.HasIndex("ServerId"); + + b.ToTable("EFServerStatistics"); + }); + + modelBuilder.Entity("Data.Models.Vector3", b => + { + b.Property("Vector3Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("X") + .HasColumnType("real"); + + b.Property("Y") + .HasColumnType("real"); + + b.Property("Z") + .HasColumnType("real"); + + b.HasKey("Vector3Id"); + + b.ToTable("Vector3"); + }); + + modelBuilder.Entity("Data.Models.Client.EFACSnapshotVector3", b => + { + b.HasOne("Data.Models.Client.Stats.EFACSnapshot", "Snapshot") + .WithMany("PredictedViewAngles") + .HasForeignKey("SnapshotId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "Vector") + .WithMany() + .HasForeignKey("Vector3Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.EFClient", b => + { + b.HasOne("Data.Models.EFAliasLink", "AliasLink") + .WithMany() + .HasForeignKey("AliasLinkId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.EFAlias", "CurrentAlias") + .WithMany() + .HasForeignKey("CurrentAliasId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientKill", b => + { + b.HasOne("Data.Models.Client.EFClient", "Attacker") + .WithMany() + .HasForeignKey("AttackerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "DeathOrigin") + .WithMany() + .HasForeignKey("DeathOriginVector3Id"); + + b.HasOne("Data.Models.Vector3", "KillOrigin") + .WithMany() + .HasForeignKey("KillOriginVector3Id"); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.EFClient", "Victim") + .WithMany() + .HasForeignKey("VictimId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "ViewAngles") + .WithMany() + .HasForeignKey("ViewAnglesVector3Id"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientMessage", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFACSnapshot", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "CurrentViewAngle") + .WithMany() + .HasForeignKey("CurrentViewAngleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "HitDestination") + .WithMany() + .HasForeignKey("HitDestinationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "HitOrigin") + .WithMany() + .HasForeignKey("HitOriginId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "LastStrainAngle") + .WithMany() + .HasForeignKey("LastStrainAngleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientHitStatistic", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.Reference.EFHitLocation", "HitLocation") + .WithMany() + .HasForeignKey("HitLocationId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFMeansOfDeath", "MeansOfDeath") + .WithMany() + .HasForeignKey("MeansOfDeathId"); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", "WeaponAttachmentCombo") + .WithMany() + .HasForeignKey("WeaponAttachmentComboId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeapon", "Weapon") + .WithMany() + .HasForeignKey("WeaponId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRankingHistory", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRatingHistory", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientStatistics", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFHitLocationCount", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("EFClientStatisticsClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("EFClientStatisticsServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.EFClientStatistics", null) + .WithMany("HitLocations") + .HasForeignKey("EFClientStatisticsClientId", "EFClientStatisticsServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFRating", b => + { + b.HasOne("Data.Models.Client.Stats.EFClientRatingHistory", "RatingHistory") + .WithMany("Ratings") + .HasForeignKey("RatingHistoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", b => + { + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment1") + .WithMany() + .HasForeignKey("Attachment1Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment2") + .WithMany() + .HasForeignKey("Attachment2Id"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment3") + .WithMany() + .HasForeignKey("Attachment3Id"); + }); + + modelBuilder.Entity("Data.Models.EFAlias", b => + { + b.HasOne("Data.Models.EFAliasLink", "Link") + .WithMany("Children") + .HasForeignKey("LinkId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.EFMeta", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany("Meta") + .HasForeignKey("ClientId"); + + b.HasOne("Data.Models.EFMeta", "LinkedMeta") + .WithMany() + .HasForeignKey("LinkedMetaId") + .OnDelete(DeleteBehavior.SetNull); + }); + + modelBuilder.Entity("Data.Models.EFPenalty", b => + { + b.HasOne("Data.Models.EFAliasLink", "Link") + .WithMany("ReceivedPenalties") + .HasForeignKey("LinkId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.EFClient", "Offender") + .WithMany("ReceivedPenalties") + .HasForeignKey("OffenderId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Data.Models.Client.EFClient", "Punisher") + .WithMany("AdministeredPenalties") + .HasForeignKey("PunisherId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Server.EFServerStatistics", b => + { + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Data/Migrations/Postgresql/20210316004759_AddAdvancedStats.cs b/Data/Migrations/Postgresql/20210316004759_AddAdvancedStats.cs new file mode 100644 index 00000000..dc966abb --- /dev/null +++ b/Data/Migrations/Postgresql/20210316004759_AddAdvancedStats.cs @@ -0,0 +1,391 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Data.Migrations.Postgresql +{ + public partial class AddAdvancedStats : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "AverageRecoilOffset", + table: "EFClientStatistics"); + + migrationBuilder.DropColumn( + name: "VisionAverage", + table: "EFClientStatistics"); + + migrationBuilder.AddColumn( + name: "UpdatedAt", + table: "EFClientStatistics", + nullable: true); + + migrationBuilder.AddColumn( + name: "ZScore", + table: "EFClientStatistics", + nullable: false, + defaultValue: 0.0); + + migrationBuilder.CreateTable( + name: "EFClientRankingHistory", + columns: table => new + { + ClientRankingHistoryId = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + ClientId = table.Column(nullable: false), + ServerId = table.Column(nullable: true), + Newest = table.Column(nullable: false), + Ranking = table.Column(nullable: true), + ZScore = table.Column(nullable: true), + PerformanceMetric = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EFClientRankingHistory", x => x.ClientRankingHistoryId); + table.ForeignKey( + name: "FK_EFClientRankingHistory_EFClients_ClientId", + column: x => x.ClientId, + principalTable: "EFClients", + principalColumn: "ClientId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_EFClientRankingHistory_EFServers_ServerId", + column: x => x.ServerId, + principalTable: "EFServers", + principalColumn: "ServerId", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "EFHitLocations", + columns: table => new + { + HitLocationId = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Name = table.Column(nullable: false), + Game = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EFHitLocations", x => x.HitLocationId); + }); + + migrationBuilder.CreateTable( + name: "EFMaps", + columns: table => new + { + MapId = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Name = table.Column(nullable: false), + Game = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EFMaps", x => x.MapId); + }); + + migrationBuilder.CreateTable( + name: "EFMeansOfDeath", + columns: table => new + { + MeansOfDeathId = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Name = table.Column(nullable: false), + Game = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EFMeansOfDeath", x => x.MeansOfDeathId); + }); + + migrationBuilder.CreateTable( + name: "EFWeaponAttachments", + columns: table => new + { + WeaponAttachmentId = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Name = table.Column(nullable: false), + Game = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EFWeaponAttachments", x => x.WeaponAttachmentId); + }); + + migrationBuilder.CreateTable( + name: "EFWeapons", + columns: table => new + { + WeaponId = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Name = table.Column(nullable: false), + Game = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EFWeapons", x => x.WeaponId); + }); + + migrationBuilder.CreateTable( + name: "EFWeaponAttachmentCombos", + columns: table => new + { + WeaponAttachmentComboId = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Game = table.Column(nullable: false), + Attachment1Id = table.Column(nullable: false), + Attachment2Id = table.Column(nullable: true), + Attachment3Id = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EFWeaponAttachmentCombos", x => x.WeaponAttachmentComboId); + table.ForeignKey( + name: "FK_EFWeaponAttachmentCombos_EFWeaponAttachments_Attachment1Id", + column: x => x.Attachment1Id, + principalTable: "EFWeaponAttachments", + principalColumn: "WeaponAttachmentId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_EFWeaponAttachmentCombos_EFWeaponAttachments_Attachment2Id", + column: x => x.Attachment2Id, + principalTable: "EFWeaponAttachments", + principalColumn: "WeaponAttachmentId", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_EFWeaponAttachmentCombos_EFWeaponAttachments_Attachment3Id", + column: x => x.Attachment3Id, + principalTable: "EFWeaponAttachments", + principalColumn: "WeaponAttachmentId", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "EFClientHitStatistics", + columns: table => new + { + ClientHitStatisticId = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + ClientId = table.Column(nullable: false), + ServerId = table.Column(nullable: true), + HitLocationId = table.Column(nullable: true), + MeansOfDeathId = table.Column(nullable: true), + WeaponId = table.Column(nullable: true), + WeaponAttachmentComboId = table.Column(nullable: true), + HitCount = table.Column(nullable: false), + KillCount = table.Column(nullable: false), + DamageInflicted = table.Column(nullable: false), + ReceivedHitCount = table.Column(nullable: false), + DeathCount = table.Column(nullable: false), + DamageReceived = table.Column(nullable: false), + SuicideCount = table.Column(nullable: false), + UsageSeconds = table.Column(nullable: true), + Score = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EFClientHitStatistics", x => x.ClientHitStatisticId); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFClients_ClientId", + column: x => x.ClientId, + principalTable: "EFClients", + principalColumn: "ClientId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFHitLocations_HitLocationId", + column: x => x.HitLocationId, + principalTable: "EFHitLocations", + principalColumn: "HitLocationId", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFMeansOfDeath_MeansOfDeathId", + column: x => x.MeansOfDeathId, + principalTable: "EFMeansOfDeath", + principalColumn: "MeansOfDeathId", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFServers_ServerId", + column: x => x.ServerId, + principalTable: "EFServers", + principalColumn: "ServerId", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFWeaponAttachmentCombos_WeaponAttach~", + column: x => x.WeaponAttachmentComboId, + principalTable: "EFWeaponAttachmentCombos", + principalColumn: "WeaponAttachmentComboId", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFWeapons_WeaponId", + column: x => x.WeaponId, + principalTable: "EFWeapons", + principalColumn: "WeaponId", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_EFClientStatistics_ZScore", + table: "EFClientStatistics", + column: "ZScore"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientStatistics_ClientId_TimePlayed_ZScore", + table: "EFClientStatistics", + columns: new[] { "ClientId", "TimePlayed", "ZScore" }); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_ClientId", + table: "EFClientHitStatistics", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_HitLocationId", + table: "EFClientHitStatistics", + column: "HitLocationId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_MeansOfDeathId", + table: "EFClientHitStatistics", + column: "MeansOfDeathId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_ServerId", + table: "EFClientHitStatistics", + column: "ServerId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_WeaponAttachmentComboId", + table: "EFClientHitStatistics", + column: "WeaponAttachmentComboId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_WeaponId", + table: "EFClientHitStatistics", + column: "WeaponId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientRankingHistory_ClientId", + table: "EFClientRankingHistory", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientRankingHistory_Ranking", + table: "EFClientRankingHistory", + column: "Ranking"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientRankingHistory_ServerId", + table: "EFClientRankingHistory", + column: "ServerId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientRankingHistory_UpdatedDateTime", + table: "EFClientRankingHistory", + column: "UpdatedDateTime"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientRankingHistory_ZScore", + table: "EFClientRankingHistory", + column: "ZScore"); + + migrationBuilder.CreateIndex( + name: "IX_EFHitLocations_Name", + table: "EFHitLocations", + column: "Name"); + + migrationBuilder.CreateIndex( + name: "IX_EFWeaponAttachmentCombos_Attachment1Id", + table: "EFWeaponAttachmentCombos", + column: "Attachment1Id"); + + migrationBuilder.CreateIndex( + name: "IX_EFWeaponAttachmentCombos_Attachment2Id", + table: "EFWeaponAttachmentCombos", + column: "Attachment2Id"); + + migrationBuilder.CreateIndex( + name: "IX_EFWeaponAttachmentCombos_Attachment3Id", + table: "EFWeaponAttachmentCombos", + column: "Attachment3Id"); + + migrationBuilder.CreateIndex( + name: "IX_EFWeapons_Name", + table: "EFWeapons", + column: "Name"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "EFClientHitStatistics"); + + migrationBuilder.DropTable( + name: "EFClientRankingHistory"); + + migrationBuilder.DropTable( + name: "EFMaps"); + + migrationBuilder.DropTable( + name: "EFHitLocations"); + + migrationBuilder.DropTable( + name: "EFMeansOfDeath"); + + migrationBuilder.DropTable( + name: "EFWeaponAttachmentCombos"); + + migrationBuilder.DropTable( + name: "EFWeapons"); + + migrationBuilder.DropTable( + name: "EFWeaponAttachments"); + + migrationBuilder.DropIndex( + name: "IX_EFClientStatistics_ZScore", + table: "EFClientStatistics"); + + migrationBuilder.DropIndex( + name: "IX_EFClientStatistics_ClientId_TimePlayed_ZScore", + table: "EFClientStatistics"); + + migrationBuilder.DropColumn( + name: "UpdatedAt", + table: "EFClientStatistics"); + + migrationBuilder.DropColumn( + name: "ZScore", + table: "EFClientStatistics"); + + migrationBuilder.AddColumn( + name: "AverageRecoilOffset", + table: "EFClientStatistics", + type: "double precision", + nullable: false, + defaultValue: 0.0); + + migrationBuilder.AddColumn( + name: "VisionAverage", + table: "EFClientStatistics", + type: "double precision", + nullable: false, + defaultValue: 0.0); + } + } +} diff --git a/SharedLibraryCore/Migrations/Postgresql/PostgresqlDatabaseContextModelSnapshot.cs b/Data/Migrations/Postgresql/PostgresqlDatabaseContextModelSnapshot.cs similarity index 61% rename from SharedLibraryCore/Migrations/Postgresql/PostgresqlDatabaseContextModelSnapshot.cs rename to Data/Migrations/Postgresql/PostgresqlDatabaseContextModelSnapshot.cs index 0d442753..85451b47 100644 --- a/SharedLibraryCore/Migrations/Postgresql/PostgresqlDatabaseContextModelSnapshot.cs +++ b/Data/Migrations/Postgresql/PostgresqlDatabaseContextModelSnapshot.cs @@ -1,12 +1,12 @@ // using System; +using Data.MigrationContext; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -using SharedLibraryCore.Database.MigrationContext; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Postgresql { [DbContext(typeof(PostgresqlDatabaseContext))] partial class PostgresqlDatabaseContextModelSnapshot : ModelSnapshot @@ -15,16 +15,204 @@ namespace SharedLibraryCore.Migrations.Postgresql { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) .HasAnnotation("ProductVersion", "3.1.10") .HasAnnotation("Relational:MaxIdentifierLength", 63); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b => + modelBuilder.Entity("Data.Models.Client.EFACSnapshotVector3", b => + { + b.Property("ACSnapshotVector3Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("SnapshotId") + .HasColumnType("integer"); + + b.Property("Vector3Id") + .HasColumnType("integer"); + + b.HasKey("ACSnapshotVector3Id"); + + b.HasIndex("SnapshotId"); + + b.HasIndex("Vector3Id"); + + b.ToTable("EFACSnapshotVector3"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClient", b => + { + b.Property("ClientId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("AliasLinkId") + .HasColumnType("integer"); + + b.Property("Connections") + .HasColumnType("integer"); + + b.Property("CurrentAliasId") + .HasColumnType("integer"); + + b.Property("FirstConnection") + .HasColumnType("timestamp without time zone"); + + b.Property("LastConnection") + .HasColumnType("timestamp without time zone"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Masked") + .HasColumnType("boolean"); + + b.Property("NetworkId") + .HasColumnType("bigint"); + + b.Property("Password") + .HasColumnType("text"); + + b.Property("PasswordSalt") + .HasColumnType("text"); + + b.Property("TotalConnectionTime") + .HasColumnType("integer"); + + b.HasKey("ClientId"); + + b.HasIndex("AliasLinkId"); + + b.HasIndex("CurrentAliasId"); + + b.HasIndex("NetworkId") + .IsUnique(); + + b.ToTable("EFClients"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientKill", b => + { + b.Property("KillId") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("AttackerId") + .HasColumnType("integer"); + + b.Property("Damage") + .HasColumnType("integer"); + + b.Property("DeathOriginVector3Id") + .HasColumnType("integer"); + + b.Property("DeathType") + .HasColumnType("integer"); + + b.Property("Fraction") + .HasColumnType("double precision"); + + b.Property("HitLoc") + .HasColumnType("integer"); + + b.Property("IsKill") + .HasColumnType("boolean"); + + b.Property("KillOriginVector3Id") + .HasColumnType("integer"); + + b.Property("Map") + .HasColumnType("integer"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("VictimId") + .HasColumnType("integer"); + + b.Property("ViewAnglesVector3Id") + .HasColumnType("integer"); + + b.Property("VisibilityPercentage") + .HasColumnType("double precision"); + + b.Property("Weapon") + .HasColumnType("integer"); + + b.Property("When") + .HasColumnType("timestamp without time zone"); + + b.HasKey("KillId"); + + b.HasIndex("AttackerId"); + + b.HasIndex("DeathOriginVector3Id"); + + b.HasIndex("KillOriginVector3Id"); + + b.HasIndex("ServerId"); + + b.HasIndex("VictimId"); + + b.HasIndex("ViewAnglesVector3Id"); + + b.ToTable("EFClientKills"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientMessage", b => + { + b.Property("MessageId") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Message") + .HasColumnType("text"); + + b.Property("SentIngame") + .HasColumnType("boolean"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("TimeSent") + .HasColumnType("timestamp without time zone"); + + b.HasKey("MessageId"); + + b.HasIndex("ClientId"); + + b.HasIndex("ServerId"); + + b.HasIndex("TimeSent"); + + b.ToTable("EFClientMessages"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFACSnapshot", b => { b.Property("SnapshotId") .ValueGeneratedOnAdd() .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); b.Property("Active") .HasColumnType("boolean"); @@ -116,145 +304,133 @@ namespace SharedLibraryCore.Migrations.Postgresql b.ToTable("EFACSnapshot"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshotVector3", b => + modelBuilder.Entity("Data.Models.Client.Stats.EFClientHitStatistic", b => { - b.Property("ACSnapshotVector3Id") + b.Property("ClientHitStatisticId") .ValueGeneratedOnAdd() .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("SnapshotId") - .HasColumnType("integer"); - - b.Property("Vector3Id") - .HasColumnType("integer"); - - b.HasKey("ACSnapshotVector3Id"); - - b.HasIndex("SnapshotId"); - - b.HasIndex("Vector3Id"); - - b.ToTable("EFACSnapshotVector3"); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b => - { - b.Property("KillId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("AttackerId") - .HasColumnType("integer"); - - b.Property("Damage") - .HasColumnType("integer"); - - b.Property("DeathOriginVector3Id") - .HasColumnType("integer"); - - b.Property("DeathType") - .HasColumnType("integer"); - - b.Property("Fraction") - .HasColumnType("double precision"); - - b.Property("HitLoc") - .HasColumnType("integer"); - - b.Property("IsKill") - .HasColumnType("boolean"); - - b.Property("KillOriginVector3Id") - .HasColumnType("integer"); - - b.Property("Map") - .HasColumnType("integer"); - - b.Property("ServerId") - .HasColumnType("bigint"); - - b.Property("VictimId") - .HasColumnType("integer"); - - b.Property("ViewAnglesVector3Id") - .HasColumnType("integer"); - - b.Property("VisibilityPercentage") - .HasColumnType("double precision"); - - b.Property("Weapon") - .HasColumnType("integer"); - - b.Property("When") - .HasColumnType("timestamp without time zone"); - - b.HasKey("KillId"); - - b.HasIndex("AttackerId"); - - b.HasIndex("DeathOriginVector3Id"); - - b.HasIndex("KillOriginVector3Id"); - - b.HasIndex("ServerId"); - - b.HasIndex("VictimId"); - - b.HasIndex("ViewAnglesVector3Id"); - - b.ToTable("EFClientKills"); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientMessage", b => - { - b.Property("MessageId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Active") - .HasColumnType("boolean"); + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); b.Property("ClientId") .HasColumnType("integer"); - b.Property("Message") - .HasColumnType("text"); - - b.Property("SentIngame") - .HasColumnType("boolean"); - - b.Property("ServerId") - .HasColumnType("bigint"); - - b.Property("TimeSent") + b.Property("CreatedDateTime") .HasColumnType("timestamp without time zone"); - b.HasKey("MessageId"); + b.Property("DamageInflicted") + .HasColumnType("integer"); + + b.Property("DamageReceived") + .HasColumnType("integer"); + + b.Property("DeathCount") + .HasColumnType("integer"); + + b.Property("HitCount") + .HasColumnType("integer"); + + b.Property("HitLocationId") + .HasColumnType("integer"); + + b.Property("KillCount") + .HasColumnType("integer"); + + b.Property("MeansOfDeathId") + .HasColumnType("integer"); + + b.Property("ReceivedHitCount") + .HasColumnType("integer"); + + b.Property("Score") + .HasColumnType("integer"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("SuicideCount") + .HasColumnType("integer"); + + b.Property("UpdatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("UsageSeconds") + .HasColumnType("integer"); + + b.Property("WeaponAttachmentComboId") + .HasColumnType("integer"); + + b.Property("WeaponId") + .HasColumnType("integer"); + + b.HasKey("ClientHitStatisticId"); b.HasIndex("ClientId"); + b.HasIndex("HitLocationId"); + + b.HasIndex("MeansOfDeathId"); + b.HasIndex("ServerId"); - b.HasIndex("TimeSent"); + b.HasIndex("WeaponAttachmentComboId"); - b.ToTable("EFClientMessages"); + b.HasIndex("WeaponId"); + + b.ToTable("EFClientHitStatistics"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b => + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRankingHistory", b => + { + b.Property("ClientRankingHistoryId") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("CreatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Newest") + .HasColumnType("boolean"); + + b.Property("PerformanceMetric") + .HasColumnType("double precision"); + + b.Property("Ranking") + .HasColumnType("integer"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("UpdatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("ZScore") + .HasColumnType("double precision"); + + b.HasKey("ClientRankingHistoryId"); + + b.HasIndex("ClientId"); + + b.HasIndex("Ranking"); + + b.HasIndex("ServerId"); + + b.HasIndex("UpdatedDateTime"); + + b.HasIndex("ZScore"); + + b.ToTable("EFClientRankingHistory"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRatingHistory", b => { b.Property("RatingHistoryId") .ValueGeneratedOnAdd() .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); b.Property("Active") .HasColumnType("boolean"); @@ -269,7 +445,7 @@ namespace SharedLibraryCore.Migrations.Postgresql b.ToTable("EFClientRatingHistory"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b => + modelBuilder.Entity("Data.Models.Client.Stats.EFClientStatistics", b => { b.Property("ClientId") .HasColumnType("integer"); @@ -280,9 +456,6 @@ namespace SharedLibraryCore.Migrations.Postgresql b.Property("Active") .HasColumnType("boolean"); - b.Property("AverageRecoilOffset") - .HasColumnType("double precision"); - b.Property("AverageSnapValue") .HasColumnType("double precision"); @@ -313,22 +486,29 @@ namespace SharedLibraryCore.Migrations.Postgresql b.Property("TimePlayed") .HasColumnType("integer"); - b.Property("VisionAverage") + b.Property("UpdatedAt") + .HasColumnType("timestamp without time zone"); + + b.Property("ZScore") .HasColumnType("double precision"); b.HasKey("ClientId", "ServerId"); b.HasIndex("ServerId"); + b.HasIndex("ZScore"); + + b.HasIndex("ClientId", "TimePlayed", "ZScore"); + b.ToTable("EFClientStatistics"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b => + modelBuilder.Entity("Data.Models.Client.Stats.EFHitLocationCount", b => { b.Property("HitLocationCountId") .ValueGeneratedOnAdd() .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); b.Property("Active") .HasColumnType("boolean"); @@ -362,12 +542,12 @@ namespace SharedLibraryCore.Migrations.Postgresql b.ToTable("EFHitLocationCounts"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b => + modelBuilder.Entity("Data.Models.Client.Stats.EFRating", b => { b.Property("RatingId") .ValueGeneratedOnAdd() .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); b.Property("Active") .HasColumnType("boolean"); @@ -406,66 +586,177 @@ namespace SharedLibraryCore.Migrations.Postgresql b.ToTable("EFRating"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServer", b => + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFHitLocation", b => { - b.Property("ServerId") - .HasColumnType("bigint"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("EndPoint") - .HasColumnType("text"); - - b.Property("GameName") - .HasColumnType("integer"); - - b.Property("HostName") - .HasColumnType("text"); - - b.Property("IsPasswordProtected") - .HasColumnType("boolean"); - - b.Property("Port") - .HasColumnType("integer"); - - b.HasKey("ServerId"); - - b.ToTable("EFServers"); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b => - { - b.Property("StatisticId") + b.Property("HitLocationId") .ValueGeneratedOnAdd() .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); - b.Property("Active") - .HasColumnType("boolean"); + b.Property("CreatedDateTime") + .HasColumnType("timestamp without time zone"); - b.Property("ServerId") - .HasColumnType("bigint"); + b.Property("Game") + .HasColumnType("integer"); - b.Property("TotalKills") - .HasColumnType("bigint"); + b.Property("Name") + .IsRequired() + .HasColumnType("text"); - b.Property("TotalPlayTime") - .HasColumnType("bigint"); + b.Property("UpdatedDateTime") + .HasColumnType("timestamp without time zone"); - b.HasKey("StatisticId"); + b.HasKey("HitLocationId"); - b.HasIndex("ServerId"); + b.HasIndex("Name"); - b.ToTable("EFServerStatistics"); + b.ToTable("EFHitLocations"); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b => + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFMap", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("CreatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Game") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.HasKey("MapId"); + + b.ToTable("EFMaps"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFMeansOfDeath", b => + { + b.Property("MeansOfDeathId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("CreatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Game") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.HasKey("MeansOfDeathId"); + + b.ToTable("EFMeansOfDeath"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeapon", b => + { + b.Property("WeaponId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("CreatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Game") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.HasKey("WeaponId"); + + b.HasIndex("Name"); + + b.ToTable("EFWeapons"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachment", b => + { + b.Property("WeaponAttachmentId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("CreatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Game") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.HasKey("WeaponAttachmentId"); + + b.ToTable("EFWeaponAttachments"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", b => + { + b.Property("WeaponAttachmentComboId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Attachment1Id") + .HasColumnType("integer"); + + b.Property("Attachment2Id") + .HasColumnType("integer"); + + b.Property("Attachment3Id") + .HasColumnType("integer"); + + b.Property("CreatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Game") + .HasColumnType("integer"); + + b.Property("UpdatedDateTime") + .HasColumnType("timestamp without time zone"); + + b.HasKey("WeaponAttachmentComboId"); + + b.HasIndex("Attachment1Id"); + + b.HasIndex("Attachment2Id"); + + b.HasIndex("Attachment3Id"); + + b.ToTable("EFWeaponAttachmentCombos"); + }); + + modelBuilder.Entity("Data.Models.EFAlias", b => { b.Property("AliasId") .ValueGeneratedOnAdd() .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); b.Property("Active") .HasColumnType("boolean"); @@ -504,12 +795,12 @@ namespace SharedLibraryCore.Migrations.Postgresql b.ToTable("EFAlias"); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAliasLink", b => + modelBuilder.Entity("Data.Models.EFAliasLink", b => { b.Property("AliasLinkId") .ValueGeneratedOnAdd() .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); b.Property("Active") .HasColumnType("boolean"); @@ -519,12 +810,12 @@ namespace SharedLibraryCore.Migrations.Postgresql b.ToTable("EFAliasLinks"); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFChangeHistory", b => + modelBuilder.Entity("Data.Models.EFChangeHistory", b => { b.Property("ChangeHistoryId") .ValueGeneratedOnAdd() .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); b.Property("Active") .HasColumnType("boolean"); @@ -559,67 +850,12 @@ namespace SharedLibraryCore.Migrations.Postgresql b.ToTable("EFChangeHistory"); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b => - { - b.Property("ClientId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("AliasLinkId") - .HasColumnType("integer"); - - b.Property("Connections") - .HasColumnType("integer"); - - b.Property("CurrentAliasId") - .HasColumnType("integer"); - - b.Property("FirstConnection") - .HasColumnType("timestamp without time zone"); - - b.Property("LastConnection") - .HasColumnType("timestamp without time zone"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Masked") - .HasColumnType("boolean"); - - b.Property("NetworkId") - .HasColumnType("bigint"); - - b.Property("Password") - .HasColumnType("text"); - - b.Property("PasswordSalt") - .HasColumnType("text"); - - b.Property("TotalConnectionTime") - .HasColumnType("integer"); - - b.HasKey("ClientId"); - - b.HasIndex("AliasLinkId"); - - b.HasIndex("CurrentAliasId"); - - b.HasIndex("NetworkId") - .IsUnique(); - - b.ToTable("EFClients"); - }); - - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFMeta", b => + modelBuilder.Entity("Data.Models.EFMeta", b => { b.Property("MetaId") .ValueGeneratedOnAdd() .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); b.Property("Active") .HasColumnType("boolean"); @@ -659,12 +895,12 @@ namespace SharedLibraryCore.Migrations.Postgresql b.ToTable("EFMeta"); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b => + modelBuilder.Entity("Data.Models.EFPenalty", b => { b.Property("PenaltyId") .ValueGeneratedOnAdd() .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); b.Property("Active") .HasColumnType("boolean"); @@ -708,12 +944,66 @@ namespace SharedLibraryCore.Migrations.Postgresql b.ToTable("EFPenalties"); }); - modelBuilder.Entity("SharedLibraryCore.Helpers.Vector3", b => + modelBuilder.Entity("Data.Models.Server.EFServer", b => + { + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("EndPoint") + .HasColumnType("text"); + + b.Property("GameName") + .HasColumnType("integer"); + + b.Property("HostName") + .HasColumnType("text"); + + b.Property("IsPasswordProtected") + .HasColumnType("boolean"); + + b.Property("Port") + .HasColumnType("integer"); + + b.HasKey("ServerId"); + + b.ToTable("EFServers"); + }); + + modelBuilder.Entity("Data.Models.Server.EFServerStatistics", b => + { + b.Property("StatisticId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("ServerId") + .HasColumnType("bigint"); + + b.Property("TotalKills") + .HasColumnType("bigint"); + + b.Property("TotalPlayTime") + .HasColumnType("bigint"); + + b.HasKey("StatisticId"); + + b.HasIndex("ServerId"); + + b.ToTable("EFServerStatistics"); + }); + + modelBuilder.Entity("Data.Models.Vector3", b => { b.Property("Vector3Id") .ValueGeneratedOnAdd() .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); b.Property("X") .HasColumnType("real"); @@ -729,225 +1019,284 @@ namespace SharedLibraryCore.Migrations.Postgresql b.ToTable("Vector3"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b => + modelBuilder.Entity("Data.Models.Client.EFACSnapshotVector3", b => { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "CurrentViewAngle") - .WithMany() - .HasForeignKey("CurrentViewAngleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "HitDestination") - .WithMany() - .HasForeignKey("HitDestinationId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "HitOrigin") - .WithMany() - .HasForeignKey("HitOriginId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "LastStrainAngle") - .WithMany() - .HasForeignKey("LastStrainAngleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshotVector3", b => - { - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", "Snapshot") + b.HasOne("Data.Models.Client.Stats.EFACSnapshot", "Snapshot") .WithMany("PredictedViewAngles") .HasForeignKey("SnapshotId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("SharedLibraryCore.Helpers.Vector3", "Vector") + b.HasOne("Data.Models.Vector3", "Vector") .WithMany() .HasForeignKey("Vector3Id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b => + modelBuilder.Entity("Data.Models.Client.EFClient", b => { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Attacker") - .WithMany() - .HasForeignKey("AttackerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "DeathOrigin") - .WithMany() - .HasForeignKey("DeathOriginVector3Id"); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "KillOrigin") - .WithMany() - .HasForeignKey("KillOriginVector3Id"); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Victim") - .WithMany() - .HasForeignKey("VictimId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "ViewAngles") - .WithMany() - .HasForeignKey("ViewAnglesVector3Id"); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientMessage", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") - .WithMany() - .HasForeignKey("EFClientStatisticsClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("EFClientStatisticsServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", null) - .WithMany("HitLocations") - .HasForeignKey("EFClientStatisticsClientId", "EFClientStatisticsServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b => - { - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", "RatingHistory") - .WithMany("Ratings") - .HasForeignKey("RatingHistoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId"); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b => - { - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link") - .WithMany("Children") - .HasForeignKey("LinkId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - }); - - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "AliasLink") + b.HasOne("Data.Models.EFAliasLink", "AliasLink") .WithMany() .HasForeignKey("AliasLinkId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("SharedLibraryCore.Database.Models.EFAlias", "CurrentAlias") + b.HasOne("Data.Models.EFAlias", "CurrentAlias") .WithMany() .HasForeignKey("CurrentAliasId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFMeta", b => + modelBuilder.Entity("Data.Models.Client.EFClientKill", b => { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") + b.HasOne("Data.Models.Client.EFClient", "Attacker") + .WithMany() + .HasForeignKey("AttackerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "DeathOrigin") + .WithMany() + .HasForeignKey("DeathOriginVector3Id"); + + b.HasOne("Data.Models.Vector3", "KillOrigin") + .WithMany() + .HasForeignKey("KillOriginVector3Id"); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.EFClient", "Victim") + .WithMany() + .HasForeignKey("VictimId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "ViewAngles") + .WithMany() + .HasForeignKey("ViewAnglesVector3Id"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientMessage", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFACSnapshot", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "CurrentViewAngle") + .WithMany() + .HasForeignKey("CurrentViewAngleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "HitDestination") + .WithMany() + .HasForeignKey("HitDestinationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "HitOrigin") + .WithMany() + .HasForeignKey("HitOriginId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "LastStrainAngle") + .WithMany() + .HasForeignKey("LastStrainAngleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientHitStatistic", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.Reference.EFHitLocation", "HitLocation") + .WithMany() + .HasForeignKey("HitLocationId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFMeansOfDeath", "MeansOfDeath") + .WithMany() + .HasForeignKey("MeansOfDeathId"); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", "WeaponAttachmentCombo") + .WithMany() + .HasForeignKey("WeaponAttachmentComboId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeapon", "Weapon") + .WithMany() + .HasForeignKey("WeaponId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRankingHistory", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRatingHistory", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientStatistics", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFHitLocationCount", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("EFClientStatisticsClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("EFClientStatisticsServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.EFClientStatistics", null) + .WithMany("HitLocations") + .HasForeignKey("EFClientStatisticsClientId", "EFClientStatisticsServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFRating", b => + { + b.HasOne("Data.Models.Client.Stats.EFClientRatingHistory", "RatingHistory") + .WithMany("Ratings") + .HasForeignKey("RatingHistoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", b => + { + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment1") + .WithMany() + .HasForeignKey("Attachment1Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment2") + .WithMany() + .HasForeignKey("Attachment2Id"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment3") + .WithMany() + .HasForeignKey("Attachment3Id"); + }); + + modelBuilder.Entity("Data.Models.EFAlias", b => + { + b.HasOne("Data.Models.EFAliasLink", "Link") + .WithMany("Children") + .HasForeignKey("LinkId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.EFMeta", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") .WithMany("Meta") .HasForeignKey("ClientId"); - b.HasOne("SharedLibraryCore.Database.Models.EFMeta", "LinkedMeta") + b.HasOne("Data.Models.EFMeta", "LinkedMeta") .WithMany() .HasForeignKey("LinkedMetaId") .OnDelete(DeleteBehavior.SetNull); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b => + modelBuilder.Entity("Data.Models.EFPenalty", b => { - b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link") + b.HasOne("Data.Models.EFAliasLink", "Link") .WithMany("ReceivedPenalties") .HasForeignKey("LinkId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Offender") + b.HasOne("Data.Models.Client.EFClient", "Offender") .WithMany("ReceivedPenalties") .HasForeignKey("OffenderId") .OnDelete(DeleteBehavior.Restrict) .IsRequired(); - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Punisher") + b.HasOne("Data.Models.Client.EFClient", "Punisher") .WithMany("AdministeredPenalties") .HasForeignKey("PunisherId") .OnDelete(DeleteBehavior.Restrict) .IsRequired(); }); + + modelBuilder.Entity("Data.Models.Server.EFServerStatistics", b => + { + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); #pragma warning restore 612, 618 } } diff --git a/SharedLibraryCore/Migrations/Sqlite/20180409183408_InitialCreate.Designer.cs b/Data/Migrations/Sqlite/20180409183408_InitialCreate.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180409183408_InitialCreate.Designer.cs rename to Data/Migrations/Sqlite/20180409183408_InitialCreate.Designer.cs index e71e66ac..969ca1b9 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180409183408_InitialCreate.Designer.cs +++ b/Data/Migrations/Sqlite/20180409183408_InitialCreate.Designer.cs @@ -5,11 +5,11 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database; -using SharedLibraryCore.Database.MigrationContext; +using Data; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180409183408_InitialCreate")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180409183408_InitialCreate.cs b/Data/Migrations/Sqlite/20180409183408_InitialCreate.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180409183408_InitialCreate.cs rename to Data/Migrations/Sqlite/20180409183408_InitialCreate.cs index acd57084..7b546334 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180409183408_InitialCreate.cs +++ b/Data/Migrations/Sqlite/20180409183408_InitialCreate.cs @@ -4,7 +4,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class InitialCreate : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180502195450_Update.Designer.cs b/Data/Migrations/Sqlite/20180502195450_Update.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180502195450_Update.Designer.cs rename to Data/Migrations/Sqlite/20180502195450_Update.Designer.cs index 9ca5b7e3..bad1e03c 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180502195450_Update.Designer.cs +++ b/Data/Migrations/Sqlite/20180502195450_Update.Designer.cs @@ -5,11 +5,11 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database; -using SharedLibraryCore.Database.MigrationContext; +using Data; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180502195450_Update")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180502195450_Update.cs b/Data/Migrations/Sqlite/20180502195450_Update.cs similarity index 95% rename from SharedLibraryCore/Migrations/Postgresql/20180502195450_Update.cs rename to Data/Migrations/Sqlite/20180502195450_Update.cs index 79b42416..e3b16650 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180502195450_Update.cs +++ b/Data/Migrations/Sqlite/20180502195450_Update.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class Update : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180516023249_AddEloField.Designer.cs b/Data/Migrations/Sqlite/20180516023249_AddEloField.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180516023249_AddEloField.Designer.cs rename to Data/Migrations/Sqlite/20180516023249_AddEloField.Designer.cs index debb8507..7ce4d36f 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180516023249_AddEloField.Designer.cs +++ b/Data/Migrations/Sqlite/20180516023249_AddEloField.Designer.cs @@ -5,11 +5,11 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database; -using SharedLibraryCore.Database.MigrationContext; +using Data; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180516023249_AddEloField")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180516023249_AddEloField.cs b/Data/Migrations/Sqlite/20180516023249_AddEloField.cs similarity index 93% rename from SharedLibraryCore/Migrations/Postgresql/20180516023249_AddEloField.cs rename to Data/Migrations/Sqlite/20180516023249_AddEloField.cs index 088d71f7..078a22cd 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180516023249_AddEloField.cs +++ b/Data/Migrations/Sqlite/20180516023249_AddEloField.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddEloField : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180517223349_AddRollingKDR.Designer.cs b/Data/Migrations/Sqlite/20180517223349_AddRollingKDR.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180517223349_AddRollingKDR.Designer.cs rename to Data/Migrations/Sqlite/20180517223349_AddRollingKDR.Designer.cs index 0888266d..d163970b 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180517223349_AddRollingKDR.Designer.cs +++ b/Data/Migrations/Sqlite/20180517223349_AddRollingKDR.Designer.cs @@ -5,11 +5,11 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database; -using SharedLibraryCore.Database.MigrationContext; +using Data; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180517223349_AddRollingKDR")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180517223349_AddRollingKDR.cs b/Data/Migrations/Sqlite/20180517223349_AddRollingKDR.cs similarity index 93% rename from SharedLibraryCore/Migrations/Postgresql/20180517223349_AddRollingKDR.cs rename to Data/Migrations/Sqlite/20180517223349_AddRollingKDR.cs index 8b971689..82dd4618 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180517223349_AddRollingKDR.cs +++ b/Data/Migrations/Sqlite/20180517223349_AddRollingKDR.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddRollingKDR : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs b/Data/Migrations/Sqlite/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs rename to Data/Migrations/Sqlite/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs index db0edba5..2964b1a2 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs +++ b/Data/Migrations/Sqlite/20180531212903_AddAutomatedOffenseAndRatingHistory.Designer.cs @@ -5,10 +5,10 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180531212903_AddAutomatedOffenseAndRatingHistory")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180531212903_AddAutomatedOffenseAndRatingHistory.cs b/Data/Migrations/Sqlite/20180531212903_AddAutomatedOffenseAndRatingHistory.cs similarity index 98% rename from SharedLibraryCore/Migrations/Postgresql/20180531212903_AddAutomatedOffenseAndRatingHistory.cs rename to Data/Migrations/Sqlite/20180531212903_AddAutomatedOffenseAndRatingHistory.cs index eeff0d6e..703a8ab6 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180531212903_AddAutomatedOffenseAndRatingHistory.cs +++ b/Data/Migrations/Sqlite/20180531212903_AddAutomatedOffenseAndRatingHistory.cs @@ -4,7 +4,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddAutomatedOffenseAndRatingHistory : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180601172317_AddActivityAmount.Designer.cs b/Data/Migrations/Sqlite/20180601172317_AddActivityAmount.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180601172317_AddActivityAmount.Designer.cs rename to Data/Migrations/Sqlite/20180601172317_AddActivityAmount.Designer.cs index 52414186..468e50f1 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180601172317_AddActivityAmount.Designer.cs +++ b/Data/Migrations/Sqlite/20180601172317_AddActivityAmount.Designer.cs @@ -5,10 +5,10 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180601172317_AddActivityAmount")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180601172317_AddActivityAmount.cs b/Data/Migrations/Sqlite/20180601172317_AddActivityAmount.cs similarity index 92% rename from SharedLibraryCore/Migrations/Postgresql/20180601172317_AddActivityAmount.cs rename to Data/Migrations/Sqlite/20180601172317_AddActivityAmount.cs index 332f10bb..a8ff76b9 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180601172317_AddActivityAmount.cs +++ b/Data/Migrations/Sqlite/20180601172317_AddActivityAmount.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddActivityAmount : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180602041758_AddClientMeta.Designer.cs b/Data/Migrations/Sqlite/20180602041758_AddClientMeta.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180602041758_AddClientMeta.Designer.cs rename to Data/Migrations/Sqlite/20180602041758_AddClientMeta.Designer.cs index ca057232..fe3503a8 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180602041758_AddClientMeta.Designer.cs +++ b/Data/Migrations/Sqlite/20180602041758_AddClientMeta.Designer.cs @@ -5,10 +5,10 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180602041758_AddClientMeta")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180602041758_AddClientMeta.cs b/Data/Migrations/Sqlite/20180602041758_AddClientMeta.cs similarity index 97% rename from SharedLibraryCore/Migrations/Postgresql/20180602041758_AddClientMeta.cs rename to Data/Migrations/Sqlite/20180602041758_AddClientMeta.cs index 31c8e15d..08dbdbf3 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180602041758_AddClientMeta.cs +++ b/Data/Migrations/Sqlite/20180602041758_AddClientMeta.cs @@ -4,7 +4,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddClientMeta : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180605191706_AddEFACSnapshots.Designer.cs b/Data/Migrations/Sqlite/20180605191706_AddEFACSnapshots.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180605191706_AddEFACSnapshots.Designer.cs rename to Data/Migrations/Sqlite/20180605191706_AddEFACSnapshots.Designer.cs index 9a941e7d..d1529495 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180605191706_AddEFACSnapshots.Designer.cs +++ b/Data/Migrations/Sqlite/20180605191706_AddEFACSnapshots.Designer.cs @@ -5,10 +5,10 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180605191706_AddEFACSnapshots")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180605191706_AddEFACSnapshots.cs b/Data/Migrations/Sqlite/20180605191706_AddEFACSnapshots.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180605191706_AddEFACSnapshots.cs rename to Data/Migrations/Sqlite/20180605191706_AddEFACSnapshots.cs index d989c1e8..b719bb8d 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180605191706_AddEFACSnapshots.cs +++ b/Data/Migrations/Sqlite/20180605191706_AddEFACSnapshots.cs @@ -4,7 +4,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddEFACSnapshots : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180614014303_IndexForEFAlias.Designer.cs b/Data/Migrations/Sqlite/20180614014303_IndexForEFAlias.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180614014303_IndexForEFAlias.Designer.cs rename to Data/Migrations/Sqlite/20180614014303_IndexForEFAlias.Designer.cs index 553c7183..3300e12f 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180614014303_IndexForEFAlias.Designer.cs +++ b/Data/Migrations/Sqlite/20180614014303_IndexForEFAlias.Designer.cs @@ -5,10 +5,10 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.Internal; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; using System; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180614014303_IndexForEFAlias")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180614014303_IndexForEFAlias.cs b/Data/Migrations/Sqlite/20180614014303_IndexForEFAlias.cs similarity index 92% rename from SharedLibraryCore/Migrations/Postgresql/20180614014303_IndexForEFAlias.cs rename to Data/Migrations/Sqlite/20180614014303_IndexForEFAlias.cs index 81ffaf1a..289a5697 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180614014303_IndexForEFAlias.cs +++ b/Data/Migrations/Sqlite/20180614014303_IndexForEFAlias.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class IndexForEFAlias : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180902035612_AddFractionAndIsKill.Designer.cs b/Data/Migrations/Sqlite/20180902035612_AddFractionAndIsKill.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180902035612_AddFractionAndIsKill.Designer.cs rename to Data/Migrations/Sqlite/20180902035612_AddFractionAndIsKill.Designer.cs index a79bb713..c477fef6 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180902035612_AddFractionAndIsKill.Designer.cs +++ b/Data/Migrations/Sqlite/20180902035612_AddFractionAndIsKill.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180902035612_AddFractionAndIsKill")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180902035612_AddFractionAndIsKill.cs b/Data/Migrations/Sqlite/20180902035612_AddFractionAndIsKill.cs similarity index 97% rename from SharedLibraryCore/Migrations/Postgresql/20180902035612_AddFractionAndIsKill.cs rename to Data/Migrations/Sqlite/20180902035612_AddFractionAndIsKill.cs index ae30df08..1fe4ab13 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180902035612_AddFractionAndIsKill.cs +++ b/Data/Migrations/Sqlite/20180902035612_AddFractionAndIsKill.cs @@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddFractionAndIsKill : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180904154622_AddVisibilityPercentage.Designer.cs b/Data/Migrations/Sqlite/20180904154622_AddVisibilityPercentage.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180904154622_AddVisibilityPercentage.Designer.cs rename to Data/Migrations/Sqlite/20180904154622_AddVisibilityPercentage.Designer.cs index c2f06539..93a6ae30 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180904154622_AddVisibilityPercentage.Designer.cs +++ b/Data/Migrations/Sqlite/20180904154622_AddVisibilityPercentage.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180904154622_AddVisibilityPercentage")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180904154622_AddVisibilityPercentage.cs b/Data/Migrations/Sqlite/20180904154622_AddVisibilityPercentage.cs similarity index 92% rename from SharedLibraryCore/Migrations/Postgresql/20180904154622_AddVisibilityPercentage.cs rename to Data/Migrations/Sqlite/20180904154622_AddVisibilityPercentage.cs index 77b24262..7d5842f9 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180904154622_AddVisibilityPercentage.cs +++ b/Data/Migrations/Sqlite/20180904154622_AddVisibilityPercentage.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddVisibilityPercentage : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180907020706_AddVision.Designer.cs b/Data/Migrations/Sqlite/20180907020706_AddVision.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180907020706_AddVision.Designer.cs rename to Data/Migrations/Sqlite/20180907020706_AddVision.Designer.cs index 7b996dc6..0521e398 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180907020706_AddVision.Designer.cs +++ b/Data/Migrations/Sqlite/20180907020706_AddVision.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180907020706_AddVision")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180907020706_AddVision.cs b/Data/Migrations/Sqlite/20180907020706_AddVision.cs similarity index 92% rename from SharedLibraryCore/Migrations/Postgresql/20180907020706_AddVision.cs rename to Data/Migrations/Sqlite/20180907020706_AddVision.cs index 17ce2ea9..ded66273 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180907020706_AddVision.cs +++ b/Data/Migrations/Sqlite/20180907020706_AddVision.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddVision : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180908004053_AddWhenToRating.Designer.cs b/Data/Migrations/Sqlite/20180908004053_AddWhenToRating.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180908004053_AddWhenToRating.Designer.cs rename to Data/Migrations/Sqlite/20180908004053_AddWhenToRating.Designer.cs index fe43268f..ad650da0 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180908004053_AddWhenToRating.Designer.cs +++ b/Data/Migrations/Sqlite/20180908004053_AddWhenToRating.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180908004053_AddWhenToRating")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180908004053_AddWhenToRating.cs b/Data/Migrations/Sqlite/20180908004053_AddWhenToRating.cs similarity index 93% rename from SharedLibraryCore/Migrations/Postgresql/20180908004053_AddWhenToRating.cs rename to Data/Migrations/Sqlite/20180908004053_AddWhenToRating.cs index f6482236..3610472f 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180908004053_AddWhenToRating.cs +++ b/Data/Migrations/Sqlite/20180908004053_AddWhenToRating.cs @@ -1,7 +1,7 @@ using System; using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddWhenToRating : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180910221749_AddRatingIndexes.Designer.cs b/Data/Migrations/Sqlite/20180910221749_AddRatingIndexes.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180910221749_AddRatingIndexes.Designer.cs rename to Data/Migrations/Sqlite/20180910221749_AddRatingIndexes.Designer.cs index 9b3b9e99..bbacef28 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180910221749_AddRatingIndexes.Designer.cs +++ b/Data/Migrations/Sqlite/20180910221749_AddRatingIndexes.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180910221749_AddRatingIndexes")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180910221749_AddRatingIndexes.cs b/Data/Migrations/Sqlite/20180910221749_AddRatingIndexes.cs similarity index 95% rename from SharedLibraryCore/Migrations/Postgresql/20180910221749_AddRatingIndexes.cs rename to Data/Migrations/Sqlite/20180910221749_AddRatingIndexes.cs index 781d5bba..07ea61fc 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180910221749_AddRatingIndexes.cs +++ b/Data/Migrations/Sqlite/20180910221749_AddRatingIndexes.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddRatingIndexes : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180911184224_AddEFAliasNameIndex.Designer.cs b/Data/Migrations/Sqlite/20180911184224_AddEFAliasNameIndex.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180911184224_AddEFAliasNameIndex.Designer.cs rename to Data/Migrations/Sqlite/20180911184224_AddEFAliasNameIndex.Designer.cs index e9feb60e..2d4d694c 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180911184224_AddEFAliasNameIndex.Designer.cs +++ b/Data/Migrations/Sqlite/20180911184224_AddEFAliasNameIndex.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180911184224_AddEFAliasNameIndex")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180911184224_AddEFAliasNameIndex.cs b/Data/Migrations/Sqlite/20180911184224_AddEFAliasNameIndex.cs similarity index 91% rename from SharedLibraryCore/Migrations/Postgresql/20180911184224_AddEFAliasNameIndex.cs rename to Data/Migrations/Sqlite/20180911184224_AddEFAliasNameIndex.cs index 90247335..5ccab445 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180911184224_AddEFAliasNameIndex.cs +++ b/Data/Migrations/Sqlite/20180911184224_AddEFAliasNameIndex.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddEFAliasNameIndex : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180911190823_AddEFAliasNameMaxLength24.Designer.cs b/Data/Migrations/Sqlite/20180911190823_AddEFAliasNameMaxLength24.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180911190823_AddEFAliasNameMaxLength24.Designer.cs rename to Data/Migrations/Sqlite/20180911190823_AddEFAliasNameMaxLength24.Designer.cs index f6275417..6abeea81 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180911190823_AddEFAliasNameMaxLength24.Designer.cs +++ b/Data/Migrations/Sqlite/20180911190823_AddEFAliasNameMaxLength24.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180911190823_AddEFAliasNameMaxLength24")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180911190823_AddEFAliasNameMaxLength24.cs b/Data/Migrations/Sqlite/20180911190823_AddEFAliasNameMaxLength24.cs similarity index 93% rename from SharedLibraryCore/Migrations/Postgresql/20180911190823_AddEFAliasNameMaxLength24.cs rename to Data/Migrations/Sqlite/20180911190823_AddEFAliasNameMaxLength24.cs index 53ef00b9..7a16d9c4 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180911190823_AddEFAliasNameMaxLength24.cs +++ b/Data/Migrations/Sqlite/20180911190823_AddEFAliasNameMaxLength24.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddEFAliasNameMaxLength24 : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs b/Data/Migrations/Sqlite/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs rename to Data/Migrations/Sqlite/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs index ba6dcaf7..72aba35e 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs +++ b/Data/Migrations/Sqlite/20180912015012_AddPreviousCurrentValueToEFChangeHistory.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180912015012_AddPreviousCurrentValueToEFChangeHistory")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs b/Data/Migrations/Sqlite/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs similarity index 94% rename from SharedLibraryCore/Migrations/Postgresql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs rename to Data/Migrations/Sqlite/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs index c7c7a911..fb3ee809 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs +++ b/Data/Migrations/Sqlite/20180912015012_AddPreviousCurrentValueToEFChangeHistory.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddPreviousCurrentValueToEFChangeHistory : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180915163111_AddIndexToMessageTimeSent.Designer.cs b/Data/Migrations/Sqlite/20180915163111_AddIndexToMessageTimeSent.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180915163111_AddIndexToMessageTimeSent.Designer.cs rename to Data/Migrations/Sqlite/20180915163111_AddIndexToMessageTimeSent.Designer.cs index 3ec9944c..4a5a0c63 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180915163111_AddIndexToMessageTimeSent.Designer.cs +++ b/Data/Migrations/Sqlite/20180915163111_AddIndexToMessageTimeSent.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180915163111_AddIndexToMessageTimeSent")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180915163111_AddIndexToMessageTimeSent.cs b/Data/Migrations/Sqlite/20180915163111_AddIndexToMessageTimeSent.cs similarity index 92% rename from SharedLibraryCore/Migrations/Postgresql/20180915163111_AddIndexToMessageTimeSent.cs rename to Data/Migrations/Sqlite/20180915163111_AddIndexToMessageTimeSent.cs index 93186b38..d24bead5 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180915163111_AddIndexToMessageTimeSent.cs +++ b/Data/Migrations/Sqlite/20180915163111_AddIndexToMessageTimeSent.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddIndexToMessageTimeSent : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180922231310_RemoveACSnapShot.Designer.cs b/Data/Migrations/Sqlite/20180922231310_RemoveACSnapShot.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180922231310_RemoveACSnapShot.Designer.cs rename to Data/Migrations/Sqlite/20180922231310_RemoveACSnapShot.Designer.cs index 1c7aac12..ecbd0cfe 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180922231310_RemoveACSnapShot.Designer.cs +++ b/Data/Migrations/Sqlite/20180922231310_RemoveACSnapShot.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180922231310_RemoveACSnapShot")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180922231310_RemoveACSnapShot.cs b/Data/Migrations/Sqlite/20180922231310_RemoveACSnapShot.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180922231310_RemoveACSnapShot.cs rename to Data/Migrations/Sqlite/20180922231310_RemoveACSnapShot.cs index b767126f..6688d46f 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180922231310_RemoveACSnapShot.cs +++ b/Data/Migrations/Sqlite/20180922231310_RemoveACSnapShot.cs @@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class RemoveACSnapShot : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20180922231600_ReaddACSnapshot.Designer.cs b/Data/Migrations/Sqlite/20180922231600_ReaddACSnapshot.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20180922231600_ReaddACSnapshot.Designer.cs rename to Data/Migrations/Sqlite/20180922231600_ReaddACSnapshot.Designer.cs index 3c43b4bf..f37f18b7 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20180922231600_ReaddACSnapshot.Designer.cs +++ b/Data/Migrations/Sqlite/20180922231600_ReaddACSnapshot.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20180922231600_ReaddACSnapshot")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20180922231600_ReaddACSnapshot.cs b/Data/Migrations/Sqlite/20180922231600_ReaddACSnapshot.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20180922231600_ReaddACSnapshot.cs rename to Data/Migrations/Sqlite/20180922231600_ReaddACSnapshot.cs index b0938c85..ad668b2b 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20180922231600_ReaddACSnapshot.cs +++ b/Data/Migrations/Sqlite/20180922231600_ReaddACSnapshot.cs @@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class ReaddACSnapshot : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20181014171848_MakePenaltyExpirationNullable.Designer.cs b/Data/Migrations/Sqlite/20181014171848_MakePenaltyExpirationNullable.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20181014171848_MakePenaltyExpirationNullable.Designer.cs rename to Data/Migrations/Sqlite/20181014171848_MakePenaltyExpirationNullable.Designer.cs index 62deb8a6..b0a0be75 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20181014171848_MakePenaltyExpirationNullable.Designer.cs +++ b/Data/Migrations/Sqlite/20181014171848_MakePenaltyExpirationNullable.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20181014171848_MakePenaltyExpirationNullable")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20181014171848_MakePenaltyExpirationNullable.cs b/Data/Migrations/Sqlite/20181014171848_MakePenaltyExpirationNullable.cs similarity index 98% rename from SharedLibraryCore/Migrations/Postgresql/20181014171848_MakePenaltyExpirationNullable.cs rename to Data/Migrations/Sqlite/20181014171848_MakePenaltyExpirationNullable.cs index 6fb055ef..3eac0d00 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20181014171848_MakePenaltyExpirationNullable.cs +++ b/Data/Migrations/Sqlite/20181014171848_MakePenaltyExpirationNullable.cs @@ -1,7 +1,7 @@ using System; using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class MakePenaltyExpirationNullable : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20181125193243_MakeClientIPNullable.Designer.cs b/Data/Migrations/Sqlite/20181125193243_MakeClientIPNullable.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20181125193243_MakeClientIPNullable.Designer.cs rename to Data/Migrations/Sqlite/20181125193243_MakeClientIPNullable.Designer.cs index 9ec28f7f..96a12275 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20181125193243_MakeClientIPNullable.Designer.cs +++ b/Data/Migrations/Sqlite/20181125193243_MakeClientIPNullable.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20181125193243_MakeClientIPNullable")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20181125193243_MakeClientIPNullable.cs b/Data/Migrations/Sqlite/20181125193243_MakeClientIPNullable.cs similarity index 97% rename from SharedLibraryCore/Migrations/Postgresql/20181125193243_MakeClientIPNullable.cs rename to Data/Migrations/Sqlite/20181125193243_MakeClientIPNullable.cs index 9999193f..a81d86d0 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20181125193243_MakeClientIPNullable.cs +++ b/Data/Migrations/Sqlite/20181125193243_MakeClientIPNullable.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class MakeClientIPNullable : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs b/Data/Migrations/Sqlite/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs rename to Data/Migrations/Sqlite/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs index 8042335f..cfce8c22 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs +++ b/Data/Migrations/Sqlite/20181127144417_AddEndpointToEFServerUpdateServerIdType.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20181127144417_AddEndpointToEFServerUpdateServerIdType")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs b/Data/Migrations/Sqlite/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs similarity index 92% rename from SharedLibraryCore/Migrations/Postgresql/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs rename to Data/Migrations/Sqlite/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs index 3f6871f1..8d9e6169 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs +++ b/Data/Migrations/Sqlite/20181127144417_AddEndpointToEFServerUpdateServerIdType.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddEndpointToEFServerUpdateServerIdType : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20181216214513_AddEvadePenaltyFlag.Designer.cs b/Data/Migrations/Sqlite/20181216214513_AddEvadePenaltyFlag.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20181216214513_AddEvadePenaltyFlag.Designer.cs rename to Data/Migrations/Sqlite/20181216214513_AddEvadePenaltyFlag.Designer.cs index 389817fd..0fd3f553 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20181216214513_AddEvadePenaltyFlag.Designer.cs +++ b/Data/Migrations/Sqlite/20181216214513_AddEvadePenaltyFlag.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20181216214513_AddEvadePenaltyFlag")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20181216214513_AddEvadePenaltyFlag.cs b/Data/Migrations/Sqlite/20181216214513_AddEvadePenaltyFlag.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20181216214513_AddEvadePenaltyFlag.cs rename to Data/Migrations/Sqlite/20181216214513_AddEvadePenaltyFlag.cs index eaf9fbf3..5d69bffe 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20181216214513_AddEvadePenaltyFlag.cs +++ b/Data/Migrations/Sqlite/20181216214513_AddEvadePenaltyFlag.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddEvadePenaltyFlag : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs b/Data/Migrations/Sqlite/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs rename to Data/Migrations/Sqlite/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs index 6f1aa63e..608600cf 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs +++ b/Data/Migrations/Sqlite/20190222234742_AddIndexToEFMeta-KeyAndClientId.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20190222234742_AddIndexToEFMeta-KeyAndClientId")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs b/Data/Migrations/Sqlite/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs similarity index 94% rename from SharedLibraryCore/Migrations/Postgresql/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs rename to Data/Migrations/Sqlite/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs index ef8fbff1..cb3ff6d6 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs +++ b/Data/Migrations/Sqlite/20190222234742_AddIndexToEFMeta-KeyAndClientId.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddIndexToEFMetaKeyAndClientId : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20190423142128_AddGameNameToEFServer.Designer.cs b/Data/Migrations/Sqlite/20190423142128_AddGameNameToEFServer.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20190423142128_AddGameNameToEFServer.Designer.cs rename to Data/Migrations/Sqlite/20190423142128_AddGameNameToEFServer.Designer.cs index 2522be0f..dc0c4941 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190423142128_AddGameNameToEFServer.Designer.cs +++ b/Data/Migrations/Sqlite/20190423142128_AddGameNameToEFServer.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20190423142128_AddGameNameToEFServer")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20190423142128_AddGameNameToEFServer.cs b/Data/Migrations/Sqlite/20190423142128_AddGameNameToEFServer.cs similarity index 91% rename from SharedLibraryCore/Migrations/Postgresql/20190423142128_AddGameNameToEFServer.cs rename to Data/Migrations/Sqlite/20190423142128_AddGameNameToEFServer.cs index f9bca4c5..bebb186c 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190423142128_AddGameNameToEFServer.cs +++ b/Data/Migrations/Sqlite/20190423142128_AddGameNameToEFServer.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddGameNameToEFServer : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20190615145212_AddAvgRecoilOffset.Designer.cs b/Data/Migrations/Sqlite/20190615145212_AddAvgRecoilOffset.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20190615145212_AddAvgRecoilOffset.Designer.cs rename to Data/Migrations/Sqlite/20190615145212_AddAvgRecoilOffset.Designer.cs index 04bcc51c..0e78cde1 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190615145212_AddAvgRecoilOffset.Designer.cs +++ b/Data/Migrations/Sqlite/20190615145212_AddAvgRecoilOffset.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20190615145212_AddAvgRecoilOffset")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20190615145212_AddAvgRecoilOffset.cs b/Data/Migrations/Sqlite/20190615145212_AddAvgRecoilOffset.cs similarity index 91% rename from SharedLibraryCore/Migrations/Postgresql/20190615145212_AddAvgRecoilOffset.cs rename to Data/Migrations/Sqlite/20190615145212_AddAvgRecoilOffset.cs index a884a9fe..735c8f5b 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190615145212_AddAvgRecoilOffset.cs +++ b/Data/Migrations/Sqlite/20190615145212_AddAvgRecoilOffset.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddAvgRecoilOffset : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs b/Data/Migrations/Sqlite/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs rename to Data/Migrations/Sqlite/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs index 51fa8efd..a26566a1 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs +++ b/Data/Migrations/Sqlite/20190615214055_AddRecoilOffsetToSnapshot.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20190615214055_AddRecoilOffsetToSnapshot")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20190615214055_AddRecoilOffsetToSnapshot.cs b/Data/Migrations/Sqlite/20190615214055_AddRecoilOffsetToSnapshot.cs similarity index 92% rename from SharedLibraryCore/Migrations/Postgresql/20190615214055_AddRecoilOffsetToSnapshot.cs rename to Data/Migrations/Sqlite/20190615214055_AddRecoilOffsetToSnapshot.cs index b7ef1b24..2b57056a 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190615214055_AddRecoilOffsetToSnapshot.cs +++ b/Data/Migrations/Sqlite/20190615214055_AddRecoilOffsetToSnapshot.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddRecoilOffsetToSnapshot : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20190725000309_AlterEFRatingIndex.Designer.cs b/Data/Migrations/Sqlite/20190725000309_AlterEFRatingIndex.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20190725000309_AlterEFRatingIndex.Designer.cs rename to Data/Migrations/Sqlite/20190725000309_AlterEFRatingIndex.Designer.cs index 1a953f48..81879a90 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190725000309_AlterEFRatingIndex.Designer.cs +++ b/Data/Migrations/Sqlite/20190725000309_AlterEFRatingIndex.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20190725000309_AlterEFRatingIndex")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20190725000309_AlterEFRatingIndex.cs b/Data/Migrations/Sqlite/20190725000309_AlterEFRatingIndex.cs similarity index 96% rename from SharedLibraryCore/Migrations/Postgresql/20190725000309_AlterEFRatingIndex.cs rename to Data/Migrations/Sqlite/20190725000309_AlterEFRatingIndex.cs index c85535b7..50d0cb96 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190725000309_AlterEFRatingIndex.cs +++ b/Data/Migrations/Sqlite/20190725000309_AlterEFRatingIndex.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AlterEFRatingIndex : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20190802174908_AddSearchNameToEFAlias.Designer.cs b/Data/Migrations/Sqlite/20190802174908_AddSearchNameToEFAlias.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20190802174908_AddSearchNameToEFAlias.Designer.cs rename to Data/Migrations/Sqlite/20190802174908_AddSearchNameToEFAlias.Designer.cs index 576968f2..069939e7 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190802174908_AddSearchNameToEFAlias.Designer.cs +++ b/Data/Migrations/Sqlite/20190802174908_AddSearchNameToEFAlias.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20190802174908_AddSearchNameToEFAlias")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20190802174908_AddSearchNameToEFAlias.cs b/Data/Migrations/Sqlite/20190802174908_AddSearchNameToEFAlias.cs similarity index 94% rename from SharedLibraryCore/Migrations/Postgresql/20190802174908_AddSearchNameToEFAlias.cs rename to Data/Migrations/Sqlite/20190802174908_AddSearchNameToEFAlias.cs index d7311093..ef154051 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190802174908_AddSearchNameToEFAlias.cs +++ b/Data/Migrations/Sqlite/20190802174908_AddSearchNameToEFAlias.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddSearchNameToEFAlias : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20190831210503_AvgSnapValueToClientStatistics.Designer.cs b/Data/Migrations/Sqlite/20190831210503_AvgSnapValueToClientStatistics.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20190831210503_AvgSnapValueToClientStatistics.Designer.cs rename to Data/Migrations/Sqlite/20190831210503_AvgSnapValueToClientStatistics.Designer.cs index da616783..6dcb4532 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190831210503_AvgSnapValueToClientStatistics.Designer.cs +++ b/Data/Migrations/Sqlite/20190831210503_AvgSnapValueToClientStatistics.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20190831210503_AvgSnapValueToClientStatistics")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20190831210503_AvgSnapValueToClientStatistics.cs b/Data/Migrations/Sqlite/20190831210503_AvgSnapValueToClientStatistics.cs similarity index 92% rename from SharedLibraryCore/Migrations/Postgresql/20190831210503_AvgSnapValueToClientStatistics.cs rename to Data/Migrations/Sqlite/20190831210503_AvgSnapValueToClientStatistics.cs index 625b3ca1..0aea6fa6 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190831210503_AvgSnapValueToClientStatistics.cs +++ b/Data/Migrations/Sqlite/20190831210503_AvgSnapValueToClientStatistics.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AvgSnapValueToClientStatistics : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs b/Data/Migrations/Sqlite/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs rename to Data/Migrations/Sqlite/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs index a199c814..40c168ec 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs +++ b/Data/Migrations/Sqlite/20190901180209_AddSnapHitCountToClientStatistics.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20190901180209_AddSnapHitCountToClientStatistics")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20190901180209_AddSnapHitCountToClientStatistics.cs b/Data/Migrations/Sqlite/20190901180209_AddSnapHitCountToClientStatistics.cs similarity index 92% rename from SharedLibraryCore/Migrations/Postgresql/20190901180209_AddSnapHitCountToClientStatistics.cs rename to Data/Migrations/Sqlite/20190901180209_AddSnapHitCountToClientStatistics.cs index d3ddd2c5..10579fc7 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190901180209_AddSnapHitCountToClientStatistics.cs +++ b/Data/Migrations/Sqlite/20190901180209_AddSnapHitCountToClientStatistics.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddSnapHitCountToClientStatistics : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs b/Data/Migrations/Sqlite/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs rename to Data/Migrations/Sqlite/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs index 4c012301..aa7e8584 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs +++ b/Data/Migrations/Sqlite/20190901223620_UseJunctionTableForSnapshotVector3.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20190901223620_UseJunctionTableForSnapshotVector3")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20190901223620_UseJunctionTableForSnapshotVector3.cs b/Data/Migrations/Sqlite/20190901223620_UseJunctionTableForSnapshotVector3.cs similarity index 98% rename from SharedLibraryCore/Migrations/Postgresql/20190901223620_UseJunctionTableForSnapshotVector3.cs rename to Data/Migrations/Sqlite/20190901223620_UseJunctionTableForSnapshotVector3.cs index 9f23f776..8f8c5ff5 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190901223620_UseJunctionTableForSnapshotVector3.cs +++ b/Data/Migrations/Sqlite/20190901223620_UseJunctionTableForSnapshotVector3.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Migrations; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class UseJunctionTableForSnapshotVector3 : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs b/Data/Migrations/Sqlite/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs rename to Data/Migrations/Sqlite/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs index 54a1a989..c0203170 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs +++ b/Data/Migrations/Sqlite/20190914011524_AddCurrentSnapValueToSnapshot.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20190914011524_AddCurrentSnapValueToSnapshot")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20190914011524_AddCurrentSnapValueToSnapshot.cs b/Data/Migrations/Sqlite/20190914011524_AddCurrentSnapValueToSnapshot.cs similarity index 92% rename from SharedLibraryCore/Migrations/Postgresql/20190914011524_AddCurrentSnapValueToSnapshot.cs rename to Data/Migrations/Sqlite/20190914011524_AddCurrentSnapValueToSnapshot.cs index e0d23b6d..3da2b5a9 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190914011524_AddCurrentSnapValueToSnapshot.cs +++ b/Data/Migrations/Sqlite/20190914011524_AddCurrentSnapValueToSnapshot.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddCurrentSnapValueToSnapshot : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs b/Data/Migrations/Sqlite/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs rename to Data/Migrations/Sqlite/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs index 9ddf2969..70c21140 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs +++ b/Data/Migrations/Sqlite/20190914012015_AddSessionSnapHitsToSnapshot.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20190914012015_AddSessionSnapHitsToSnapshot")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20190914012015_AddSessionSnapHitsToSnapshot.cs b/Data/Migrations/Sqlite/20190914012015_AddSessionSnapHitsToSnapshot.cs similarity index 92% rename from SharedLibraryCore/Migrations/Postgresql/20190914012015_AddSessionSnapHitsToSnapshot.cs rename to Data/Migrations/Sqlite/20190914012015_AddSessionSnapHitsToSnapshot.cs index 687fe3ed..cf3a3d1c 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20190914012015_AddSessionSnapHitsToSnapshot.cs +++ b/Data/Migrations/Sqlite/20190914012015_AddSessionSnapHitsToSnapshot.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddSessionSnapHitsToSnapshot : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20191004172550_RenameClientHitLocationCountColumns.Designer.cs b/Data/Migrations/Sqlite/20191004172550_RenameClientHitLocationCountColumns.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20191004172550_RenameClientHitLocationCountColumns.Designer.cs rename to Data/Migrations/Sqlite/20191004172550_RenameClientHitLocationCountColumns.Designer.cs index 200be1d0..f294aca6 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20191004172550_RenameClientHitLocationCountColumns.Designer.cs +++ b/Data/Migrations/Sqlite/20191004172550_RenameClientHitLocationCountColumns.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20191004172550_RenameClientHitLocationCountColumns")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20191004172550_RenameClientHitLocationCountColumns.cs b/Data/Migrations/Sqlite/20191004172550_RenameClientHitLocationCountColumns.cs similarity index 99% rename from SharedLibraryCore/Migrations/Postgresql/20191004172550_RenameClientHitLocationCountColumns.cs rename to Data/Migrations/Sqlite/20191004172550_RenameClientHitLocationCountColumns.cs index ec56f701..bf1e7967 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20191004172550_RenameClientHitLocationCountColumns.cs +++ b/Data/Migrations/Sqlite/20191004172550_RenameClientHitLocationCountColumns.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class RenameClientHitLocationCountColumns : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs b/Data/Migrations/Sqlite/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs rename to Data/Migrations/Sqlite/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs index 7000be7a..3e91ebef 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs +++ b/Data/Migrations/Sqlite/20191030000713_EnforceUniqueIndexForEFAliasIPName.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20191030000713_EnforceUniqueIndexForEFAliasIPName")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs b/Data/Migrations/Sqlite/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs similarity index 98% rename from SharedLibraryCore/Migrations/Postgresql/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs rename to Data/Migrations/Sqlite/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs index f8d77113..3f9652e1 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs +++ b/Data/Migrations/Sqlite/20191030000713_EnforceUniqueIndexForEFAliasIPName.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class EnforceUniqueIndexForEFAliasIPName : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs b/Data/Migrations/Sqlite/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs rename to Data/Migrations/Sqlite/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs index 840ea878..62e6845a 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs +++ b/Data/Migrations/Sqlite/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs b/Data/Migrations/Sqlite/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs similarity index 94% rename from SharedLibraryCore/Migrations/Postgresql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs rename to Data/Migrations/Sqlite/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs index ae96a8c4..e58ca32e 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs +++ b/Data/Migrations/Sqlite/20191225202141_SetCaseSensitiveCoallationForAliasNameMySQL.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class SetCaseSensitiveCoallationForAliasNameMySQL : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20191230140947_AddMissingActiveColumns.Designer.cs b/Data/Migrations/Sqlite/20191230140947_AddMissingActiveColumns.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20191230140947_AddMissingActiveColumns.Designer.cs rename to Data/Migrations/Sqlite/20191230140947_AddMissingActiveColumns.Designer.cs index e412d2c7..dcebb574 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20191230140947_AddMissingActiveColumns.Designer.cs +++ b/Data/Migrations/Sqlite/20191230140947_AddMissingActiveColumns.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20191230140947_AddMissingActiveColumns")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20191230140947_AddMissingActiveColumns.cs b/Data/Migrations/Sqlite/20191230140947_AddMissingActiveColumns.cs similarity index 93% rename from SharedLibraryCore/Migrations/Postgresql/20191230140947_AddMissingActiveColumns.cs rename to Data/Migrations/Sqlite/20191230140947_AddMissingActiveColumns.cs index c1ce223a..f1292963 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20191230140947_AddMissingActiveColumns.cs +++ b/Data/Migrations/Sqlite/20191230140947_AddMissingActiveColumns.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddMissingActiveColumns : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs b/Data/Migrations/Sqlite/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs rename to Data/Migrations/Sqlite/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs index 6a74f44c..7512ca9f 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs +++ b/Data/Migrations/Sqlite/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20200423225137_AddImpersonationIdToEFChangeHistory")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20200423225137_AddImpersonationIdToEFChangeHistory.cs b/Data/Migrations/Sqlite/20200423225137_AddImpersonationIdToEFChangeHistory.cs similarity index 92% rename from SharedLibraryCore/Migrations/Postgresql/20200423225137_AddImpersonationIdToEFChangeHistory.cs rename to Data/Migrations/Sqlite/20200423225137_AddImpersonationIdToEFChangeHistory.cs index b2e74946..d2a62b0a 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20200423225137_AddImpersonationIdToEFChangeHistory.cs +++ b/Data/Migrations/Sqlite/20200423225137_AddImpersonationIdToEFChangeHistory.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddImpersonationIdToEFChangeHistory : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20200521203304_AddHostnameToEFServer.Designer.cs b/Data/Migrations/Sqlite/20200521203304_AddHostnameToEFServer.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20200521203304_AddHostnameToEFServer.Designer.cs rename to Data/Migrations/Sqlite/20200521203304_AddHostnameToEFServer.Designer.cs index 4bcbd7b7..89d5572e 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20200521203304_AddHostnameToEFServer.Designer.cs +++ b/Data/Migrations/Sqlite/20200521203304_AddHostnameToEFServer.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20200521203304_AddHostnameToEFServer")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20200521203304_AddHostnameToEFServer.cs b/Data/Migrations/Sqlite/20200521203304_AddHostnameToEFServer.cs similarity index 91% rename from SharedLibraryCore/Migrations/Postgresql/20200521203304_AddHostnameToEFServer.cs rename to Data/Migrations/Sqlite/20200521203304_AddHostnameToEFServer.cs index 3fa054c4..8211d5c1 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20200521203304_AddHostnameToEFServer.cs +++ b/Data/Migrations/Sqlite/20200521203304_AddHostnameToEFServer.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddHostnameToEFServer : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20200819224119_AddIsPasswordProtectedColumn.Designer.cs b/Data/Migrations/Sqlite/20200819224119_AddIsPasswordProtectedColumn.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20200819224119_AddIsPasswordProtectedColumn.Designer.cs rename to Data/Migrations/Sqlite/20200819224119_AddIsPasswordProtectedColumn.Designer.cs index cb82b6fb..e4c0a039 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20200819224119_AddIsPasswordProtectedColumn.Designer.cs +++ b/Data/Migrations/Sqlite/20200819224119_AddIsPasswordProtectedColumn.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20200819224119_AddIsPasswordProtectedColumn")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20200819224119_AddIsPasswordProtectedColumn.cs b/Data/Migrations/Sqlite/20200819224119_AddIsPasswordProtectedColumn.cs similarity index 95% rename from SharedLibraryCore/Migrations/Postgresql/20200819224119_AddIsPasswordProtectedColumn.cs rename to Data/Migrations/Sqlite/20200819224119_AddIsPasswordProtectedColumn.cs index 0fb89d05..4f6231dd 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20200819224119_AddIsPasswordProtectedColumn.cs +++ b/Data/Migrations/Sqlite/20200819224119_AddIsPasswordProtectedColumn.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddIsPasswordProtectedColumn : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20201114232340_UpdateEFRatingIndex.Designer.cs b/Data/Migrations/Sqlite/20201114232340_UpdateEFRatingIndex.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20201114232340_UpdateEFRatingIndex.Designer.cs rename to Data/Migrations/Sqlite/20201114232340_UpdateEFRatingIndex.Designer.cs index 1a50b70f..e0fde6cb 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20201114232340_UpdateEFRatingIndex.Designer.cs +++ b/Data/Migrations/Sqlite/20201114232340_UpdateEFRatingIndex.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20201114232340_UpdateEFRatingIndex")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20201114232340_UpdateEFRatingIndex.cs b/Data/Migrations/Sqlite/20201114232340_UpdateEFRatingIndex.cs similarity index 93% rename from SharedLibraryCore/Migrations/Postgresql/20201114232340_UpdateEFRatingIndex.cs rename to Data/Migrations/Sqlite/20201114232340_UpdateEFRatingIndex.cs index 779a1dc6..220f4acb 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20201114232340_UpdateEFRatingIndex.cs +++ b/Data/Migrations/Sqlite/20201114232340_UpdateEFRatingIndex.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class UpdateEFRatingIndex : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs b/Data/Migrations/Sqlite/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs rename to Data/Migrations/Sqlite/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs index c43c421f..81eb862d 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs +++ b/Data/Migrations/Sqlite/20201118023106_AddSentIngameFlagToClientMessage.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20201118023106_AddSentIngameFlagToClientMessage")] diff --git a/SharedLibraryCore/Migrations/Postgresql/20201118023106_AddSentIngameFlagToClientMessage.cs b/Data/Migrations/Sqlite/20201118023106_AddSentIngameFlagToClientMessage.cs similarity index 92% rename from SharedLibraryCore/Migrations/Postgresql/20201118023106_AddSentIngameFlagToClientMessage.cs rename to Data/Migrations/Sqlite/20201118023106_AddSentIngameFlagToClientMessage.cs index eb652b89..6fbc1576 100644 --- a/SharedLibraryCore/Migrations/Postgresql/20201118023106_AddSentIngameFlagToClientMessage.cs +++ b/Data/Migrations/Sqlite/20201118023106_AddSentIngameFlagToClientMessage.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Postgresql +namespace Data.Migrations.Sqlite { public partial class AddSentIngameFlagToClientMessage : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/20210124164906_UpdateEFMetaToSupportNonClientMetaAndLinkedMeta.Designer.cs b/Data/Migrations/Sqlite/20210124164906_UpdateEFMetaToSupportNonClientMetaAndLinkedMeta.Designer.cs similarity index 99% rename from SharedLibraryCore/Migrations/Sqlite/20210124164906_UpdateEFMetaToSupportNonClientMetaAndLinkedMeta.Designer.cs rename to Data/Migrations/Sqlite/20210124164906_UpdateEFMetaToSupportNonClientMetaAndLinkedMeta.Designer.cs index 8966c2d4..9c4e5de2 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20210124164906_UpdateEFMetaToSupportNonClientMetaAndLinkedMeta.Designer.cs +++ b/Data/Migrations/Sqlite/20210124164906_UpdateEFMetaToSupportNonClientMetaAndLinkedMeta.Designer.cs @@ -4,9 +4,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; +using Data.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] [Migration("20210124164906_UpdateEFMetaToSupportNonClientMetaAndLinkedMeta")] diff --git a/SharedLibraryCore/Migrations/Sqlite/20210124164906_UpdateEFMetaToSupportNonClientMetaAndLinkedMeta.cs b/Data/Migrations/Sqlite/20210124164906_UpdateEFMetaToSupportNonClientMetaAndLinkedMeta.cs similarity index 98% rename from SharedLibraryCore/Migrations/Sqlite/20210124164906_UpdateEFMetaToSupportNonClientMetaAndLinkedMeta.cs rename to Data/Migrations/Sqlite/20210124164906_UpdateEFMetaToSupportNonClientMetaAndLinkedMeta.cs index 5137722e..0a6f6411 100644 --- a/SharedLibraryCore/Migrations/Sqlite/20210124164906_UpdateEFMetaToSupportNonClientMetaAndLinkedMeta.cs +++ b/Data/Migrations/Sqlite/20210124164906_UpdateEFMetaToSupportNonClientMetaAndLinkedMeta.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore.Migrations; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { public partial class UpdateEFMetaToSupportNonClientMetaAndLinkedMeta : Migration { diff --git a/SharedLibraryCore/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs b/Data/Migrations/Sqlite/20210301231432_AddAdditionalClientStatsAndZScore.Designer.cs similarity index 65% rename from SharedLibraryCore/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs rename to Data/Migrations/Sqlite/20210301231432_AddAdditionalClientStatsAndZScore.Designer.cs index 90f555e4..246a50c0 100644 --- a/SharedLibraryCore/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs +++ b/Data/Migrations/Sqlite/20210301231432_AddAdditionalClientStatsAndZScore.Designer.cs @@ -1,22 +1,208 @@ // using System; +using Data.MigrationContext; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using SharedLibraryCore.Database.MigrationContext; -namespace SharedLibraryCore.Migrations.Sqlite +namespace Data.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] - partial class SqliteDatabaseContextModelSnapshot : ModelSnapshot + [Migration("20210301231432_AddAdditionalClientStatsAndZScore")] + partial class AddAdditionalClientStatsAndZScore { - protected override void BuildModel(ModelBuilder modelBuilder) + protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder .HasAnnotation("ProductVersion", "3.1.10"); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b => + modelBuilder.Entity("Data.Models.Client.EFACSnapshotVector3", b => + { + b.Property("ACSnapshotVector3Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("SnapshotId") + .HasColumnType("INTEGER"); + + b.Property("Vector3Id") + .HasColumnType("INTEGER"); + + b.HasKey("ACSnapshotVector3Id"); + + b.HasIndex("SnapshotId"); + + b.HasIndex("Vector3Id"); + + b.ToTable("EFACSnapshotVector3"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClient", b => + { + b.Property("ClientId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("AliasLinkId") + .HasColumnType("INTEGER"); + + b.Property("Connections") + .HasColumnType("INTEGER"); + + b.Property("CurrentAliasId") + .HasColumnType("INTEGER"); + + b.Property("FirstConnection") + .HasColumnType("TEXT"); + + b.Property("LastConnection") + .HasColumnType("TEXT"); + + b.Property("Level") + .HasColumnType("INTEGER"); + + b.Property("Masked") + .HasColumnType("INTEGER"); + + b.Property("NetworkId") + .HasColumnType("INTEGER"); + + b.Property("Password") + .HasColumnType("TEXT"); + + b.Property("PasswordSalt") + .HasColumnType("TEXT"); + + b.Property("TotalConnectionTime") + .HasColumnType("INTEGER"); + + b.HasKey("ClientId"); + + b.HasIndex("AliasLinkId"); + + b.HasIndex("CurrentAliasId"); + + b.HasIndex("NetworkId") + .IsUnique(); + + b.ToTable("EFClients"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientKill", b => + { + b.Property("KillId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("AttackerId") + .HasColumnType("INTEGER"); + + b.Property("Damage") + .HasColumnType("INTEGER"); + + b.Property("DeathOriginVector3Id") + .HasColumnType("INTEGER"); + + b.Property("DeathType") + .HasColumnType("INTEGER"); + + b.Property("Fraction") + .HasColumnType("REAL"); + + b.Property("HitLoc") + .HasColumnType("INTEGER"); + + b.Property("IsKill") + .HasColumnType("INTEGER"); + + b.Property("KillOriginVector3Id") + .HasColumnType("INTEGER"); + + b.Property("Map") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("VictimId") + .HasColumnType("INTEGER"); + + b.Property("ViewAnglesVector3Id") + .HasColumnType("INTEGER"); + + b.Property("VisibilityPercentage") + .HasColumnType("REAL"); + + b.Property("Weapon") + .HasColumnType("INTEGER"); + + b.Property("When") + .HasColumnType("TEXT"); + + b.HasKey("KillId"); + + b.HasIndex("AttackerId"); + + b.HasIndex("DeathOriginVector3Id"); + + b.HasIndex("KillOriginVector3Id"); + + b.HasIndex("ServerId"); + + b.HasIndex("VictimId"); + + b.HasIndex("ViewAnglesVector3Id"); + + b.ToTable("EFClientKills"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientMessage", b => + { + b.Property("MessageId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("Message") + .HasColumnType("TEXT"); + + b.Property("SentIngame") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("TimeSent") + .HasColumnType("TEXT"); + + b.HasKey("MessageId"); + + b.HasIndex("ClientId"); + + b.HasIndex("ServerId"); + + b.HasIndex("TimeSent"); + + b.ToTable("EFClientMessages"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFACSnapshot", b => { b.Property("SnapshotId") .ValueGeneratedOnAdd() @@ -112,137 +298,81 @@ namespace SharedLibraryCore.Migrations.Sqlite b.ToTable("EFACSnapshot"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshotVector3", b => + modelBuilder.Entity("Data.Models.Client.Stats.EFClientHitStatistic", b => { - b.Property("ACSnapshotVector3Id") + b.Property("ClientHitStatisticId") .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("SnapshotId") - .HasColumnType("INTEGER"); - - b.Property("Vector3Id") - .HasColumnType("INTEGER"); - - b.HasKey("ACSnapshotVector3Id"); - - b.HasIndex("SnapshotId"); - - b.HasIndex("Vector3Id"); - - b.ToTable("EFACSnapshotVector3"); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b => - { - b.Property("KillId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("AttackerId") - .HasColumnType("INTEGER"); - - b.Property("Damage") - .HasColumnType("INTEGER"); - - b.Property("DeathOriginVector3Id") - .HasColumnType("INTEGER"); - - b.Property("DeathType") - .HasColumnType("INTEGER"); - - b.Property("Fraction") - .HasColumnType("REAL"); - - b.Property("HitLoc") - .HasColumnType("INTEGER"); - - b.Property("IsKill") - .HasColumnType("INTEGER"); - - b.Property("KillOriginVector3Id") - .HasColumnType("INTEGER"); - - b.Property("Map") - .HasColumnType("INTEGER"); - - b.Property("ServerId") - .HasColumnType("INTEGER"); - - b.Property("VictimId") - .HasColumnType("INTEGER"); - - b.Property("ViewAnglesVector3Id") - .HasColumnType("INTEGER"); - - b.Property("VisibilityPercentage") - .HasColumnType("REAL"); - - b.Property("Weapon") - .HasColumnType("INTEGER"); - - b.Property("When") - .HasColumnType("TEXT"); - - b.HasKey("KillId"); - - b.HasIndex("AttackerId"); - - b.HasIndex("DeathOriginVector3Id"); - - b.HasIndex("KillOriginVector3Id"); - - b.HasIndex("ServerId"); - - b.HasIndex("VictimId"); - - b.HasIndex("ViewAnglesVector3Id"); - - b.ToTable("EFClientKills"); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientMessage", b => - { - b.Property("MessageId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - b.Property("ClientId") .HasColumnType("INTEGER"); - b.Property("Message") + b.Property("CreatedDateTime") .HasColumnType("TEXT"); - b.Property("SentIngame") + b.Property("DamageInflicted") .HasColumnType("INTEGER"); - b.Property("ServerId") + b.Property("DamageReceived") .HasColumnType("INTEGER"); - b.Property("TimeSent") + b.Property("DeathCount") + .HasColumnType("INTEGER"); + + b.Property("HitCount") + .HasColumnType("INTEGER"); + + b.Property("HitLocationId") + .HasColumnType("INTEGER"); + + b.Property("KillCount") + .HasColumnType("INTEGER"); + + b.Property("MeansOfDeathId") + .HasColumnType("INTEGER"); + + b.Property("ReceivedHitCount") + .HasColumnType("INTEGER"); + + b.Property("Score") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("SuicideCount") + .HasColumnType("INTEGER"); + + b.Property("UpdatedDateTime") .HasColumnType("TEXT"); - b.HasKey("MessageId"); + b.Property("UsageSeconds") + .HasColumnType("INTEGER"); + + b.Property("WeaponAttachmentComboId") + .HasColumnType("INTEGER"); + + b.Property("WeaponId") + .HasColumnType("INTEGER"); + + b.HasKey("ClientHitStatisticId"); b.HasIndex("ClientId"); + b.HasIndex("HitLocationId"); + + b.HasIndex("MeansOfDeathId"); + b.HasIndex("ServerId"); - b.HasIndex("TimeSent"); + b.HasIndex("WeaponAttachmentComboId"); - b.ToTable("EFClientMessages"); + b.HasIndex("WeaponId"); + + b.ToTable("EFClientHitStatistics"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b => + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRatingHistory", b => { b.Property("RatingHistoryId") .ValueGeneratedOnAdd() @@ -261,7 +391,7 @@ namespace SharedLibraryCore.Migrations.Sqlite b.ToTable("EFClientRatingHistory"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b => + modelBuilder.Entity("Data.Models.Client.Stats.EFClientStatistics", b => { b.Property("ClientId") .HasColumnType("INTEGER"); @@ -272,9 +402,6 @@ namespace SharedLibraryCore.Migrations.Sqlite b.Property("Active") .HasColumnType("INTEGER"); - b.Property("AverageRecoilOffset") - .HasColumnType("REAL"); - b.Property("AverageSnapValue") .HasColumnType("REAL"); @@ -305,17 +432,24 @@ namespace SharedLibraryCore.Migrations.Sqlite b.Property("TimePlayed") .HasColumnType("INTEGER"); - b.Property("VisionAverage") + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("ZScore") .HasColumnType("REAL"); b.HasKey("ClientId", "ServerId"); b.HasIndex("ServerId"); + b.HasIndex("ZScore"); + + b.HasIndex("ClientId", "TimePlayed", "ZScore"); + b.ToTable("EFClientStatistics"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b => + modelBuilder.Entity("Data.Models.Client.Stats.EFHitLocationCount", b => { b.Property("HitLocationCountId") .ValueGeneratedOnAdd() @@ -353,7 +487,7 @@ namespace SharedLibraryCore.Migrations.Sqlite b.ToTable("EFHitLocationCounts"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b => + modelBuilder.Entity("Data.Models.Client.Stats.EFRating", b => { b.Property("RatingId") .ValueGeneratedOnAdd() @@ -396,60 +530,166 @@ namespace SharedLibraryCore.Migrations.Sqlite b.ToTable("EFRating"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServer", b => + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFHitLocation", b => { - b.Property("ServerId") - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("EndPoint") - .HasColumnType("TEXT"); - - b.Property("GameName") - .HasColumnType("INTEGER"); - - b.Property("HostName") - .HasColumnType("TEXT"); - - b.Property("IsPasswordProtected") - .HasColumnType("INTEGER"); - - b.Property("Port") - .HasColumnType("INTEGER"); - - b.HasKey("ServerId"); - - b.ToTable("EFServers"); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b => - { - b.Property("StatisticId") + b.Property("HitLocationId") .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); - b.Property("Active") + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") .HasColumnType("INTEGER"); - b.Property("ServerId") - .HasColumnType("INTEGER"); + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); - b.Property("TotalKills") - .HasColumnType("INTEGER"); + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); - b.Property("TotalPlayTime") - .HasColumnType("INTEGER"); + b.HasKey("HitLocationId"); - b.HasKey("StatisticId"); + b.HasIndex("Name"); - b.HasIndex("ServerId"); - - b.ToTable("EFServerStatistics"); + b.ToTable("EFHitLocations"); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b => + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFMap", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.HasKey("MapId"); + + b.ToTable("EFMaps"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFMeansOfDeath", b => + { + b.Property("MeansOfDeathId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.HasKey("MeansOfDeathId"); + + b.ToTable("EFMeansOfDeath"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeapon", b => + { + b.Property("WeaponId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.HasKey("WeaponId"); + + b.HasIndex("Name"); + + b.ToTable("EFWeapons"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachment", b => + { + b.Property("WeaponAttachmentId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.HasKey("WeaponAttachmentId"); + + b.ToTable("EFWeaponAttachments"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", b => + { + b.Property("WeaponAttachmentComboId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attachment1Id") + .HasColumnType("INTEGER"); + + b.Property("Attachment2Id") + .HasColumnType("INTEGER"); + + b.Property("Attachment3Id") + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") + .HasColumnType("INTEGER"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.HasKey("WeaponAttachmentComboId"); + + b.HasIndex("Attachment1Id"); + + b.HasIndex("Attachment2Id"); + + b.HasIndex("Attachment3Id"); + + b.ToTable("EFWeaponAttachmentCombos"); + }); + + modelBuilder.Entity("Data.Models.EFAlias", b => { b.Property("AliasId") .ValueGeneratedOnAdd() @@ -492,7 +732,7 @@ namespace SharedLibraryCore.Migrations.Sqlite b.ToTable("EFAlias"); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAliasLink", b => + modelBuilder.Entity("Data.Models.EFAliasLink", b => { b.Property("AliasLinkId") .ValueGeneratedOnAdd() @@ -506,7 +746,7 @@ namespace SharedLibraryCore.Migrations.Sqlite b.ToTable("EFAliasLinks"); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFChangeHistory", b => + modelBuilder.Entity("Data.Models.EFChangeHistory", b => { b.Property("ChangeHistoryId") .ValueGeneratedOnAdd() @@ -545,61 +785,7 @@ namespace SharedLibraryCore.Migrations.Sqlite b.ToTable("EFChangeHistory"); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b => - { - b.Property("ClientId") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Active") - .HasColumnType("INTEGER"); - - b.Property("AliasLinkId") - .HasColumnType("INTEGER"); - - b.Property("Connections") - .HasColumnType("INTEGER"); - - b.Property("CurrentAliasId") - .HasColumnType("INTEGER"); - - b.Property("FirstConnection") - .HasColumnType("TEXT"); - - b.Property("LastConnection") - .HasColumnType("TEXT"); - - b.Property("Level") - .HasColumnType("INTEGER"); - - b.Property("Masked") - .HasColumnType("INTEGER"); - - b.Property("NetworkId") - .HasColumnType("INTEGER"); - - b.Property("Password") - .HasColumnType("TEXT"); - - b.Property("PasswordSalt") - .HasColumnType("TEXT"); - - b.Property("TotalConnectionTime") - .HasColumnType("INTEGER"); - - b.HasKey("ClientId"); - - b.HasIndex("AliasLinkId"); - - b.HasIndex("CurrentAliasId"); - - b.HasIndex("NetworkId") - .IsUnique(); - - b.ToTable("EFClients"); - }); - - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFMeta", b => + modelBuilder.Entity("Data.Models.EFMeta", b => { b.Property("MetaId") .ValueGeneratedOnAdd() @@ -643,7 +829,7 @@ namespace SharedLibraryCore.Migrations.Sqlite b.ToTable("EFMeta"); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b => + modelBuilder.Entity("Data.Models.EFPenalty", b => { b.Property("PenaltyId") .ValueGeneratedOnAdd() @@ -691,7 +877,60 @@ namespace SharedLibraryCore.Migrations.Sqlite b.ToTable("EFPenalties"); }); - modelBuilder.Entity("SharedLibraryCore.Helpers.Vector3", b => + modelBuilder.Entity("Data.Models.Server.EFServer", b => + { + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("EndPoint") + .HasColumnType("TEXT"); + + b.Property("GameName") + .HasColumnType("INTEGER"); + + b.Property("HostName") + .HasColumnType("TEXT"); + + b.Property("IsPasswordProtected") + .HasColumnType("INTEGER"); + + b.Property("Port") + .HasColumnType("INTEGER"); + + b.HasKey("ServerId"); + + b.ToTable("EFServers"); + }); + + modelBuilder.Entity("Data.Models.Server.EFServerStatistics", b => + { + b.Property("StatisticId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("TotalKills") + .HasColumnType("INTEGER"); + + b.Property("TotalPlayTime") + .HasColumnType("INTEGER"); + + b.HasKey("StatisticId"); + + b.HasIndex("ServerId"); + + b.ToTable("EFServerStatistics"); + }); + + modelBuilder.Entity("Data.Models.Vector3", b => { b.Property("Vector3Id") .ValueGeneratedOnAdd() @@ -711,225 +950,271 @@ namespace SharedLibraryCore.Migrations.Sqlite b.ToTable("Vector3"); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b => + modelBuilder.Entity("Data.Models.Client.EFACSnapshotVector3", b => { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "CurrentViewAngle") - .WithMany() - .HasForeignKey("CurrentViewAngleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "HitDestination") - .WithMany() - .HasForeignKey("HitDestinationId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "HitOrigin") - .WithMany() - .HasForeignKey("HitOriginId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "LastStrainAngle") - .WithMany() - .HasForeignKey("LastStrainAngleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshotVector3", b => - { - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", "Snapshot") + b.HasOne("Data.Models.Client.Stats.EFACSnapshot", "Snapshot") .WithMany("PredictedViewAngles") .HasForeignKey("SnapshotId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("SharedLibraryCore.Helpers.Vector3", "Vector") + b.HasOne("Data.Models.Vector3", "Vector") .WithMany() .HasForeignKey("Vector3Id") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b => + modelBuilder.Entity("Data.Models.Client.EFClient", b => { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Attacker") - .WithMany() - .HasForeignKey("AttackerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "DeathOrigin") - .WithMany() - .HasForeignKey("DeathOriginVector3Id"); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "KillOrigin") - .WithMany() - .HasForeignKey("KillOriginVector3Id"); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Victim") - .WithMany() - .HasForeignKey("VictimId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("SharedLibraryCore.Helpers.Vector3", "ViewAngles") - .WithMany() - .HasForeignKey("ViewAnglesVector3Id"); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientMessage", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") - .WithMany() - .HasForeignKey("ClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") - .WithMany() - .HasForeignKey("EFClientStatisticsClientId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("EFClientStatisticsServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", null) - .WithMany("HitLocations") - .HasForeignKey("EFClientStatisticsClientId", "EFClientStatisticsServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b => - { - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", "RatingHistory") - .WithMany("Ratings") - .HasForeignKey("RatingHistoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId"); - }); - - modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b => - { - b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") - .WithMany() - .HasForeignKey("ServerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link") - .WithMany("Children") - .HasForeignKey("LinkId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - }); - - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b => - { - b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "AliasLink") + b.HasOne("Data.Models.EFAliasLink", "AliasLink") .WithMany() .HasForeignKey("AliasLinkId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("SharedLibraryCore.Database.Models.EFAlias", "CurrentAlias") + b.HasOne("Data.Models.EFAlias", "CurrentAlias") .WithMany() .HasForeignKey("CurrentAliasId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFMeta", b => + modelBuilder.Entity("Data.Models.Client.EFClientKill", b => { - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") + b.HasOne("Data.Models.Client.EFClient", "Attacker") + .WithMany() + .HasForeignKey("AttackerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "DeathOrigin") + .WithMany() + .HasForeignKey("DeathOriginVector3Id"); + + b.HasOne("Data.Models.Vector3", "KillOrigin") + .WithMany() + .HasForeignKey("KillOriginVector3Id"); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.EFClient", "Victim") + .WithMany() + .HasForeignKey("VictimId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "ViewAngles") + .WithMany() + .HasForeignKey("ViewAnglesVector3Id"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientMessage", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFACSnapshot", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "CurrentViewAngle") + .WithMany() + .HasForeignKey("CurrentViewAngleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "HitDestination") + .WithMany() + .HasForeignKey("HitDestinationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "HitOrigin") + .WithMany() + .HasForeignKey("HitOriginId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "LastStrainAngle") + .WithMany() + .HasForeignKey("LastStrainAngleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientHitStatistic", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.Reference.EFHitLocation", "HitLocation") + .WithMany() + .HasForeignKey("HitLocationId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFMeansOfDeath", "MeansOfDeath") + .WithMany() + .HasForeignKey("MeansOfDeathId"); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", "WeaponAttachmentCombo") + .WithMany() + .HasForeignKey("WeaponAttachmentComboId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeapon", "Weapon") + .WithMany() + .HasForeignKey("WeaponId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRatingHistory", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientStatistics", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFHitLocationCount", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("EFClientStatisticsClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("EFClientStatisticsServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.EFClientStatistics", null) + .WithMany("HitLocations") + .HasForeignKey("EFClientStatisticsClientId", "EFClientStatisticsServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFRating", b => + { + b.HasOne("Data.Models.Client.Stats.EFClientRatingHistory", "RatingHistory") + .WithMany("Ratings") + .HasForeignKey("RatingHistoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", b => + { + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment1") + .WithMany() + .HasForeignKey("Attachment1Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment2") + .WithMany() + .HasForeignKey("Attachment2Id"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment3") + .WithMany() + .HasForeignKey("Attachment3Id"); + }); + + modelBuilder.Entity("Data.Models.EFAlias", b => + { + b.HasOne("Data.Models.EFAliasLink", "Link") + .WithMany("Children") + .HasForeignKey("LinkId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.EFMeta", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") .WithMany("Meta") .HasForeignKey("ClientId"); - b.HasOne("SharedLibraryCore.Database.Models.EFMeta", "LinkedMeta") + b.HasOne("Data.Models.EFMeta", "LinkedMeta") .WithMany() .HasForeignKey("LinkedMetaId") .OnDelete(DeleteBehavior.SetNull); }); - modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b => + modelBuilder.Entity("Data.Models.EFPenalty", b => { - b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link") + b.HasOne("Data.Models.EFAliasLink", "Link") .WithMany("ReceivedPenalties") .HasForeignKey("LinkId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Offender") + b.HasOne("Data.Models.Client.EFClient", "Offender") .WithMany("ReceivedPenalties") .HasForeignKey("OffenderId") .OnDelete(DeleteBehavior.Restrict) .IsRequired(); - b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Punisher") + b.HasOne("Data.Models.Client.EFClient", "Punisher") .WithMany("AdministeredPenalties") .HasForeignKey("PunisherId") .OnDelete(DeleteBehavior.Restrict) .IsRequired(); }); + + modelBuilder.Entity("Data.Models.Server.EFServerStatistics", b => + { + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); #pragma warning restore 612, 618 } } diff --git a/Data/Migrations/Sqlite/20210301231432_AddAdditionalClientStatsAndZScore.cs b/Data/Migrations/Sqlite/20210301231432_AddAdditionalClientStatsAndZScore.cs new file mode 100644 index 00000000..da480a02 --- /dev/null +++ b/Data/Migrations/Sqlite/20210301231432_AddAdditionalClientStatsAndZScore.cs @@ -0,0 +1,273 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Data.Migrations.Sqlite +{ + public partial class AddAdditionalClientStatsAndZScore : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "UpdatedAt", + table: "EFClientStatistics", + nullable: true); + + migrationBuilder.AddColumn( + name: "ZScore", + table: "EFClientStatistics", + nullable: false, + defaultValue: 0.0); + + migrationBuilder.CreateTable( + name: "EFHitLocations", + columns: table => new + { + HitLocationId = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Name = table.Column(nullable: false), + Game = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EFHitLocations", x => x.HitLocationId); + }); + + migrationBuilder.CreateTable( + name: "EFMaps", + columns: table => new + { + MapId = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Name = table.Column(nullable: false), + Game = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EFMaps", x => x.MapId); + }); + + migrationBuilder.CreateTable( + name: "EFMeansOfDeath", + columns: table => new + { + MeansOfDeathId = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Name = table.Column(nullable: false), + Game = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EFMeansOfDeath", x => x.MeansOfDeathId); + }); + + migrationBuilder.CreateTable( + name: "EFWeaponAttachments", + columns: table => new + { + WeaponAttachmentId = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Name = table.Column(nullable: false), + Game = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EFWeaponAttachments", x => x.WeaponAttachmentId); + }); + + migrationBuilder.CreateTable( + name: "EFWeapons", + columns: table => new + { + WeaponId = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Name = table.Column(nullable: false), + Game = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EFWeapons", x => x.WeaponId); + }); + + migrationBuilder.CreateTable( + name: "EFWeaponAttachmentCombos", + columns: table => new + { + WeaponAttachmentComboId = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + Game = table.Column(nullable: false), + Attachment1Id = table.Column(nullable: false), + Attachment2Id = table.Column(nullable: true), + Attachment3Id = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EFWeaponAttachmentCombos", x => x.WeaponAttachmentComboId); + table.ForeignKey( + name: "FK_EFWeaponAttachmentCombos_EFWeaponAttachments_Attachment1Id", + column: x => x.Attachment1Id, + principalTable: "EFWeaponAttachments", + principalColumn: "WeaponAttachmentId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_EFWeaponAttachmentCombos_EFWeaponAttachments_Attachment2Id", + column: x => x.Attachment2Id, + principalTable: "EFWeaponAttachments", + principalColumn: "WeaponAttachmentId", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_EFWeaponAttachmentCombos_EFWeaponAttachments_Attachment3Id", + column: x => x.Attachment3Id, + principalTable: "EFWeaponAttachments", + principalColumn: "WeaponAttachmentId", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "EFClientHitStatistics", + columns: table => new + { + ClientHitStatisticId = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + ClientId = table.Column(nullable: false), + ServerId = table.Column(nullable: true), + HitLocationId = table.Column(nullable: true), + MeansOfDeathId = table.Column(nullable: true), + WeaponId = table.Column(nullable: true), + WeaponAttachmentComboId = table.Column(nullable: true), + HitCount = table.Column(nullable: false), + KillCount = table.Column(nullable: false), + DamageInflicted = table.Column(nullable: false), + ReceivedHitCount = table.Column(nullable: false), + DeathCount = table.Column(nullable: false), + DamageReceived = table.Column(nullable: false), + SuicideCount = table.Column(nullable: false), + UsageSeconds = table.Column(nullable: true), + Score = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EFClientHitStatistics", x => x.ClientHitStatisticId); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFClients_ClientId", + column: x => x.ClientId, + principalTable: "EFClients", + principalColumn: "ClientId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFHitLocations_HitLocationId", + column: x => x.HitLocationId, + principalTable: "EFHitLocations", + principalColumn: "HitLocationId", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFMeansOfDeath_MeansOfDeathId", + column: x => x.MeansOfDeathId, + principalTable: "EFMeansOfDeath", + principalColumn: "MeansOfDeathId", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFServers_ServerId", + column: x => x.ServerId, + principalTable: "EFServers", + principalColumn: "ServerId", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFWeaponAttachmentCombos_WeaponAttachmentComboId", + column: x => x.WeaponAttachmentComboId, + principalTable: "EFWeaponAttachmentCombos", + principalColumn: "WeaponAttachmentComboId", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_EFClientHitStatistics_EFWeapons_WeaponId", + column: x => x.WeaponId, + principalTable: "EFWeapons", + principalColumn: "WeaponId", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_EFClientStatistics_ZScore", + table: "EFClientStatistics", + column: "ZScore"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientStatistics_ClientId_TimePlayed_ZScore", + table: "EFClientStatistics", + columns: new[] { "ClientId", "TimePlayed", "ZScore" }); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_ClientId", + table: "EFClientHitStatistics", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_HitLocationId", + table: "EFClientHitStatistics", + column: "HitLocationId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_MeansOfDeathId", + table: "EFClientHitStatistics", + column: "MeansOfDeathId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_ServerId", + table: "EFClientHitStatistics", + column: "ServerId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_WeaponAttachmentComboId", + table: "EFClientHitStatistics", + column: "WeaponAttachmentComboId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientHitStatistics_WeaponId", + table: "EFClientHitStatistics", + column: "WeaponId"); + + migrationBuilder.CreateIndex( + name: "IX_EFHitLocations_Name", + table: "EFHitLocations", + column: "Name"); + + migrationBuilder.CreateIndex( + name: "IX_EFWeaponAttachmentCombos_Attachment1Id", + table: "EFWeaponAttachmentCombos", + column: "Attachment1Id"); + + migrationBuilder.CreateIndex( + name: "IX_EFWeaponAttachmentCombos_Attachment2Id", + table: "EFWeaponAttachmentCombos", + column: "Attachment2Id"); + + migrationBuilder.CreateIndex( + name: "IX_EFWeaponAttachmentCombos_Attachment3Id", + table: "EFWeaponAttachmentCombos", + column: "Attachment3Id"); + + migrationBuilder.CreateIndex( + name: "IX_EFWeapons_Name", + table: "EFWeapons", + column: "Name"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/Data/Migrations/Sqlite/20210310231004_AddRankingHistory.Designer.cs b/Data/Migrations/Sqlite/20210310231004_AddRankingHistory.Designer.cs new file mode 100644 index 00000000..e4fe819a --- /dev/null +++ b/Data/Migrations/Sqlite/20210310231004_AddRankingHistory.Designer.cs @@ -0,0 +1,1279 @@ +// +using System; +using Data.MigrationContext; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Data.Migrations.Sqlite +{ + [DbContext(typeof(SqliteDatabaseContext))] + [Migration("20210310231004_AddRankingHistory")] + partial class AddRankingHistory + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.10"); + + modelBuilder.Entity("Data.Models.Client.EFACSnapshotVector3", b => + { + b.Property("ACSnapshotVector3Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("SnapshotId") + .HasColumnType("INTEGER"); + + b.Property("Vector3Id") + .HasColumnType("INTEGER"); + + b.HasKey("ACSnapshotVector3Id"); + + b.HasIndex("SnapshotId"); + + b.HasIndex("Vector3Id"); + + b.ToTable("EFACSnapshotVector3"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClient", b => + { + b.Property("ClientId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("AliasLinkId") + .HasColumnType("INTEGER"); + + b.Property("Connections") + .HasColumnType("INTEGER"); + + b.Property("CurrentAliasId") + .HasColumnType("INTEGER"); + + b.Property("FirstConnection") + .HasColumnType("TEXT"); + + b.Property("LastConnection") + .HasColumnType("TEXT"); + + b.Property("Level") + .HasColumnType("INTEGER"); + + b.Property("Masked") + .HasColumnType("INTEGER"); + + b.Property("NetworkId") + .HasColumnType("INTEGER"); + + b.Property("Password") + .HasColumnType("TEXT"); + + b.Property("PasswordSalt") + .HasColumnType("TEXT"); + + b.Property("TotalConnectionTime") + .HasColumnType("INTEGER"); + + b.HasKey("ClientId"); + + b.HasIndex("AliasLinkId"); + + b.HasIndex("CurrentAliasId"); + + b.HasIndex("NetworkId") + .IsUnique(); + + b.ToTable("EFClients"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientKill", b => + { + b.Property("KillId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("AttackerId") + .HasColumnType("INTEGER"); + + b.Property("Damage") + .HasColumnType("INTEGER"); + + b.Property("DeathOriginVector3Id") + .HasColumnType("INTEGER"); + + b.Property("DeathType") + .HasColumnType("INTEGER"); + + b.Property("Fraction") + .HasColumnType("REAL"); + + b.Property("HitLoc") + .HasColumnType("INTEGER"); + + b.Property("IsKill") + .HasColumnType("INTEGER"); + + b.Property("KillOriginVector3Id") + .HasColumnType("INTEGER"); + + b.Property("Map") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("VictimId") + .HasColumnType("INTEGER"); + + b.Property("ViewAnglesVector3Id") + .HasColumnType("INTEGER"); + + b.Property("VisibilityPercentage") + .HasColumnType("REAL"); + + b.Property("Weapon") + .HasColumnType("INTEGER"); + + b.Property("When") + .HasColumnType("TEXT"); + + b.HasKey("KillId"); + + b.HasIndex("AttackerId"); + + b.HasIndex("DeathOriginVector3Id"); + + b.HasIndex("KillOriginVector3Id"); + + b.HasIndex("ServerId"); + + b.HasIndex("VictimId"); + + b.HasIndex("ViewAnglesVector3Id"); + + b.ToTable("EFClientKills"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientMessage", b => + { + b.Property("MessageId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("Message") + .HasColumnType("TEXT"); + + b.Property("SentIngame") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("TimeSent") + .HasColumnType("TEXT"); + + b.HasKey("MessageId"); + + b.HasIndex("ClientId"); + + b.HasIndex("ServerId"); + + b.HasIndex("TimeSent"); + + b.ToTable("EFClientMessages"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFACSnapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("CurrentSessionLength") + .HasColumnType("INTEGER"); + + b.Property("CurrentStrain") + .HasColumnType("REAL"); + + b.Property("CurrentViewAngleId") + .HasColumnType("INTEGER"); + + b.Property("Deaths") + .HasColumnType("INTEGER"); + + b.Property("Distance") + .HasColumnType("REAL"); + + b.Property("EloRating") + .HasColumnType("REAL"); + + b.Property("HitDestinationId") + .HasColumnType("INTEGER"); + + b.Property("HitLocation") + .HasColumnType("INTEGER"); + + b.Property("HitOriginId") + .HasColumnType("INTEGER"); + + b.Property("HitType") + .HasColumnType("INTEGER"); + + b.Property("Hits") + .HasColumnType("INTEGER"); + + b.Property("Kills") + .HasColumnType("INTEGER"); + + b.Property("LastStrainAngleId") + .HasColumnType("INTEGER"); + + b.Property("RecoilOffset") + .HasColumnType("REAL"); + + b.Property("SessionAngleOffset") + .HasColumnType("REAL"); + + b.Property("SessionAverageSnapValue") + .HasColumnType("REAL"); + + b.Property("SessionSPM") + .HasColumnType("REAL"); + + b.Property("SessionScore") + .HasColumnType("INTEGER"); + + b.Property("SessionSnapHits") + .HasColumnType("INTEGER"); + + b.Property("StrainAngleBetween") + .HasColumnType("REAL"); + + b.Property("TimeSinceLastEvent") + .HasColumnType("INTEGER"); + + b.Property("WeaponId") + .HasColumnType("INTEGER"); + + b.Property("When") + .HasColumnType("TEXT"); + + b.HasKey("SnapshotId"); + + b.HasIndex("ClientId"); + + b.HasIndex("CurrentViewAngleId"); + + b.HasIndex("HitDestinationId"); + + b.HasIndex("HitOriginId"); + + b.HasIndex("LastStrainAngleId"); + + b.ToTable("EFACSnapshot"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientHitStatistic", b => + { + b.Property("ClientHitStatisticId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("DamageInflicted") + .HasColumnType("INTEGER"); + + b.Property("DamageReceived") + .HasColumnType("INTEGER"); + + b.Property("DeathCount") + .HasColumnType("INTEGER"); + + b.Property("HitCount") + .HasColumnType("INTEGER"); + + b.Property("HitLocationId") + .HasColumnType("INTEGER"); + + b.Property("KillCount") + .HasColumnType("INTEGER"); + + b.Property("MeansOfDeathId") + .HasColumnType("INTEGER"); + + b.Property("ReceivedHitCount") + .HasColumnType("INTEGER"); + + b.Property("Score") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("SuicideCount") + .HasColumnType("INTEGER"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.Property("UsageSeconds") + .HasColumnType("INTEGER"); + + b.Property("WeaponAttachmentComboId") + .HasColumnType("INTEGER"); + + b.Property("WeaponId") + .HasColumnType("INTEGER"); + + b.HasKey("ClientHitStatisticId"); + + b.HasIndex("ClientId"); + + b.HasIndex("HitLocationId"); + + b.HasIndex("MeansOfDeathId"); + + b.HasIndex("ServerId"); + + b.HasIndex("WeaponAttachmentComboId"); + + b.HasIndex("WeaponId"); + + b.ToTable("EFClientHitStatistics"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRankingHistory", b => + { + b.Property("ClientRankingHistoryId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Newest") + .HasColumnType("INTEGER"); + + b.Property("PerformanceMetric") + .HasColumnType("REAL"); + + b.Property("Ranking") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.Property("ZScore") + .HasColumnType("REAL"); + + b.HasKey("ClientRankingHistoryId"); + + b.HasIndex("ClientId"); + + b.HasIndex("Ranking"); + + b.HasIndex("ServerId"); + + b.HasIndex("UpdatedDateTime"); + + b.HasIndex("ZScore"); + + b.ToTable("EFClientRankingHistory"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRatingHistory", b => + { + b.Property("RatingHistoryId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.HasKey("RatingHistoryId"); + + b.HasIndex("ClientId"); + + b.ToTable("EFClientRatingHistory"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientStatistics", b => + { + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("AverageSnapValue") + .HasColumnType("REAL"); + + b.Property("Deaths") + .HasColumnType("INTEGER"); + + b.Property("EloRating") + .HasColumnType("REAL"); + + b.Property("Kills") + .HasColumnType("INTEGER"); + + b.Property("MaxStrain") + .HasColumnType("REAL"); + + b.Property("RollingWeightedKDR") + .HasColumnType("REAL"); + + b.Property("SPM") + .HasColumnType("REAL"); + + b.Property("Skill") + .HasColumnType("REAL"); + + b.Property("SnapHitCount") + .HasColumnType("INTEGER"); + + b.Property("TimePlayed") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("ZScore") + .HasColumnType("REAL"); + + b.HasKey("ClientId", "ServerId"); + + b.HasIndex("ServerId"); + + b.HasIndex("ZScore"); + + b.HasIndex("ClientId", "TimePlayed", "ZScore"); + + b.ToTable("EFClientStatistics"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFHitLocationCount", b => + { + b.Property("HitLocationCountId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("EFClientStatisticsClientId") + .HasColumnName("EFClientStatisticsClientId") + .HasColumnType("INTEGER"); + + b.Property("EFClientStatisticsServerId") + .HasColumnName("EFClientStatisticsServerId") + .HasColumnType("INTEGER"); + + b.Property("HitCount") + .HasColumnType("INTEGER"); + + b.Property("HitOffsetAverage") + .HasColumnType("REAL"); + + b.Property("Location") + .HasColumnType("INTEGER"); + + b.Property("MaxAngleDistance") + .HasColumnType("REAL"); + + b.HasKey("HitLocationCountId"); + + b.HasIndex("EFClientStatisticsServerId"); + + b.HasIndex("EFClientStatisticsClientId", "EFClientStatisticsServerId"); + + b.ToTable("EFHitLocationCounts"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFRating", b => + { + b.Property("RatingId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("ActivityAmount") + .HasColumnType("INTEGER"); + + b.Property("Newest") + .HasColumnType("INTEGER"); + + b.Property("Performance") + .HasColumnType("REAL"); + + b.Property("Ranking") + .HasColumnType("INTEGER"); + + b.Property("RatingHistoryId") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("When") + .HasColumnType("TEXT"); + + b.HasKey("RatingId"); + + b.HasIndex("RatingHistoryId"); + + b.HasIndex("ServerId"); + + b.HasIndex("Performance", "Ranking", "When"); + + b.HasIndex("When", "ServerId", "Performance", "ActivityAmount"); + + b.ToTable("EFRating"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFHitLocation", b => + { + b.Property("HitLocationId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.HasKey("HitLocationId"); + + b.HasIndex("Name"); + + b.ToTable("EFHitLocations"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFMap", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.HasKey("MapId"); + + b.ToTable("EFMaps"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFMeansOfDeath", b => + { + b.Property("MeansOfDeathId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.HasKey("MeansOfDeathId"); + + b.ToTable("EFMeansOfDeath"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeapon", b => + { + b.Property("WeaponId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.HasKey("WeaponId"); + + b.HasIndex("Name"); + + b.ToTable("EFWeapons"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachment", b => + { + b.Property("WeaponAttachmentId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.HasKey("WeaponAttachmentId"); + + b.ToTable("EFWeaponAttachments"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", b => + { + b.Property("WeaponAttachmentComboId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attachment1Id") + .HasColumnType("INTEGER"); + + b.Property("Attachment2Id") + .HasColumnType("INTEGER"); + + b.Property("Attachment3Id") + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") + .HasColumnType("INTEGER"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.HasKey("WeaponAttachmentComboId"); + + b.HasIndex("Attachment1Id"); + + b.HasIndex("Attachment2Id"); + + b.HasIndex("Attachment3Id"); + + b.ToTable("EFWeaponAttachmentCombos"); + }); + + modelBuilder.Entity("Data.Models.EFAlias", b => + { + b.Property("AliasId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("IPAddress") + .HasColumnType("INTEGER"); + + b.Property("LinkId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(24); + + b.Property("SearchableName") + .HasColumnType("TEXT") + .HasMaxLength(24); + + b.HasKey("AliasId"); + + b.HasIndex("IPAddress"); + + b.HasIndex("LinkId"); + + b.HasIndex("Name"); + + b.HasIndex("SearchableName"); + + b.HasIndex("Name", "IPAddress") + .IsUnique(); + + b.ToTable("EFAlias"); + }); + + modelBuilder.Entity("Data.Models.EFAliasLink", b => + { + b.Property("AliasLinkId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.HasKey("AliasLinkId"); + + b.ToTable("EFAliasLinks"); + }); + + modelBuilder.Entity("Data.Models.EFChangeHistory", b => + { + b.Property("ChangeHistoryId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("Comment") + .HasColumnType("TEXT") + .HasMaxLength(128); + + b.Property("CurrentValue") + .HasColumnType("TEXT"); + + b.Property("ImpersonationEntityId") + .HasColumnType("INTEGER"); + + b.Property("OriginEntityId") + .HasColumnType("INTEGER"); + + b.Property("PreviousValue") + .HasColumnType("TEXT"); + + b.Property("TargetEntityId") + .HasColumnType("INTEGER"); + + b.Property("TimeChanged") + .HasColumnType("TEXT"); + + b.Property("TypeOfChange") + .HasColumnType("INTEGER"); + + b.HasKey("ChangeHistoryId"); + + b.ToTable("EFChangeHistory"); + }); + + modelBuilder.Entity("Data.Models.EFMeta", b => + { + b.Property("MetaId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Extra") + .HasColumnType("TEXT"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("LinkedMetaId") + .HasColumnType("INTEGER"); + + b.Property("Updated") + .HasColumnType("TEXT"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MetaId"); + + b.HasIndex("ClientId"); + + b.HasIndex("Key"); + + b.HasIndex("LinkedMetaId"); + + b.ToTable("EFMeta"); + }); + + modelBuilder.Entity("Data.Models.EFPenalty", b => + { + b.Property("PenaltyId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("AutomatedOffense") + .HasColumnType("TEXT"); + + b.Property("Expires") + .HasColumnType("TEXT"); + + b.Property("IsEvadedOffense") + .HasColumnType("INTEGER"); + + b.Property("LinkId") + .HasColumnType("INTEGER"); + + b.Property("OffenderId") + .HasColumnType("INTEGER"); + + b.Property("Offense") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PunisherId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("When") + .HasColumnType("TEXT"); + + b.HasKey("PenaltyId"); + + b.HasIndex("LinkId"); + + b.HasIndex("OffenderId"); + + b.HasIndex("PunisherId"); + + b.ToTable("EFPenalties"); + }); + + modelBuilder.Entity("Data.Models.Server.EFServer", b => + { + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("EndPoint") + .HasColumnType("TEXT"); + + b.Property("GameName") + .HasColumnType("INTEGER"); + + b.Property("HostName") + .HasColumnType("TEXT"); + + b.Property("IsPasswordProtected") + .HasColumnType("INTEGER"); + + b.Property("Port") + .HasColumnType("INTEGER"); + + b.HasKey("ServerId"); + + b.ToTable("EFServers"); + }); + + modelBuilder.Entity("Data.Models.Server.EFServerStatistics", b => + { + b.Property("StatisticId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("TotalKills") + .HasColumnType("INTEGER"); + + b.Property("TotalPlayTime") + .HasColumnType("INTEGER"); + + b.HasKey("StatisticId"); + + b.HasIndex("ServerId"); + + b.ToTable("EFServerStatistics"); + }); + + modelBuilder.Entity("Data.Models.Vector3", b => + { + b.Property("Vector3Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("X") + .HasColumnType("REAL"); + + b.Property("Y") + .HasColumnType("REAL"); + + b.Property("Z") + .HasColumnType("REAL"); + + b.HasKey("Vector3Id"); + + b.ToTable("Vector3"); + }); + + modelBuilder.Entity("Data.Models.Client.EFACSnapshotVector3", b => + { + b.HasOne("Data.Models.Client.Stats.EFACSnapshot", "Snapshot") + .WithMany("PredictedViewAngles") + .HasForeignKey("SnapshotId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "Vector") + .WithMany() + .HasForeignKey("Vector3Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.EFClient", b => + { + b.HasOne("Data.Models.EFAliasLink", "AliasLink") + .WithMany() + .HasForeignKey("AliasLinkId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.EFAlias", "CurrentAlias") + .WithMany() + .HasForeignKey("CurrentAliasId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientKill", b => + { + b.HasOne("Data.Models.Client.EFClient", "Attacker") + .WithMany() + .HasForeignKey("AttackerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "DeathOrigin") + .WithMany() + .HasForeignKey("DeathOriginVector3Id"); + + b.HasOne("Data.Models.Vector3", "KillOrigin") + .WithMany() + .HasForeignKey("KillOriginVector3Id"); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.EFClient", "Victim") + .WithMany() + .HasForeignKey("VictimId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "ViewAngles") + .WithMany() + .HasForeignKey("ViewAnglesVector3Id"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientMessage", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFACSnapshot", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "CurrentViewAngle") + .WithMany() + .HasForeignKey("CurrentViewAngleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "HitDestination") + .WithMany() + .HasForeignKey("HitDestinationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "HitOrigin") + .WithMany() + .HasForeignKey("HitOriginId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "LastStrainAngle") + .WithMany() + .HasForeignKey("LastStrainAngleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientHitStatistic", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.Reference.EFHitLocation", "HitLocation") + .WithMany() + .HasForeignKey("HitLocationId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFMeansOfDeath", "MeansOfDeath") + .WithMany() + .HasForeignKey("MeansOfDeathId"); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", "WeaponAttachmentCombo") + .WithMany() + .HasForeignKey("WeaponAttachmentComboId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeapon", "Weapon") + .WithMany() + .HasForeignKey("WeaponId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRankingHistory", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRatingHistory", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientStatistics", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFHitLocationCount", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("EFClientStatisticsClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("EFClientStatisticsServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.EFClientStatistics", null) + .WithMany("HitLocations") + .HasForeignKey("EFClientStatisticsClientId", "EFClientStatisticsServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFRating", b => + { + b.HasOne("Data.Models.Client.Stats.EFClientRatingHistory", "RatingHistory") + .WithMany("Ratings") + .HasForeignKey("RatingHistoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", b => + { + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment1") + .WithMany() + .HasForeignKey("Attachment1Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment2") + .WithMany() + .HasForeignKey("Attachment2Id"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment3") + .WithMany() + .HasForeignKey("Attachment3Id"); + }); + + modelBuilder.Entity("Data.Models.EFAlias", b => + { + b.HasOne("Data.Models.EFAliasLink", "Link") + .WithMany("Children") + .HasForeignKey("LinkId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.EFMeta", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany("Meta") + .HasForeignKey("ClientId"); + + b.HasOne("Data.Models.EFMeta", "LinkedMeta") + .WithMany() + .HasForeignKey("LinkedMetaId") + .OnDelete(DeleteBehavior.SetNull); + }); + + modelBuilder.Entity("Data.Models.EFPenalty", b => + { + b.HasOne("Data.Models.EFAliasLink", "Link") + .WithMany("ReceivedPenalties") + .HasForeignKey("LinkId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.EFClient", "Offender") + .WithMany("ReceivedPenalties") + .HasForeignKey("OffenderId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Data.Models.Client.EFClient", "Punisher") + .WithMany("AdministeredPenalties") + .HasForeignKey("PunisherId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Server.EFServerStatistics", b => + { + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Data/Migrations/Sqlite/20210310231004_AddRankingHistory.cs b/Data/Migrations/Sqlite/20210310231004_AddRankingHistory.cs new file mode 100644 index 00000000..2196f757 --- /dev/null +++ b/Data/Migrations/Sqlite/20210310231004_AddRankingHistory.cs @@ -0,0 +1,74 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Data.Migrations.Sqlite +{ + public partial class AddRankingHistory : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "EFClientRankingHistory", + columns: table => new + { + ClientRankingHistoryId = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CreatedDateTime = table.Column(nullable: false), + UpdatedDateTime = table.Column(nullable: true), + ClientId = table.Column(nullable: false), + ServerId = table.Column(nullable: true), + Newest = table.Column(nullable: false), + Ranking = table.Column(nullable: true), + ZScore = table.Column(nullable: true), + PerformanceMetric = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EFClientRankingHistory", x => x.ClientRankingHistoryId); + table.ForeignKey( + name: "FK_EFClientRankingHistory_EFClients_ClientId", + column: x => x.ClientId, + principalTable: "EFClients", + principalColumn: "ClientId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_EFClientRankingHistory_EFServers_ServerId", + column: x => x.ServerId, + principalTable: "EFServers", + principalColumn: "ServerId", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_EFClientRankingHistory_ClientId", + table: "EFClientRankingHistory", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientRankingHistory_Ranking", + table: "EFClientRankingHistory", + column: "Ranking"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientRankingHistory_ServerId", + table: "EFClientRankingHistory", + column: "ServerId"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientRankingHistory_UpdatedDateTime", + table: "EFClientRankingHistory", + column: "UpdatedDateTime"); + + migrationBuilder.CreateIndex( + name: "IX_EFClientRankingHistory_ZScore", + table: "EFClientRankingHistory", + column: "ZScore"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "EFClientRankingHistory"); + } + } +} diff --git a/Data/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs b/Data/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs new file mode 100644 index 00000000..02302175 --- /dev/null +++ b/Data/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs @@ -0,0 +1,1277 @@ +// +using System; +using Data.MigrationContext; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Data.Migrations.Sqlite +{ + [DbContext(typeof(SqliteDatabaseContext))] + partial class SqliteDatabaseContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.10"); + + modelBuilder.Entity("Data.Models.Client.EFACSnapshotVector3", b => + { + b.Property("ACSnapshotVector3Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("SnapshotId") + .HasColumnType("INTEGER"); + + b.Property("Vector3Id") + .HasColumnType("INTEGER"); + + b.HasKey("ACSnapshotVector3Id"); + + b.HasIndex("SnapshotId"); + + b.HasIndex("Vector3Id"); + + b.ToTable("EFACSnapshotVector3"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClient", b => + { + b.Property("ClientId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("AliasLinkId") + .HasColumnType("INTEGER"); + + b.Property("Connections") + .HasColumnType("INTEGER"); + + b.Property("CurrentAliasId") + .HasColumnType("INTEGER"); + + b.Property("FirstConnection") + .HasColumnType("TEXT"); + + b.Property("LastConnection") + .HasColumnType("TEXT"); + + b.Property("Level") + .HasColumnType("INTEGER"); + + b.Property("Masked") + .HasColumnType("INTEGER"); + + b.Property("NetworkId") + .HasColumnType("INTEGER"); + + b.Property("Password") + .HasColumnType("TEXT"); + + b.Property("PasswordSalt") + .HasColumnType("TEXT"); + + b.Property("TotalConnectionTime") + .HasColumnType("INTEGER"); + + b.HasKey("ClientId"); + + b.HasIndex("AliasLinkId"); + + b.HasIndex("CurrentAliasId"); + + b.HasIndex("NetworkId") + .IsUnique(); + + b.ToTable("EFClients"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientKill", b => + { + b.Property("KillId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("AttackerId") + .HasColumnType("INTEGER"); + + b.Property("Damage") + .HasColumnType("INTEGER"); + + b.Property("DeathOriginVector3Id") + .HasColumnType("INTEGER"); + + b.Property("DeathType") + .HasColumnType("INTEGER"); + + b.Property("Fraction") + .HasColumnType("REAL"); + + b.Property("HitLoc") + .HasColumnType("INTEGER"); + + b.Property("IsKill") + .HasColumnType("INTEGER"); + + b.Property("KillOriginVector3Id") + .HasColumnType("INTEGER"); + + b.Property("Map") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("VictimId") + .HasColumnType("INTEGER"); + + b.Property("ViewAnglesVector3Id") + .HasColumnType("INTEGER"); + + b.Property("VisibilityPercentage") + .HasColumnType("REAL"); + + b.Property("Weapon") + .HasColumnType("INTEGER"); + + b.Property("When") + .HasColumnType("TEXT"); + + b.HasKey("KillId"); + + b.HasIndex("AttackerId"); + + b.HasIndex("DeathOriginVector3Id"); + + b.HasIndex("KillOriginVector3Id"); + + b.HasIndex("ServerId"); + + b.HasIndex("VictimId"); + + b.HasIndex("ViewAnglesVector3Id"); + + b.ToTable("EFClientKills"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientMessage", b => + { + b.Property("MessageId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("Message") + .HasColumnType("TEXT"); + + b.Property("SentIngame") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("TimeSent") + .HasColumnType("TEXT"); + + b.HasKey("MessageId"); + + b.HasIndex("ClientId"); + + b.HasIndex("ServerId"); + + b.HasIndex("TimeSent"); + + b.ToTable("EFClientMessages"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFACSnapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("CurrentSessionLength") + .HasColumnType("INTEGER"); + + b.Property("CurrentStrain") + .HasColumnType("REAL"); + + b.Property("CurrentViewAngleId") + .HasColumnType("INTEGER"); + + b.Property("Deaths") + .HasColumnType("INTEGER"); + + b.Property("Distance") + .HasColumnType("REAL"); + + b.Property("EloRating") + .HasColumnType("REAL"); + + b.Property("HitDestinationId") + .HasColumnType("INTEGER"); + + b.Property("HitLocation") + .HasColumnType("INTEGER"); + + b.Property("HitOriginId") + .HasColumnType("INTEGER"); + + b.Property("HitType") + .HasColumnType("INTEGER"); + + b.Property("Hits") + .HasColumnType("INTEGER"); + + b.Property("Kills") + .HasColumnType("INTEGER"); + + b.Property("LastStrainAngleId") + .HasColumnType("INTEGER"); + + b.Property("RecoilOffset") + .HasColumnType("REAL"); + + b.Property("SessionAngleOffset") + .HasColumnType("REAL"); + + b.Property("SessionAverageSnapValue") + .HasColumnType("REAL"); + + b.Property("SessionSPM") + .HasColumnType("REAL"); + + b.Property("SessionScore") + .HasColumnType("INTEGER"); + + b.Property("SessionSnapHits") + .HasColumnType("INTEGER"); + + b.Property("StrainAngleBetween") + .HasColumnType("REAL"); + + b.Property("TimeSinceLastEvent") + .HasColumnType("INTEGER"); + + b.Property("WeaponId") + .HasColumnType("INTEGER"); + + b.Property("When") + .HasColumnType("TEXT"); + + b.HasKey("SnapshotId"); + + b.HasIndex("ClientId"); + + b.HasIndex("CurrentViewAngleId"); + + b.HasIndex("HitDestinationId"); + + b.HasIndex("HitOriginId"); + + b.HasIndex("LastStrainAngleId"); + + b.ToTable("EFACSnapshot"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientHitStatistic", b => + { + b.Property("ClientHitStatisticId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("DamageInflicted") + .HasColumnType("INTEGER"); + + b.Property("DamageReceived") + .HasColumnType("INTEGER"); + + b.Property("DeathCount") + .HasColumnType("INTEGER"); + + b.Property("HitCount") + .HasColumnType("INTEGER"); + + b.Property("HitLocationId") + .HasColumnType("INTEGER"); + + b.Property("KillCount") + .HasColumnType("INTEGER"); + + b.Property("MeansOfDeathId") + .HasColumnType("INTEGER"); + + b.Property("ReceivedHitCount") + .HasColumnType("INTEGER"); + + b.Property("Score") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("SuicideCount") + .HasColumnType("INTEGER"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.Property("UsageSeconds") + .HasColumnType("INTEGER"); + + b.Property("WeaponAttachmentComboId") + .HasColumnType("INTEGER"); + + b.Property("WeaponId") + .HasColumnType("INTEGER"); + + b.HasKey("ClientHitStatisticId"); + + b.HasIndex("ClientId"); + + b.HasIndex("HitLocationId"); + + b.HasIndex("MeansOfDeathId"); + + b.HasIndex("ServerId"); + + b.HasIndex("WeaponAttachmentComboId"); + + b.HasIndex("WeaponId"); + + b.ToTable("EFClientHitStatistics"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRankingHistory", b => + { + b.Property("ClientRankingHistoryId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Newest") + .HasColumnType("INTEGER"); + + b.Property("PerformanceMetric") + .HasColumnType("REAL"); + + b.Property("Ranking") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.Property("ZScore") + .HasColumnType("REAL"); + + b.HasKey("ClientRankingHistoryId"); + + b.HasIndex("ClientId"); + + b.HasIndex("Ranking"); + + b.HasIndex("ServerId"); + + b.HasIndex("UpdatedDateTime"); + + b.HasIndex("ZScore"); + + b.ToTable("EFClientRankingHistory"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRatingHistory", b => + { + b.Property("RatingHistoryId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.HasKey("RatingHistoryId"); + + b.HasIndex("ClientId"); + + b.ToTable("EFClientRatingHistory"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientStatistics", b => + { + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("AverageSnapValue") + .HasColumnType("REAL"); + + b.Property("Deaths") + .HasColumnType("INTEGER"); + + b.Property("EloRating") + .HasColumnType("REAL"); + + b.Property("Kills") + .HasColumnType("INTEGER"); + + b.Property("MaxStrain") + .HasColumnType("REAL"); + + b.Property("RollingWeightedKDR") + .HasColumnType("REAL"); + + b.Property("SPM") + .HasColumnType("REAL"); + + b.Property("Skill") + .HasColumnType("REAL"); + + b.Property("SnapHitCount") + .HasColumnType("INTEGER"); + + b.Property("TimePlayed") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("ZScore") + .HasColumnType("REAL"); + + b.HasKey("ClientId", "ServerId"); + + b.HasIndex("ServerId"); + + b.HasIndex("ZScore"); + + b.HasIndex("ClientId", "TimePlayed", "ZScore"); + + b.ToTable("EFClientStatistics"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFHitLocationCount", b => + { + b.Property("HitLocationCountId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("EFClientStatisticsClientId") + .HasColumnName("EFClientStatisticsClientId") + .HasColumnType("INTEGER"); + + b.Property("EFClientStatisticsServerId") + .HasColumnName("EFClientStatisticsServerId") + .HasColumnType("INTEGER"); + + b.Property("HitCount") + .HasColumnType("INTEGER"); + + b.Property("HitOffsetAverage") + .HasColumnType("REAL"); + + b.Property("Location") + .HasColumnType("INTEGER"); + + b.Property("MaxAngleDistance") + .HasColumnType("REAL"); + + b.HasKey("HitLocationCountId"); + + b.HasIndex("EFClientStatisticsServerId"); + + b.HasIndex("EFClientStatisticsClientId", "EFClientStatisticsServerId"); + + b.ToTable("EFHitLocationCounts"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFRating", b => + { + b.Property("RatingId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("ActivityAmount") + .HasColumnType("INTEGER"); + + b.Property("Newest") + .HasColumnType("INTEGER"); + + b.Property("Performance") + .HasColumnType("REAL"); + + b.Property("Ranking") + .HasColumnType("INTEGER"); + + b.Property("RatingHistoryId") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("When") + .HasColumnType("TEXT"); + + b.HasKey("RatingId"); + + b.HasIndex("RatingHistoryId"); + + b.HasIndex("ServerId"); + + b.HasIndex("Performance", "Ranking", "When"); + + b.HasIndex("When", "ServerId", "Performance", "ActivityAmount"); + + b.ToTable("EFRating"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFHitLocation", b => + { + b.Property("HitLocationId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.HasKey("HitLocationId"); + + b.HasIndex("Name"); + + b.ToTable("EFHitLocations"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFMap", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.HasKey("MapId"); + + b.ToTable("EFMaps"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFMeansOfDeath", b => + { + b.Property("MeansOfDeathId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.HasKey("MeansOfDeathId"); + + b.ToTable("EFMeansOfDeath"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeapon", b => + { + b.Property("WeaponId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.HasKey("WeaponId"); + + b.HasIndex("Name"); + + b.ToTable("EFWeapons"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachment", b => + { + b.Property("WeaponAttachmentId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.HasKey("WeaponAttachmentId"); + + b.ToTable("EFWeaponAttachments"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", b => + { + b.Property("WeaponAttachmentComboId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attachment1Id") + .HasColumnType("INTEGER"); + + b.Property("Attachment2Id") + .HasColumnType("INTEGER"); + + b.Property("Attachment3Id") + .HasColumnType("INTEGER"); + + b.Property("CreatedDateTime") + .HasColumnType("TEXT"); + + b.Property("Game") + .HasColumnType("INTEGER"); + + b.Property("UpdatedDateTime") + .HasColumnType("TEXT"); + + b.HasKey("WeaponAttachmentComboId"); + + b.HasIndex("Attachment1Id"); + + b.HasIndex("Attachment2Id"); + + b.HasIndex("Attachment3Id"); + + b.ToTable("EFWeaponAttachmentCombos"); + }); + + modelBuilder.Entity("Data.Models.EFAlias", b => + { + b.Property("AliasId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("IPAddress") + .HasColumnType("INTEGER"); + + b.Property("LinkId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(24); + + b.Property("SearchableName") + .HasColumnType("TEXT") + .HasMaxLength(24); + + b.HasKey("AliasId"); + + b.HasIndex("IPAddress"); + + b.HasIndex("LinkId"); + + b.HasIndex("Name"); + + b.HasIndex("SearchableName"); + + b.HasIndex("Name", "IPAddress") + .IsUnique(); + + b.ToTable("EFAlias"); + }); + + modelBuilder.Entity("Data.Models.EFAliasLink", b => + { + b.Property("AliasLinkId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.HasKey("AliasLinkId"); + + b.ToTable("EFAliasLinks"); + }); + + modelBuilder.Entity("Data.Models.EFChangeHistory", b => + { + b.Property("ChangeHistoryId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("Comment") + .HasColumnType("TEXT") + .HasMaxLength(128); + + b.Property("CurrentValue") + .HasColumnType("TEXT"); + + b.Property("ImpersonationEntityId") + .HasColumnType("INTEGER"); + + b.Property("OriginEntityId") + .HasColumnType("INTEGER"); + + b.Property("PreviousValue") + .HasColumnType("TEXT"); + + b.Property("TargetEntityId") + .HasColumnType("INTEGER"); + + b.Property("TimeChanged") + .HasColumnType("TEXT"); + + b.Property("TypeOfChange") + .HasColumnType("INTEGER"); + + b.HasKey("ChangeHistoryId"); + + b.ToTable("EFChangeHistory"); + }); + + modelBuilder.Entity("Data.Models.EFMeta", b => + { + b.Property("MetaId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Extra") + .HasColumnType("TEXT"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("LinkedMetaId") + .HasColumnType("INTEGER"); + + b.Property("Updated") + .HasColumnType("TEXT"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MetaId"); + + b.HasIndex("ClientId"); + + b.HasIndex("Key"); + + b.HasIndex("LinkedMetaId"); + + b.ToTable("EFMeta"); + }); + + modelBuilder.Entity("Data.Models.EFPenalty", b => + { + b.Property("PenaltyId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("AutomatedOffense") + .HasColumnType("TEXT"); + + b.Property("Expires") + .HasColumnType("TEXT"); + + b.Property("IsEvadedOffense") + .HasColumnType("INTEGER"); + + b.Property("LinkId") + .HasColumnType("INTEGER"); + + b.Property("OffenderId") + .HasColumnType("INTEGER"); + + b.Property("Offense") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PunisherId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("When") + .HasColumnType("TEXT"); + + b.HasKey("PenaltyId"); + + b.HasIndex("LinkId"); + + b.HasIndex("OffenderId"); + + b.HasIndex("PunisherId"); + + b.ToTable("EFPenalties"); + }); + + modelBuilder.Entity("Data.Models.Server.EFServer", b => + { + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("EndPoint") + .HasColumnType("TEXT"); + + b.Property("GameName") + .HasColumnType("INTEGER"); + + b.Property("HostName") + .HasColumnType("TEXT"); + + b.Property("IsPasswordProtected") + .HasColumnType("INTEGER"); + + b.Property("Port") + .HasColumnType("INTEGER"); + + b.HasKey("ServerId"); + + b.ToTable("EFServers"); + }); + + modelBuilder.Entity("Data.Models.Server.EFServerStatistics", b => + { + b.Property("StatisticId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Active") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("TotalKills") + .HasColumnType("INTEGER"); + + b.Property("TotalPlayTime") + .HasColumnType("INTEGER"); + + b.HasKey("StatisticId"); + + b.HasIndex("ServerId"); + + b.ToTable("EFServerStatistics"); + }); + + modelBuilder.Entity("Data.Models.Vector3", b => + { + b.Property("Vector3Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("X") + .HasColumnType("REAL"); + + b.Property("Y") + .HasColumnType("REAL"); + + b.Property("Z") + .HasColumnType("REAL"); + + b.HasKey("Vector3Id"); + + b.ToTable("Vector3"); + }); + + modelBuilder.Entity("Data.Models.Client.EFACSnapshotVector3", b => + { + b.HasOne("Data.Models.Client.Stats.EFACSnapshot", "Snapshot") + .WithMany("PredictedViewAngles") + .HasForeignKey("SnapshotId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "Vector") + .WithMany() + .HasForeignKey("Vector3Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.EFClient", b => + { + b.HasOne("Data.Models.EFAliasLink", "AliasLink") + .WithMany() + .HasForeignKey("AliasLinkId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.EFAlias", "CurrentAlias") + .WithMany() + .HasForeignKey("CurrentAliasId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientKill", b => + { + b.HasOne("Data.Models.Client.EFClient", "Attacker") + .WithMany() + .HasForeignKey("AttackerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "DeathOrigin") + .WithMany() + .HasForeignKey("DeathOriginVector3Id"); + + b.HasOne("Data.Models.Vector3", "KillOrigin") + .WithMany() + .HasForeignKey("KillOriginVector3Id"); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.EFClient", "Victim") + .WithMany() + .HasForeignKey("VictimId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "ViewAngles") + .WithMany() + .HasForeignKey("ViewAnglesVector3Id"); + }); + + modelBuilder.Entity("Data.Models.Client.EFClientMessage", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFACSnapshot", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "CurrentViewAngle") + .WithMany() + .HasForeignKey("CurrentViewAngleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "HitDestination") + .WithMany() + .HasForeignKey("HitDestinationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "HitOrigin") + .WithMany() + .HasForeignKey("HitOriginId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Vector3", "LastStrainAngle") + .WithMany() + .HasForeignKey("LastStrainAngleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientHitStatistic", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.Reference.EFHitLocation", "HitLocation") + .WithMany() + .HasForeignKey("HitLocationId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFMeansOfDeath", "MeansOfDeath") + .WithMany() + .HasForeignKey("MeansOfDeathId"); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", "WeaponAttachmentCombo") + .WithMany() + .HasForeignKey("WeaponAttachmentComboId"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeapon", "Weapon") + .WithMany() + .HasForeignKey("WeaponId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRankingHistory", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientRatingHistory", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFClientStatistics", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFHitLocationCount", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany() + .HasForeignKey("EFClientStatisticsClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("EFClientStatisticsServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.EFClientStatistics", null) + .WithMany("HitLocations") + .HasForeignKey("EFClientStatisticsClientId", "EFClientStatisticsServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.EFRating", b => + { + b.HasOne("Data.Models.Client.Stats.EFClientRatingHistory", "RatingHistory") + .WithMany("Ratings") + .HasForeignKey("RatingHistoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Data.Models.Client.Stats.Reference.EFWeaponAttachmentCombo", b => + { + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment1") + .WithMany() + .HasForeignKey("Attachment1Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment2") + .WithMany() + .HasForeignKey("Attachment2Id"); + + b.HasOne("Data.Models.Client.Stats.Reference.EFWeaponAttachment", "Attachment3") + .WithMany() + .HasForeignKey("Attachment3Id"); + }); + + modelBuilder.Entity("Data.Models.EFAlias", b => + { + b.HasOne("Data.Models.EFAliasLink", "Link") + .WithMany("Children") + .HasForeignKey("LinkId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.EFMeta", b => + { + b.HasOne("Data.Models.Client.EFClient", "Client") + .WithMany("Meta") + .HasForeignKey("ClientId"); + + b.HasOne("Data.Models.EFMeta", "LinkedMeta") + .WithMany() + .HasForeignKey("LinkedMetaId") + .OnDelete(DeleteBehavior.SetNull); + }); + + modelBuilder.Entity("Data.Models.EFPenalty", b => + { + b.HasOne("Data.Models.EFAliasLink", "Link") + .WithMany("ReceivedPenalties") + .HasForeignKey("LinkId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Data.Models.Client.EFClient", "Offender") + .WithMany("ReceivedPenalties") + .HasForeignKey("OffenderId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Data.Models.Client.EFClient", "Punisher") + .WithMany("AdministeredPenalties") + .HasForeignKey("PunisherId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Data.Models.Server.EFServerStatistics", b => + { + b.HasOne("Data.Models.Server.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Data/Models/AuditFields.cs b/Data/Models/AuditFields.cs new file mode 100644 index 00000000..43dcfecf --- /dev/null +++ b/Data/Models/AuditFields.cs @@ -0,0 +1,12 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace Stats.Models +{ + public class AuditFields + { + [Required] + public DateTime CreatedDateTime { get; set; } = DateTime.UtcNow; + public DateTime? UpdatedDateTime { get; set; } + } +} \ No newline at end of file diff --git a/Plugins/Stats/Models/EFACSnapshotVector3.cs b/Data/Models/Client/EFACSnapshotVector3.cs similarity index 73% rename from Plugins/Stats/Models/EFACSnapshotVector3.cs rename to Data/Models/Client/EFACSnapshotVector3.cs index 1401f5aa..8751c3eb 100644 --- a/Plugins/Stats/Models/EFACSnapshotVector3.cs +++ b/Data/Models/Client/EFACSnapshotVector3.cs @@ -1,9 +1,9 @@ -using SharedLibraryCore.Database.Models; -using SharedLibraryCore.Helpers; -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Numerics; +using Data.Models.Client.Stats; -namespace IW4MAdmin.Plugins.Stats.Models +namespace Data.Models.Client { public class EFACSnapshotVector3 : SharedEntity { diff --git a/SharedLibraryCore/Database/Models/EFClient.cs b/Data/Models/Client/EFClient.cs similarity index 50% rename from SharedLibraryCore/Database/Models/EFClient.cs rename to Data/Models/Client/EFClient.cs index 0117b84f..89703050 100644 --- a/SharedLibraryCore/Database/Models/EFClient.cs +++ b/Data/Models/Client/EFClient.cs @@ -3,10 +3,54 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace SharedLibraryCore.Database.Models +namespace Data.Models.Client { - public partial class EFClient : SharedEntity + public class EFClient : SharedEntity { + public enum Permission + { + /// + /// client has been banned + /// + Banned = -1, + /// + /// default client state upon first connect + /// + User = 0, + /// + /// client has been flagged + /// + Flagged = 1, + /// + /// client is trusted + /// + Trusted = 2, + /// + /// client is a moderator + /// + Moderator = 3, + /// + /// client is an administrator + /// + Administrator = 4, + /// + /// client is a senior administrator + /// + SeniorAdmin = 5, + /// + /// client is a owner + /// + Owner = 6, + /// + /// not used + /// + Creator = 7, + /// + /// reserved for default account + /// + Console = 8 + } + [Key] public int ClientId { get; set; } public long NetworkId { get; set; } diff --git a/Plugins/Stats/Models/EFClientKill.cs b/Data/Models/Client/EFClientKill.cs similarity index 51% rename from Plugins/Stats/Models/EFClientKill.cs rename to Data/Models/Client/EFClientKill.cs index 29f6dcc6..1c84f5c3 100644 --- a/Plugins/Stats/Models/EFClientKill.cs +++ b/Data/Models/Client/EFClientKill.cs @@ -1,52 +1,41 @@ using System; - -using SharedLibraryCore.Database.Models; -using System.ComponentModel.DataAnnotations.Schema; -using SharedLibraryCore.Helpers; -using System.ComponentModel.DataAnnotations; using System.Collections.Generic; -using static SharedLibraryCore.Server; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Data.Models.Server; -namespace IW4MAdmin.Plugins.Stats.Models +namespace Data.Models.Client { public class EFClientKill : SharedEntity { - [Key] - public long KillId { get; set; } + [Key] public long KillId { get; set; } public int VictimId { get; set; } - [ForeignKey("VictimId")] - public virtual EFClient Victim { get; set; } + [ForeignKey("VictimId")] public virtual EFClient Victim { get; set; } public int AttackerId { get; set; } - [ForeignKey("AttackerId")] - public virtual EFClient Attacker { get; set; } + [ForeignKey("AttackerId")] public virtual EFClient Attacker { get; set; } public long ServerId { get; set; } - [ForeignKey("ServerId")] - public virtual EFServer Server { get; set; } - public IW4Info.HitLocation HitLoc { get; set; } - public IW4Info.MeansOfDeath DeathType { get; set; } + [ForeignKey("ServerId")] public virtual EFServer Server { get; set; } + public int HitLoc { get; set; } + public int DeathType { get; set; } public int Damage { get; set; } - public IW4Info.WeaponName Weapon { get; set; } + public int Weapon { get; set; } public Vector3 KillOrigin { get; set; } public Vector3 DeathOrigin { get; set; } public Vector3 ViewAngles { get; set; } public DateTime When { get; set; } public double Fraction { get; set; } public bool IsKill { get; set; } + public double VisibilityPercentage { get; set; } + // http://wiki.modsrepository.com/index.php?title=Call_of_Duty_5:_Gameplay_standards for conversion to meters - [NotMapped] - public double Distance => Vector3.Distance(KillOrigin, DeathOrigin) * 0.0254; - public IW4Info.MapName Map { get; set; } - [NotMapped] - public long TimeOffset { get; set; } - [NotMapped] - public bool IsKillstreakKill { get; set; } - [NotMapped] - public float AdsPercent { get; set; } - [NotMapped] - public List AnglesList { get; set; } - [NotMapped] - public Game GameName { get; set; } + [NotMapped] public double Distance => Vector3.Distance(KillOrigin, DeathOrigin) * 0.0254; + public int Map { get; set; } + [NotMapped] public long TimeOffset { get; set; } + [NotMapped] public bool IsKillstreakKill { get; set; } + [NotMapped] public float AdsPercent { get; set; } + [NotMapped] public List AnglesList { get; set; } + [NotMapped] public int GameName { get; set; } /// /// Indicates if the attacker was alive after last captured angle @@ -60,4 +49,4 @@ namespace IW4MAdmin.Plugins.Stats.Models [NotMapped] public long TimeSinceLastAttack { get; set; } } -} +} \ No newline at end of file diff --git a/Plugins/Stats/Models/EFClientMessage.cs b/Data/Models/Client/EFClientMessage.cs similarity index 86% rename from Plugins/Stats/Models/EFClientMessage.cs rename to Data/Models/Client/EFClientMessage.cs index 49c2a931..d491e477 100644 --- a/Plugins/Stats/Models/EFClientMessage.cs +++ b/Data/Models/Client/EFClientMessage.cs @@ -1,9 +1,9 @@ -using SharedLibraryCore.Database.Models; -using System; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using Data.Models.Server; -namespace IW4MAdmin.Plugins.Stats.Models +namespace Data.Models.Client { public class EFClientMessage : SharedEntity { diff --git a/Plugins/Stats/Models/EFACSnapshot.cs b/Data/Models/Client/Stats/EFACSnapshot.cs similarity index 87% rename from Plugins/Stats/Models/EFACSnapshot.cs rename to Data/Models/Client/Stats/EFACSnapshot.cs index 7c2abdac..f59f8720 100644 --- a/Plugins/Stats/Models/EFACSnapshot.cs +++ b/Data/Models/Client/Stats/EFACSnapshot.cs @@ -1,12 +1,11 @@ -using SharedLibraryCore.Database.Models; -using SharedLibraryCore.Helpers; -using System; +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; +using System.Numerics; -namespace IW4MAdmin.Plugins.Stats.Models +namespace Data.Models.Client.Stats { /// /// This class houses the information for anticheat snapshots (used for validating a ban) @@ -47,9 +46,9 @@ namespace IW4MAdmin.Plugins.Stats.Models public int CurrentViewAngleId { get; set; } [ForeignKey("CurrentViewAngleId")] public Vector3 CurrentViewAngle { get; set; } - public IW4Info.WeaponName WeaponId { get; set; } - public IW4Info.HitLocation HitLocation { get; set; } - public IW4Info.MeansOfDeath HitType { get; set; } + public int WeaponId { get; set; } + public int HitLocation { get; set; } + public int HitType { get; set; } public virtual ICollection PredictedViewAngles { get; set; } [NotMapped] diff --git a/Data/Models/Client/Stats/EFClientHitStatistic.cs b/Data/Models/Client/Stats/EFClientHitStatistic.cs new file mode 100644 index 00000000..ad25716b --- /dev/null +++ b/Data/Models/Client/Stats/EFClientHitStatistic.cs @@ -0,0 +1,91 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Data.Models.Client.Stats.Reference; +using Data.Models.Server; +using Stats.Models; + +namespace Data.Models.Client.Stats +{ + public class EFClientHitStatistic : AuditFields + { + [Key] + public int ClientHitStatisticId { get; set; } + + [Required] + public int ClientId { get; set; } + + [ForeignKey(nameof(ClientId))] + public virtual EFClient Client { get; set; } + + public long? ServerId { get; set; } + + [ForeignKey(nameof(ServerId))] + public virtual EFServer Server { get; set; } + + public int? HitLocationId { get; set; } + + [ForeignKey(nameof(HitLocationId))] + public virtual EFHitLocation HitLocation { get; set; } + + public int? MeansOfDeathId { get; set; } + + [ForeignKey(nameof(MeansOfDeathId))] + public virtual EFMeansOfDeath MeansOfDeath { get; set; } + + public int? WeaponId { get; set; } + + [ForeignKey(nameof(WeaponId))] + public virtual EFWeapon Weapon { get; set; } + + public int? WeaponAttachmentComboId { get; set; } + + [ForeignKey(nameof(WeaponAttachmentComboId))] + public virtual EFWeaponAttachmentCombo WeaponAttachmentCombo { get; set; } + + /// + /// how many hits the player got + /// + public int HitCount { get; set; } + + /// + /// how many kills the player got + /// + public int KillCount { get; set; } + + /// + /// how much damage the player inflicted + /// + public int DamageInflicted { get; set; } + + /// + /// how many hits the player received + /// + public int ReceivedHitCount { get; set; } + + /// + /// how many kills the player received + /// + public int DeathCount { get; set; } + + /// + /// how much damage the player received + /// + public int DamageReceived { get; set; } + + /// + /// how many times the player killed themself + /// + public int SuicideCount { get; set; } + + /// + /// estimation of time spent with the configuration + /// + public int? UsageSeconds { get; set; } + + /// + /// total in-game score + /// + public int? Score { get; set; } + } +} diff --git a/Data/Models/Client/Stats/EFClientRankingHistory.cs b/Data/Models/Client/Stats/EFClientRankingHistory.cs new file mode 100644 index 00000000..1991a5b3 --- /dev/null +++ b/Data/Models/Client/Stats/EFClientRankingHistory.cs @@ -0,0 +1,31 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Data.Models.Server; +using Stats.Models; + +namespace Data.Models.Client.Stats +{ + public class EFClientRankingHistory: AuditFields + { + public const int MaxRankingCount = 30; + + [Key] + public long ClientRankingHistoryId { get; set; } + + [Required] + public int ClientId { get; set; } + + [ForeignKey(nameof(ClientId))] + public virtual EFClient Client { get; set; } + + public long? ServerId { get; set; } + + [ForeignKey(nameof(ServerId))] + public virtual EFServer Server { get; set; } + + public bool Newest { get; set; } + public int? Ranking { get; set; } + public double? ZScore { get; set; } + public double? PerformanceMetric { get; set; } + } +} \ No newline at end of file diff --git a/Plugins/Stats/Models/EFClientRatingHistory.cs b/Data/Models/Client/Stats/EFClientRatingHistory.cs similarity index 69% rename from Plugins/Stats/Models/EFClientRatingHistory.cs rename to Data/Models/Client/Stats/EFClientRatingHistory.cs index 51d04d0e..e5e37c6e 100644 --- a/Plugins/Stats/Models/EFClientRatingHistory.cs +++ b/Data/Models/Client/Stats/EFClientRatingHistory.cs @@ -1,12 +1,8 @@ -using IW4MAdmin.Plugins.Stats.Models; -using SharedLibraryCore.Database.Models; -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Text; -namespace IW4MAdmin.Plugins.Stats.Models +namespace Data.Models.Client.Stats { public class EFClientRatingHistory : SharedEntity { diff --git a/Plugins/Stats/Models/EFClientStatistics.cs b/Data/Models/Client/Stats/EFClientStatistics.cs similarity index 90% rename from Plugins/Stats/Models/EFClientStatistics.cs rename to Data/Models/Client/Stats/EFClientStatistics.cs index 83f1524b..ed6d01c1 100644 --- a/Plugins/Stats/Models/EFClientStatistics.cs +++ b/Data/Models/Client/Stats/EFClientStatistics.cs @@ -4,9 +4,9 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Threading; -using SharedLibraryCore.Database.Models; +using Data.Models.Server; -namespace IW4MAdmin.Plugins.Stats.Models +namespace Data.Models.Client.Stats { public class EFClientStatistics : SharedEntity { @@ -31,16 +31,16 @@ namespace IW4MAdmin.Plugins.Stats.Models [Required] public int Deaths { get; set; } public double EloRating { get; set; } + public double ZScore { get; set; } + public DateTime? UpdatedAt { get; set; } public virtual ICollection HitLocations { get; set; } public double RollingWeightedKDR { get; set; } - public double VisionAverage { get; set; } - public double AverageRecoilOffset { get; set; } public double AverageSnapValue { get; set; } public int SnapHitCount { get; set; } [NotMapped] public double Performance { - get => Math.Round((EloRating + Skill) / 2.0, 2); + get => Math.Round(EloRating * 1/3.0 + Skill * 2/3.0, 2); } [NotMapped] public double KDR @@ -83,7 +83,7 @@ namespace IW4MAdmin.Plugins.Stats.Models DeathStreak = 0; LastScore = 0; SessionScores.Add(0); - Team = IW4Info.Team.None; + Team = 0; } [NotMapped] public int SessionScore @@ -103,7 +103,7 @@ namespace IW4MAdmin.Plugins.Stats.Models [NotMapped] private readonly List SessionScores = new List() { 0 }; [NotMapped] - public IW4Info.Team Team { get; set; } + public int Team { get; set; } [NotMapped] public DateTime LastStatHistoryUpdate { get; set; } = DateTime.UtcNow; [NotMapped] diff --git a/Plugins/Stats/Models/EFHitLocationCount.cs b/Data/Models/Client/Stats/EFHitLocationCount.cs similarity index 81% rename from Plugins/Stats/Models/EFHitLocationCount.cs rename to Data/Models/Client/Stats/EFHitLocationCount.cs index 726dc9b4..cc8bd042 100644 --- a/Plugins/Stats/Models/EFHitLocationCount.cs +++ b/Data/Models/Client/Stats/EFHitLocationCount.cs @@ -1,15 +1,15 @@ -using SharedLibraryCore.Database.Models; -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using Data.Models.Server; -namespace IW4MAdmin.Plugins.Stats.Models +namespace Data.Models.Client.Stats { public class EFHitLocationCount : SharedEntity { [Key] public int HitLocationCountId { get; set; } [Required] - public IW4Info.HitLocation Location { get; set; } + public int Location { get; set; } [Required] public int HitCount { get; set; } [Required] diff --git a/Plugins/Stats/Models/EFRating.cs b/Data/Models/Client/Stats/EFRating.cs similarity index 91% rename from Plugins/Stats/Models/EFRating.cs rename to Data/Models/Client/Stats/EFRating.cs index 9aae5f4e..2e50b08c 100644 --- a/Plugins/Stats/Models/EFRating.cs +++ b/Data/Models/Client/Stats/EFRating.cs @@ -1,9 +1,9 @@ -using SharedLibraryCore.Database.Models; -using System; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using Data.Models.Server; -namespace IW4MAdmin.Plugins.Stats.Models +namespace Data.Models.Client.Stats { public class EFRating : SharedEntity { diff --git a/Data/Models/Client/Stats/Reference/EFHitLocation.cs b/Data/Models/Client/Stats/Reference/EFHitLocation.cs new file mode 100644 index 00000000..dde2dcf8 --- /dev/null +++ b/Data/Models/Client/Stats/Reference/EFHitLocation.cs @@ -0,0 +1,21 @@ +using System.ComponentModel.DataAnnotations; +using Data.Abstractions; +using Stats.Models; + +namespace Data.Models.Client.Stats.Reference +{ + public class EFHitLocation : AuditFields, IUniqueId + { + [Key] + public int HitLocationId { get; set; } + + [Required] + public string Name { get; set; } + + [Required] + public Models.Reference.Game Game { get; set; } + + public long Id => HitLocationId; + public string Value => Name; + } +} \ No newline at end of file diff --git a/Data/Models/Client/Stats/Reference/EFMap.cs b/Data/Models/Client/Stats/Reference/EFMap.cs new file mode 100644 index 00000000..2f765b7a --- /dev/null +++ b/Data/Models/Client/Stats/Reference/EFMap.cs @@ -0,0 +1,21 @@ +using System.ComponentModel.DataAnnotations; +using Data.Abstractions; +using Stats.Models; + +namespace Data.Models.Client.Stats.Reference +{ + public class EFMap : AuditFields, IUniqueId + { + [Key] + public int MapId { get; set; } + + [Required] + public string Name { get; set; } + + [Required] + public Models.Reference.Game Game { get; set; } + + public long Id => MapId; + public string Value => Name; + } +} \ No newline at end of file diff --git a/Data/Models/Client/Stats/Reference/EFMeansOfDeath.cs b/Data/Models/Client/Stats/Reference/EFMeansOfDeath.cs new file mode 100644 index 00000000..ba3c0d55 --- /dev/null +++ b/Data/Models/Client/Stats/Reference/EFMeansOfDeath.cs @@ -0,0 +1,21 @@ +using System.ComponentModel.DataAnnotations; +using Data.Abstractions; +using Stats.Models; + +namespace Data.Models.Client.Stats.Reference +{ + public class EFMeansOfDeath: AuditFields, IUniqueId + { + [Key] + public int MeansOfDeathId { get; set; } + + [Required] + public string Name { get; set; } + + [Required] + public Models.Reference.Game Game { get; set; } + + public long Id => MeansOfDeathId; + public string Value => Name; + } +} \ No newline at end of file diff --git a/Data/Models/Client/Stats/Reference/EFWeapon.cs b/Data/Models/Client/Stats/Reference/EFWeapon.cs new file mode 100644 index 00000000..54b67443 --- /dev/null +++ b/Data/Models/Client/Stats/Reference/EFWeapon.cs @@ -0,0 +1,21 @@ +using System.ComponentModel.DataAnnotations; +using Data.Abstractions; +using Stats.Models; + +namespace Data.Models.Client.Stats.Reference +{ + public class EFWeapon : AuditFields, IUniqueId + { + [Key] + public int WeaponId { get; set; } + + [Required] + public string Name { get; set; } + + [Required] + public Models.Reference.Game Game { get; set; } + + public long Id => WeaponId; + public string Value => Name; + } +} \ No newline at end of file diff --git a/Data/Models/Client/Stats/Reference/EFWeaponAttachment.cs b/Data/Models/Client/Stats/Reference/EFWeaponAttachment.cs new file mode 100644 index 00000000..0d92ea52 --- /dev/null +++ b/Data/Models/Client/Stats/Reference/EFWeaponAttachment.cs @@ -0,0 +1,21 @@ +using System.ComponentModel.DataAnnotations; +using Data.Abstractions; +using Stats.Models; + +namespace Data.Models.Client.Stats.Reference +{ + public class EFWeaponAttachment : AuditFields, IUniqueId + { + [Key] + public int WeaponAttachmentId { get; set; } + + [Required] + public string Name { get; set; } + + [Required] + public Models.Reference.Game Game { get; set; } + + public long Id => WeaponAttachmentId; + public string Value => Name; + } +} diff --git a/Data/Models/Client/Stats/Reference/EFWeaponAttachmentCombo.cs b/Data/Models/Client/Stats/Reference/EFWeaponAttachmentCombo.cs new file mode 100644 index 00000000..1560bf94 --- /dev/null +++ b/Data/Models/Client/Stats/Reference/EFWeaponAttachmentCombo.cs @@ -0,0 +1,35 @@ +using Data.Abstractions; +using Stats.Models; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Data.Models.Client.Stats.Reference +{ + public class EFWeaponAttachmentCombo : AuditFields, IUniqueId + { + [Key] + public int WeaponAttachmentComboId { get; set; } + + [Required] + public Models.Reference.Game Game { get; set; } + + [Required] + public int Attachment1Id { get; set; } + + [ForeignKey(nameof(Attachment1Id))] + public virtual EFWeaponAttachment Attachment1 { get; set; } + + public int? Attachment2Id { get; set; } + + [ForeignKey(nameof(Attachment2Id))] + public virtual EFWeaponAttachment Attachment2 { get; set; } + + public int? Attachment3Id { get; set; } + + [ForeignKey(nameof(Attachment3Id))] + public virtual EFWeaponAttachment Attachment3 { get; set; } + + public long Id => WeaponAttachmentComboId; + public string Value => $"{Attachment1Id}{Attachment2Id}{Attachment3Id}"; + } +} diff --git a/Data/Models/Configuration/StatsModelConfiguration.cs b/Data/Models/Configuration/StatsModelConfiguration.cs new file mode 100644 index 00000000..ad172a2e --- /dev/null +++ b/Data/Models/Configuration/StatsModelConfiguration.cs @@ -0,0 +1,92 @@ +using Data.Models.Client; +using Data.Models.Client.Stats; +using Data.Models.Client.Stats.Reference; +using Data.Models.Server; +using Microsoft.EntityFrameworkCore; + +namespace Data.Models.Configuration +{ + public class StatsModelConfiguration + { + public static void Configure(ModelBuilder builder) + { + builder.Entity(entity => + { + entity.HasKey(cs => new {cs.ClientId, cs.ServerId}); + entity.HasIndex(cs => new {cs.ClientId, cs.TimePlayed, PerformancePercentile = cs.ZScore}); + entity.HasIndex(cs => new {PerformancePercentile = cs.ZScore}); + entity.ToTable("EFClientStatistics"); + }); + + + // fix linking from SQLCe + builder.Entity(entity => + { + entity.Property(c => c.EFClientStatisticsClientId) + .HasColumnName("EFClientStatisticsClientId"); + entity.Property(c => c.EFClientStatisticsServerId) + .HasColumnName("EFClientStatisticsServerId"); + + entity.ToTable("EFHitLocationCounts"); + }); + + + builder.Entity(entity => + { + entity.HasIndex(p => new {p.Performance, p.Ranking, p.When}); + entity.HasIndex(p => new {p.When, p.ServerId, p.Performance, p.ActivityAmount}); + entity.ToTable(nameof(EFRating)); + }); + + + builder.Entity(entity => + { + entity.HasIndex(p => p.TimeSent); + entity.ToTable("EFClientMessages"); + }); + + builder.Entity(entity => { entity.ToTable(nameof(EFClientStatistics)); }); + + builder.Entity(entity => { entity.ToTable(nameof(EFRating)); }); + + builder.Entity(entity => { entity.ToTable(nameof(EFClientRatingHistory)); }); + + builder.Entity(entity => { entity.ToTable("EFHitLocationCounts"); }); + + builder.Entity(entity => { entity.ToTable("EFServerStatistics"); }); + + builder.Entity(entity => { entity.ToTable("EFServers"); }); + + builder.Entity(entity => { entity.ToTable("EFClientKills"); }); + + builder.Entity().ToTable(nameof(Vector3)); + builder.Entity().ToTable(nameof(EFACSnapshot)); + builder.Entity().ToTable(nameof(EFACSnapshotVector3)); + + builder.Entity(entity => + { + entity.HasIndex(loc => loc.Name); + entity.ToTable("EFHitLocations"); + }); + + builder.Entity(entity => + { + entity.HasIndex(weapon => weapon.Name); + entity.ToTable("EFWeapons"); + }); + + builder.Entity(entity => { entity.ToTable("EFMaps"); }); + builder.Entity(entity => { entity.ToTable("EFClientHitStatistics"); }); + builder.Entity(entity => { entity.ToTable("EFWeaponAttachments"); }); + builder.Entity(entity => { entity.ToTable("EFWeaponAttachmentCombos"); }); + builder.Entity(entity => { entity.ToTable("EFMeansOfDeath"); }); + builder.Entity(entity => + { + entity.ToTable(nameof(EFClientRankingHistory)); + entity.HasIndex(ranking => ranking.Ranking); + entity.HasIndex(ranking => ranking.ZScore); + entity.HasIndex(ranking => ranking.UpdatedDateTime); + }); + } + } +} \ No newline at end of file diff --git a/SharedLibraryCore/Database/Models/EFAlias.cs b/Data/Models/EFAlias.cs similarity index 94% rename from SharedLibraryCore/Database/Models/EFAlias.cs rename to Data/Models/EFAlias.cs index b8eee0eb..7f9bbd35 100644 --- a/SharedLibraryCore/Database/Models/EFAlias.cs +++ b/Data/Models/EFAlias.cs @@ -2,7 +2,7 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace SharedLibraryCore.Database.Models +namespace Data.Models { public partial class EFAlias : SharedEntity { diff --git a/SharedLibraryCore/Database/Models/EFAliasLink.cs b/Data/Models/EFAliasLink.cs similarity index 81% rename from SharedLibraryCore/Database/Models/EFAliasLink.cs rename to Data/Models/EFAliasLink.cs index b6b08eb1..3cb4c559 100644 --- a/SharedLibraryCore/Database/Models/EFAliasLink.cs +++ b/Data/Models/EFAliasLink.cs @@ -1,9 +1,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -namespace SharedLibraryCore.Database.Models +namespace Data.Models { public class EFAliasLink : SharedEntity { diff --git a/SharedLibraryCore/Database/Models/EFChangeHistory.cs b/Data/Models/EFChangeHistory.cs similarity index 95% rename from SharedLibraryCore/Database/Models/EFChangeHistory.cs rename to Data/Models/EFChangeHistory.cs index fae53ab0..733b01fc 100644 --- a/SharedLibraryCore/Database/Models/EFChangeHistory.cs +++ b/Data/Models/EFChangeHistory.cs @@ -1,7 +1,7 @@ using System; using System.ComponentModel.DataAnnotations; -namespace SharedLibraryCore.Database.Models +namespace Data.Models { /// /// This class models the change to different entities diff --git a/SharedLibraryCore/Database/Models/EFMeta.cs b/Data/Models/EFMeta.cs similarity index 94% rename from SharedLibraryCore/Database/Models/EFMeta.cs rename to Data/Models/EFMeta.cs index 792797ee..2d2f81ac 100644 --- a/SharedLibraryCore/Database/Models/EFMeta.cs +++ b/Data/Models/EFMeta.cs @@ -1,8 +1,9 @@ -using System; +using Data.Models.Client; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace SharedLibraryCore.Database.Models +namespace Data.Models { /// /// This class encapsulates any meta fields as a simple string diff --git a/SharedLibraryCore/Database/Models/EFPenalty.cs b/Data/Models/EFPenalty.cs similarity index 73% rename from SharedLibraryCore/Database/Models/EFPenalty.cs rename to Data/Models/EFPenalty.cs index 5aa370ce..2102ec0f 100644 --- a/SharedLibraryCore/Database/Models/EFPenalty.cs +++ b/Data/Models/EFPenalty.cs @@ -1,11 +1,26 @@ -using System; +using Data.Models.Client; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace SharedLibraryCore.Database.Models +namespace Data.Models { - public partial class EFPenalty : SharedEntity + public class EFPenalty : SharedEntity { + public enum PenaltyType + { + Report, + Warning, + Flag, + Kick, + TempBan, + Ban, + Unban, + Any, + Unflag, + Other = 100 + } + [Key] public int PenaltyId { get; set; } [Required] diff --git a/Data/Models/Reference.cs b/Data/Models/Reference.cs new file mode 100644 index 00000000..6322d6df --- /dev/null +++ b/Data/Models/Reference.cs @@ -0,0 +1,19 @@ +namespace Data.Models +{ + public class Reference + { + public enum Game + { + COD = -1, + UKN = 0, + IW3 = 1, + IW4 = 2, + IW5 = 3, + IW6 = 4, + T4 = 5, + T5 = 6, + T6 = 7, + T7 = 8 + } + } +} \ No newline at end of file diff --git a/Plugins/Stats/Models/EFServer.cs b/Data/Models/Server/EFServer.cs similarity index 57% rename from Plugins/Stats/Models/EFServer.cs rename to Data/Models/Server/EFServer.cs index c547278d..70a49cd4 100644 --- a/Plugins/Stats/Models/EFServer.cs +++ b/Data/Models/Server/EFServer.cs @@ -1,12 +1,10 @@ - -using SharedLibraryCore.Database.Models; -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using static SharedLibraryCore.Server; +using Data.Abstractions; -namespace IW4MAdmin.Plugins.Stats.Models +namespace Data.Models.Server { - public class EFServer : SharedEntity + public class EFServer : SharedEntity, IUniqueId { [Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] @@ -14,8 +12,10 @@ namespace IW4MAdmin.Plugins.Stats.Models [Required] public int Port { get; set; } public string EndPoint { get; set; } - public Game? GameName { get; set; } + public Reference.Game? GameName { get; set; } public string HostName { get; set; } public bool IsPasswordProtected { get; set; } + public long Id => ServerId; + public string Value => EndPoint; } } diff --git a/Plugins/Stats/Models/EFServerStatistics.cs b/Data/Models/Server/EFServerStatistics.cs similarity index 75% rename from Plugins/Stats/Models/EFServerStatistics.cs rename to Data/Models/Server/EFServerStatistics.cs index c60f5908..9cc22e62 100644 --- a/Plugins/Stats/Models/EFServerStatistics.cs +++ b/Data/Models/Server/EFServerStatistics.cs @@ -1,8 +1,7 @@ -using SharedLibraryCore.Database.Models; -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -namespace IW4MAdmin.Plugins.Stats.Models +namespace Data.Models.Server { public class EFServerStatistics : SharedEntity { diff --git a/SharedLibraryCore/Database/Models/SharedEntity.cs b/Data/Models/SharedEntity.cs similarity index 63% rename from SharedLibraryCore/Database/Models/SharedEntity.cs rename to Data/Models/SharedEntity.cs index cd7c2b94..bd5271ce 100644 --- a/SharedLibraryCore/Database/Models/SharedEntity.cs +++ b/Data/Models/SharedEntity.cs @@ -1,9 +1,7 @@ -using SharedLibraryCore.Interfaces; -using System; +using Data.Abstractions; using System.Collections.Concurrent; -using System.ComponentModel.DataAnnotations.Schema; -namespace SharedLibraryCore.Database.Models +namespace Data.Models { public class SharedEntity : IPropertyExtender { @@ -35,17 +33,5 @@ namespace SharedLibraryCore.Database.Models _additionalProperties.TryAdd(name, value); } } - - ///// - ///// Specifies when the entity was created - ///// - //[Column(TypeName="datetime")] - //public DateTime CreatedDateTime { get; set; } - - ///// - ///// Specifies when the entity was updated - ///// - //[Column(TypeName = "datetime")] - //public DateTime? UpdatedDateTime { get;set; } } } diff --git a/SharedLibraryCore/Helpers/Vector3.cs b/Data/Models/Vector3.cs similarity index 64% rename from SharedLibraryCore/Helpers/Vector3.cs rename to Data/Models/Vector3.cs index 4bdf3c9d..c4c53af5 100644 --- a/SharedLibraryCore/Helpers/Vector3.cs +++ b/Data/Models/Vector3.cs @@ -1,17 +1,12 @@ using System; -using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Text; using System.Text.RegularExpressions; -using System.Threading.Tasks; -namespace SharedLibraryCore.Helpers +namespace Data.Models { public class Vector3 { - [Key] - public int Vector3Id { get; set; } + [Key] public int Vector3Id { get; set; } public float X { get; protected set; } public float Y { get; protected set; } public float Z { get; protected set; } @@ -19,7 +14,6 @@ namespace SharedLibraryCore.Helpers // this is for EF and really should be somewhere else public Vector3() { - } public Vector3(float x, float y, float z) @@ -46,7 +40,9 @@ namespace SharedLibraryCore.Helpers public static Vector3 Parse(string s) { - bool valid = Regex.Match(s, @"\((-?[0-9]+\.?[0-9]*|-?[0-9]+\.?[0-9]*e-[0-9]+),\ (-?[0-9]+\.?[0-9]*|-?[0-9]+\.?[0-9]*e-[0-9]+),\ (-?[0-9]+\.?[0-9]*|-?[0-9]+\.?[0-9]*e-[0-9]+)\)").Success; + bool valid = Regex.Match(s, + @"\((-?[0-9]+\.?[0-9]*|-?[0-9]+\.?[0-9]*e-[0-9]+),\ (-?[0-9]+\.?[0-9]*|-?[0-9]+\.?[0-9]*e-[0-9]+),\ (-?[0-9]+\.?[0-9]*|-?[0-9]+\.?[0-9]*e-[0-9]+)\)") + .Success; if (!valid) { throw new FormatException("Vector3 is not in correct format"); @@ -55,9 +51,13 @@ namespace SharedLibraryCore.Helpers string removeParenthesis = s.Substring(1, s.Length - 2); string[] eachPoint = removeParenthesis.Split(','); - return new Vector3(float.Parse(eachPoint[0], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture), - float.Parse(eachPoint[1], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture), - float.Parse(eachPoint[2], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture)); + return new Vector3( + float.Parse(eachPoint[0], System.Globalization.NumberStyles.Any, + System.Globalization.CultureInfo.InvariantCulture), + float.Parse(eachPoint[1], System.Globalization.NumberStyles.Any, + System.Globalization.CultureInfo.InvariantCulture), + float.Parse(eachPoint[2], System.Globalization.NumberStyles.Any, + System.Globalization.CultureInfo.InvariantCulture)); } public static double Distance(Vector3 a, Vector3 b) @@ -76,44 +76,7 @@ namespace SharedLibraryCore.Helpers return Math.Sqrt((dx * dx) + (dy * dy)); } - - public static double SnapDistance(Vector3 a, Vector3 b, Vector3 c) - { - a = a.FixIW4Angles(); - b = b.FixIW4Angles(); - c = c.FixIW4Angles(); - - float preserveDirectionAngle(float a1, float b1) - { - float difference = b1 - a1; - while (difference < -180) difference += 360; - while (difference > 180) difference -= 360; - return difference; - } - - var directions = new[] - { - new Vector3() - { - X = preserveDirectionAngle(b.X, a.X), - Y = preserveDirectionAngle(b.Y, a.Y) - }, - new Vector3() - { - X = preserveDirectionAngle(c.X, b.X), - Y = preserveDirectionAngle(c.Y, b.Y) - } - }; - - var distance = new Vector3 - { - X = Math.Abs(directions[1].X - directions[0].X), - Y = Math.Abs(directions[1].Y - directions[0].Y) - }; - - return Math.Sqrt((distance.X * distance.X) + (distance.Y * distance.Y)); - } - + public static double ViewAngleDistance(Vector3 a, Vector3 b, Vector3 c) { double dabX = Math.Abs(a.X - b.X); @@ -147,4 +110,4 @@ namespace SharedLibraryCore.Helpers public double AngleBetween(Vector3 a) => Math.Acos(this.DotProduct(a) / (a.Magnitude() * this.Magnitude())); } -} +} \ No newline at end of file diff --git a/IW4MAdmin.sln b/IW4MAdmin.sln index 1cc50347..e8a9d1c1 100644 --- a/IW4MAdmin.sln +++ b/IW4MAdmin.sln @@ -39,18 +39,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ScriptPlugins", "ScriptPlug Plugins\ScriptPlugins\ParserPIW5.js = Plugins\ScriptPlugins\ParserPIW5.js Plugins\ScriptPlugins\ParserPT6.js = Plugins\ScriptPlugins\ParserPT6.js Plugins\ScriptPlugins\ParserRektT5M.js = Plugins\ScriptPlugins\ParserRektT5M.js + Plugins\ScriptPlugins\ParserT4.js = Plugins\ScriptPlugins\ParserT4.js Plugins\ScriptPlugins\ParserT7.js = Plugins\ScriptPlugins\ParserT7.js Plugins\ScriptPlugins\ParserTeknoMW3.js = Plugins\ScriptPlugins\ParserTeknoMW3.js Plugins\ScriptPlugins\SampleScriptPluginCommand.js = Plugins\ScriptPlugins\SampleScriptPluginCommand.js Plugins\ScriptPlugins\SharedGUIDKick.js = Plugins\ScriptPlugins\SharedGUIDKick.js Plugins\ScriptPlugins\VPNDetection.js = Plugins\ScriptPlugins\VPNDetection.js - Plugins\ScriptPlugins\ParserT4.js = Plugins\ScriptPlugins\ParserT4.js EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web", "Web", "{A848FCF1-8527-4AA8-A1AA-50D29695C678}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StatsWeb", "Plugins\Web\StatsWeb\StatsWeb.csproj", "{776B348B-F818-4A0F-A625-D0AF8BAD3E9B}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutomessageFeed", "Plugins\AutomessageFeed\AutomessageFeed.csproj", "{F5815359-CFC7-44B4-9A3B-C04BACAD5836}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LiveRadar", "Plugins\LiveRadar\LiveRadar.csproj", "{00A1FED2-2254-4AF7-A5DB-2357FA7C88CD}" @@ -59,6 +55,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{3065279E EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApplicationTests", "Tests\ApplicationTests\ApplicationTests.csproj", "{581FA7AF-FEF6-483C-A7D0-2D13EF50801B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Data", "Data\Data.csproj", "{81689023-E55E-48ED-B7A8-53F4E21BBF2D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -267,30 +265,6 @@ Global {6C706CE5-A206-4E46-8712-F8C48D526091}.Release|x64.Build.0 = Release|Any CPU {6C706CE5-A206-4E46-8712-F8C48D526091}.Release|x86.ActiveCfg = Release|Any CPU {6C706CE5-A206-4E46-8712-F8C48D526091}.Release|x86.Build.0 = Release|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Debug|x64.ActiveCfg = Debug|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Debug|x64.Build.0 = Debug|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Debug|x86.ActiveCfg = Debug|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Debug|x86.Build.0 = Debug|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Prerelease|Any CPU.ActiveCfg = Prerelease|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Prerelease|Any CPU.Build.0 = Prerelease|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Prerelease|Mixed Platforms.ActiveCfg = Debug|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Prerelease|Mixed Platforms.Build.0 = Debug|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Prerelease|x64.ActiveCfg = Debug|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Prerelease|x64.Build.0 = Debug|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Prerelease|x86.ActiveCfg = Debug|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Prerelease|x86.Build.0 = Debug|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Release|Any CPU.Build.0 = Release|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Release|x64.ActiveCfg = Release|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Release|x64.Build.0 = Release|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Release|x86.ActiveCfg = Release|Any CPU - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B}.Release|x86.Build.0 = Release|Any CPU {F5815359-CFC7-44B4-9A3B-C04BACAD5836}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F5815359-CFC7-44B4-9A3B-C04BACAD5836}.Debug|Any CPU.Build.0 = Debug|Any CPU {F5815359-CFC7-44B4-9A3B-C04BACAD5836}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -362,6 +336,30 @@ Global {581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Release|x64.Build.0 = Release|Any CPU {581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Release|x86.ActiveCfg = Release|Any CPU {581FA7AF-FEF6-483C-A7D0-2D13EF50801B}.Release|x86.Build.0 = Release|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Debug|x64.ActiveCfg = Debug|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Debug|x64.Build.0 = Debug|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Debug|x86.ActiveCfg = Debug|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Debug|x86.Build.0 = Debug|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Prerelease|Mixed Platforms.ActiveCfg = Debug|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Prerelease|Mixed Platforms.Build.0 = Debug|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Prerelease|x64.ActiveCfg = Debug|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Prerelease|x64.Build.0 = Debug|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Prerelease|x86.ActiveCfg = Debug|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Prerelease|x86.Build.0 = Debug|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Release|Any CPU.Build.0 = Release|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Release|x64.ActiveCfg = Release|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Release|x64.Build.0 = Release|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Release|x86.ActiveCfg = Release|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Release|x86.Build.0 = Release|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Prerelease|Any CPU.ActiveCfg = Prerelease|Any CPU + {81689023-E55E-48ED-B7A8-53F4E21BBF2D}.Prerelease|Any CPU.Build.0 = Prerelease|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -373,8 +371,6 @@ Global {D9F2ED28-6FA5-40CA-9912-E7A849147AB1} = {26E8B310-269E-46D4-A612-24601F16065F} {6C706CE5-A206-4E46-8712-F8C48D526091} = {26E8B310-269E-46D4-A612-24601F16065F} {3F9ACC27-26DB-49FA-BCD2-50C54A49C9FA} = {26E8B310-269E-46D4-A612-24601F16065F} - {A848FCF1-8527-4AA8-A1AA-50D29695C678} = {26E8B310-269E-46D4-A612-24601F16065F} - {776B348B-F818-4A0F-A625-D0AF8BAD3E9B} = {A848FCF1-8527-4AA8-A1AA-50D29695C678} {F5815359-CFC7-44B4-9A3B-C04BACAD5836} = {26E8B310-269E-46D4-A612-24601F16065F} {00A1FED2-2254-4AF7-A5DB-2357FA7C88CD} = {26E8B310-269E-46D4-A612-24601F16065F} {581FA7AF-FEF6-483C-A7D0-2D13EF50801B} = {3065279E-17F0-4CE0-AF5B-014E04263D77} diff --git a/Plugins/AutomessageFeed/AutomessageFeed.csproj b/Plugins/AutomessageFeed/AutomessageFeed.csproj index 78bf21a1..f7b0ad0d 100644 --- a/Plugins/AutomessageFeed/AutomessageFeed.csproj +++ b/Plugins/AutomessageFeed/AutomessageFeed.csproj @@ -10,7 +10,7 @@ - + diff --git a/Plugins/IW4ScriptCommands/IW4ScriptCommands.csproj b/Plugins/IW4ScriptCommands/IW4ScriptCommands.csproj index 24f83fe5..0f23e151 100644 --- a/Plugins/IW4ScriptCommands/IW4ScriptCommands.csproj +++ b/Plugins/IW4ScriptCommands/IW4ScriptCommands.csproj @@ -10,7 +10,7 @@ - + diff --git a/Plugins/LiveRadar/LiveRadar.csproj b/Plugins/LiveRadar/LiveRadar.csproj index c767d453..77c28bf4 100644 --- a/Plugins/LiveRadar/LiveRadar.csproj +++ b/Plugins/LiveRadar/LiveRadar.csproj @@ -15,9 +15,6 @@ - - - @@ -25,6 +22,10 @@ + + + + diff --git a/Plugins/LiveRadar/Plugin.cs b/Plugins/LiveRadar/Plugin.cs index 245129af..7c921a14 100644 --- a/Plugins/LiveRadar/Plugin.cs +++ b/Plugins/LiveRadar/Plugin.cs @@ -6,6 +6,7 @@ using System.Globalization; using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using SharedLibraryCore.Configuration; using SharedLibraryCore.Interfaces; using ILogger = Microsoft.Extensions.Logging.ILogger; @@ -24,12 +25,14 @@ namespace LiveRadar private bool addedPage; private readonly object lockObject = new object(); private readonly ILogger _logger; + private readonly ApplicationConfiguration _appConfig; - public Plugin(ILogger logger, IConfigurationHandlerFactory configurationHandlerFactory) + public Plugin(ILogger logger, IConfigurationHandlerFactory configurationHandlerFactory, ApplicationConfiguration appConfig) { _configurationHandler = configurationHandlerFactory.GetConfigurationHandler("LiveRadarConfiguration"); _botGuidLookups = new Dictionary(); _logger = logger; + _appConfig = appConfig; } public Task OnEventAsync(GameEvent E, Server S) @@ -64,6 +67,11 @@ namespace LiveRadar { try { + if (((string) E.Extra).IsBotGuid() && _appConfig.IgnoreBots) + { + return Task.CompletedTask; + } + string botKey = $"BotGuid_{E.Extra}"; long generatedBotGuid; diff --git a/Plugins/LiveRadar/RadarEvent.cs b/Plugins/LiveRadar/RadarEvent.cs index dc2354c0..3dcf8bfa 100644 --- a/Plugins/LiveRadar/RadarEvent.cs +++ b/Plugins/LiveRadar/RadarEvent.cs @@ -1,5 +1,5 @@ -using SharedLibraryCore; -using SharedLibraryCore.Helpers; +using Data.Models; +using SharedLibraryCore; using System; using System.Linq; diff --git a/Plugins/Login/Login.csproj b/Plugins/Login/Login.csproj index 03a890c1..406a1f32 100644 --- a/Plugins/Login/Login.csproj +++ b/Plugins/Login/Login.csproj @@ -18,12 +18,12 @@ TRACE;DEBUG; + + + + - - - - diff --git a/Plugins/ProfanityDeterment/Plugin.cs b/Plugins/ProfanityDeterment/Plugin.cs index de2fda40..be0f752b 100644 --- a/Plugins/ProfanityDeterment/Plugin.cs +++ b/Plugins/ProfanityDeterment/Plugin.cs @@ -2,9 +2,8 @@ using System.Reflection; using System.Text.RegularExpressions; using System.Threading.Tasks; +using Data.Models; using SharedLibraryCore; -using SharedLibraryCore.Configuration; -using SharedLibraryCore.Database.Models; using SharedLibraryCore.Interfaces; namespace IW4MAdmin.Plugins.ProfanityDeterment diff --git a/Plugins/ProfanityDeterment/ProfanityDeterment.csproj b/Plugins/ProfanityDeterment/ProfanityDeterment.csproj index 3c4a7c0e..d3d0fbb9 100644 --- a/Plugins/ProfanityDeterment/ProfanityDeterment.csproj +++ b/Plugins/ProfanityDeterment/ProfanityDeterment.csproj @@ -16,7 +16,7 @@ - + diff --git a/Plugins/Stats/Cheat/Detection.cs b/Plugins/Stats/Cheat/Detection.cs index f5357939..64172b1e 100644 --- a/Plugins/Stats/Cheat/Detection.cs +++ b/Plugins/Stats/Cheat/Detection.cs @@ -1,12 +1,15 @@ -using IW4MAdmin.Plugins.Stats.Models; -using SharedLibraryCore.Database.Models; +using SharedLibraryCore.Database.Models; using SharedLibraryCore.Helpers; using SharedLibraryCore.Interfaces; using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; +using Data.Models; +using Data.Models.Client; +using Data.Models.Client.Stats; using Microsoft.Extensions.Logging; +using SharedLibraryCore; using ILogger = Microsoft.Extensions.Logging.ILogger; namespace IW4MAdmin.Plugins.Stats.Cheat @@ -66,6 +69,33 @@ namespace IW4MAdmin.Plugins.Stats.Cheat Tracker = new ChangeTracking(); TrackedHits = new List(); } + + private static double SnapDistance(Vector3 a, Vector3 b, Vector3 c) + { + a = a.FixIW4Angles(); + b = b.FixIW4Angles(); + c = c.FixIW4Angles(); + + + float preserveDirectionAngle(float a1, float b1) + { + float difference = b1 - a1; + while (difference < -180) difference += 360; + while (difference > 180) difference -= 360; + return difference; + } + + var directions = new[] + { + new Vector3(preserveDirectionAngle(b.X, a.X),preserveDirectionAngle(b.Y, a.Y), 0), + new Vector3( preserveDirectionAngle(c.X, b.X), preserveDirectionAngle(c.Y, b.Y), 0) + }; + + var distance = new Vector3(Math.Abs(directions[1].X - directions[0].X), + Math.Abs(directions[1].Y - directions[0].Y), 0); + + return Math.Sqrt((distance.X * distance.X) + (distance.Y * distance.Y)); + } /// /// Analyze kill and see if performed by a cheater @@ -76,12 +106,12 @@ namespace IW4MAdmin.Plugins.Stats.Cheat { var results = new List(); - if ((hit.DeathType != IW4Info.MeansOfDeath.MOD_PISTOL_BULLET && - hit.DeathType != IW4Info.MeansOfDeath.MOD_RIFLE_BULLET && - hit.DeathType != IW4Info.MeansOfDeath.MOD_HEAD_SHOT) || - hit.HitLoc == IW4Info.HitLocation.none || hit.TimeOffset - LastOffset < 0 || + if ((hit.DeathType != (int)IW4Info.MeansOfDeath.MOD_PISTOL_BULLET && + hit.DeathType != (int)IW4Info.MeansOfDeath.MOD_RIFLE_BULLET && + hit.DeathType != (int)IW4Info.MeansOfDeath.MOD_HEAD_SHOT) || + hit.HitLoc == (int)IW4Info.HitLocation.none || hit.TimeOffset - LastOffset < 0 || // hack: prevents false positives - (LastWeapon != hit.Weapon && (hit.TimeOffset - LastOffset) == 50)) + ((int)LastWeapon != hit.Weapon && (hit.TimeOffset - LastOffset) == 50)) { return new[] {new DetectionPenaltyResult() { @@ -89,9 +119,9 @@ namespace IW4MAdmin.Plugins.Stats.Cheat }}; } - LastWeapon = hit.Weapon; + LastWeapon = (IW4Info.WeaponName)(hit.Weapon); - HitLocationCount[hit.HitLoc].Count++; + HitLocationCount[(IW4Info.HitLocation)hit.HitLoc].Count++; HitCount++; if (hit.IsKill) @@ -116,7 +146,7 @@ namespace IW4MAdmin.Plugins.Stats.Cheat { ClientStats.SnapHitCount++; sessionSnapHits++; - var currentSnapDistance = Vector3.SnapDistance(hit.AnglesList[0], hit.AnglesList[1], hit.ViewAngles); + var currentSnapDistance = SnapDistance(hit.AnglesList[0], hit.AnglesList[1], hit.ViewAngles); double previousAverage = ClientStats.AverageSnapValue; ClientStats.AverageSnapValue = (previousAverage * (ClientStats.SnapHitCount - 1) + currentSnapDistance) / ClientStats.SnapHitCount; double previousSessionAverage = sessionAverageSnapAmount; @@ -211,7 +241,7 @@ namespace IW4MAdmin.Plugins.Stats.Cheat } // SESSION - var sessionHitLoc = HitLocationCount[hit.HitLoc]; + var sessionHitLoc = HitLocationCount[(IW4Info.HitLocation)hit.HitLoc]; sessionHitLoc.Offset = (sessionHitLoc.Offset * (sessionHitLoc.Count - 1) + realAgainstPredict) / sessionHitLoc.Count; int totalSessionHits = HitLocationCount.Sum(_hit => _hit.Value.Count); @@ -229,7 +259,7 @@ namespace IW4MAdmin.Plugins.Stats.Cheat Value = weightedSessionAverage, HitCount = HitCount, Type = DetectionType.Offset, - Location = hitLoc.Location + Location = (IW4Info.HitLocation)hitLoc.Location }); } @@ -278,8 +308,8 @@ namespace IW4MAdmin.Plugins.Stats.Cheat bool shouldIgnoreDetection = false; try { - shouldIgnoreDetection = Plugin.Config.Configuration().AnticheatConfiguration.IgnoredDetectionSpecification[hit.GameName][DetectionType.Recoil] - .Any(_weaponRegex => Regex.IsMatch(hit.Weapon.ToString(), _weaponRegex)); + shouldIgnoreDetection = Plugin.Config.Configuration().AnticheatConfiguration.IgnoredDetectionSpecification[(Server.Game)hit.GameName][DetectionType.Recoil] + .Any(_weaponRegex => Regex.IsMatch(((IW4Info.WeaponName)(hit.Weapon)).ToString(), _weaponRegex)); } catch (KeyNotFoundException) @@ -310,8 +340,8 @@ namespace IW4MAdmin.Plugins.Stats.Cheat try { shouldIgnoreDetection = false; - shouldIgnoreDetection = Plugin.Config.Configuration().AnticheatConfiguration.IgnoredDetectionSpecification[hit.GameName][DetectionType.Button] - .Any(_weaponRegex => Regex.IsMatch(hit.Weapon.ToString(), _weaponRegex)); + shouldIgnoreDetection = Plugin.Config.Configuration().AnticheatConfiguration.IgnoredDetectionSpecification[(Server.Game)hit.GameName][DetectionType.Button] + .Any(_weaponRegex => Regex.IsMatch(((IW4Info.WeaponName)(hit.Weapon)).ToString(), _weaponRegex)); } catch (KeyNotFoundException) @@ -423,8 +453,8 @@ namespace IW4MAdmin.Plugins.Stats.Cheat try { shouldIgnoreDetection = false; // reset previous value - shouldIgnoreDetection = Plugin.Config.Configuration().AnticheatConfiguration.IgnoredDetectionSpecification[hit.GameName][DetectionType.Chest] - .Any(_weaponRegex => Regex.IsMatch(hit.Weapon.ToString(), _weaponRegex)); + shouldIgnoreDetection = Plugin.Config.Configuration().AnticheatConfiguration.IgnoredDetectionSpecification[(Server.Game)hit.GameName][DetectionType.Chest] + .Any(_weaponRegex => Regex.IsMatch(((IW4Info.WeaponName)(hit.Weapon)).ToString(), _weaponRegex)); } catch (KeyNotFoundException) diff --git a/Plugins/Stats/Cheat/DetectionPenaltyResult.cs b/Plugins/Stats/Cheat/DetectionPenaltyResult.cs index 1f1edf2d..ae9be54d 100644 --- a/Plugins/Stats/Cheat/DetectionPenaltyResult.cs +++ b/Plugins/Stats/Cheat/DetectionPenaltyResult.cs @@ -1,4 +1,4 @@ -using SharedLibraryCore.Database.Models; +using Data.Models; namespace IW4MAdmin.Plugins.Stats.Cheat { diff --git a/Plugins/Stats/Cheat/Strain.cs b/Plugins/Stats/Cheat/Strain.cs index 7fe4b1d5..e06caf22 100644 --- a/Plugins/Stats/Cheat/Strain.cs +++ b/Plugins/Stats/Cheat/Strain.cs @@ -1,9 +1,6 @@ using SharedLibraryCore; -using SharedLibraryCore.Helpers; -using SharedLibraryCore.Interfaces; using System; -using System.Collections.Generic; -using System.Text; +using Data.Models; namespace IW4MAdmin.Plugins.Stats.Cheat { diff --git a/Plugins/Stats/Cheat/Thresholds.cs b/Plugins/Stats/Cheat/Thresholds.cs index 37f2c960..f9b0fa94 100644 --- a/Plugins/Stats/Cheat/Thresholds.cs +++ b/Plugins/Stats/Cheat/Thresholds.cs @@ -1,19 +1,19 @@ using Stats.Config; using System; -using static SharedLibraryCore.Database.Models.EFPenalty; +using Data.Models; namespace IW4MAdmin.Plugins.Stats.Cheat { public static class DistributionHelper { - public static double CalculateMaxValue(this DistributionConfiguration config, PenaltyType penaltyType, int sampleSize) + public static double CalculateMaxValue(this DistributionConfiguration config, EFPenalty.PenaltyType penaltyType, int sampleSize) { switch (config.Type) { case DistributionConfiguration.DistributionType.Normal: break; case DistributionConfiguration.DistributionType.LogNormal: - double deviationNumber = penaltyType == PenaltyType.Flag ? 3.0 : 4.0; + double deviationNumber = penaltyType == EFPenalty.PenaltyType.Flag ? 3.0 : 4.0; double marginOfError = 1.644 / (config.StandardDeviation / Math.Sqrt(sampleSize)); double maxValue = (config.StandardDeviation * deviationNumber) + marginOfError; return maxValue; diff --git a/Plugins/Stats/Client/Abstractions/IClientStatisticCalculator.cs b/Plugins/Stats/Client/Abstractions/IClientStatisticCalculator.cs new file mode 100644 index 00000000..872278b9 --- /dev/null +++ b/Plugins/Stats/Client/Abstractions/IClientStatisticCalculator.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; +using SharedLibraryCore; + +namespace IW4MAdmin.Plugins.Stats.Client.Abstractions +{ + public interface IClientStatisticCalculator + { + Task GatherDependencies(); + Task CalculateForEvent(GameEvent gameEvent); + } +} \ No newline at end of file diff --git a/Plugins/Stats/Client/Abstractions/IHitInfoBuilder.cs b/Plugins/Stats/Client/Abstractions/IHitInfoBuilder.cs new file mode 100644 index 00000000..93ff90c0 --- /dev/null +++ b/Plugins/Stats/Client/Abstractions/IHitInfoBuilder.cs @@ -0,0 +1,10 @@ +using IW4MAdmin.Plugins.Stats.Client.Game; +using SharedLibraryCore; + +namespace Stats.Client.Abstractions +{ + public interface IHitInfoBuilder + { + HitInfo Build(string[] log, int entityId, bool isSelf, bool isVictim, Server.Game gameName); + } +} \ No newline at end of file diff --git a/Plugins/Stats/Client/Abstractions/IServerDistributionCalculator.cs b/Plugins/Stats/Client/Abstractions/IServerDistributionCalculator.cs new file mode 100644 index 00000000..9630c123 --- /dev/null +++ b/Plugins/Stats/Client/Abstractions/IServerDistributionCalculator.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; + +namespace Stats.Client.Abstractions +{ + public interface IServerDistributionCalculator + { + Task Initialize(); + Task GetZScoreForServer(long serverId, double value); + Task GetRatingForZScore(double? value); + } +} \ No newline at end of file diff --git a/Plugins/Stats/Client/Abstractions/IWeaponNameParser.cs b/Plugins/Stats/Client/Abstractions/IWeaponNameParser.cs new file mode 100644 index 00000000..17367af1 --- /dev/null +++ b/Plugins/Stats/Client/Abstractions/IWeaponNameParser.cs @@ -0,0 +1,10 @@ +using SharedLibraryCore; +using Stats.Client.Game; + +namespace Stats.Client.Abstractions +{ + public interface IWeaponNameParser + { + WeaponInfo Parse(string weaponName, Server.Game gameName); + } +} diff --git a/Plugins/Stats/Client/Game/AttachmentInfo.cs b/Plugins/Stats/Client/Game/AttachmentInfo.cs new file mode 100644 index 00000000..8b60870a --- /dev/null +++ b/Plugins/Stats/Client/Game/AttachmentInfo.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Stats.Client.Game +{ + public class AttachmentInfo + { + public string Name { get; set; } + } +} diff --git a/Plugins/Stats/Client/Game/HitInfo.cs b/Plugins/Stats/Client/Game/HitInfo.cs new file mode 100644 index 00000000..55d0dcb3 --- /dev/null +++ b/Plugins/Stats/Client/Game/HitInfo.cs @@ -0,0 +1,27 @@ +using Data.Models; +using Stats.Client.Game; + +namespace IW4MAdmin.Plugins.Stats.Client.Game +{ + public enum HitType + { + Unknown, + Kill, + Damage, + WasKilled, + WasDamaged, + Suicide + } + + public class HitInfo + { + public Reference.Game Game { get; set; } + public int EntityId { get; set; } + public bool IsVictim { get; set; } + public HitType HitType { get; set; } + public int Damage { get; set; } + public string Location { get; set; } + public string MeansOfDeath { get; set; } + public WeaponInfo Weapon { get; set; } + } +} \ No newline at end of file diff --git a/Plugins/Stats/Client/Game/WeaponInfo.cs b/Plugins/Stats/Client/Game/WeaponInfo.cs new file mode 100644 index 00000000..09aea1b1 --- /dev/null +++ b/Plugins/Stats/Client/Game/WeaponInfo.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace Stats.Client.Game +{ + public class WeaponInfo + { + public string RawName { get; set; } + public string Name { get; set; } + public IList Attachments { get; set; } = new List(); + } +} diff --git a/Plugins/Stats/Client/HitCalculator.cs b/Plugins/Stats/Client/HitCalculator.cs new file mode 100644 index 00000000..8b23a0a4 --- /dev/null +++ b/Plugins/Stats/Client/HitCalculator.cs @@ -0,0 +1,611 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Data.Abstractions; +using Data.Models; +using Data.Models.Client.Stats; +using Data.Models.Client.Stats.Reference; +using Data.Models.Server; +using IW4MAdmin.Plugins.Stats.Client.Abstractions; +using IW4MAdmin.Plugins.Stats.Client.Game; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using SharedLibraryCore; +using SharedLibraryCore.Database.Models; +using Stats.Client.Abstractions; +using Stats.Client.Game; + +namespace IW4MAdmin.Plugins.Stats.Client +{ + public class HitState + { + public HitState() + { + OnTransaction = new SemaphoreSlim(1, 1); + } + + ~HitState() + { + OnTransaction.Dispose(); + } + + public List Hits { get; set; } + public DateTime? LastUsage { get; set; } + public int? LastWeaponId { get; set; } + public EFServer Server { get; set; } + public SemaphoreSlim OnTransaction { get; } + public int UpdateCount { get; set; } + } + + public class HitCalculator : IClientStatisticCalculator + { + private readonly IDatabaseContextFactory _contextFactory; + private readonly ILogger _logger; + + private readonly ConcurrentDictionary _clientHitStatistics = + new ConcurrentDictionary(); + + private readonly SemaphoreSlim _onTransaction = new SemaphoreSlim(1, 1); + + private readonly ILookupCache _serverCache; + private readonly ILookupCache _hitLocationCache; + private readonly ILookupCache _weaponCache; + private readonly ILookupCache _attachmentCache; + private readonly ILookupCache _attachmentComboCache; + private readonly ILookupCache _modCache; + private readonly IHitInfoBuilder _hitInfoBuilder; + private readonly IServerDistributionCalculator _serverDistributionCalculator; + + private readonly TimeSpan _maxActiveTime = TimeSpan.FromMinutes(2); + private const int MaxUpdatesBeforePersist = 20; + private const string SessionScores = nameof(SessionScores); + + public HitCalculator(ILogger logger, IDatabaseContextFactory contextFactory, + ILookupCache hitLocationCache, ILookupCache weaponCache, + ILookupCache attachmentCache, + ILookupCache attachmentComboCache, + ILookupCache serverCache, ILookupCache modCache, IHitInfoBuilder hitInfoBuilder, + IServerDistributionCalculator serverDistributionCalculator) + { + _contextFactory = contextFactory; + _logger = logger; + _hitLocationCache = hitLocationCache; + _weaponCache = weaponCache; + _attachmentCache = attachmentCache; + _attachmentComboCache = attachmentComboCache; + _serverCache = serverCache; + _hitInfoBuilder = hitInfoBuilder; + _modCache = modCache; + _serverDistributionCalculator = serverDistributionCalculator; + } + + public async Task GatherDependencies() + { + await _hitLocationCache.InitializeAsync(); + await _weaponCache.InitializeAsync(); + await _attachmentCache.InitializeAsync(); + await _attachmentComboCache.InitializeAsync(); + await _serverCache.InitializeAsync(); + await _modCache.InitializeAsync(); + } + + public async Task CalculateForEvent(GameEvent gameEvent) + { + if (gameEvent.Type == GameEvent.EventType.Connect) + { + // if no servers have been cached yet we need to pull them here + // as they could have gotten added after we've initialized + if (!_serverCache.GetAll().Any()) + { + await _serverCache.InitializeAsync(); + } + + gameEvent.Origin.SetAdditionalProperty(SessionScores, new List<(int, DateTime)>()); + return; + } + + if (gameEvent.Type == GameEvent.EventType.Disconnect) + { + _clientHitStatistics.Remove(gameEvent.Origin.ClientId, out var state); + + if (state == null) + { + _logger.LogWarning("No client hit state available for disconnecting client {client}", + gameEvent.Origin.ToString()); + return; + } + + try + { + await state.OnTransaction.WaitAsync(); + HandleDisconnectCalculations(gameEvent.Origin, state); + await UpdateClientStatistics(gameEvent.Origin.ClientId, state); + } + + catch (Exception ex) + { + _logger.LogError(ex, "Could not handle disconnect calculations for client {client}", + gameEvent.Origin.ToString()); + } + + finally + { + if (state.OnTransaction.CurrentCount == 0) + { + state.OnTransaction.Release(); + } + } + + return; + } + + if (gameEvent.Type == GameEvent.EventType.MapEnd) + { + foreach (var client in gameEvent.Owner.GetClientsAsList()) + { + var scores = client.GetAdditionalProperty>(SessionScores); + scores?.Add((client.Score, DateTime.Now)); + } + } + + if (gameEvent.Type != GameEvent.EventType.Kill && gameEvent.Type != GameEvent.EventType.Damage) + { + return; + } + + var eventRegex = gameEvent.Type == GameEvent.EventType.Kill + ? gameEvent.Owner.EventParser.Configuration.Kill + : gameEvent.Owner.EventParser.Configuration.Damage; + + var match = eventRegex.PatternMatcher.Match(gameEvent.Data); + + if (!match.Success) + { + _logger.LogWarning("Log for event type {type} does not match pattern {logLine}", gameEvent.Type, + gameEvent.Data); + return; + } + + var attackerHitInfo = _hitInfoBuilder.Build(match.Values.Skip(1).ToArray(), gameEvent.Origin.ClientId, + gameEvent.Origin.ClientId == gameEvent.Target.ClientId, false, gameEvent.Owner.GameName); + var victimHitInfo = _hitInfoBuilder.Build(match.Values.Skip(1).ToArray(), gameEvent.Target.ClientId, + gameEvent.Origin.ClientId == gameEvent.Target.ClientId, true, gameEvent.Owner.GameName); + + foreach (var hitInfo in new[] {attackerHitInfo, victimHitInfo}) + { + try + { + await _onTransaction.WaitAsync(); + if (!_clientHitStatistics.ContainsKey(hitInfo.EntityId)) + { + _logger.LogDebug("Starting to track hits for {client}", hitInfo.EntityId); + var clientHits = await GetHitsForClient(hitInfo.EntityId); + _clientHitStatistics.TryAdd(hitInfo.EntityId, new HitState() + { + Hits = clientHits, + Server = (await _serverCache + .FirstAsync(server => + server.EndPoint == gameEvent.Owner.ToString() && server.HostName != null)) + }); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Could not retrieve previous hit data for client {client}"); + continue; + } + + finally + { + if (_onTransaction.CurrentCount == 0) + { + _onTransaction.Release(); + } + } + + var state = _clientHitStatistics[hitInfo.EntityId]; + + try + { + await _onTransaction.WaitAsync(); + var calculatedHits = await RunTasksForHitInfo(hitInfo, state.Server.ServerId); + + foreach (var clientHit in calculatedHits) + { + RunCalculation(clientHit, hitInfo, state); + } + } + + catch (Exception ex) + { + _logger.LogError(ex, "Could not update hit calculations for {client}", hitInfo.EntityId); + } + + finally + { + if (_onTransaction.CurrentCount == 0) + { + _onTransaction.Release(); + } + } + } + } + + + + private async Task> RunTasksForHitInfo(HitInfo hitInfo, long? serverId) + { + var weapon = await GetOrAddWeapon(hitInfo.Weapon, hitInfo.Game); + var attachments = + await Task.WhenAll(hitInfo.Weapon.Attachments.Select(attachment => + GetOrAddAttachment(attachment, hitInfo.Game))); + var attachmentCombo = await GetOrAddAttachmentCombo(attachments, hitInfo.Game); + var matchingLocation = await GetOrAddHitLocation(hitInfo.Location, hitInfo.Game); + var meansOfDeath = await GetOrAddMeansOfDeath(hitInfo.MeansOfDeath, hitInfo.Game); + + var baseTasks = new[] + { + // just the client + GetOrAddClientHit(hitInfo.EntityId, null), + // client and server + GetOrAddClientHit(hitInfo.EntityId, serverId), + // just the location + GetOrAddClientHit(hitInfo.EntityId, null, matchingLocation.HitLocationId), + // location and server + GetOrAddClientHit(hitInfo.EntityId, serverId, matchingLocation.HitLocationId), + // per weapon + GetOrAddClientHit(hitInfo.EntityId, null, null, weapon.WeaponId), + // per weapon and server + GetOrAddClientHit(hitInfo.EntityId, serverId, null, weapon.WeaponId), + // means of death aggregate + GetOrAddClientHit(hitInfo.EntityId, meansOfDeathId: meansOfDeath.MeansOfDeathId), + // means of death per server aggregate + GetOrAddClientHit(hitInfo.EntityId, serverId, + meansOfDeathId: meansOfDeath.MeansOfDeathId) + }; + + var allTasks = baseTasks.AsEnumerable(); + + if (attachmentCombo != null) + { + allTasks = allTasks + // per weapon per attachment combo + .Append(GetOrAddClientHit(hitInfo.EntityId, null, null, + weapon.WeaponId, attachmentCombo.WeaponAttachmentComboId)) + .Append(GetOrAddClientHit(hitInfo.EntityId, serverId, null, + weapon.WeaponId, attachmentCombo.WeaponAttachmentComboId)); + } + + return await Task.WhenAll(allTasks); + } + + private void RunCalculation(EFClientHitStatistic clientHit, HitInfo hitInfo, HitState hitState) + { + if (hitInfo.HitType == HitType.Kill || hitInfo.HitType == HitType.Damage) + { + if (clientHit.WeaponId != null) // we only want to calculate usage time for weapons + { + var timeElapsed = DateTime.Now - hitState.LastUsage; + var isSameWeapon = clientHit.WeaponId == hitState.LastWeaponId; + + clientHit.UsageSeconds ??= 60; + + if (timeElapsed.HasValue && timeElapsed <= _maxActiveTime) + { + clientHit.UsageSeconds + += // if it's the same weapon we can count the entire elapsed time + // otherwise we split it to make a best guess + (int) Math.Round(timeElapsed.Value.TotalSeconds / (isSameWeapon ? 1.0 : 2.0)); + } + + hitState.LastUsage = DateTime.Now; + } + + clientHit.DamageInflicted += hitInfo.Damage; + clientHit.HitCount++; + } + + if (hitInfo.HitType == HitType.Kill) + { + clientHit.KillCount++; + } + + if (hitInfo.HitType == HitType.WasKilled || hitInfo.HitType == HitType.WasDamaged || + hitInfo.HitType == HitType.Suicide) + { + clientHit.ReceivedHitCount++; + clientHit.DamageReceived += hitInfo.Damage; + } + + if (hitInfo.HitType == HitType.WasKilled) + { + clientHit.DeathCount++; + } + } + + private async Task> GetHitsForClient(int clientId) + { + try + { + await using var context = _contextFactory.CreateContext(); + var hitLocations = await context.Set() + .Where(stat => stat.ClientId == clientId) + .ToListAsync(); + + return !hitLocations.Any() ? new List() : hitLocations; + } + catch (Exception ex) + { + _logger.LogError(ex, "Could not retrieve {hitName} for client with id {id}", + nameof(EFClientHitStatistic), clientId); + } + + return new List(); + } + + private async Task UpdateClientStatistics(int clientId, HitState locState = null) + { + if (!_clientHitStatistics.ContainsKey(clientId) && locState == null) + { + _logger.LogError("No {statsName} found for id {id}", nameof(EFClientHitStatistic), clientId); + return; + } + + var state = locState ?? _clientHitStatistics[clientId]; + + try + { + await using var context = _contextFactory.CreateContext(); + context.Set().UpdateRange(state.Hits); + await context.SaveChangesAsync(); + } + + catch (Exception ex) + { + _logger.LogError(ex, "Could not update hit location stats for id {id}", clientId); + } + } + + private async Task GetOrAddClientHit(int clientId, long? serverId = null, + int? hitLocationId = null, int? weaponId = null, int? attachmentComboId = null, + int? meansOfDeathId = null) + { + var state = _clientHitStatistics[clientId]; + await state.OnTransaction.WaitAsync(); + + var hitStat = state.Hits + .FirstOrDefault(hit => hit.HitLocationId == hitLocationId + && hit.WeaponId == weaponId + && hit.WeaponAttachmentComboId == attachmentComboId + && hit.MeansOfDeathId == meansOfDeathId + && hit.ServerId == serverId); + + if (hitStat != null) + { + state.OnTransaction.Release(); + return hitStat; + } + + hitStat = new EFClientHitStatistic() + { + ClientId = clientId, + ServerId = serverId, + WeaponId = weaponId, + WeaponAttachmentComboId = attachmentComboId, + HitLocationId = hitLocationId, + MeansOfDeathId = meansOfDeathId + }; + + try + { + /*if (state.UpdateCount > MaxUpdatesBeforePersist) + { + await UpdateClientStatistics(clientId); + state.UpdateCount = 0; + } + + state.UpdateCount++;*/ + state.Hits.Add(hitStat); + } + catch (Exception ex) + { + _logger.LogError(ex, "Could not add {statsName} for {id}", nameof(EFClientHitStatistic), + clientId); + state.Hits.Remove(hitStat); + } + finally + { + if (state.OnTransaction.CurrentCount == 0) + { + state.OnTransaction.Release(); + } + } + + return hitStat; + } + + private async Task GetOrAddHitLocation(string location, Reference.Game game) + { + var matchingLocation = (await _hitLocationCache + .FirstAsync(loc => loc.Name == location && loc.Game == game)); + + if (matchingLocation != null) + { + return matchingLocation; + } + + var hitLocation = new EFHitLocation() + { + Name = location, + Game = game + }; + + hitLocation = await _hitLocationCache.AddAsync(hitLocation); + + return hitLocation; + } + + private async Task GetOrAddWeapon(WeaponInfo weapon, Reference.Game game) + { + var matchingWeapon = (await _weaponCache + .FirstAsync(wep => wep.Name == weapon.Name && wep.Game == game)); + + if (matchingWeapon != null) + { + return matchingWeapon; + } + + matchingWeapon = new EFWeapon() + { + Name = weapon.Name, + Game = game + }; + + matchingWeapon = await _weaponCache.AddAsync(matchingWeapon); + + return matchingWeapon; + } + + private async Task GetOrAddAttachment(AttachmentInfo attachment, Reference.Game game) + { + var matchingAttachment = (await _attachmentCache + .FirstAsync(attach => attach.Name == attachment.Name && attach.Game == game)); + + if (matchingAttachment != null) + { + return matchingAttachment; + } + + matchingAttachment = new EFWeaponAttachment() + { + Name = attachment.Name, + Game = game + }; + + matchingAttachment = await _attachmentCache.AddAsync(matchingAttachment); + + return matchingAttachment; + } + + private async Task GetOrAddAttachmentCombo(EFWeaponAttachment[] attachments, + Reference.Game game) + { + if (!attachments.Any()) + { + return null; + } + + var allAttachments = attachments.ToList(); + + if (allAttachments.Count() < 3) + { + for (var i = allAttachments.Count(); i <= 3; i++) + { + allAttachments.Add(null); + } + } + + var matchingAttachmentCombo = (await _attachmentComboCache.FirstAsync(combo => + combo.Game == game + && combo.Attachment1Id == allAttachments[0].Id + && combo.Attachment2Id == allAttachments[1]?.Id + && combo.Attachment3Id == allAttachments[2]?.Id)); + + if (matchingAttachmentCombo != null) + { + return matchingAttachmentCombo; + } + + matchingAttachmentCombo = new EFWeaponAttachmentCombo() + { + Game = game, + Attachment1Id = (int) allAttachments[0].Id, + Attachment2Id = (int?) allAttachments[1]?.Id, + Attachment3Id = (int?) allAttachments[2]?.Id, + }; + + matchingAttachmentCombo = await _attachmentComboCache.AddAsync(matchingAttachmentCombo); + + return matchingAttachmentCombo; + } + + private async Task GetOrAddMeansOfDeath(string meansOfDeath, Reference.Game game) + { + var matchingMod = (await _modCache + .FirstAsync(mod => mod.Name == meansOfDeath && mod.Game == game)); + + if (matchingMod != null) + { + return matchingMod; + } + + var mod = new EFMeansOfDeath() + { + Name = meansOfDeath, + Game = game + }; + + mod = await _modCache.AddAsync(mod); + + return mod; + } + + private void HandleDisconnectCalculations(EFClient client, HitState state) + { + // todo: this not added to states fast connect/disconnect + var serverStats = state.Hits.FirstOrDefault(stat => + stat.ServerId == state.Server.ServerId && stat.WeaponId == null && + stat.WeaponAttachmentComboId == null && stat.HitLocationId == null && stat.MeansOfDeathId == null); + + if (serverStats == null) + { + _logger.LogWarning("No server hits were found for {serverId} on disconnect for {client}", + state.Server.ServerId, client.ToString()); + return; + } + + var aggregate = state.Hits.FirstOrDefault(stat => stat.WeaponId == null && + stat.WeaponAttachmentComboId == null && + stat.HitLocationId == null && + stat.MeansOfDeathId == null && + stat.ServerId == null); + + if (aggregate == null) + { + _logger.LogWarning("No aggregate found for {serverId} on disconnect for {client}", + state.Server.ServerId, client.ToString()); + return; + } + + var sessionScores = client.GetAdditionalProperty>(SessionScores); + + if (sessionScores == null) + { + _logger.LogWarning($"No session scores available for {client}"); + return; + } + + foreach (var stat in new[] {serverStats, aggregate}) + { + stat.Score ??= 0; + + if (sessionScores.Count == 0) + { + stat.Score += client.Score; + } + + else + { + stat.Score += sessionScores.Sum(item => item.Item1) + + (sessionScores.Last().Item1 == client.Score && + (DateTime.Now - sessionScores.Last().Item2).TotalMinutes < 1 + ? 0 + : client.Score); + } + } + } + } +} \ No newline at end of file diff --git a/Plugins/Stats/Client/HitInfoBuilder.cs b/Plugins/Stats/Client/HitInfoBuilder.cs new file mode 100644 index 00000000..e203b3b4 --- /dev/null +++ b/Plugins/Stats/Client/HitInfoBuilder.cs @@ -0,0 +1,64 @@ +using System; +using System.Linq; +using Data.Models; +using IW4MAdmin.Plugins.Stats.Client.Game; +using Microsoft.Extensions.Logging; +using SharedLibraryCore; +using SharedLibraryCore.Interfaces; +using Stats.Client.Abstractions; +using ILogger = Microsoft.Extensions.Logging.ILogger; + +namespace Stats.Client +{ + public class HitInfoBuilder : IHitInfoBuilder + { + private readonly IWeaponNameParser _weaponNameParser; + private readonly ILogger _logger; + private const int MaximumDamage = 1000; + + public HitInfoBuilder(ILogger logger, IWeaponNameParser weaponNameParser) + { + _weaponNameParser = weaponNameParser; + _logger = logger; + } + + public HitInfo Build(string[] log, int entityId, bool isSelf, bool isVictim, Server.Game gameName) + { + var eventType = log[(uint) ParserRegex.GroupType.EventType].First(); + HitType hitType; + + if (isVictim) + { + if (isSelf) + { + hitType = HitType.Suicide; + } + + else + { + hitType = eventType == 'D' ? HitType.WasDamaged : HitType.WasKilled; + } + } + + else + { + hitType = eventType == 'D' ? HitType.Damage : HitType.Kill; + } + + var hitInfo = new HitInfo() + { + EntityId = entityId, + IsVictim = isVictim, + HitType = hitType, + Damage = Math.Min(MaximumDamage, int.Parse(log[(uint) ParserRegex.GroupType.Damage])), + Location = log[(uint) ParserRegex.GroupType.HitLocation], + Weapon = _weaponNameParser.Parse(log[(uint) ParserRegex.GroupType.Weapon], gameName), + MeansOfDeath = log[(uint)ParserRegex.GroupType.MeansOfDeath], + Game = (Reference.Game)gameName + }; + + //_logger.LogDebug("Generated new hitInfo {@hitInfo}", hitInfo); + return hitInfo; + } + } +} \ No newline at end of file diff --git a/Plugins/Stats/Client/ServerDistributionCalculator.cs b/Plugins/Stats/Client/ServerDistributionCalculator.cs new file mode 100644 index 00000000..aa54753f --- /dev/null +++ b/Plugins/Stats/Client/ServerDistributionCalculator.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Data.Abstractions; +using Data.Models.Client; +using Data.Models.Client.Stats; +using IW4MAdmin.Plugins.Stats; +using IW4MAdmin.Plugins.Stats.Config; +using Microsoft.EntityFrameworkCore; +using SharedLibraryCore; +using SharedLibraryCore.Interfaces; +using Stats.Client.Abstractions; +using Stats.Helpers; + +namespace Stats.Client +{ + public class ServerDistributionCalculator : IServerDistributionCalculator + { + private readonly IDatabaseContextFactory _contextFactory; + + private readonly IDataValueCache> + _distributionCache; + + private readonly IDataValueCache + _maxZScoreCache; + + private readonly IConfigurationHandler _configurationHandler; + private readonly List _serverIds = new List(); + + private const string DistributionCacheKey = nameof(DistributionCacheKey); + private const string MaxZScoreCacheKey = nameof(MaxZScoreCacheKey); + + public ServerDistributionCalculator(IDatabaseContextFactory contextFactory, + IDataValueCache> distributionCache, + IDataValueCache maxZScoreCache, + IConfigurationHandlerFactory configFactory) + { + _contextFactory = contextFactory; + _distributionCache = distributionCache; + _maxZScoreCache = maxZScoreCache; + _configurationHandler = configFactory.GetConfigurationHandler("StatsPluginSettings"); + } + + public async Task Initialize() + { + await LoadServers(); + _distributionCache.SetCacheItem((async set => + { + var validPlayTime = _configurationHandler.Configuration()?.TopPlayersMinPlayTime ?? 3600 * 3; + + var distributions = new Dictionary(); + + await LoadServers(); + + foreach (var serverId in _serverIds) + { + var performance = await set + .Where(s => s.ServerId == serverId) + .Where(s => s.Skill > 0) + .Where(s => s.EloRating > 0) + .Where(s => s.Client.Level != EFClient.Permission.Banned) + .Where(s => s.TimePlayed >= validPlayTime) + .Where(s => s.UpdatedAt >= Extensions.FifteenDaysAgo()) + .Select(s => s.EloRating * 1/3.0 + s.Skill * 2/3.0).ToListAsync(); + var distributionParams = performance.GenerateDistributionParameters(); + distributions.Add(serverId, distributionParams); + } + + return distributions; + }), DistributionCacheKey, Utilities.IsDevelopment ? TimeSpan.FromMinutes(5) : TimeSpan.FromHours(1)); + + _maxZScoreCache.SetCacheItem(async set => + { + var validPlayTime = _configurationHandler.Configuration()?.TopPlayersMinPlayTime ?? 3600 * 3; + + var zScore = await set + .Where(AdvancedClientStatsResourceQueryHelper.GetRankingFunc(validPlayTime)) + .Where(s => s.Skill > 0) + .Where(s => s.EloRating > 0) + .MaxAsync(s => (double?)s.ZScore); + return zScore ?? 0; + }, MaxZScoreCacheKey, Utilities.IsDevelopment ? TimeSpan.FromMinutes(5) : TimeSpan.FromMinutes(30)); + + await _distributionCache.GetCacheItem(DistributionCacheKey); + await _maxZScoreCache.GetCacheItem(MaxZScoreCacheKey); + + /*foreach (var serverId in _serverIds) + { + await using var ctx = _contextFactory.CreateContext(enableTracking: true); + + var a = await ctx.Set() + .Where(s => s.ServerId == serverId) + //.Where(s=> s.ClientId == 216105) + .Where(s => s.Skill > 0) + .Where(s => s.EloRating > 0) + .Where(s => s.Client.Level != EFClient.Permission.Banned) + .Where(s => s.TimePlayed >= 3600 * 3) + .Where(s => s.UpdatedAt >= Extensions.FifteenDaysAgo()) + .ToListAsync(); + + var b = a.Distinct(); + + foreach (var item in b) + { + await Plugin.Manager.UpdateHistoricalRanking(item.ClientId, item, item.ServerId); + //item.ZScore = await GetZScoreForServer(serverId, item.Performance); + //item.UpdatedAt = DateTime.UtcNow; + } + + await ctx.SaveChangesAsync(); + }*/ + } + + private async Task LoadServers() + { + if (_serverIds.Count == 0) + { + await using var context = _contextFactory.CreateContext(false); + _serverIds.AddRange(await context.Servers + .Where(s => s.EndPoint != null && s.HostName != null) + .Select(s => s.ServerId) + .ToListAsync()); + } + } + + public async Task GetZScoreForServer(long serverId, double value) + { + var serverParams = await _distributionCache.GetCacheItem(DistributionCacheKey); + if (!serverParams.ContainsKey(serverId)) + { + return 0.0; + } + + var sdParams = serverParams[serverId]; + if (sdParams.Sigma == 0) + { + return 0.0; + } + var zScore = (Math.Log(value) - sdParams.Mean) / sdParams.Sigma; + return zScore; + } + + public async Task GetRatingForZScore(double? value) + { + var maxZScore = await _maxZScoreCache.GetCacheItem(MaxZScoreCacheKey); + return maxZScore == 0 ? 0 : value.GetRatingForZScore(maxZScore); + } + } +} \ No newline at end of file diff --git a/Plugins/Stats/Client/WeaponNameParser.cs b/Plugins/Stats/Client/WeaponNameParser.cs new file mode 100644 index 00000000..62e1503f --- /dev/null +++ b/Plugins/Stats/Client/WeaponNameParser.cs @@ -0,0 +1,75 @@ +using Microsoft.Extensions.Logging; +using Stats.Client.Abstractions; +using Stats.Client.Game; +using System.Collections.Generic; +using System.Linq; +using IW4MAdmin.Plugins.Stats.Config; +using SharedLibraryCore; +using SharedLibraryCore.Interfaces; +using ILogger = Microsoft.Extensions.Logging.ILogger; + +namespace Stats.Client +{ + public class WeaponNameParser : IWeaponNameParser + { + private readonly ILogger _logger; + private readonly StatsConfiguration _config; + + public WeaponNameParser(ILogger logger, IConfigurationHandler config) + { + _logger = logger; + _config = config.Configuration(); + } + + public WeaponInfo Parse(string weaponName, Server.Game gameName) + { + var configForGame = _config.WeaponNameParserConfigurations + ?.FirstOrDefault(config => config.Game == gameName); + + if (configForGame == null) + { + _logger.LogWarning("No weapon parser config available for game {game}", gameName); + return new WeaponInfo() + { + Name = "Unknown" + }; + } + + var splitWeaponName = weaponName.Split(configForGame.Delimiters); + + if (!splitWeaponName.Any()) + { + _logger.LogError("Could not parse weapon name {weapon}", weaponName); + + return new WeaponInfo() + { + Name = "Unknown" + }; + } + + // remove the _mp suffix + var filtered = splitWeaponName.Where(part => part != configForGame.WeaponSuffix); + var baseName = splitWeaponName.First(); + var attachments = new List(); + + if (filtered.Count() > 1) + { + attachments.AddRange(filtered.Skip(1)); + } + + var weaponInfo = new WeaponInfo() + { + RawName = weaponName, + Name = baseName, + Attachments = attachments.Select(attachment => new AttachmentInfo() + { + Name = attachment + }).ToList() + }; + + // _logger.LogDebug("Parsed weapon info {@info}", weaponInfo); + + return weaponInfo; + } + } +} \ No newline at end of file diff --git a/Plugins/Stats/Commands/MostKillsCommand.cs b/Plugins/Stats/Commands/MostKillsCommand.cs index 71d081cc..b6f34294 100644 --- a/Plugins/Stats/Commands/MostKillsCommand.cs +++ b/Plugins/Stats/Commands/MostKillsCommand.cs @@ -3,8 +3,9 @@ using System; using System.Linq; using System.Threading.Tasks; using SharedLibraryCore; -using IW4MAdmin.Plugins.Stats.Models; using System.Collections.Generic; +using Data.Abstractions; +using Data.Models.Client.Stats; using SharedLibraryCore.Database.Models; using SharedLibraryCore.Configuration; using SharedLibraryCore.Interfaces; diff --git a/Plugins/Stats/Commands/MostPlayedCommand.cs b/Plugins/Stats/Commands/MostPlayedCommand.cs index 9ad77736..b93ebc28 100644 --- a/Plugins/Stats/Commands/MostPlayedCommand.cs +++ b/Plugins/Stats/Commands/MostPlayedCommand.cs @@ -4,9 +4,9 @@ using System.Linq; using System.Threading.Tasks; using SharedLibraryCore; -using IW4MAdmin.Plugins.Stats.Models; -using SharedLibraryCore.Database; using System.Collections.Generic; +using Data.Abstractions; +using Data.Models.Client.Stats; using SharedLibraryCore.Database.Models; using IW4MAdmin.Plugins.Stats.Helpers; using SharedLibraryCore.Configuration; diff --git a/Plugins/Stats/Commands/ResetStats.cs b/Plugins/Stats/Commands/ResetStats.cs index 320b319c..69395cea 100644 --- a/Plugins/Stats/Commands/ResetStats.cs +++ b/Plugins/Stats/Commands/ResetStats.cs @@ -1,12 +1,12 @@ -using IW4MAdmin.Plugins.Stats.Models; -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; using SharedLibraryCore; using SharedLibraryCore.Configuration; -using SharedLibraryCore.Database; using SharedLibraryCore.Database.Models; using SharedLibraryCore.Interfaces; using System.Linq; using System.Threading.Tasks; +using Data.Abstractions; +using Data.Models.Client.Stats; namespace IW4MAdmin.Plugins.Stats.Commands { diff --git a/Plugins/Stats/Commands/TopStats.cs b/Plugins/Stats/Commands/TopStats.cs index 19b33f99..81a9a05b 100644 --- a/Plugins/Stats/Commands/TopStats.cs +++ b/Plugins/Stats/Commands/TopStats.cs @@ -4,9 +4,9 @@ using System.Linq; using System.Threading.Tasks; using SharedLibraryCore; -using IW4MAdmin.Plugins.Stats.Models; -using SharedLibraryCore.Database; using System.Collections.Generic; +using Data.Abstractions; +using Data.Models.Client.Stats; using SharedLibraryCore.Database.Models; using IW4MAdmin.Plugins.Stats.Helpers; using SharedLibraryCore.Configuration; @@ -16,7 +16,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands { class TopStats : Command { - public static async Task> GetTopStats(Server s, ITranslationLookup translationLookup, IDatabaseContextFactory contextFactory) + public static async Task> GetTopStats(Server s, ITranslationLookup translationLookup) { long serverId = StatManager.GetIdForServer(s); var topStatsText = new List() @@ -24,30 +24,8 @@ namespace IW4MAdmin.Plugins.Stats.Commands $"^5--{translationLookup["PLUGINS_STATS_COMMANDS_TOP_TEXT"]}--" }; - await using var context = contextFactory.CreateContext(false); - var fifteenDaysAgo = DateTime.UtcNow.AddDays(-15); - int minPlayTime = Plugin.Config.Configuration().TopPlayersMinPlayTime; - - var iqStats = (from stats in context.Set() - join client in context.Clients - on stats.ClientId equals client.ClientId - join alias in context.Aliases - on client.CurrentAliasId equals alias.AliasId - where stats.ServerId == serverId - where stats.TimePlayed >= minPlayTime - where client.Level != EFClient.Permission.Banned - where client.LastConnection >= fifteenDaysAgo - orderby (stats.EloRating + stats.Skill) / 2.0d descending - select new - { - stats.KDR, - stats.Performance, - alias.Name - }) - .Take(5); - - var statsList = (await iqStats.ToListAsync()) - .Select(stats => $"^3{stats.Name}^7 - ^5{stats.KDR} ^7{translationLookup["PLUGINS_STATS_TEXT_KDR"]} | ^5{stats.Performance} ^7{translationLookup["PLUGINS_STATS_COMMANDS_PERFORMANCE"]}"); + var stats = await Plugin.Manager.GetTopStats(0, 5, serverId); + var statsList = stats.Select(stats => $"^3{stats.Name}^7 - ^5{stats.KDR} ^7{translationLookup["PLUGINS_STATS_TEXT_KDR"]} | ^5{stats.Performance} ^7{translationLookup["PLUGINS_STATS_COMMANDS_PERFORMANCE"]}"); topStatsText.AddRange(statsList); @@ -81,7 +59,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands public override async Task ExecuteAsync(GameEvent E) { - var topStats = await GetTopStats(E.Owner, _translationLookup, _contextFactory); + var topStats = await GetTopStats(E.Owner, _translationLookup); if (!E.Message.IsBroadcastCommand(_config.BroadcastCommandPrefix)) { foreach (var stat in topStats) diff --git a/Plugins/Stats/Commands/ViewStats.cs b/Plugins/Stats/Commands/ViewStats.cs index 2ace6997..96c409f4 100644 --- a/Plugins/Stats/Commands/ViewStats.cs +++ b/Plugins/Stats/Commands/ViewStats.cs @@ -1,8 +1,8 @@ using SharedLibraryCore; -using IW4MAdmin.Plugins.Stats.Models; using System.Linq; using System.Threading.Tasks; -using SharedLibraryCore.Database; +using Data.Abstractions; +using Data.Models.Client.Stats; using Microsoft.EntityFrameworkCore; using IW4MAdmin.Plugins.Stats.Helpers; using SharedLibraryCore.Database.Models; @@ -56,7 +56,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands // getting stats for a particular client if (E.Target != null) { - var performanceRanking = await Plugin.Manager.GetClientOverallRanking(E.Target.ClientId); + var performanceRanking = await Plugin.Manager.GetClientOverallRanking(E.Target.ClientId, serverId); var performanceRankingString = performanceRanking == 0 ? _translationLookup["WEBFRONT_STATS_INDEX_UNRANKED"] : $"{_translationLookup["WEBFRONT_STATS_INDEX_RANKED"]} #{performanceRanking}"; @@ -84,7 +84,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands // getting self stats else { - var performanceRanking = await Plugin.Manager.GetClientOverallRanking(E.Origin.ClientId); + var performanceRanking = await Plugin.Manager.GetClientOverallRanking(E.Origin.ClientId, serverId); var performanceRankingString = performanceRanking == 0 ? _translationLookup["WEBFRONT_STATS_INDEX_UNRANKED"] : $"{_translationLookup["WEBFRONT_STATS_INDEX_RANKED"]} #{performanceRanking}"; diff --git a/Plugins/Stats/Config/StatsConfiguration.cs b/Plugins/Stats/Config/StatsConfiguration.cs index c4d091b3..d1438822 100644 --- a/Plugins/Stats/Config/StatsConfiguration.cs +++ b/Plugins/Stats/Config/StatsConfiguration.cs @@ -9,16 +9,32 @@ namespace IW4MAdmin.Plugins.Stats.Config { public class StatsConfiguration : IBaseConfiguration { - [Obsolete] - public bool? EnableAntiCheat { get; set; } + [Obsolete] public bool? EnableAntiCheat { get; set; } public List KillstreakMessages { get; set; } public List DeathstreakMessages { get; set; } public int TopPlayersMinPlayTime { get; set; } public bool StoreClientKills { get; set; } public int MostKillsMaxInactivityDays { get; set; } = 30; public int MostKillsClientLimit { get; set; } = 5; - [Obsolete] - public IDictionary ServerDetectionTypes { get; set; } + public bool EnableAdvancedMetrics { get; set; } = true; + + public WeaponNameParserConfiguration[] WeaponNameParserConfigurations { get; set; } = new[] + { + new WeaponNameParserConfiguration() + { + Game = Server.Game.IW4, + WeaponSuffix = "mp", + Delimiters = new[] {'_'} + }, + new WeaponNameParserConfiguration() + { + Game = Server.Game.T6, + WeaponSuffix = "mp", + Delimiters = new[] {'_', '+'} + } + }; + + [Obsolete] public IDictionary ServerDetectionTypes { get; set; } public AnticheatConfiguration AnticheatConfiguration { get; set; } = new AnticheatConfiguration(); #pragma warning disable CS0612 // Type or member is obsolete @@ -41,41 +57,47 @@ namespace IW4MAdmin.Plugins.Stats.Config #pragma warning restore CS0612 // Type or member is obsolete public string Name() => "StatsPluginSettings"; + public IBaseConfiguration Generate() { - AnticheatConfiguration.Enable = Utilities.PromptBool(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_SETUP_ENABLEAC"]); + AnticheatConfiguration.Enable = + Utilities.PromptBool(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_SETUP_ENABLEAC"]); KillstreakMessages = new List() { - new StreakMessageConfiguration(){ + new StreakMessageConfiguration() + { Count = -1, Message = "Try not to kill yourself anymore" }, - new StreakMessageConfiguration() { - Count = 5, - Message = "Great job! You're on a ^55 killstreak!" - }, - new StreakMessageConfiguration() - { - Count = 10, - Message = "Amazing! ^510 kills ^7without dying!" - }, - new StreakMessageConfiguration(){ - Count = 25, - Message = "You better call in that nuke, ^525 killstreak^7!" - } + new StreakMessageConfiguration() + { + Count = 5, + Message = "Great job! You're on a ^55 killstreak!" + }, + new StreakMessageConfiguration() + { + Count = 10, + Message = "Amazing! ^510 kills ^7without dying!" + }, + new StreakMessageConfiguration() + { + Count = 25, + Message = "You better call in that nuke, ^525 killstreak^7!" + } }; DeathstreakMessages = new List() { - new StreakMessageConfiguration() - { - Count = 5, - Message = "Pick it up soldier, you've died ^55 times ^7in a row..." - }, - new StreakMessageConfiguration(){ - Count = 10, - Message = "Seriously? ^510 deaths ^7without getting a kill?" - }, + new StreakMessageConfiguration() + { + Count = 5, + Message = "Pick it up soldier, you've died ^55 times ^7in a row..." + }, + new StreakMessageConfiguration() + { + Count = 10, + Message = "Seriously? ^510 deaths ^7without getting a kill?" + }, }; TopPlayersMinPlayTime = 3600 * 3; @@ -84,4 +106,4 @@ namespace IW4MAdmin.Plugins.Stats.Config return this; } } -} +} \ No newline at end of file diff --git a/Plugins/Stats/Config/WeaponNameParserConfiguration.cs b/Plugins/Stats/Config/WeaponNameParserConfiguration.cs new file mode 100644 index 00000000..d824ad9e --- /dev/null +++ b/Plugins/Stats/Config/WeaponNameParserConfiguration.cs @@ -0,0 +1,11 @@ +using SharedLibraryCore; + +namespace Stats.Config +{ + public class WeaponNameParserConfiguration + { + public Server.Game Game { get; set; } + public char[] Delimiters { get; set; } + public string WeaponSuffix { get; set; } + } +} \ No newline at end of file diff --git a/Plugins/Stats/Dtos/AdvancedStatsInfo.cs b/Plugins/Stats/Dtos/AdvancedStatsInfo.cs new file mode 100644 index 00000000..d12f6405 --- /dev/null +++ b/Plugins/Stats/Dtos/AdvancedStatsInfo.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using Data.Models.Client; +using Data.Models.Client.Stats; +using SharedLibraryCore.Dtos; + +namespace Stats.Dtos +{ + public class AdvancedStatsInfo + { + public long? ServerId { get; set; } + public string ServerEndpoint { get; set; } + public string ClientName { get; set; } + public int ClientId { get; set; } + public EFClient.Permission Level { get; set; } + public double? Performance { get; set; } + public int? Ranking { get; set; } + public double? ZScore { get; set; } + public double? Rating { get; set; } + public List Servers { get; set; } + public List All { get; set; } + public EFClientHitStatistic Aggregate { get; set; } + public List ByHitLocation { get; set; } + public List ByWeapon { get; set; } + public List ByAttachmentCombo { get; set; } + public List Ratings { get; set; } + public List LegacyStats { get; set; } + } +} \ No newline at end of file diff --git a/Plugins/Stats/Dtos/StatsInfoRequest.cs b/Plugins/Stats/Dtos/StatsInfoRequest.cs index 5cca4e86..3340a06f 100644 --- a/Plugins/Stats/Dtos/StatsInfoRequest.cs +++ b/Plugins/Stats/Dtos/StatsInfoRequest.cs @@ -6,5 +6,6 @@ /// client identifier /// public int? ClientId { get; set; } + public string ServerEndpoint { get; set; } } } diff --git a/Plugins/Stats/Dtos/TopStatsInfo.cs b/Plugins/Stats/Dtos/TopStatsInfo.cs index 22fa8a8f..fdd357a1 100644 --- a/Plugins/Stats/Dtos/TopStatsInfo.cs +++ b/Plugins/Stats/Dtos/TopStatsInfo.cs @@ -11,12 +11,16 @@ namespace IW4MAdmin.Plugins.Stats.Web.Dtos public string Name { get; set; } public int ClientId { get; set; } public double KDR { get; set; } - public double Performance { get; set; } + public double? Performance { get; set; } public string TimePlayed { get; set; } + public TimeSpan TimePlayedValue { get; set; } public string LastSeen { get; set; } + public TimeSpan LastSeenValue { get; set; } public int Kills { get; set; } public int Deaths { get; set; } public int RatingChange { get; set; } public List PerformanceHistory { get; set; } + public double? ZScore { get; set; } + public long? ServerId { get; set; } } } diff --git a/Plugins/Stats/Extensions.cs b/Plugins/Stats/Extensions.cs new file mode 100644 index 00000000..22acfdc9 --- /dev/null +++ b/Plugins/Stats/Extensions.cs @@ -0,0 +1,196 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using Data.Models.Client.Stats; +using Microsoft.EntityFrameworkCore.Internal; +using SharedLibraryCore.Dtos; +using Stats.Dtos; + +namespace IW4MAdmin.Plugins.Stats +{ + public static class Extensions + { + private const int ZScoreRange = 3; + private const int RankIconDivisions = 24; + private const int MaxMessages = 100; + + public class LogParams + { + public double Mean { get; set; } + public double Sigma { get; set; } + } + + public static DateTime FifteenDaysAgo() => DateTime.UtcNow.AddDays(-15); + + public static double? WeightValueByPlaytime(this IEnumerable stats, string propertyName, + int minTimePlayed, Func validation = null) + { + if (!stats.Any()) + { + return null; + } + + validation ??= (item) => item.Performance > 0 && item.TimePlayed >= minTimePlayed; + + var items = stats.Where(validation).ToList(); + var performancePlayTime = items.Sum(s => s.TimePlayed); + + var propInfo = typeof(EFClientStatistics).GetProperty(propertyName); + var weightedValues = items.Sum(item => + (double?) propInfo?.GetValue(item) * (item.TimePlayed / (double) performancePlayTime)); + return weightedValues.Equals(double.NaN) ? 0 : weightedValues ?? 0; + } + + public static LogParams GenerateDistributionParameters(this IEnumerable values) + { + if (!values.Any()) + { + return new LogParams() + { + Mean = 0, + Sigma = 0 + }; + } + + var ti = 0.0; + var ti2 = 0.0; + var n = 0L; + + foreach (var val in values) + { + var logVal = Math.Log(val); + ti += logVal * logVal; + ti2 += logVal; + n++; + if (n % 50 == 0) // this isn't ideal, but we want to reduce the amount of CPU usage that the + // loops takes so people don't complain + { + Thread.Sleep(1); + } + } + + var mean = ti2 / n; + ti2 *= ti2; + var bottom = n == 1 ? 1 : n * (n - 1); + var sigma = Math.Sqrt(((n * ti) - ti2) / bottom); + + return new LogParams() + { + Sigma = sigma, + Mean = mean + }; + } + + public static double? GetRatingForZScore(this double? zScore, double maxZScore) + { + const int ratingScalar = 1000; + + if (!zScore.HasValue) + { + return null; + } + + // we just want everything positive so we can go from 0-max + var adjustedZScore = zScore < -ZScoreRange ? 0 : zScore + ZScoreRange; + return adjustedZScore / (maxZScore + ZScoreRange) * ratingScalar; + } + + public static int RankIconIndexForZScore(this double? zScore) + { + if (zScore == null) + { + return 0; + } + + const double divisionIncrement = (ZScoreRange * 2) / (double) RankIconDivisions; + var rank = 1; + for (var i = rank; i <= RankIconDivisions; i++) + { + var bottom = Math.Round(-ZScoreRange + (i - 1) * divisionIncrement, 5); + var top = Math.Round(-ZScoreRange + i * divisionIncrement, 5); + + if (zScore > bottom && zScore <= top) + { + return rank; + } + + if (i == 1 && zScore < bottom // catch all for really bad players + // catch all for very good players + || i == RankIconDivisions && zScore > top) + { + return i; + } + + rank++; + } + + return 0; + } + + /// + /// todo: lets abstract this out to a generic buildable query + /// this is just a dirty PoC + /// + /// + /// + public static ChatSearchQuery ParseSearchInfo(this string query, int count, int offset) + { + string[] filters = query.Split('|'); + var searchRequest = new ChatSearchQuery + { + Filter = query, + Count = count, + Offset = offset + }; + + // sanity checks + searchRequest.Count = Math.Min(searchRequest.Count, MaxMessages); + searchRequest.Count = Math.Max(searchRequest.Count, 0); + searchRequest.Offset = Math.Max(searchRequest.Offset, 0); + + if (filters.Length > 1) + { + if (filters[0].ToLower() != "chat") + { + throw new ArgumentException("Query is not compatible with chat"); + } + + foreach (string filter in filters.Skip(1)) + { + string[] args = filter.Split(' '); + + if (args.Length > 1) + { + string recombinedArgs = string.Join(' ', args.Skip(1)); + switch (args[0].ToLower()) + { + case "before": + searchRequest.SentBefore = DateTime.Parse(recombinedArgs); + break; + case "after": + searchRequest.SentAfter = DateTime.Parse(recombinedArgs); + break; + case "server": + searchRequest.ServerId = args[1]; + break; + case "client": + searchRequest.ClientId = int.Parse(args[1]); + break; + case "contains": + searchRequest.MessageContains = string.Join(' ', args.Skip(1)); + break; + case "sort": + searchRequest.Direction = Enum.Parse(args[1], ignoreCase: true); + break; + } + } + } + + return searchRequest; + } + + throw new ArgumentException("No filters specified for chat search"); + } + } +} \ No newline at end of file diff --git a/Plugins/Stats/Helpers/AdvancedClientStatsResourceQueryHelper.cs b/Plugins/Stats/Helpers/AdvancedClientStatsResourceQueryHelper.cs new file mode 100644 index 00000000..57165425 --- /dev/null +++ b/Plugins/Stats/Helpers/AdvancedClientStatsResourceQueryHelper.cs @@ -0,0 +1,156 @@ +using System; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; +using Data.Abstractions; +using Data.Models.Client; +using Data.Models.Client.Stats; +using IW4MAdmin.Plugins.Stats; +using IW4MAdmin.Plugins.Stats.Config; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using SharedLibraryCore.Dtos; +using SharedLibraryCore.Helpers; +using SharedLibraryCore.Interfaces; +using Stats.Client.Abstractions; +using Stats.Dtos; +using ILogger = Microsoft.Extensions.Logging.ILogger; + +namespace Stats.Helpers +{ + public class AdvancedClientStatsResourceQueryHelper : IResourceQueryHelper + { + private readonly IDatabaseContextFactory _contextFactory; + private readonly ILogger _logger; + private readonly IManager _manager; + + public AdvancedClientStatsResourceQueryHelper(ILogger logger, + IDatabaseContextFactory contextFactory, IManager manager) + { + _contextFactory = contextFactory; + _logger = logger; + _manager = manager; + } + + public async Task> QueryResource(StatsInfoRequest query) + { + await using var context = _contextFactory.CreateContext(enableTracking: false); + + long? serverId = null; + + if (!string.IsNullOrEmpty(query.ServerEndpoint)) + { + serverId = (await context.Servers + .Select(server => new {server.EndPoint, server.Id}) + .FirstOrDefaultAsync(server => server.EndPoint == query.ServerEndpoint)) + ?.Id; + } + + var clientInfo = await context.Clients.Select(client => new + { + client.ClientId, + client.CurrentAlias.Name, + client.Level + }).FirstOrDefaultAsync(client => client.ClientId == query.ClientId); + + if (clientInfo == null) + { + return null; + } + + // gets all the hit stats for the client + var hitStats = await context.Set() + .Include(stat => stat.HitLocation) + .Include(stat => stat.MeansOfDeath) + .Include(stat => stat.Weapon) + .Include(stat => stat.WeaponAttachmentCombo) + .ThenInclude(attachment => attachment.Attachment1) + .Include(stat => stat.WeaponAttachmentCombo) + .ThenInclude(attachment => attachment.Attachment2) + .Include(stat => stat.WeaponAttachmentCombo) + .ThenInclude(attachment => attachment.Attachment3) + .Where(stat => stat.ClientId == query.ClientId) + .Where(stat => stat.ServerId == serverId) + .ToListAsync(); + + var ratings = await context.Set() + .Where(r => r.ClientId == clientInfo.ClientId) + .Where(r => r.ServerId == serverId) + .Where(r => r.Ranking != null) + .OrderByDescending(r => r.UpdatedDateTime) + .ToListAsync(); + + var mostRecentRanking = ratings.FirstOrDefault(ranking => ranking.Newest); + var ranking = mostRecentRanking?.Ranking + 1; + + // get stat for server, or all if no serverId + var legacyStats = await context.Set() + .Where(stat => stat.ClientId == query.ClientId) + .Where(stat => serverId == null || stat.ServerId == serverId) + .ToListAsync(); + + if (mostRecentRanking != null && mostRecentRanking.CreatedDateTime < Extensions.FifteenDaysAgo()) + { + ranking = 0; + } + + if (clientInfo.Level == EFClient.Permission.Banned) + { + ranking = null; + } + + var hitInfo = new AdvancedStatsInfo() + { + ServerId = serverId, + Performance = mostRecentRanking?.PerformanceMetric, + ZScore = mostRecentRanking?.ZScore, + ServerEndpoint = query.ServerEndpoint, + ClientName = clientInfo.Name, + ClientId = clientInfo.ClientId, + Level = clientInfo.Level, + Rating = mostRecentRanking?.PerformanceMetric, + All = hitStats, + Servers = _manager.GetServers() + .Select(server => new ServerInfo() + {Name = server.Hostname, IPAddress = server.IP, Port = server.Port}) + .ToList(), + Aggregate = hitStats.FirstOrDefault(hit => + hit.HitLocationId == null && hit.ServerId == serverId && hit.WeaponId == null && + hit.MeansOfDeathId == null), + ByHitLocation = hitStats + .Where(hit => hit.HitLocationId != null) + .Where(hit => hit.WeaponId == null) + .Where(hit => hit.WeaponAttachmentComboId == null) + .ToList(), + ByWeapon = hitStats + .Where(hit => hit.HitLocationId == null) + .Where(hit => hit.WeaponId != null) + .ToList(), + ByAttachmentCombo = hitStats + .Where(hit => hit.HitLocationId == null) + .Where(hit => hit.WeaponId != null) + .Where(hit => hit.WeaponAttachmentComboId != null) + .ToList(), + Ratings = ratings, + LegacyStats = legacyStats, + Ranking = ranking, + }; + + // todo: when nothign found + return new ResourceQueryHelperResult() + { + Results = new[] {hitInfo} + }; + } + + public static Expression> GetRankingFunc(int minPlayTime, double? zScore = null, + long? serverId = null) + { + return (stats) => (serverId == null || stats.ServerId == serverId) && + stats.UpdatedAt >= Extensions.FifteenDaysAgo() && + stats.Client.Level != EFClient.Permission.Banned && + stats.TimePlayed >= minPlayTime + && (zScore == null || stats.ZScore > zScore); + } + } +} \ No newline at end of file diff --git a/Plugins/Web/StatsWeb/ChatResourceQueryHelper.cs b/Plugins/Stats/Helpers/ChatResourceQueryHelper.cs similarity index 96% rename from Plugins/Web/StatsWeb/ChatResourceQueryHelper.cs rename to Plugins/Stats/Helpers/ChatResourceQueryHelper.cs index c8b484ba..4b871906 100644 --- a/Plugins/Web/StatsWeb/ChatResourceQueryHelper.cs +++ b/Plugins/Stats/Helpers/ChatResourceQueryHelper.cs @@ -1,19 +1,21 @@ -using IW4MAdmin.Plugins.Stats.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Data.Abstractions; +using Data.Models.Client; +using Data.Models.Server; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; using SharedLibraryCore; using SharedLibraryCore.Configuration; using SharedLibraryCore.Dtos.Meta.Responses; using SharedLibraryCore.Helpers; using SharedLibraryCore.Interfaces; using Stats.Dtos; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; using ILogger = Microsoft.Extensions.Logging.ILogger; -namespace StatsWeb +namespace Stats.Helpers { /// /// implementation of IResourceQueryHelper @@ -81,7 +83,7 @@ namespace StatsWeb When = _message.TimeSent, Message = _message.Message, ServerName = query.IsProfileMeta ? "" : _message.Server.HostName, - GameName = _message.Server.GameName == null ? Server.Game.IW4 : _message.Server.GameName.Value, + GameName = _message.Server.GameName == null ? Server.Game.IW4 : (Server.Game)_message.Server.GameName.Value, SentIngame = _message.SentIngame }); diff --git a/Plugins/Stats/Helpers/ServerStats.cs b/Plugins/Stats/Helpers/ServerStats.cs index e1c9af66..f9e25d83 100644 --- a/Plugins/Stats/Helpers/ServerStats.cs +++ b/Plugins/Stats/Helpers/ServerStats.cs @@ -1,12 +1,11 @@ -using IW4MAdmin.Plugins.Stats.Cheat; -using IW4MAdmin.Plugins.Stats.Models; -using SharedLibraryCore; -using SharedLibraryCore.Database.Models; +using SharedLibraryCore; using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading; +using Data.Models.Client; +using Data.Models.Client.Stats; +using Data.Models.Server; namespace IW4MAdmin.Plugins.Stats.Helpers { @@ -39,9 +38,9 @@ namespace IW4MAdmin.Plugins.Stats.Helpers .Select(_c => _c.GetAdditionalProperty(StatManager.CLIENT_STATS_KEY)) .Where(_c => _c != null); - if (PlayerStats.Count(p => p.Team == IW4Info.Team.None) / (double)PlayerStats.Count() <= 0.25) + if (PlayerStats.Count(p => p.Team == (int)IW4Info.Team.None) / (double)PlayerStats.Count() <= 0.25) { - return IsTeamBased ? Math.Max(PlayerStats.Count(p => p.Team == teamName), 1) : Math.Max(PlayerStats.Count() - 1, 1); + return IsTeamBased ? Math.Max(PlayerStats.Count(p => p.Team == (int)teamName), 1) : Math.Max(PlayerStats.Count() - 1, 1); } else diff --git a/Plugins/Stats/Helpers/StatManager.cs b/Plugins/Stats/Helpers/StatManager.cs index b9df54b9..312d145e 100644 --- a/Plugins/Stats/Helpers/StatManager.cs +++ b/Plugins/Stats/Helpers/StatManager.cs @@ -1,10 +1,8 @@ using IW4MAdmin.Plugins.Stats.Cheat; using IW4MAdmin.Plugins.Stats.Config; -using IW4MAdmin.Plugins.Stats.Models; using IW4MAdmin.Plugins.Stats.Web.Dtos; using Microsoft.EntityFrameworkCore; using SharedLibraryCore; -using SharedLibraryCore.Database.Models; using SharedLibraryCore.Helpers; using SharedLibraryCore.Interfaces; using System; @@ -14,8 +12,18 @@ using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using Data.Abstractions; +using Data.Context; +using Data.Models; +using Data.Models.Client; +using Data.Models.Client.Stats; +using Data.Models.Server; +using Humanizer.Localisation; using Microsoft.Extensions.Logging; +using Stats.Client.Abstractions; +using Stats.Helpers; using static IW4MAdmin.Plugins.Stats.Cheat.Detection; +using EFClient = SharedLibraryCore.Database.Models.EFClient; using ILogger = Microsoft.Extensions.Logging.ILogger; namespace IW4MAdmin.Plugins.Stats.Helpers @@ -30,21 +38,25 @@ namespace IW4MAdmin.Plugins.Stats.Helpers private static List serverModels; public static string CLIENT_STATS_KEY = "ClientStats"; public static string CLIENT_DETECTIONS_KEY = "ClientDetections"; - private readonly SemaphoreSlim _addPlayerWaiter = new SemaphoreSlim(1, 1); + private readonly SemaphoreSlim _addPlayerWaiter = new SemaphoreSlim(1, 1); + private readonly IServerDistributionCalculator _serverDistributionCalculator; - public StatManager(ILogger logger, IManager mgr, IDatabaseContextFactory contextFactory, IConfigurationHandler configHandler) + public StatManager(ILogger logger, IManager mgr, IDatabaseContextFactory contextFactory, + IConfigurationHandler configHandler, + IServerDistributionCalculator serverDistributionCalculator) { _servers = new ConcurrentDictionary(); _log = logger; _contextFactory = contextFactory; _configHandler = configHandler; + _serverDistributionCalculator = serverDistributionCalculator; } ~StatManager() { _addPlayerWaiter.Dispose(); } - + private void SetupServerIds() { using var ctx = _contextFactory.CreateContext(enableTracking: false); @@ -55,10 +67,10 @@ namespace IW4MAdmin.Plugins.Stats.Helpers { var fifteenDaysAgo = DateTime.UtcNow.AddDays(-15); return (r) => r.ServerId == serverId && - r.When > fifteenDaysAgo && - r.RatingHistory.Client.Level != EFClient.Permission.Banned && - r.Newest && - r.ActivityAmount >= _configHandler.Configuration().TopPlayersMinPlayTime; + r.When > fifteenDaysAgo && + r.RatingHistory.Client.Level != EFClient.Permission.Banned && + r.Newest && + r.ActivityAmount >= _configHandler.Configuration().TopPlayersMinPlayTime; } /// @@ -66,13 +78,23 @@ namespace IW4MAdmin.Plugins.Stats.Helpers /// /// client id of the player /// - public async Task GetClientOverallRanking(int clientId) + public async Task GetClientOverallRanking(int clientId, long? serverId = null) { await using var context = _contextFactory.CreateContext(enableTracking: false); + + if (_configHandler.Configuration().EnableAdvancedMetrics) + { + var clientRanking = await context.Set() + .Where(r => r.ClientId == clientId) + .Where(r => r.ServerId == serverId) + .Where(r => r.Newest) + .FirstOrDefaultAsync(); + return clientRanking?.Ranking + 1 ?? 0; + } var clientPerformance = await context.Set() .Where(r => r.RatingHistory.ClientId == clientId) - .Where(r => r.ServerId == null) + .Where(r => r.ServerId == serverId) .Where(r => r.Newest) .Select(r => r.Performance) .FirstOrDefaultAsync(); @@ -90,25 +112,115 @@ namespace IW4MAdmin.Plugins.Stats.Helpers return 0; } + public async Task> GetNewTopStats(int start, int count, long? serverId = null) + { + await using var context = _contextFactory.CreateContext(false); + + var clientIdsList = await context.Set() + .Where(ranking => ranking.ServerId == serverId) + .Where(ranking => ranking.Client.Level != Data.Models.Client.EFClient.Permission.Banned) + .Where(ranking => ranking.Client.LastConnection >= Extensions.FifteenDaysAgo()) + .Where(ranking => ranking.ZScore != null) + .Where(ranking => ranking.PerformanceMetric != null) + .Where(ranking => ranking.Newest) + .Where(ranking => + ranking.Client.TotalConnectionTime >= _configHandler.Configuration().TopPlayersMinPlayTime) + .OrderByDescending(ranking => ranking.PerformanceMetric) + .Select(ranking => ranking.ClientId) + .Skip(start) + .Take(count) + .ToListAsync(); + + var rankings = await context.Set() + .Where(ranking => clientIdsList.Contains(ranking.ClientId)) + .Where(ranking => ranking.ServerId == serverId) + .Select(ranking => new + { + ranking.ClientId, + ranking.Client.CurrentAlias.Name, + ranking.Client.LastConnection, + ranking.PerformanceMetric, + ranking.ZScore, + ranking.Ranking, + ranking.CreatedDateTime + }) + .ToListAsync(); + + var rankingsDict = rankings.GroupBy(rank => rank.ClientId) + .ToDictionary(rank => rank.Key, rank => rank.OrderBy(r => r.CreatedDateTime).ToList()); + + var statsInfo = await context.Set() + .Where(stat => clientIdsList.Contains(stat.ClientId)) + .Where(stat => stat.TimePlayed > 0) + .Where(stat => stat.Kills > 0 || stat.Deaths > 0) + .Where(stat => serverId == null || stat.ServerId == serverId) + .GroupBy(stat => stat.ClientId) + .Select(s => new + { + ClientId = s.Key, + Kills = s.Sum(c => c.Kills), + Deaths = s.Sum(c => c.Deaths), + KDR = s.Sum(c => (c.Kills / (double) (c.Deaths == 0 ? 1 : c.Deaths)) * c.TimePlayed) / + s.Sum(c => c.TimePlayed), + TotalTimePlayed = s.Sum(c => c.TimePlayed), + }) + .ToListAsync(); + + var finished = statsInfo + .OrderByDescending(stat => rankingsDict[stat.ClientId].Last().PerformanceMetric) + .Select((s, index) => new TopStatsInfo() + { + ClientId = s.ClientId, + Id = (int?) serverId ?? 0, + Deaths = s.Deaths, + Kills = s.Kills, + KDR = Math.Round(s.KDR, 2), + LastSeen = (DateTime.UtcNow - rankingsDict[s.ClientId].First().LastConnection) + .HumanizeForCurrentCulture(1, TimeUnit.Week, TimeUnit.Second, ",", false), + LastSeenValue = (DateTime.UtcNow - rankingsDict[s.ClientId].First().LastConnection), + Name = rankingsDict[s.ClientId].First().Name, + Performance = Math.Round(rankingsDict[s.ClientId].Last().PerformanceMetric ?? 0, 2), + RatingChange = (rankingsDict[s.ClientId].First().Ranking - + rankingsDict[s.ClientId].Last().Ranking) ?? 0, + PerformanceHistory = rankingsDict[s.ClientId].Select(ranking => ranking.PerformanceMetric ?? 0).ToList(), + TimePlayed = Math.Round(s.TotalTimePlayed / 3600.0, 1).ToString("#,##0"), + TimePlayedValue = TimeSpan.FromSeconds(s.TotalTimePlayed), + Ranking = index + start + 1, + ZScore = rankingsDict[s.ClientId].Last().ZScore, + ServerId = serverId + }) + .OrderBy(r => r.Ranking) + .ToList(); + + return finished; + } + public async Task> GetTopStats(int start, int count, long? serverId = null) { + if (_configHandler.Configuration().EnableAdvancedMetrics) + { + return await GetNewTopStats(start, count, serverId); + } + await using var context = _contextFactory.CreateContext(enableTracking: false); // setup the query for the clients within the given rating range var iqClientRatings = (from rating in context.Set() - .Where(GetRankingFunc(serverId)) - select new - { - rating.RatingHistory.ClientId, - rating.RatingHistory.Client.CurrentAlias.Name, - rating.RatingHistory.Client.LastConnection, - rating.Performance, - }) + .Where(GetRankingFunc(serverId)) + select new + { + rating.RatingHistory.ClientId, + rating.RatingHistory.Client.CurrentAlias.Name, + rating.RatingHistory.Client.LastConnection, + rating.Performance, + }) .OrderByDescending(c => c.Performance) .Skip(start) .Take(count); // materialized list - var clientRatings = await iqClientRatings.ToListAsync(); + var clientRatings = (await iqClientRatings.ToListAsync()) + .GroupBy(rating => rating.ClientId) // prevent duplicate keys + .Select(group => group.FirstOrDefault()); // get all the unique client ids that are in the top stats var clientIds = clientRatings @@ -117,59 +229,67 @@ namespace IW4MAdmin.Plugins.Stats.Helpers .ToList(); var iqRatingInfo = from rating in context.Set() - where clientIds.Contains(rating.RatingHistory.ClientId) - where rating.ServerId == serverId - select new - { - rating.Ranking, - rating.Performance, - rating.RatingHistory.ClientId, - rating.When - }; + where clientIds.Contains(rating.RatingHistory.ClientId) + where rating.ServerId == serverId + select new + { + rating.Ranking, + rating.Performance, + rating.RatingHistory.ClientId, + rating.When + }; var ratingInfo = (await iqRatingInfo.ToListAsync()) .GroupBy(r => r.ClientId) .Select(grp => new { grp.Key, - Ratings = grp.Select(r => new { r.Performance, r.Ranking, r.When }) + Ratings = grp.Select(r => new {r.Performance, r.Ranking, r.When}) }); var iqStatsInfo = (from stat in context.Set() - where clientIds.Contains(stat.ClientId) - where stat.Kills > 0 || stat.Deaths > 0 - where serverId == null ? true : stat.ServerId == serverId - group stat by stat.ClientId into s - select new - { - ClientId = s.Key, - Kills = s.Sum(c => c.Kills), - Deaths = s.Sum(c => c.Deaths), - KDR = s.Sum(c => (c.Kills / (double)(c.Deaths == 0 ? 1 : c.Deaths)) * c.TimePlayed) / s.Sum(c => c.TimePlayed), - TotalTimePlayed = s.Sum(c => c.TimePlayed), - }); + where clientIds.Contains(stat.ClientId) + where stat.Kills > 0 || stat.Deaths > 0 + where serverId == null || stat.ServerId == serverId + group stat by stat.ClientId + into s + select new + { + ClientId = s.Key, + Kills = s.Sum(c => c.Kills), + Deaths = s.Sum(c => c.Deaths), + KDR = s.Sum(c => (c.Kills / (double) (c.Deaths == 0 ? 1 : c.Deaths)) * c.TimePlayed) / + s.Sum(c => c.TimePlayed), + TotalTimePlayed = s.Sum(c => c.TimePlayed), + }); var topPlayers = await iqStatsInfo.ToListAsync(); var clientRatingsDict = clientRatings.ToDictionary(r => r.ClientId); var finished = topPlayers.Select(s => new TopStatsInfo() - { - ClientId = s.ClientId, - Id = (int?)serverId ?? 0, - Deaths = s.Deaths, - Kills = s.Kills, - KDR = Math.Round(s.KDR, 2), - LastSeen = (DateTime.UtcNow - clientRatingsDict[s.ClientId].LastConnection).HumanizeForCurrentCulture(), - Name = clientRatingsDict[s.ClientId].Name, - Performance = Math.Round(clientRatingsDict[s.ClientId].Performance, 2), - RatingChange = ratingInfo.First(r => r.Key == s.ClientId).Ratings.First().Ranking - ratingInfo.First(r => r.Key == s.ClientId).Ratings.Last().Ranking, - PerformanceHistory = ratingInfo.First(r => r.Key == s.ClientId).Ratings.Count() > 1 ? - ratingInfo.First(r => r.Key == s.ClientId).Ratings.OrderBy(r => r.When).Select(r => r.Performance).ToList() : - new List() { clientRatingsDict[s.ClientId].Performance, clientRatingsDict[s.ClientId].Performance }, - TimePlayed = Math.Round(s.TotalTimePlayed / 3600.0, 1).ToString("#,##0"), - }) - .OrderByDescending(r => r.Performance) - .ToList(); + { + ClientId = s.ClientId, + Id = (int?) serverId ?? 0, + Deaths = s.Deaths, + Kills = s.Kills, + KDR = Math.Round(s.KDR, 2), + LastSeen = (DateTime.UtcNow - clientRatingsDict[s.ClientId].LastConnection) + .HumanizeForCurrentCulture(), + LastSeenValue = DateTime.UtcNow - clientRatingsDict[s.ClientId].LastConnection, + Name = clientRatingsDict[s.ClientId].Name, + Performance = Math.Round(clientRatingsDict[s.ClientId].Performance, 2), + RatingChange = ratingInfo.First(r => r.Key == s.ClientId).Ratings.First().Ranking - + ratingInfo.First(r => r.Key == s.ClientId).Ratings.Last().Ranking, + PerformanceHistory = ratingInfo.First(r => r.Key == s.ClientId).Ratings.Count() > 1 + ? ratingInfo.First(r => r.Key == s.ClientId).Ratings.OrderBy(r => r.When) + .Select(r => r.Performance).ToList() + : new List() + {clientRatingsDict[s.ClientId].Performance, clientRatingsDict[s.ClientId].Performance}, + TimePlayed = Math.Round(s.TotalTimePlayed / 3600.0, 1).ToString("#,##0"), + TimePlayedValue = TimeSpan.FromSeconds(s.TotalTimePlayed) + }) + .OrderByDescending(r => r.Performance) + .ToList(); // set the ranking numerically int i = start + 1; @@ -226,7 +346,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers Port = sv.Port, EndPoint = sv.ToString(), ServerId = serverId, - GameName = sv.GameName, + GameName = (Reference.Game?) sv.GameName, HostName = sv.Hostname }; @@ -236,9 +356,9 @@ namespace IW4MAdmin.Plugins.Stats.Helpers } // we want to set the gamename up if it's never been set, or it changed - else if (!server.GameName.HasValue || server.GameName.HasValue && server.GameName.Value != sv.GameName) + else if (!server.GameName.HasValue || server.GameName.Value != (Reference.Game) sv.GameName) { - server.GameName = sv.GameName; + server.GameName = (Reference.Game) sv.GameName; ctx.Entry(server).Property(_prop => _prop.GameName).IsModified = true; ctx.SaveChanges(); } @@ -265,7 +385,8 @@ namespace IW4MAdmin.Plugins.Stats.Helpers catch (Exception e) { - _log.LogError(e, "{message}", Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_ERROR_ADD"]); + _log.LogError(e, "{message}", + Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_ERROR_ADD"]); } } @@ -277,7 +398,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers public async Task AddPlayer(EFClient pl) { var existingStats = pl.GetAdditionalProperty(CLIENT_STATS_KEY); - + if (existingStats != null) { return existingStats; @@ -322,7 +443,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers { Active = true, HitCount = 0, - Location = hl + Location = (int) hl }).ToList() }; @@ -342,7 +463,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers { Active = true, HitCount = 0, - Location = hl + Location = (int) hl }) .ToList(); @@ -404,7 +525,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers return; } - long serverId = GetIdForServer(pl.CurrentServer); + var serverId = GetIdForServer(pl.CurrentServer); var serverStats = _servers[serverId].ServerStatistics; // get individual client's stats @@ -414,9 +535,14 @@ namespace IW4MAdmin.Plugins.Stats.Helpers { clientStats = UpdateStats(clientStats); await SaveClientStats(clientStats); + if (_configHandler.Configuration().EnableAdvancedMetrics) + { + await UpdateHistoricalRanking(pl.ClientId, clientStats, serverId); + } // increment the total play time serverStats.TotalPlayTime += pl.ConnectionLength; + pl.SetAdditionalProperty(CLIENT_STATS_KEY, null); } else @@ -440,8 +566,10 @@ namespace IW4MAdmin.Plugins.Stats.Helpers /// Process stats for kill event /// /// - public async Task AddScriptHit(bool isDamage, DateTime time, EFClient attacker, EFClient victim, long serverId, string map, string hitLoc, string type, - string damage, string weapon, string killOrigin, string deathOrigin, string viewAngles, string offset, string isKillstreakKill, string Ads, + public async Task AddScriptHit(bool isDamage, DateTime time, EFClient attacker, EFClient victim, long serverId, + string map, string hitLoc, string type, + string damage, string weapon, string killOrigin, string deathOrigin, string viewAngles, string offset, + string isKillstreakKill, string Ads, string fraction, string visibilityPercentage, string snapAngles, string isAlive, string lastAttackTime) { Vector3 vDeathOrigin = null; @@ -478,25 +606,26 @@ namespace IW4MAdmin.Plugins.Stats.Helpers ServerId = serverId, DeathOrigin = vDeathOrigin, KillOrigin = vKillOrigin, - DeathType = ParseEnum.Get(type, typeof(IW4Info.MeansOfDeath)), + DeathType = (int) ParseEnum.Get(type, typeof(IW4Info.MeansOfDeath)), Damage = int.Parse(damage), - HitLoc = ParseEnum.Get(hitLoc, typeof(IW4Info.HitLocation)), - Weapon = ParseEnum.Get(weapon, typeof(IW4Info.WeaponName)), + HitLoc = (int) ParseEnum.Get(hitLoc, typeof(IW4Info.HitLocation)), + Weapon = (int) ParseEnum.Get(weapon, typeof(IW4Info.WeaponName)), ViewAngles = vViewAngles, TimeOffset = long.Parse(offset), When = time, IsKillstreakKill = isKillstreakKill[0] != '0', AdsPercent = float.Parse(Ads, System.Globalization.CultureInfo.InvariantCulture), Fraction = double.Parse(fraction, System.Globalization.CultureInfo.InvariantCulture), - VisibilityPercentage = double.Parse(visibilityPercentage, System.Globalization.CultureInfo.InvariantCulture), + VisibilityPercentage = double.Parse(visibilityPercentage, + System.Globalization.CultureInfo.InvariantCulture), IsKill = !isDamage, AnglesList = snapshotAngles, IsAlive = isAlive == "1", TimeSinceLastAttack = long.Parse(lastAttackTime), - GameName = attacker.CurrentServer.GameName + GameName = (int) attacker.CurrentServer.GameName }; - if (hit.HitLoc == IW4Info.HitLocation.shield) + if (hit.HitLoc == (int) IW4Info.HitLocation.shield) { // we don't care about shield hits return; @@ -509,9 +638,9 @@ namespace IW4MAdmin.Plugins.Stats.Helpers await waiter.WaitAsync(Utilities.DefaultCommandTimeout, Plugin.ServerManager.CancellationToken); // increment their hit count - if (hit.DeathType == IW4Info.MeansOfDeath.MOD_PISTOL_BULLET || - hit.DeathType == IW4Info.MeansOfDeath.MOD_RIFLE_BULLET || - hit.DeathType == IW4Info.MeansOfDeath.MOD_HEAD_SHOT) + if (hit.DeathType == (int) IW4Info.MeansOfDeath.MOD_PISTOL_BULLET || + hit.DeathType == (int) IW4Info.MeansOfDeath.MOD_RIFLE_BULLET || + hit.DeathType == (int) IW4Info.MeansOfDeath.MOD_HEAD_SHOT) { clientStats.HitLocations.First(hl => hl.Location == hit.HitLoc).HitCount += 1; } @@ -550,7 +679,8 @@ namespace IW4MAdmin.Plugins.Stats.Helpers } } - if (Plugin.Config.Configuration().AnticheatConfiguration.Enable && !attacker.IsBot && attacker.ClientId != victim.ClientId) + if (Plugin.Config.Configuration().AnticheatConfiguration.Enable && !attacker.IsBot && + attacker.ClientId != victim.ClientId) { clientDetection.TrackedHits.Add(hit); @@ -573,7 +703,8 @@ namespace IW4MAdmin.Plugins.Stats.Helpers await ApplyPenalty(result, attacker); } - if (clientDetection.Tracker.HasChanges && result.ClientPenalty != EFPenalty.PenaltyType.Any) + if (clientDetection.Tracker.HasChanges && + result.ClientPenalty != EFPenalty.PenaltyType.Any) { await SaveTrackedSnapshots(clientDetection); @@ -590,10 +721,13 @@ namespace IW4MAdmin.Plugins.Stats.Helpers } } - catch (TaskCanceledException) { } + catch (TaskCanceledException) + { + } catch (Exception ex) { - _log.LogError(ex, "Could not save hit or anti-cheat info {@attacker} {@victim} {server}", attacker, victim, serverId); + _log.LogError(ex, "Could not save hit or anti-cheat info {@attacker} {@victim} {server}", attacker, + victim, serverId); } finally @@ -605,16 +739,17 @@ namespace IW4MAdmin.Plugins.Stats.Helpers } } - private DetectionPenaltyResult DeterminePenaltyResult(IEnumerable results, EFClient client) + private DetectionPenaltyResult DeterminePenaltyResult(IEnumerable results, + EFClient client) { // allow disabling of certain detection types results = results.Where(_result => ShouldUseDetection(client.CurrentServer, _result.Type, client.ClientId)); return results.FirstOrDefault(_result => _result.ClientPenalty == EFPenalty.PenaltyType.Ban) ?? - results.FirstOrDefault(_result => _result.ClientPenalty == EFPenalty.PenaltyType.Flag) ?? - new DetectionPenaltyResult() - { - ClientPenalty = EFPenalty.PenaltyType.Any, - }; + results.FirstOrDefault(_result => _result.ClientPenalty == EFPenalty.PenaltyType.Flag) ?? + new DetectionPenaltyResult() + { + ClientPenalty = EFPenalty.PenaltyType.Any, + }; } public async Task SaveHitCache(long serverId) @@ -647,7 +782,6 @@ namespace IW4MAdmin.Plugins.Stats.Helpers catch (KeyNotFoundException) { - } return true; @@ -668,13 +802,16 @@ namespace IW4MAdmin.Plugins.Stats.Helpers { new EFPenalty() { - AutomatedOffense = penalty.Type == Detection.DetectionType.Bone ? - $"{penalty.Type}-{(int)penalty.Location}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}" : - $"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}", + AutomatedOffense = penalty.Type == Detection.DetectionType.Bone + ? $"{penalty.Type}-{(int) penalty.Location}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}" + : $"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}", } }; - await attacker.Ban(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_CHEAT_DETECTED"], penaltyClient, false).WaitAsync(Utilities.DefaultCommandTimeout, attacker.CurrentServer.Manager.CancellationToken); + await attacker + .Ban(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_CHEAT_DETECTED"], + penaltyClient, false).WaitAsync(Utilities.DefaultCommandTimeout, + attacker.CurrentServer.Manager.CancellationToken); break; case EFPenalty.PenaltyType.Flag: if (attacker.Level != EFClient.Permission.User) @@ -682,9 +819,9 @@ namespace IW4MAdmin.Plugins.Stats.Helpers break; } - string flagReason = penalty.Type == Cheat.Detection.DetectionType.Bone ? - $"{penalty.Type}-{(int)penalty.Location}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}" : - $"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}"; + string flagReason = penalty.Type == Cheat.Detection.DetectionType.Bone + ? $"{penalty.Type}-{(int) penalty.Location}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}" + : $"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}"; penaltyClient.AdministeredPenalties = new List() { @@ -694,7 +831,8 @@ namespace IW4MAdmin.Plugins.Stats.Helpers } }; - await attacker.Flag(flagReason, penaltyClient, new TimeSpan(168, 0, 0)).WaitAsync(Utilities.DefaultCommandTimeout, attacker.CurrentServer.Manager.CancellationToken); + await attacker.Flag(flagReason, penaltyClient, new TimeSpan(168, 0, 0)) + .WaitAsync(Utilities.DefaultCommandTimeout, attacker.CurrentServer.Manager.CancellationToken); break; } } @@ -708,6 +846,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers { ctx.Add(change); } + await ctx.SaveChangesAsync(); } @@ -743,9 +882,9 @@ namespace IW4MAdmin.Plugins.Stats.Helpers victimStats.LastScore = victim.Score; // show encouragement/discouragement - string streakMessage = (attackerStats.ClientId != victimStats.ClientId) ? - StreakMessage.MessageOnStreak(attackerStats.KillStreak, attackerStats.DeathStreak) : - StreakMessage.MessageOnStreak(-1, -1); + string streakMessage = (attackerStats.ClientId != victimStats.ClientId) + ? StreakMessage.MessageOnStreak(attackerStats.KillStreak, attackerStats.DeathStreak) + : StreakMessage.MessageOnStreak(-1, -1); if (streakMessage != string.Empty) { @@ -768,15 +907,26 @@ namespace IW4MAdmin.Plugins.Stats.Helpers } // update their performance - if ((DateTime.UtcNow - attackerStats.LastStatHistoryUpdate).TotalMinutes >= 2.5) + if ((DateTime.UtcNow - attackerStats.LastStatHistoryUpdate).TotalMinutes >= + (Utilities.IsDevelopment ? 0.5 : _configHandler.Configuration().EnableAdvancedMetrics ? 10.0 : 2.5)) { try { // kill event is not designated as blocking, so we should be able to enter and exit // we need to make this thread safe because we can potentially have kills qualify // for stat history update, but one is already processing that invalidates the original - await attackerStats.ProcessingHit.WaitAsync(Utilities.DefaultCommandTimeout, Plugin.ServerManager.CancellationToken); - await UpdateStatHistory(attacker, attackerStats); + await attackerStats.ProcessingHit.WaitAsync(Utilities.DefaultCommandTimeout, + Plugin.ServerManager.CancellationToken); + if (_configHandler.Configuration().EnableAdvancedMetrics) + { + await UpdateHistoricalRanking(attacker.ClientId, attackerStats, serverId); + } + + else + { + await UpdateStatHistory(attacker, attackerStats); + } + attackerStats.LastStatHistoryUpdate = DateTime.UtcNow; } @@ -796,14 +946,14 @@ namespace IW4MAdmin.Plugins.Stats.Helpers } /// - /// Update the invidual and average stat history for a client + /// Update the individual and average stat history for a client /// /// client to update /// stats of client that is being updated /// public async Task UpdateStatHistory(EFClient client, EFClientStatistics clientStats) { - int currentSessionTime = (int)(DateTime.UtcNow - client.LastConnection).TotalSeconds; + int currentSessionTime = (int) (DateTime.UtcNow - client.LastConnection).TotalSeconds; // don't update their stat history if they haven't played long if (currentSessionTime < 60) @@ -816,18 +966,18 @@ namespace IW4MAdmin.Plugins.Stats.Helpers await using var ctx = _contextFactory.CreateContext(enableTracking: true); // select the rating history for client var iqHistoryLink = from history in ctx.Set() - .Include(h => h.Ratings) - where history.ClientId == client.ClientId - select history; + .Include(h => h.Ratings) + where history.ClientId == client.ClientId + select history; // get the client ratings var clientHistory = await iqHistoryLink .FirstOrDefaultAsync() ?? new EFClientRatingHistory() - { - Active = true, - ClientId = client.ClientId, - Ratings = new List() - }; + { + Active = true, + ClientId = client.ClientId, + Ratings = new List() + }; // it's the first time they've played if (clientHistory.RatingHistoryId == 0) @@ -836,13 +986,14 @@ namespace IW4MAdmin.Plugins.Stats.Helpers } #region INDIVIDUAL_SERVER_PERFORMANCE + // get the client ranking for the current server int individualClientRanking = await ctx.Set() - .Where(GetRankingFunc(clientStats.ServerId)) - // ignore themselves in the query - .Where(c => c.RatingHistory.ClientId != client.ClientId) - .Where(c => c.Performance > clientStats.Performance) - .CountAsync() + 1; + .Where(GetRankingFunc(clientStats.ServerId)) + // ignore themselves in the query + .Where(c => c.RatingHistory.ClientId != client.ClientId) + .Where(c => c.Performance > clientStats.Performance) + .CountAsync() + 1; // limit max history per server to 40 if (clientHistory.Ratings.Count(r => r.ServerId == clientStats.ServerId) >= 40) @@ -887,16 +1038,18 @@ namespace IW4MAdmin.Plugins.Stats.Helpers ctx.Add(newServerRating); #endregion + #region OVERALL_RATING + // select all performance & time played for current client var iqClientStats = from stats in ctx.Set() - where stats.ClientId == client.ClientId - where stats.ServerId != clientStats.ServerId - select new - { - stats.Performance, - stats.TimePlayed - }; + where stats.ClientId == client.ClientId + where stats.ServerId != clientStats.ServerId + select new + { + stats.Performance, + stats.TimePlayed + }; var clientStatsList = await iqClientStats.ToListAsync(); @@ -908,7 +1061,8 @@ namespace IW4MAdmin.Plugins.Stats.Helpers }); // weight the overall performance based on play time - double performanceAverage = clientStatsList.Sum(p => (p.Performance * p.TimePlayed)) / clientStatsList.Sum(p => p.TimePlayed); + double performanceAverage = clientStatsList.Sum(p => (p.Performance * p.TimePlayed)) / + clientStatsList.Sum(p => p.TimePlayed); // shouldn't happen but just in case the sum of time played is 0 if (double.IsNaN(performanceAverage)) @@ -917,10 +1071,10 @@ namespace IW4MAdmin.Plugins.Stats.Helpers } int overallClientRanking = await ctx.Set() - .Where(GetRankingFunc()) - .Where(r => r.RatingHistory.ClientId != client.ClientId) - .Where(r => r.Performance > performanceAverage) - .CountAsync() + 1; + .Where(GetRankingFunc()) + .Where(r => r.RatingHistory.ClientId != client.ClientId) + .Where(r => r.Performance > performanceAverage) + .CountAsync() + 1; // limit max average history to 40 if (clientHistory.Ratings.Count(r => r.ServerId == null) >= 40) @@ -962,11 +1116,112 @@ namespace IW4MAdmin.Plugins.Stats.Helpers }; ctx.Add(averageRating); + #endregion await ctx.SaveChangesAsync(); } + public async Task UpdateHistoricalRanking(int clientId, EFClientStatistics clientStats, long serverId) + { + await using var context = _contextFactory.CreateContext(); + + var performances = await context.Set() + .AsNoTracking() + .Where(stat => stat.ClientId == clientId) + .Where(stat => stat.ServerId != serverId) // ignore the one we're currently tracking + .Where(stats => stats.UpdatedAt >= Extensions.FifteenDaysAgo()) + .Where(stats => stats.TimePlayed >= _configHandler.Configuration().TopPlayersMinPlayTime) + .ToListAsync(); + + if (clientStats.TimePlayed >= _configHandler.Configuration().TopPlayersMinPlayTime) + { + clientStats.ZScore = await _serverDistributionCalculator.GetZScoreForServer(serverId, + clientStats.Performance); + + var serverRanking = await context.Set() + .Where(stats => stats.ClientId != clientStats.ClientId) + .Where(AdvancedClientStatsResourceQueryHelper.GetRankingFunc( + _configHandler.Configuration().TopPlayersMinPlayTime, clientStats.ZScore, serverId)) + .CountAsync(); + + var serverRankingSnapshot = new EFClientRankingHistory() + { + ClientId = clientId, + ServerId = serverId, + ZScore = clientStats.ZScore, + Ranking = serverRanking, + PerformanceMetric = clientStats.Performance, + Newest = true + }; + + context.Add(serverRankingSnapshot); + await PruneOldRankings(context, clientId, serverId); + await context.SaveChangesAsync(); + + performances.Add(clientStats); + } + + if (performances.Any(performance => performance.TimePlayed >= _configHandler.Configuration().TopPlayersMinPlayTime)) + { + var aggregateZScore = performances.WeightValueByPlaytime(nameof(EFClientStatistics.ZScore), _configHandler.Configuration().TopPlayersMinPlayTime); + + int? aggregateRanking = await context.Set() + .Where(stat => stat.ClientId != clientId) + .Where(AdvancedClientStatsResourceQueryHelper.GetRankingFunc(_configHandler.Configuration() + .TopPlayersMinPlayTime)) + .GroupBy(stat => stat.ClientId) + .Where(group => + group.Sum(stat => stat.ZScore * stat.TimePlayed) / group.Sum(stat => stat.TimePlayed) > + aggregateZScore) + .Select(c => c.Key) + .CountAsync(); + + var aggregateRankingSnapshot = new EFClientRankingHistory() + { + ClientId = clientId, + ZScore = aggregateZScore, + Ranking = aggregateRanking, + PerformanceMetric = await _serverDistributionCalculator.GetRatingForZScore(aggregateZScore), + Newest = true, + }; + + context.Add(aggregateRankingSnapshot); + + await PruneOldRankings(context, clientId); + await context.SaveChangesAsync(); + } + } + + private async Task PruneOldRankings(DatabaseContext context, int clientId, long? serverId = null) + { + var totalRankingEntries = await context.Set() + .Where(r => r.ClientId == clientId) + .Where(r => r.ServerId == serverId) + .CountAsync(); + + var mostRecent = await context.Set() + .Where(r => r.ClientId == clientId) + .Where(r => r.ServerId == serverId) + .FirstOrDefaultAsync(r => r.Newest); + + if (mostRecent != null) + { + mostRecent.Newest = false; + context.Update(mostRecent); + } + + if (totalRankingEntries > EFClientRankingHistory.MaxRankingCount) + { + var lastRating = await context.Set() + .Where(r => r.ClientId == clientId) + .Where(r => r.ServerId == serverId) + .OrderBy(r => r.CreatedDateTime) + .FirstOrDefaultAsync(); + context.Remove(lastRating); + } + } + /// /// Performs the incrementation of kills and deaths for client statistics /// @@ -994,6 +1249,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers attackerStats = UpdateStats(attackerStats); #region DEPRECATED + /* var validAttackerLobbyRatings = Servers[attackerStats.ServerId].PlayerStats .Where(cs => cs.Value.ClientId != attackerStats.ClientId) .Where(cs => @@ -1017,10 +1273,12 @@ namespace IW4MAdmin.Plugins.Stats.Helpers double victimLobbyRating = validVictimLobbyRatings.Count() > 0 ? validVictimLobbyRatings.Average(cs => cs.Value.EloRating) : victimStats.EloRating;*/ + #endregion // calculate elo - double attackerEloDifference = Math.Log(Math.Max(1, victimStats.EloRating)) - Math.Log(Math.Max(1, attackerStats.EloRating)); + double attackerEloDifference = Math.Log(Math.Max(1, victimStats.EloRating)) - + Math.Log(Math.Max(1, attackerStats.EloRating)); double winPercentage = 1.0 / (1 + Math.Pow(10, attackerEloDifference / Math.E)); // double victimEloDifference = Math.Log(Math.Max(1, attackerStats.EloRating)) - Math.Log(Math.Max(1, victimStats.EloRating)); @@ -1033,8 +1291,8 @@ namespace IW4MAdmin.Plugins.Stats.Helpers victimStats.EloRating = Math.Max(0, Math.Round(victimStats.EloRating, 2)); // update after calculation - attackerStats.TimePlayed += (int)(DateTime.UtcNow - attackerStats.LastActive).TotalSeconds; - victimStats.TimePlayed += (int)(DateTime.UtcNow - victimStats.LastActive).TotalSeconds; + attackerStats.TimePlayed += (int) (DateTime.UtcNow - attackerStats.LastActive).TotalSeconds; + victimStats.TimePlayed += (int) (DateTime.UtcNow - victimStats.LastActive).TotalSeconds; attackerStats.LastActive = DateTime.UtcNow; victimStats.LastActive = DateTime.UtcNow; } @@ -1072,7 +1330,12 @@ namespace IW4MAdmin.Plugins.Stats.Helpers } double killSPM = scoreDifference / timeSinceLastCalc; - double spmMultiplier = 2.934 * Math.Pow(_servers[clientStats.ServerId].TeamCount(clientStats.Team == IW4Info.Team.Allies ? IW4Info.Team.Axis : IW4Info.Team.Allies), -0.454); + double spmMultiplier = 2.934 * + Math.Pow( + _servers[clientStats.ServerId] + .TeamCount((IW4Info.Team) clientStats.Team == IW4Info.Team.Allies + ? IW4Info.Team.Axis + : IW4Info.Team.Allies), -0.454); killSPM *= Math.Max(1, spmMultiplier); // update this for ac tracking @@ -1080,15 +1343,17 @@ namespace IW4MAdmin.Plugins.Stats.Helpers // calculate how much the KDR should weigh // 1.637 is a Eddie-Generated number that weights the KDR nicely - double currentKDR = clientStats.SessionDeaths == 0 ? clientStats.SessionKills : clientStats.SessionKills / clientStats.SessionDeaths; + double currentKDR = clientStats.SessionDeaths == 0 + ? clientStats.SessionKills + : clientStats.SessionKills / clientStats.SessionDeaths; double alpha = Math.Sqrt(2) / Math.Min(600, Math.Max(clientStats.Kills + clientStats.Deaths, 1)); clientStats.RollingWeightedKDR = (alpha * currentKDR) + (1.0 - alpha) * clientStats.KDR; double KDRWeight = Math.Round(Math.Pow(clientStats.RollingWeightedKDR, 1.637 / Math.E), 3); // calculate the weight of the new play time against last 10 hours of gameplay - int totalPlayTime = (clientStats.TimePlayed == 0) ? - (int)(DateTime.UtcNow - clientStats.LastActive).TotalSeconds : - clientStats.TimePlayed + (int)(DateTime.UtcNow - clientStats.LastActive).TotalSeconds; + int totalPlayTime = (clientStats.TimePlayed == 0) + ? (int) (DateTime.UtcNow - clientStats.LastActive).TotalSeconds + : clientStats.TimePlayed + (int) (DateTime.UtcNow - clientStats.LastActive).TotalSeconds; double SPMAgainstPlayWeight = timeSinceLastCalc / Math.Min(600, (totalPlayTime / 60.0)); @@ -1107,13 +1372,15 @@ namespace IW4MAdmin.Plugins.Stats.Helpers // fixme: how does this happen? if (double.IsNaN(clientStats.SPM) || double.IsNaN(clientStats.Skill)) { - _log.LogWarning("clientStats SPM/Skill NaN {@killInfo}", new {killSPM, KDRWeight, totalPlayTime, SPMAgainstPlayWeight, clientStats, scoreDifference}); + _log.LogWarning("clientStats SPM/Skill NaN {@killInfo}", + new {killSPM, KDRWeight, totalPlayTime, SPMAgainstPlayWeight, clientStats, scoreDifference}); clientStats.SPM = 0; clientStats.Skill = 0; } clientStats.LastStatCalculation = DateTime.UtcNow; //clientStats.LastScore = clientStats.SessionScore; + clientStats.UpdatedAt = DateTime.UtcNow; return clientStats; } @@ -1161,13 +1428,13 @@ namespace IW4MAdmin.Plugins.Stats.Helpers public void ResetStats(EFClient client) { var stats = client.GetAdditionalProperty(CLIENT_STATS_KEY); - + // the cached stats have not been loaded yet if (stats == null) { return; } - + stats.Kills = 0; stats.Deaths = 0; stats.SPM = 0; @@ -1253,8 +1520,8 @@ namespace IW4MAdmin.Plugins.Stats.Helpers long? serverId; serverId = serverModels.FirstOrDefault(_server => _server.ServerId == server.EndPoint || - _server.EndPoint == server.ToString() || - _server.ServerId == id)?.ServerId; + _server.EndPoint == server.ToString() || + _server.ServerId == id)?.ServerId; if (!serverId.HasValue) { @@ -1264,4 +1531,4 @@ namespace IW4MAdmin.Plugins.Stats.Helpers return serverId.Value; } } -} +} \ No newline at end of file diff --git a/Plugins/Stats/Helpers/StatsResourceQueryHelper.cs b/Plugins/Stats/Helpers/StatsResourceQueryHelper.cs index 219f671e..165f12de 100644 --- a/Plugins/Stats/Helpers/StatsResourceQueryHelper.cs +++ b/Plugins/Stats/Helpers/StatsResourceQueryHelper.cs @@ -1,11 +1,12 @@ -using IW4MAdmin.Plugins.Stats.Models; -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; using SharedLibraryCore.Helpers; using SharedLibraryCore.Interfaces; using Stats.Dtos; using System; using System.Linq; using System.Threading.Tasks; +using Data.Abstractions; +using Data.Models.Client.Stats; namespace Stats.Helpers { @@ -48,7 +49,7 @@ namespace Stats.Helpers ServerId = _stats.ServerId, Kills = _stats.Kills, Deaths = _stats.Deaths, - Performance = Math.Round((_stats.EloRating + _stats.Skill) / 2.0, 2), + Performance = Math.Round(_stats.EloRating * 1/3.0 + _stats.Skill * 2/3.0, 2), ScorePerMinute = _stats.SPM, LastPlayed = _stats.Client.LastConnection, TotalSecondsPlayed = _stats.TimePlayed, diff --git a/Plugins/Stats/Helpers/WeaponNameExtensions.cs b/Plugins/Stats/Helpers/WeaponNameExtensions.cs new file mode 100644 index 00000000..76da43b0 --- /dev/null +++ b/Plugins/Stats/Helpers/WeaponNameExtensions.cs @@ -0,0 +1,10 @@ +using Data.Models.Client.Stats; + +namespace Stats.Helpers +{ + public static class WeaponNameExtensions + { + public static string RebuildWeaponName(this EFClientHitStatistic stat) => + $"{stat.Weapon?.Name}{string.Join("_", stat.WeaponAttachmentCombo?.Attachment1?.Name, stat.WeaponAttachmentCombo?.Attachment2?.Name, stat.WeaponAttachmentCombo?.Attachment3?.Name)}"; + } +} \ No newline at end of file diff --git a/Plugins/Stats/Models/ModelConfiguration.cs b/Plugins/Stats/Models/ModelConfiguration.cs deleted file mode 100644 index b2427afc..00000000 --- a/Plugins/Stats/Models/ModelConfiguration.cs +++ /dev/null @@ -1,43 +0,0 @@ -using IW4MAdmin.Plugins.Stats.Models; -using Microsoft.EntityFrameworkCore; -using SharedLibraryCore.Interfaces; - -namespace Stats.Models -{ - public class ModelConfiguration : IModelConfiguration - { - public void Configure(ModelBuilder builder) - { - builder.Entity() - .HasKey(cs => new { cs.ClientId, cs.ServerId }); - - // fix linking from SQLCe - builder.Entity() - .Property(c => c.EFClientStatisticsClientId) - .HasColumnName("EFClientStatisticsClientId"); - - builder.Entity() - .Property(c => c.EFClientStatisticsServerId) - .HasColumnName("EFClientStatisticsServerId"); - - builder.Entity() - .HasIndex(p => new { p.Performance, p.Ranking, p.When }); - - builder.Entity() - .HasIndex(p => new { p.When, p.ServerId, p.Performance, p.ActivityAmount }); - - builder.Entity(message => - { - message.HasIndex(p => p.TimeSent); - }); - - // force pluralization - builder.Entity().ToTable("EFClientKills"); - builder.Entity().ToTable("EFClientMessages"); - builder.Entity().ToTable("EFClientStatistics"); - builder.Entity().ToTable("EFHitLocationCounts"); - builder.Entity().ToTable("EFServers"); - builder.Entity().ToTable("EFServerStatistics"); - } - } -} diff --git a/Plugins/Stats/Plugin.cs b/Plugins/Stats/Plugin.cs index d21e613a..fe6456f4 100644 --- a/Plugins/Stats/Plugin.cs +++ b/Plugins/Stats/Plugin.cs @@ -1,10 +1,7 @@ using IW4MAdmin.Plugins.Stats.Config; using IW4MAdmin.Plugins.Stats.Helpers; -using IW4MAdmin.Plugins.Stats.Models; using Microsoft.EntityFrameworkCore; using SharedLibraryCore; -using SharedLibraryCore.Database; -using SharedLibraryCore.Database.Models; using SharedLibraryCore.Dtos.Meta.Responses; using SharedLibraryCore.Helpers; using SharedLibraryCore.Interfaces; @@ -14,8 +11,16 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Data.Abstractions; +using Data.Models.Client; +using Data.Models.Client.Stats; +using Data.Models.Server; +using Humanizer; using Microsoft.Extensions.Logging; using SharedLibraryCore.Commands; +using IW4MAdmin.Plugins.Stats.Client.Abstractions; +using Stats.Client.Abstractions; +using EFClient = SharedLibraryCore.Database.Models.EFClient; namespace IW4MAdmin.Plugins.Stats { @@ -37,9 +42,12 @@ namespace IW4MAdmin.Plugins.Stats private readonly IResourceQueryHelper _chatQueryHelper; private readonly ILogger _managerLogger; private readonly ILogger _logger; + private readonly List _statCalculators; + private readonly IServerDistributionCalculator _serverDistributionCalculator; public Plugin(ILogger logger, IConfigurationHandlerFactory configurationHandlerFactory, IDatabaseContextFactory databaseContextFactory, - ITranslationLookup translationLookup, IMetaService metaService, IResourceQueryHelper chatQueryHelper, ILogger managerLogger) + ITranslationLookup translationLookup, IMetaService metaService, IResourceQueryHelper chatQueryHelper, ILogger managerLogger, + IEnumerable statCalculators, IServerDistributionCalculator serverDistributionCalculator) { Config = configurationHandlerFactory.GetConfigurationHandler("StatsPluginSettings"); _databaseContextFactory = databaseContextFactory; @@ -48,6 +56,8 @@ namespace IW4MAdmin.Plugins.Stats _chatQueryHelper = chatQueryHelper; _managerLogger = managerLogger; _logger = logger; + _statCalculators = statCalculators.ToList(); + _serverDistributionCalculator = serverDistributionCalculator; } public async Task OnEventAsync(GameEvent E, Server S) @@ -149,6 +159,16 @@ namespace IW4MAdmin.Plugins.Stats } break; } + + if (!Config.Configuration().EnableAdvancedMetrics) + { + return; + } + + foreach (var calculator in _statCalculators) + { + await calculator.CalculateForEvent(E); + } } public async Task OnLoadAsync(IManager manager) @@ -267,20 +287,20 @@ namespace IW4MAdmin.Plugins.Stats if (clientStats.Where(cs => cs.HitLocations.Count > 0).FirstOrDefault() != null) { chestRatio = Math.Round((clientStats.Where(c => c.HitLocations.Count > 0).Sum(c => - c.HitLocations.First(hl => hl.Location == IW4Info.HitLocation.torso_upper).HitCount) / + c.HitLocations.First(hl => hl.Location == (int)IW4Info.HitLocation.torso_upper).HitCount) / (double)clientStats.Where(c => c.HitLocations.Count > 0) - .Sum(c => c.HitLocations.Where(hl => hl.Location != IW4Info.HitLocation.none).Sum(f => f.HitCount))) * 100.0, 0); + .Sum(c => c.HitLocations.Where(hl => hl.Location != (int)IW4Info.HitLocation.none).Sum(f => f.HitCount))) * 100.0, 0); abdomenRatio = Math.Round((clientStats.Where(c => c.HitLocations.Count > 0).Sum(c => - c.HitLocations.First(hl => hl.Location == IW4Info.HitLocation.torso_lower).HitCount) / - (double)clientStats.Where(c => c.HitLocations.Count > 0).Sum(c => c.HitLocations.Where(hl => hl.Location != IW4Info.HitLocation.none).Sum(f => f.HitCount))) * 100.0, 0); + c.HitLocations.First(hl => hl.Location == (int)IW4Info.HitLocation.torso_lower).HitCount) / + (double)clientStats.Where(c => c.HitLocations.Count > 0).Sum(c => c.HitLocations.Where(hl => hl.Location != (int)IW4Info.HitLocation.none).Sum(f => f.HitCount))) * 100.0, 0); - chestAbdomenRatio = Math.Round((clientStats.Where(c => c.HitLocations.Count > 0).Sum(cs => cs.HitLocations.First(hl => hl.Location == IW4Info.HitLocation.torso_upper).HitCount) / - (double)clientStats.Where(c => c.HitLocations.Count > 0).Sum(cs => cs.HitLocations.First(hl => hl.Location == IW4Info.HitLocation.torso_lower).HitCount)) * 100.0, 0); + chestAbdomenRatio = Math.Round((clientStats.Where(c => c.HitLocations.Count > 0).Sum(cs => cs.HitLocations.First(hl => hl.Location == (int)IW4Info.HitLocation.torso_upper).HitCount) / + (double)clientStats.Where(c => c.HitLocations.Count > 0).Sum(cs => cs.HitLocations.First(hl => hl.Location == (int)IW4Info.HitLocation.torso_lower).HitCount)) * 100.0, 0); - headRatio = Math.Round((clientStats.Where(c => c.HitLocations.Count > 0).Sum(cs => cs.HitLocations.First(hl => hl.Location == IW4Info.HitLocation.head).HitCount) / + headRatio = Math.Round((clientStats.Where(c => c.HitLocations.Count > 0).Sum(cs => cs.HitLocations.First(hl => hl.Location == (int)IW4Info.HitLocation.head).HitCount) / (double)clientStats.Where(c => c.HitLocations.Count > 0) - .Sum(c => c.HitLocations.Where(hl => hl.Location != IW4Info.HitLocation.none).Sum(f => f.HitCount))) * 100.0, 0); + .Sum(c => c.HitLocations.Where(hl => hl.Location != (int)IW4Info.HitLocation.none).Sum(f => f.HitCount))) * 100.0, 0); var validOffsets = clientStats.Where(c => c.HitLocations.Count(hl => hl.HitCount > 0) > 0).SelectMany(hl => hl.HitLocations); hitOffsetAverage = validOffsets.Sum(o => o.HitCount * o.HitOffsetAverage) / (double)validOffsets.Sum(o => o.HitCount); @@ -402,7 +422,7 @@ namespace IW4MAdmin.Plugins.Stats async Task topStats(Server s) { // todo: this needs to needs to be updated when we DI the lookup - return string.Join(Environment.NewLine, await Commands.TopStats.GetTopStats(s, Utilities.CurrentLocalization.LocalizationIndex, _databaseContextFactory)); + return string.Join(Environment.NewLine, await Commands.TopStats.GetTopStats(s, Utilities.CurrentLocalization.LocalizationIndex)); } async Task mostPlayed(Server s) @@ -423,8 +443,17 @@ namespace IW4MAdmin.Plugins.Stats manager.GetMessageTokens().Add(new MessageToken("MOSTPLAYED", mostPlayed)); manager.GetMessageTokens().Add(new MessageToken("MOSTKILLS", mostKills)); + if (Config.Configuration().EnableAdvancedMetrics) + { + foreach (var calculator in _statCalculators) + { + await calculator.GatherDependencies(); + } + } + ServerManager = manager; - Manager = new StatManager(_managerLogger, manager, _databaseContextFactory, Config); + Manager = new StatManager(_managerLogger, manager, _databaseContextFactory, Config, _serverDistributionCalculator); + await _serverDistributionCalculator.Initialize(); } public Task OnTickAsync(Server S) diff --git a/Plugins/Stats/Stats.csproj b/Plugins/Stats/Stats.csproj index 79344a62..1dd2a9c9 100644 --- a/Plugins/Stats/Stats.csproj +++ b/Plugins/Stats/Stats.csproj @@ -15,9 +15,9 @@ 8.0 false - + - + diff --git a/Plugins/Web/StatsWeb/Extensions/SearchQueryExtensions.cs b/Plugins/Web/StatsWeb/Extensions/SearchQueryExtensions.cs deleted file mode 100644 index bde74b82..00000000 --- a/Plugins/Web/StatsWeb/Extensions/SearchQueryExtensions.cs +++ /dev/null @@ -1,77 +0,0 @@ -using SharedLibraryCore.Dtos; -using Stats.Dtos; -using System; -using System.Linq; - -namespace StatsWeb.Extensions -{ - public static class SearchQueryExtensions - { - private const int MAX_MESSAGES = 100; - - /// - /// todo: lets abstract this out to a generic buildable query - /// this is just a dirty PoC - /// - /// - /// - public static ChatSearchQuery ParseSearchInfo(this string query, int count, int offset) - { - string[] filters = query.Split('|'); - var searchRequest = new ChatSearchQuery - { - Filter = query, - Count = count, - Offset = offset - }; - - // sanity checks - searchRequest.Count = Math.Min(searchRequest.Count, MAX_MESSAGES); - searchRequest.Count = Math.Max(searchRequest.Count, 0); - searchRequest.Offset = Math.Max(searchRequest.Offset, 0); - - if (filters.Length > 1) - { - if (filters[0].ToLower() != "chat") - { - throw new ArgumentException("Query is not compatible with chat"); - } - - foreach (string filter in filters.Skip(1)) - { - string[] args = filter.Split(' '); - - if (args.Length > 1) - { - string recombinedArgs = string.Join(' ', args.Skip(1)); - switch (args[0].ToLower()) - { - case "before": - searchRequest.SentBefore = DateTime.Parse(recombinedArgs); - break; - case "after": - searchRequest.SentAfter = DateTime.Parse(recombinedArgs); - break; - case "server": - searchRequest.ServerId = args[1]; - break; - case "client": - searchRequest.ClientId = int.Parse(args[1]); - break; - case "contains": - searchRequest.MessageContains = string.Join(' ', args.Skip(1)); - break; - case "sort": - searchRequest.Direction = Enum.Parse(args[1], ignoreCase: true); - break; - } - } - } - - return searchRequest; - } - - throw new ArgumentException("No filters specified for chat search"); - } - } -} diff --git a/Plugins/Web/StatsWeb/StatsWeb.csproj b/Plugins/Web/StatsWeb/StatsWeb.csproj deleted file mode 100644 index 65b5a055..00000000 --- a/Plugins/Web/StatsWeb/StatsWeb.csproj +++ /dev/null @@ -1,35 +0,0 @@ - - - netcoreapp3.1 - true - true - false - false - true - Debug;Release;Prerelease - 8.0 - - Library - - Always - - - - - - - - false - - - - - - Never - - - - - - - diff --git a/Plugins/Web/StatsWeb/ViewComponents/TopPlayersViewComponent.cs b/Plugins/Web/StatsWeb/ViewComponents/TopPlayersViewComponent.cs deleted file mode 100644 index d6951bc0..00000000 --- a/Plugins/Web/StatsWeb/ViewComponents/TopPlayersViewComponent.cs +++ /dev/null @@ -1,28 +0,0 @@ -using IW4MAdmin.Plugins.Stats; -using IW4MAdmin.Plugins.Stats.Helpers; -using Microsoft.AspNetCore.Mvc; -using System.Linq; -using System.Threading.Tasks; - -namespace IW4MAdmin.Plugins.Web.StatsWeb.Controllers -{ - public class TopPlayersViewComponent : ViewComponent - { - public async Task InvokeAsync(int count, int offset, long? serverId = null) - { - if (serverId == 0) - { - serverId = null; - } - - var server = Plugin.ServerManager.GetServers().FirstOrDefault(_server => _server.EndPoint == serverId); - - if (server != null) - { - serverId = StatManager.GetIdForServer(server); - } - - return View("_List", await Plugin.Manager.GetTopStats(offset, count, serverId)); - } - } -} diff --git a/Plugins/Web/StatsWeb/Views/Stats/Components/TopPlayers/_List.cshtml b/Plugins/Web/StatsWeb/Views/Stats/Components/TopPlayers/_List.cshtml deleted file mode 100644 index b747b6fc..00000000 --- a/Plugins/Web/StatsWeb/Views/Stats/Components/TopPlayers/_List.cshtml +++ /dev/null @@ -1,91 +0,0 @@ -@model List -@{ - Layout = null; - var loc = SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex.Set; - double getDeviation(double deviations) => Math.Pow(Math.E, 5.259 + (deviations * 0.812)); - string rankIcon(double elo) - { - if (elo >= getDeviation(-0.75) && elo < getDeviation(1.25)) - { - return "0_no-place/menu_div_no_place.png"; - } - if (elo >= getDeviation(0.125) && elo < getDeviation(0.625)) - { - return "1_iron/menu_div_iron_sub03.png"; - } - if (elo >= getDeviation(0.625) && elo < getDeviation(1.0)) - { - return "2_bronze/menu_div_bronze_sub03.png"; - } - if (elo >= getDeviation(1.0) && elo < getDeviation(1.25)) - { - return "3_silver/menu_div_silver_sub03.png"; - } - if (elo >= getDeviation(1.25) && elo < getDeviation(1.5)) - { - return "4_gold/menu_div_gold_sub03.png"; - } - if (elo >= getDeviation(1.5) && elo < getDeviation(1.75)) - { - return "5_platinum/menu_div_platinum_sub03.png"; - } - if (elo >= getDeviation(1.75) && elo < getDeviation(2.0)) - { - return "6_semipro/menu_div_semipro_sub03.png"; - } - if (elo >= getDeviation(2.0)) - { - return "7_pro/menu_div_pro_sub03.png"; - } - - return "0_no-place/menu_div_no_place.png"; - } -} - -@if (Model.Count == 0) -{ -
@SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_NOQUALIFY"]
-} -@foreach (var stat in Model) -{ -
-
-
-
#@stat.Ranking
- @if (stat.RatingChange > 0) - { -
-
-
@stat.RatingChange
-
- } - @if (stat.RatingChange < 0) - { -
-
@Math.Abs(stat.RatingChange)
-
-
- } - - - - -
- - @stat.Performance @loc["PLUGINS_STATS_COMMANDS_PERFORMANCE"]
- @stat.KDR @loc["PLUGINS_STATS_TEXT_KDR"] - @stat.Kills @loc["PLUGINS_STATS_TEXT_KILLS"] - @stat.Deaths @loc["PLUGINS_STATS_TEXT_DEATHS"]
- @loc["WEBFRONT_PROFILE_PLAYER"] @stat.TimePlayed @loc["GLOBAL_TIME_HOURS"]
- @loc["WEBFRONT_PROFILE_LSEEN"] @stat.LastSeen @loc["WEBFRONT_PENALTY_TEMPLATE_AGO"] -
- -
- -
- -
- -
-
-} diff --git a/Plugins/Web/StatsWeb/Views/_ViewImports.cshtml b/Plugins/Web/StatsWeb/Views/_ViewImports.cshtml deleted file mode 100644 index 1ba5217d..00000000 --- a/Plugins/Web/StatsWeb/Views/_ViewImports.cshtml +++ /dev/null @@ -1,3 +0,0 @@ -@using SharedLibraryCore -@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers -@addTagHelper *, SharedLibraryCore \ No newline at end of file diff --git a/Plugins/Web/StatsWeb/wwwroot/images/icons/0_no-place/menu_div_no_place.png b/Plugins/Web/StatsWeb/wwwroot/images/icons/0_no-place/menu_div_no_place.png deleted file mode 100644 index cc9e0e56..00000000 Binary files a/Plugins/Web/StatsWeb/wwwroot/images/icons/0_no-place/menu_div_no_place.png and /dev/null differ diff --git a/Plugins/Web/StatsWeb/wwwroot/images/icons/1_iron/menu_div_iron_sub03.png b/Plugins/Web/StatsWeb/wwwroot/images/icons/1_iron/menu_div_iron_sub03.png deleted file mode 100644 index 9ee5d882..00000000 Binary files a/Plugins/Web/StatsWeb/wwwroot/images/icons/1_iron/menu_div_iron_sub03.png and /dev/null differ diff --git a/Plugins/Web/StatsWeb/wwwroot/images/icons/2_bronze/menu_div_bronze_sub03.png b/Plugins/Web/StatsWeb/wwwroot/images/icons/2_bronze/menu_div_bronze_sub03.png deleted file mode 100644 index c644c8ed..00000000 Binary files a/Plugins/Web/StatsWeb/wwwroot/images/icons/2_bronze/menu_div_bronze_sub03.png and /dev/null differ diff --git a/Plugins/Web/StatsWeb/wwwroot/images/icons/3_silver/menu_div_silver_sub03.png b/Plugins/Web/StatsWeb/wwwroot/images/icons/3_silver/menu_div_silver_sub03.png deleted file mode 100644 index 8eb75894..00000000 Binary files a/Plugins/Web/StatsWeb/wwwroot/images/icons/3_silver/menu_div_silver_sub03.png and /dev/null differ diff --git a/Plugins/Web/StatsWeb/wwwroot/images/icons/4_gold/menu_div_gold_sub03.png b/Plugins/Web/StatsWeb/wwwroot/images/icons/4_gold/menu_div_gold_sub03.png deleted file mode 100644 index f44ef164..00000000 Binary files a/Plugins/Web/StatsWeb/wwwroot/images/icons/4_gold/menu_div_gold_sub03.png and /dev/null differ diff --git a/Plugins/Web/StatsWeb/wwwroot/images/icons/5_platinum/menu_div_platinum_sub03.png b/Plugins/Web/StatsWeb/wwwroot/images/icons/5_platinum/menu_div_platinum_sub03.png deleted file mode 100644 index 5738a84a..00000000 Binary files a/Plugins/Web/StatsWeb/wwwroot/images/icons/5_platinum/menu_div_platinum_sub03.png and /dev/null differ diff --git a/Plugins/Web/StatsWeb/wwwroot/images/icons/6_semipro/menu_div_semipro_sub03.png b/Plugins/Web/StatsWeb/wwwroot/images/icons/6_semipro/menu_div_semipro_sub03.png deleted file mode 100644 index 284818b7..00000000 Binary files a/Plugins/Web/StatsWeb/wwwroot/images/icons/6_semipro/menu_div_semipro_sub03.png and /dev/null differ diff --git a/Plugins/Web/StatsWeb/wwwroot/images/icons/7_pro/menu_div_pro_sub03.png b/Plugins/Web/StatsWeb/wwwroot/images/icons/7_pro/menu_div_pro_sub03.png deleted file mode 100644 index 23ba7eae..00000000 Binary files a/Plugins/Web/StatsWeb/wwwroot/images/icons/7_pro/menu_div_pro_sub03.png and /dev/null differ diff --git a/Plugins/Welcome/Plugin.cs b/Plugins/Welcome/Plugin.cs index 5d19ac1d..0498bd4c 100644 --- a/Plugins/Welcome/Plugin.cs +++ b/Plugins/Welcome/Plugin.cs @@ -3,17 +3,15 @@ using System.Threading.Tasks; using SharedLibraryCore; using SharedLibraryCore.Interfaces; -using SharedLibraryCore.Configuration; -using SharedLibraryCore.Services; using SharedLibraryCore.Database.Models; using System.Linq; -using SharedLibraryCore.Database; using Microsoft.EntityFrameworkCore; using System.Net; using Newtonsoft.Json.Linq; -using System.Text.RegularExpressions; -using static SharedLibraryCore.Database.Models.EFClient; using Humanizer; +using Data.Abstractions; +using Data.Models; +using static Data.Models.Client.EFClient; namespace IW4MAdmin.Plugins.Welcome { diff --git a/Plugins/Welcome/Welcome.csproj b/Plugins/Welcome/Welcome.csproj index 804718cc..d91cdf82 100644 --- a/Plugins/Welcome/Welcome.csproj +++ b/Plugins/Welcome/Welcome.csproj @@ -15,12 +15,12 @@ Latest - - - - + + + + diff --git a/SharedLibraryCore/BaseController.cs b/SharedLibraryCore/BaseController.cs index d03dfac7..c9107042 100644 --- a/SharedLibraryCore/BaseController.cs +++ b/SharedLibraryCore/BaseController.cs @@ -1,9 +1,7 @@ using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; -using SharedLibraryCore.Database; using SharedLibraryCore.Database.Models; using SharedLibraryCore.Dtos; using SharedLibraryCore.Interfaces; @@ -12,6 +10,8 @@ using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; +using Data.Context; +using Data.Models; namespace SharedLibraryCore { @@ -25,7 +25,7 @@ namespace SharedLibraryCore public IManager Manager { get; private set; } protected readonly DatabaseContext Context; protected bool Authorized { get; set; } - protected SharedLibraryCore.Localization.TranslationLookup Localization { get; private set; } + protected Localization.TranslationLookup Localization { get; private set; } protected EFClient Client { get; private set; } private static readonly byte[] LocalHost = { 127, 0, 0, 1 }; private static string SocialLink; diff --git a/SharedLibraryCore/Commands/AddClientTagCommand.cs b/SharedLibraryCore/Commands/AddClientTagCommand.cs index c696f5ad..9cd7c408 100644 --- a/SharedLibraryCore/Commands/AddClientTagCommand.cs +++ b/SharedLibraryCore/Commands/AddClientTagCommand.cs @@ -2,6 +2,7 @@ using SharedLibraryCore.Database.Models; using SharedLibraryCore.Interfaces; using System.Threading.Tasks; +using Data.Models; namespace SharedLibraryCore.Commands { diff --git a/SharedLibraryCore/Commands/ListClientTags.cs b/SharedLibraryCore/Commands/ListClientTags.cs index ef1f23f1..7ce5588c 100644 --- a/SharedLibraryCore/Commands/ListClientTags.cs +++ b/SharedLibraryCore/Commands/ListClientTags.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Data.Models; namespace SharedLibraryCore.Commands { diff --git a/SharedLibraryCore/Commands/NativeCommands.cs b/SharedLibraryCore/Commands/NativeCommands.cs index abd659b6..eb403798 100644 --- a/SharedLibraryCore/Commands/NativeCommands.cs +++ b/SharedLibraryCore/Commands/NativeCommands.cs @@ -1,6 +1,5 @@ using Microsoft.EntityFrameworkCore; using SharedLibraryCore.Configuration; -using SharedLibraryCore.Database; using SharedLibraryCore.Database.Models; using SharedLibraryCore.Helpers; using SharedLibraryCore.Interfaces; @@ -12,9 +11,11 @@ using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; +using Data.Abstractions; +using Data.Models; using Microsoft.Extensions.Logging; using Serilog.Context; -using static SharedLibraryCore.Database.Models.EFClient; +using static Data.Models.Client.EFClient; namespace SharedLibraryCore.Commands { @@ -1474,6 +1475,7 @@ namespace SharedLibraryCore.Commands inactiveUsers = await context.Clients .Where(c => c.Level > Permission.Flagged && c.Level <= Permission.Moderator) .Where(c => c.LastConnection < lastActive) + .Select(c => c.ToPartialClient()) .ToListAsync(); inactiveUsers.ForEach(c => c.SetLevel(Permission.User, E.Origin)); await context.SaveChangesAsync(); diff --git a/SharedLibraryCore/Commands/RemoveClientTagCommand.cs b/SharedLibraryCore/Commands/RemoveClientTagCommand.cs index 10c52910..95e7e16b 100644 --- a/SharedLibraryCore/Commands/RemoveClientTagCommand.cs +++ b/SharedLibraryCore/Commands/RemoveClientTagCommand.cs @@ -2,6 +2,7 @@ using SharedLibraryCore.Database.Models; using SharedLibraryCore.Interfaces; using System.Threading.Tasks; +using Data.Models; namespace SharedLibraryCore.Commands { diff --git a/SharedLibraryCore/Commands/SetClientTagCommand.cs b/SharedLibraryCore/Commands/SetClientTagCommand.cs index c0952c8a..52e3628c 100644 --- a/SharedLibraryCore/Commands/SetClientTagCommand.cs +++ b/SharedLibraryCore/Commands/SetClientTagCommand.cs @@ -3,6 +3,7 @@ using SharedLibraryCore.Database.Models; using SharedLibraryCore.Interfaces; using System.Linq; using System.Threading.Tasks; +using Data.Models; namespace SharedLibraryCore.Commands { diff --git a/SharedLibraryCore/Commands/UnsetClientTagCommand.cs b/SharedLibraryCore/Commands/UnsetClientTagCommand.cs index 4dbd2a1c..96737acc 100644 --- a/SharedLibraryCore/Commands/UnsetClientTagCommand.cs +++ b/SharedLibraryCore/Commands/UnsetClientTagCommand.cs @@ -3,6 +3,7 @@ using SharedLibraryCore.Database.Models; using SharedLibraryCore.Interfaces; using System.Linq; using System.Threading.Tasks; +using Data.Models; namespace SharedLibraryCore.Commands { diff --git a/SharedLibraryCore/Configuration/ApplicationConfiguration.cs b/SharedLibraryCore/Configuration/ApplicationConfiguration.cs index 3ec1ad80..630f0da3 100644 --- a/SharedLibraryCore/Configuration/ApplicationConfiguration.cs +++ b/SharedLibraryCore/Configuration/ApplicationConfiguration.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; -using static SharedLibraryCore.Database.Models.EFClient; +using static Data.Models.Client.EFClient; namespace SharedLibraryCore.Configuration { diff --git a/SharedLibraryCore/Configuration/CommandProperties.cs b/SharedLibraryCore/Configuration/CommandProperties.cs index 88e52914..3643c8c5 100644 --- a/SharedLibraryCore/Configuration/CommandProperties.cs +++ b/SharedLibraryCore/Configuration/CommandProperties.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; using Newtonsoft.Json.Converters; -using static SharedLibraryCore.Database.Models.EFClient; +using static Data.Models.Client.EFClient; using static SharedLibraryCore.Server; namespace SharedLibraryCore.Configuration diff --git a/SharedLibraryCore/Configuration/DefaultConfiguration.cs b/SharedLibraryCore/Configuration/DefaultSettings.cs similarity index 80% rename from SharedLibraryCore/Configuration/DefaultConfiguration.cs rename to SharedLibraryCore/Configuration/DefaultSettings.cs index d6f56090..d9ebd0a6 100644 --- a/SharedLibraryCore/Configuration/DefaultConfiguration.cs +++ b/SharedLibraryCore/Configuration/DefaultSettings.cs @@ -2,13 +2,14 @@ namespace SharedLibraryCore.Configuration { - public class DefaultConfiguration : IBaseConfiguration + public class DefaultSettings : IBaseConfiguration { public string[] AutoMessages { get; set; } public string[] GlobalRules { get; set; } public MapConfiguration[] Maps { get; set; } public QuickMessageConfiguration[] QuickMessages {get; set;} public string[] DisallowedClientNames { get; set; } + public GameStringConfiguration GameStrings { get; set; } public IBaseConfiguration Generate() => this; diff --git a/SharedLibraryCore/Configuration/GameStringConfiguration.cs b/SharedLibraryCore/Configuration/GameStringConfiguration.cs new file mode 100644 index 00000000..9f465b2a --- /dev/null +++ b/SharedLibraryCore/Configuration/GameStringConfiguration.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using Humanizer; + +namespace SharedLibraryCore.Configuration +{ + public class GameStringConfiguration : Dictionary> + { + public string GetStringForGame(string key, Server.Game game = Server.Game.IW4) + { + if (key == null) + { + return null; + } + + if (!ContainsKey(game)) + { + return key.Transform(To.TitleCase); + } + + var strings = this[game]; + return !strings.ContainsKey(key) ? key.Transform(To.TitleCase) : strings[key]; + } + } +} \ No newline at end of file diff --git a/SharedLibraryCore/Database/DatabaseContext.cs b/SharedLibraryCore/Database/DatabaseContext.cs deleted file mode 100644 index c7e7a920..00000000 --- a/SharedLibraryCore/Database/DatabaseContext.cs +++ /dev/null @@ -1,196 +0,0 @@ -using Microsoft.Data.Sqlite; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Console; -using SharedLibraryCore.Database.Models; -using SharedLibraryCore.Interfaces; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Threading; -using System.Threading.Tasks; - -namespace SharedLibraryCore.Database -{ - public abstract class DatabaseContext : DbContext - { - public DbSet Clients { get; set; } - public DbSet Aliases { get; set; } - public DbSet AliasLinks { get; set; } - public DbSet Penalties { get; set; } - public DbSet EFMeta { get; set; } - public DbSet EFChangeHistory { get; set; } - - private void SetAuditColumns() - { - return; - var entries = ChangeTracker - .Entries() - .Where(e => e.Entity is SharedEntity && ( - e.State == EntityState.Added - || e.State == EntityState.Modified)).ToList(); - - foreach (var entityEntry in entries) - { - if (entityEntry.State == EntityState.Added) - { - //((SharedEntity)entityEntry.Entity).CreatedDateTime = DateTime.UtcNow; - } - - else - { - //((SharedEntity)entityEntry.Entity).UpdatedDateTime = DateTime.UtcNow; - } - } - } - - public DatabaseContext() - { - if (!Utilities.IsMigration) - { - throw new InvalidOperationException(); - } - } - - public DatabaseContext(DbContextOptions options) : base(options) - { - - } - - protected DatabaseContext(DbContextOptions options) : base(options) - { - - } - - public override Task SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default) - { - SetAuditColumns(); - return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken); - } - - public override int SaveChanges() - { - SetAuditColumns(); - return base.SaveChanges(); - } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - // make network id unique - modelBuilder.Entity(entity => - { - entity.HasIndex(e => e.NetworkId).IsUnique(); - }); - - modelBuilder.Entity(entity => - { - entity.HasOne(p => p.Offender) - .WithMany(c => c.ReceivedPenalties) - .HasForeignKey(c => c.OffenderId) - .OnDelete(DeleteBehavior.Restrict); - - entity.HasOne(p => p.Punisher) - .WithMany(p => p.AdministeredPenalties) - .HasForeignKey(c => c.PunisherId) - .OnDelete(DeleteBehavior.Restrict); - - entity.Property(p => p.Expires) - .IsRequired(false); - }); - - modelBuilder.Entity(entity => - { - entity.HasMany(e => e.Children) - .WithOne(a => a.Link) - .HasForeignKey(k => k.LinkId) - .OnDelete(DeleteBehavior.Restrict); - }); - - modelBuilder.Entity(ent => - { - ent.Property(a => a.IPAddress).IsRequired(false); - ent.HasIndex(a => a.IPAddress); - ent.Property(a => a.Name).HasMaxLength(24); - ent.HasIndex(a => a.Name); - ent.Property(_alias => _alias.SearchableName).HasMaxLength(24); - ent.HasIndex(_alias => _alias.SearchableName); - ent.HasIndex(_alias => new { _alias.Name, _alias.IPAddress }).IsUnique(); - }); - - modelBuilder.Entity(ent => - { - ent.HasIndex(_meta => _meta.Key); - ent.HasIndex(_meta => _meta.LinkedMetaId); - ent.HasOne(_meta => _meta.LinkedMeta) - .WithMany() - .OnDelete(DeleteBehavior.SetNull); - }); - - // force full name for database conversion - modelBuilder.Entity().ToTable("EFClients"); - modelBuilder.Entity().ToTable("EFAlias"); - modelBuilder.Entity().ToTable("EFAliasLinks"); - modelBuilder.Entity().ToTable("EFPenalties"); - - // adapted from - // https://aleemkhan.wordpress.com/2013/02/28/dynamically-adding-dbset-properties-in-dbcontext-for-entity-framework-code-first/ - - string pluginDir = Path.Join(Utilities.OperatingDirectory, "Plugins"); - - if (Utilities.IsDevelopment) - { - pluginDir = Path.Join(Utilities.OperatingDirectory, "..", "..", "..", "..", "BUILD", "Plugins"); - } - - IEnumerable directoryFiles = Enumerable.Empty(); - - try - { - directoryFiles = Directory.GetFiles(pluginDir).Where(f => f.EndsWith(".dll")); - } - - catch (DirectoryNotFoundException) - { - // this is just an ugly thing for unit testing - directoryFiles = Directory.GetFiles(@"X:\IW4MAdmin\Tests\ApplicationTests\bin\Debug\netcoreapp3.1").Where(f => f.EndsWith("dll")); - } - - foreach (string dllPath in directoryFiles) - { - Assembly library; - try - { - library = Assembly.LoadFrom(dllPath); - } - - // not a valid assembly, ie plugin support files - catch (Exception) - { - continue; - } - - var configurations = library.ExportedTypes.Where(c => c.GetInterfaces().FirstOrDefault(i => typeof(IModelConfiguration).IsAssignableFrom(i)) != null) - .Select(c => (IModelConfiguration)Activator.CreateInstance(c)); - - foreach (var configurable in configurations) - { - configurable.Configure(modelBuilder); - } - - foreach (var type in library.ExportedTypes) - { - if (type.IsClass && type.IsSubclassOf(typeof(SharedEntity))) - { - var method = modelBuilder.GetType().GetMethod("Entity", new[] { typeof(Type) }); - method.Invoke(modelBuilder, new[] { type }); - } - } - } - - base.OnModelCreating(modelBuilder); - } - } -} diff --git a/SharedLibraryCore/Dtos/Meta/Responses/ReceivedPenaltyResponse.cs b/SharedLibraryCore/Dtos/Meta/Responses/ReceivedPenaltyResponse.cs index 6911ab7f..9a796f01 100644 --- a/SharedLibraryCore/Dtos/Meta/Responses/ReceivedPenaltyResponse.cs +++ b/SharedLibraryCore/Dtos/Meta/Responses/ReceivedPenaltyResponse.cs @@ -1,5 +1,5 @@ using System; -using static SharedLibraryCore.Database.Models.EFPenalty; +using Data.Models; namespace SharedLibraryCore.Dtos.Meta.Responses { @@ -10,7 +10,7 @@ namespace SharedLibraryCore.Dtos.Meta.Responses public string OffenderName { get; set; } public string PunisherName { get; set; } public int PunisherClientId { get; set; } - public PenaltyType PenaltyType { get; set; } + public EFPenalty.PenaltyType PenaltyType { get; set; } public string Offense { get; set; } public string AutomatedOffense { get; set; } public DateTime? ExpirationDate { get; set; } diff --git a/SharedLibraryCore/Dtos/PenaltyInfo.cs b/SharedLibraryCore/Dtos/PenaltyInfo.cs index e8f4c887..f325227c 100644 --- a/SharedLibraryCore/Dtos/PenaltyInfo.cs +++ b/SharedLibraryCore/Dtos/PenaltyInfo.cs @@ -1,6 +1,6 @@ using System; -using static SharedLibraryCore.Database.Models.EFClient; -using static SharedLibraryCore.Database.Models.EFPenalty; +using Data.Models; +using static Data.Models.Client.EFClient; namespace SharedLibraryCore.Dtos { @@ -18,14 +18,14 @@ namespace SharedLibraryCore.Dtos public string PunisherLevelText => PunisherLevel.ToLocalizedLevelName(); public string Offense { get; set; } public string AutomatedOffense { get; set; } - public PenaltyType PenaltyType { get; set; } + public EFPenalty.PenaltyType PenaltyType { get; set; } public string PenaltyTypeText => PenaltyType.ToString(); public DateTime TimePunished { get; set; } public string TimePunishedString => TimePunished.HumanizeForCurrentCulture(); public string TimeRemaining => DateTime.UtcNow > Expires ? "" : $"{((Expires ?? DateTime.MaxValue).Year == DateTime.MaxValue.Year ? TimePunishedString : ((Expires ?? DateTime.MaxValue) - DateTime.UtcNow).HumanizeForCurrentCulture())}"; public bool Expired => Expires.HasValue && Expires <= DateTime.UtcNow; public DateTime? Expires { get; set; } - public override bool Sensitive => PenaltyType == PenaltyType.Flag || PenaltyType == PenaltyType.Unflag; + public override bool Sensitive => PenaltyType == EFPenalty.PenaltyType.Flag || PenaltyType == EFPenalty.PenaltyType.Unflag; public bool IsEvade { get; set; } public string AdditionalPenaltyInformation => $"{(!string.IsNullOrEmpty(AutomatedOffense) ? $" ({AutomatedOffense})" : "")}{(IsEvade ? $" ({Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PENALTY_EVADE"]})" : "")}"; } diff --git a/SharedLibraryCore/Dtos/PlayerInfo.cs b/SharedLibraryCore/Dtos/PlayerInfo.cs index eecaa615..d5aed2c7 100644 --- a/SharedLibraryCore/Dtos/PlayerInfo.cs +++ b/SharedLibraryCore/Dtos/PlayerInfo.cs @@ -1,8 +1,8 @@ -using SharedLibraryCore.Database.Models; -using SharedLibraryCore.Dtos.Meta.Responses; +using SharedLibraryCore.Dtos.Meta.Responses; using SharedLibraryCore.Interfaces; using System; using System.Collections.Generic; +using Data.Models; namespace SharedLibraryCore.Dtos { diff --git a/SharedLibraryCore/Dtos/ServerInfo.cs b/SharedLibraryCore/Dtos/ServerInfo.cs index ca54da2a..f1bc891a 100644 --- a/SharedLibraryCore/Dtos/ServerInfo.cs +++ b/SharedLibraryCore/Dtos/ServerInfo.cs @@ -22,5 +22,6 @@ namespace SharedLibraryCore.Dtos public string ConnectProtocolUrl { get; set; } public string IPAddress { get; set; } public bool IsPasswordProtected { get; set; } + public string Endpoint => $"{IPAddress}:{Port}"; } } diff --git a/SharedLibraryCore/Interfaces/IAuditFields.cs b/SharedLibraryCore/Interfaces/IAuditFields.cs new file mode 100644 index 00000000..6a70977e --- /dev/null +++ b/SharedLibraryCore/Interfaces/IAuditFields.cs @@ -0,0 +1,9 @@ +using System; + +namespace SharedLibraryCore.Interfaces +{ + public interface IAuditFields + { + DateTime CreatedDateTime { get; set; } + } +} \ No newline at end of file diff --git a/SharedLibraryCore/Interfaces/IClientNoticeMessageFormatter.cs b/SharedLibraryCore/Interfaces/IClientNoticeMessageFormatter.cs index 503daf89..b7af3ea7 100644 --- a/SharedLibraryCore/Interfaces/IClientNoticeMessageFormatter.cs +++ b/SharedLibraryCore/Interfaces/IClientNoticeMessageFormatter.cs @@ -1,4 +1,4 @@ -using SharedLibraryCore.Database.Models; +using Data.Models; namespace SharedLibraryCore.Interfaces { diff --git a/SharedLibraryCore/Interfaces/IGameServer.cs b/SharedLibraryCore/Interfaces/IGameServer.cs index 614b0b46..0b5df51c 100644 --- a/SharedLibraryCore/Interfaces/IGameServer.cs +++ b/SharedLibraryCore/Interfaces/IGameServer.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using Data.Models; using SharedLibraryCore.Database.Models; namespace SharedLibraryCore.Interfaces diff --git a/SharedLibraryCore/Interfaces/IManagerCommand.cs b/SharedLibraryCore/Interfaces/IManagerCommand.cs index d9222bda..2999cac5 100644 --- a/SharedLibraryCore/Interfaces/IManagerCommand.cs +++ b/SharedLibraryCore/Interfaces/IManagerCommand.cs @@ -1,5 +1,5 @@ using System.Threading.Tasks; -using static SharedLibraryCore.Database.Models.EFClient; +using static Data.Models.Client.EFClient; using static SharedLibraryCore.Server; namespace SharedLibraryCore.Interfaces diff --git a/SharedLibraryCore/Interfaces/IMetaService.cs b/SharedLibraryCore/Interfaces/IMetaService.cs index 42c06c8b..8c124f94 100644 --- a/SharedLibraryCore/Interfaces/IMetaService.cs +++ b/SharedLibraryCore/Interfaces/IMetaService.cs @@ -1,4 +1,5 @@ -using SharedLibraryCore.Database.Models; +using Data.Models; +using SharedLibraryCore.Database.Models; using SharedLibraryCore.Dtos; using SharedLibraryCore.QueryHelper; using System; diff --git a/SharedLibraryCore/Interfaces/IPluginImporter.cs b/SharedLibraryCore/Interfaces/IPluginImporter.cs index 32173efa..4748506b 100644 --- a/SharedLibraryCore/Interfaces/IPluginImporter.cs +++ b/SharedLibraryCore/Interfaces/IPluginImporter.cs @@ -12,7 +12,7 @@ namespace SharedLibraryCore.Interfaces /// discovers C# assembly plugin and command types ///
/// tuple of IPlugin implementation type definitions, and IManagerCommand type definitions - (IEnumerable, IEnumerable) DiscoverAssemblyPluginImplementations(); + (IEnumerable, IEnumerable, IEnumerable) DiscoverAssemblyPluginImplementations(); /// /// discovers the script plugins diff --git a/SharedLibraryCore/Localization/Permission.cs b/SharedLibraryCore/Localization/Permission.cs index fe12686b..0fca389c 100644 --- a/SharedLibraryCore/Localization/Permission.cs +++ b/SharedLibraryCore/Localization/Permission.cs @@ -1,4 +1,4 @@ -using static SharedLibraryCore.Database.Models.EFClient; +using static Data.Models.Client.EFClient; namespace SharedLibraryCore.Localization { diff --git a/SharedLibraryCore/PartialEntities/EFAlias.cs b/SharedLibraryCore/PartialEntities/EFAlias.cs deleted file mode 100644 index a7aeba98..00000000 --- a/SharedLibraryCore/PartialEntities/EFAlias.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace SharedLibraryCore.Database.Models -{ - public partial class EFAlias : SharedEntity - { - - } -} diff --git a/SharedLibraryCore/PartialEntities/EFClient.cs b/SharedLibraryCore/PartialEntities/EFClient.cs index b0789462..cba16f07 100644 --- a/SharedLibraryCore/PartialEntities/EFClient.cs +++ b/SharedLibraryCore/PartialEntities/EFClient.cs @@ -1,19 +1,18 @@ -using Newtonsoft.Json.Converters; -using SharedLibraryCore.Localization; +using SharedLibraryCore.Localization; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; -using System.Text.Json.Serialization; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Serilog.Context; +using Data.Models; namespace SharedLibraryCore.Database.Models { - public partial class EFClient + public class EFClient : Data.Models.Client.EFClient { public enum ClientState { @@ -40,50 +39,6 @@ namespace SharedLibraryCore.Database.Models Disconnecting } - public enum Permission - { - /// - /// client has been banned - /// - Banned = -1, - /// - /// default client state upon first connect - /// - User = 0, - /// - /// client has been flagged - /// - Flagged = 1, - /// - /// client is trusted - /// - Trusted = 2, - /// - /// client is a moderator - /// - Moderator = 3, - /// - /// client is an administrator - /// - Administrator = 4, - /// - /// client is a senior administrator - /// - SeniorAdmin = 5, - /// - /// client is a owner - /// - Owner = 6, - /// - /// not used - /// - Creator = 7, - /// - /// reserved for default account - /// - Console = 8 - } - public EFClient() { ConnectionTime = DateTime.UtcNow; diff --git a/SharedLibraryCore/PartialEntities/EFPenalty.cs b/SharedLibraryCore/PartialEntities/EFPenalty.cs deleted file mode 100644 index 8663d6b9..00000000 --- a/SharedLibraryCore/PartialEntities/EFPenalty.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using SharedLibraryCore; - -namespace SharedLibraryCore.Database.Models -{ - public partial class EFPenalty - { - public enum PenaltyType - { - Report, - Warning, - Flag, - Kick, - TempBan, - Ban, - Unban, - Any, - Unflag, - Other = 100 - } - } -} diff --git a/SharedLibraryCore/Repositories/AuditInformationRepository.cs b/SharedLibraryCore/Repositories/AuditInformationRepository.cs index d712ad2f..6a654806 100644 --- a/SharedLibraryCore/Repositories/AuditInformationRepository.cs +++ b/SharedLibraryCore/Repositories/AuditInformationRepository.cs @@ -4,6 +4,7 @@ using SharedLibraryCore.Interfaces; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Data.Abstractions; namespace SharedLibraryCore.Repositories { @@ -24,7 +25,7 @@ namespace SharedLibraryCore.Repositories { await using var ctx = _contextFactory.CreateContext(enableTracking: false); var iqItems = (from change in ctx.EFChangeHistory - where change.TypeOfChange != Database.Models.EFChangeHistory.ChangeType.Ban + where change.TypeOfChange != Data.Models.EFChangeHistory.ChangeType.Ban orderby change.TimeChanged descending join originClient in ctx.Clients on (change.ImpersonationEntityId ?? change.OriginEntityId) equals originClient.ClientId diff --git a/SharedLibraryCore/Server.cs b/SharedLibraryCore/Server.cs index f13e1239..9622be95 100644 --- a/SharedLibraryCore/Server.cs +++ b/SharedLibraryCore/Server.cs @@ -11,6 +11,7 @@ using SharedLibraryCore.Configuration; using SharedLibraryCore.Interfaces; using SharedLibraryCore.Database.Models; using ILogger = Microsoft.Extensions.Logging.ILogger; +using Data.Models; namespace SharedLibraryCore { diff --git a/SharedLibraryCore/Services/ChangeHistoryService.cs b/SharedLibraryCore/Services/ChangeHistoryService.cs index 24e00f8f..4aa4a3f6 100644 --- a/SharedLibraryCore/Services/ChangeHistoryService.cs +++ b/SharedLibraryCore/Services/ChangeHistoryService.cs @@ -1,10 +1,9 @@ -using SharedLibraryCore.Database; -using SharedLibraryCore.Database.Models; -using SharedLibraryCore.Interfaces; +using SharedLibraryCore.Database.Models; using System; -using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Data.Abstractions; +using Data.Models; using Microsoft.Extensions.Logging; using ILogger = Microsoft.Extensions.Logging.ILogger; diff --git a/SharedLibraryCore/Services/ClientService.cs b/SharedLibraryCore/Services/ClientService.cs index 2397e890..9de5bc08 100644 --- a/SharedLibraryCore/Services/ClientService.cs +++ b/SharedLibraryCore/Services/ClientService.cs @@ -1,5 +1,4 @@ using Microsoft.EntityFrameworkCore; -using SharedLibraryCore.Database; using SharedLibraryCore.Database.Models; using SharedLibraryCore.Dtos; using SharedLibraryCore.Helpers; @@ -9,10 +8,13 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using Data.Abstractions; +using Data.Context; using Microsoft.Extensions.Logging; using Serilog.Context; -using static SharedLibraryCore.Database.Models.EFClient; +using static Data.Models.Client.EFClient; using ILogger = Microsoft.Extensions.Logging.ILogger; +using Data.Models; namespace SharedLibraryCore.Services { @@ -118,9 +120,8 @@ namespace SharedLibraryCore.Services } } - private async Task UpdateAlias(string originalName, int? ip, EFClient entity, DatabaseContext context) + private async Task UpdateAlias(string originalName, int? ip, Data.Models.Client.EFClient entity, DatabaseContext context) { - using (LogContext.PushProperty("Server", entity?.CurrentServer?.ToString())) { string name = originalName.CapClientName(EFAlias.MAX_NAME_LENGTH); @@ -276,7 +277,7 @@ namespace SharedLibraryCore.Services entity.Level = newPermission; await ctx.SaveChangesAsync(); - using (LogContext.PushProperty("Server", entity?.CurrentServer?.ToString())) + using (LogContext.PushProperty("Server", temporalClient?.CurrentServer?.ToString())) { _logger.LogInformation("Updated {clientId} to {newPermission}", temporalClient.ClientId, newPermission); @@ -413,15 +414,13 @@ namespace SharedLibraryCore.Services public async Task UpdateAlias(EFClient temporalClient) { - await using var context = _contextFactory.CreateContext(); + await using var context = _contextFactory.CreateContext(enableTracking:true); var entity = context.Clients .Include(c => c.AliasLink) .Include(c => c.CurrentAlias) .First(e => e.ClientId == temporalClient.ClientId); - entity.CurrentServer = temporalClient.CurrentServer; - await UpdateAlias(temporalClient.Name, temporalClient.IPAddress, entity, context); temporalClient.CurrentAlias = entity.CurrentAlias; @@ -474,7 +473,7 @@ namespace SharedLibraryCore.Services // update in database await context.SaveChangesAsync(); - return entity; + return entity.ToPartialClient(); } #region ServiceSpecific @@ -483,6 +482,7 @@ namespace SharedLibraryCore.Services await using var context = _contextFactory.CreateContext(false); return await context.Clients .Where(c => c.Level == Permission.Owner) + .Select(c => c.ToPartialClient()) .ToListAsync(); } @@ -704,7 +704,7 @@ namespace SharedLibraryCore.Services client.AliasLinkId = newLink.AliasLinkId; client.Level = Permission.User; - await ctx.Aliases.Where(_alias => _alias.IPAddress == client.IPAddress) + await ctx.Aliases.Where(_alias => _alias.IPAddress == client.CurrentAlias.IPAddress && _alias.IPAddress != null) .ForEachAsync(_alias => _alias.LinkId = newLink.AliasLinkId); await ctx.SaveChangesAsync(); @@ -725,12 +725,16 @@ namespace SharedLibraryCore.Services if (!string.IsNullOrEmpty(query.Xuid)) { long networkId = query.Xuid.ConvertGuidToLong(System.Globalization.NumberStyles.HexNumber); - iqClients = context.Clients.Where(_client => _client.NetworkId == networkId); + iqClients = context.Clients. + Where(_client => _client.NetworkId == networkId) + .Select(client => client.ToPartialClient()); } else if (!string.IsNullOrEmpty(query.Name)) { - iqClients = context.Clients.Where(_client => EF.Functions.Like(_client.CurrentAlias.Name.ToLower(), $"%{query.Name.ToLower()}%")); + iqClients = context.Clients + .Where(_client => EF.Functions.Like(_client.CurrentAlias.Name.ToLower(), $"%{query.Name.ToLower()}%")) + .Select(client => client.ToPartialClient()); } if (query.Direction == SortDirection.Ascending) diff --git a/SharedLibraryCore/Services/PenaltyService.cs b/SharedLibraryCore/Services/PenaltyService.cs index 1270699e..28e3b1da 100644 --- a/SharedLibraryCore/Services/PenaltyService.cs +++ b/SharedLibraryCore/Services/PenaltyService.cs @@ -7,11 +7,13 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; +using Data.Abstractions; +using Data.Models; using SharedLibraryCore.Interfaces; namespace SharedLibraryCore.Services { - public class PenaltyService : Interfaces.IEntityService + public class PenaltyService : IEntityService { private readonly IDatabaseContextFactory _contextFactory; diff --git a/SharedLibraryCore/SharedLibraryCore.csproj b/SharedLibraryCore/SharedLibraryCore.csproj index 8bbcf55b..39eed5ae 100644 --- a/SharedLibraryCore/SharedLibraryCore.csproj +++ b/SharedLibraryCore/SharedLibraryCore.csproj @@ -4,7 +4,7 @@ Library netcoreapp3.1 RaidMax.IW4MAdmin.SharedLibraryCore - 2020.12.20.1 + 2021.3.5.1 RaidMax Forever None Debug;Release;Prerelease @@ -13,13 +13,13 @@ IW4MAdmin https://github.com/RaidMax/IW4M-Admin/ https://www.raidmax.org/IW4MAdmin/ - 2020 + 2021 true true true MIT Shared Library for IW4MAdmin - 2020.12.20.1 + 2021.3.19.1 @@ -37,10 +37,6 @@ - - all - runtime; build; native; contentfiles - @@ -48,23 +44,11 @@ - - - + - - - - - - - - - - diff --git a/SharedLibraryCore/Utilities.cs b/SharedLibraryCore/Utilities.cs index 4d727247..03d28f6a 100644 --- a/SharedLibraryCore/Utilities.cs +++ b/SharedLibraryCore/Utilities.cs @@ -3,7 +3,6 @@ using Humanizer; using Humanizer.Localisation; using SharedLibraryCore.Database.Models; using SharedLibraryCore.Dtos.Meta; -using SharedLibraryCore.Helpers; using SharedLibraryCore.Interfaces; using System; using System.Collections.Generic; @@ -19,10 +18,11 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using SharedLibraryCore.Configuration; -using static SharedLibraryCore.Database.Models.EFClient; -using static SharedLibraryCore.Database.Models.EFPenalty; using static SharedLibraryCore.Server; using ILogger = Microsoft.Extensions.Logging.ILogger; +using static Data.Models.Client.EFClient; +using Data.Models; +using static Data.Models.EFPenalty; namespace SharedLibraryCore { @@ -965,9 +965,6 @@ namespace SharedLibraryCore /// public static bool IsDevelopment => Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development"; - public static bool IsMigration => Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Migration"; - - /// /// replaces any directory separator chars with the platform specific character /// @@ -987,7 +984,7 @@ namespace SharedLibraryCore /// wrapper method for humanizee that uses current current culture /// public static string HumanizeForCurrentCulture(this TimeSpan timeSpan, int precision = 1, TimeUnit maxUnit = TimeUnit.Week, - TimeUnit minUnit = TimeUnit.Millisecond, string collectionSeparator = ", ", bool toWords = false) + TimeUnit minUnit = TimeUnit.Second, string collectionSeparator = ", ", bool toWords = false) { return timeSpan.Humanize(precision, CurrentLocalization.Culture, maxUnit, minUnit, collectionSeparator, toWords); } @@ -1005,6 +1002,51 @@ namespace SharedLibraryCore return CurrentLocalization.LocalizationIndex[$"META_TYPE_{metaType.ToString().ToUpper()}_NAME"]; } + public static EFClient ToPartialClient(this Data.Models.Client.EFClient client) + { + return new EFClient() + { + ClientId = client.ClientId, + NetworkId = client.NetworkId, + Connections = client.Connections, + TotalConnectionTime = client.TotalConnectionTime, + FirstConnection = client.FirstConnection, + LastConnection = client.LastConnection, + Masked = client.Masked, + AliasLinkId = client.AliasLinkId, + AliasLink = client.AliasLink, + Level = client.Level, + CurrentAliasId = client.CurrentAliasId, + CurrentAlias = client.CurrentAlias, + Password = client.Password, + PasswordSalt = client.PasswordSalt, + Meta = client.Meta, + ReceivedPenalties = client.ReceivedPenalties, + AdministeredPenalties = client.AdministeredPenalties, + Active = client.Active + }; + } + + public static string ToNumericalString(this int? value) + { + return value?.ToNumericalString(); + } + + public static string ToNumericalString(this int value) + { + return value.ToString("#,##0", CurrentLocalization.Culture); + } + + public static string ToNumericalString(this double value, int precision = 0) + { + return value.ToString("#,##0" + $"{(precision > 0 ? "." : "")}" + new string(Enumerable.Repeat('0', precision).ToArray()), CurrentLocalization.Culture); + } + + public static string ToNumericalString(this double? value, int precision = 0) + { + return value?.ToNumericalString(precision); + } + public static string FindRuleForReason(this string reason, ApplicationConfiguration appConfig, Server server) { // allow for penalty presets diff --git a/Tests/ApplicationTests/StatsWebTests.cs b/Tests/ApplicationTests/StatsWebTests.cs deleted file mode 100644 index c4b95e99..00000000 --- a/Tests/ApplicationTests/StatsWebTests.cs +++ /dev/null @@ -1,269 +0,0 @@ -using ApplicationTests.Fixtures; -using IW4MAdmin.Plugins.Stats.Models; -using Microsoft.Extensions.DependencyInjection; -using NUnit.Framework; -using SharedLibraryCore.Database; -using SharedLibraryCore.Dtos; -using SharedLibraryCore.Interfaces; -using StatsWeb; -using StatsWeb.Extensions; -using System; -using System.Linq; -using System.Threading.Tasks; - -namespace ApplicationTests -{ - [TestFixture] - public class StatsWebTests - { - private IServiceProvider serviceProvider; - private DatabaseContext dbContext; - private ChatResourceQueryHelper queryHelper; - - ~StatsWebTests() - { - dbContext.Dispose(); - } - - [SetUp] - public void Setup() - { - serviceProvider = new ServiceCollection() - .AddSingleton() - .BuildBase() - .BuildServiceProvider(); - - SetupDatabase(); - - queryHelper = serviceProvider.GetRequiredService(); - } - - private void SetupDatabase() - { - var contextFactory = serviceProvider.GetRequiredService(); - dbContext = contextFactory.CreateContext(); - } - - #region PARSE_SEARCH_INFO - [Test] - public void Test_ParseSearchInfo_SanityChecks() - { - var query = "chat|".ParseSearchInfo(-1, -1); - - Assert.AreEqual(0, query.Count); - Assert.AreEqual(0, query.Offset); - - query = "chat|".ParseSearchInfo(int.MaxValue, int.MaxValue); - - Assert.Greater(int.MaxValue, query.Count); - } - - [Test] - public void Test_ParseSearchInfo_BeforeFilter_Happy() - { - var now = DateTime.Now; - var date = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second); - var query = $"chat|before {date.ToString()}".ParseSearchInfo(0, 0); - - Assert.AreEqual(date, query.SentBefore); - } - - [Test] - public void Test_ParseSearchInfo_AfterFilter_Happy() - { - var now = DateTime.Now; - var date = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second); - var query = $"chat|after {date.ToString()}".ParseSearchInfo(0, 0); - - Assert.AreEqual(date, query.SentAfter); - } - - [Test] - public void Test_ParseSearchInfo_ServerFilter_Happy() - { - string serverId = "127.0.0.1:28960"; - var query = $"chat|server {serverId}".ParseSearchInfo(0, 0); - - Assert.AreEqual(serverId, query.ServerId); - } - - [Test] - public void Test_ParseSearchInfo_ClientFilter_Happy() - { - int clientId = 123; - var query = $"chat|client {clientId.ToString()}".ParseSearchInfo(0, 0); - - Assert.AreEqual(clientId, query.ClientId); - } - - [Test] - public void Test_ParseSearchInfo_ContainsFilter_Happy() - { - string content = "test"; - var query = $"chat|contains {content}".ParseSearchInfo(0, 0); - - Assert.AreEqual(content, query.MessageContains); - } - - [Test] - public void Test_ParseSearchInfo_SortFilter_Happy() - { - var direction = SortDirection.Ascending; - var query = $"chat|sort {direction.ToString().ToLower()}".ParseSearchInfo(0, 0); - - Assert.AreEqual(direction, query.Direction); - - direction = SortDirection.Descending; - query = $"chat|sort {direction.ToString().ToLower()}".ParseSearchInfo(0, 0); - - Assert.AreEqual(direction, query.Direction); - } - - [Test] - public void Test_ParseSearchInfo_InvalidQueryType() - { - Assert.Throws(() => "player|test".ParseSearchInfo(0, 0)); - } - - [Test] - public void Test_ParseSearchInfo_NoQueryType() - { - Assert.Throws(() => "".ParseSearchInfo(0, 0)); - } - #endregion] - - #region CHAT_RESOURCE_QUERY_HELPER - [Test] - public void Test_ChatResourceQueryHelper_Invalid() - { - var helper = serviceProvider.GetRequiredService(); - - Assert.ThrowsAsync(() => helper.QueryResource(null)); - } - - [Test] - public async Task Test_ChatResourceQueryHelper_SentAfter() - { - var oneHourAhead = DateTime.Now.AddHours(1); - var msg = MessageGenerators.GenerateMessage(sent: oneHourAhead); - - dbContext.Set() - .Add(msg); - await dbContext.SaveChangesAsync(); - - var query = $"chat|after {DateTime.Now.ToString()}".ParseSearchInfo(1, 0); - var result = await queryHelper.QueryResource(query); - - Assert.AreEqual(oneHourAhead, result.Results.First().When); - - dbContext.Remove(msg); - await dbContext.SaveChangesAsync(); - } - - [Test] - public async Task Test_ChatResourceQueryHelper_SentBefore() - { - var oneHourAgo = DateTime.Now.AddHours(-1); - var msg = MessageGenerators.GenerateMessage(sent: oneHourAgo); - - dbContext.Set() - .Add(msg); - await dbContext.SaveChangesAsync(); - - var query = $"chat|before {DateTime.Now.ToString()}".ParseSearchInfo(1, 0); - var result = await queryHelper.QueryResource(query); - - Assert.AreEqual(oneHourAgo, result.Results.First().When); - - dbContext.Remove(msg); - await dbContext.SaveChangesAsync(); - } - - [Test] - public async Task Test_ChatResourceQueryHelper_Server() - { - var msg = MessageGenerators.GenerateMessage(sent: DateTime.Now); - - dbContext.Set() - .Add(msg); - await dbContext.SaveChangesAsync(); - - string serverId = msg.Server.EndPoint; - var query = $"chat|server {serverId}".ParseSearchInfo(1, 0); - var result = await queryHelper.QueryResource(query); - - Assert.IsNotEmpty(result.Results); - - dbContext.Remove(msg); - await dbContext.SaveChangesAsync(); - } - - [Test] - public async Task Test_ChatResourceQueryHelper_Client() - { - var msg = MessageGenerators.GenerateMessage(sent: DateTime.Now); - - dbContext.Set() - .Add(msg); - await dbContext.SaveChangesAsync(); - - int clientId = msg.Client.ClientId; - var query = $"chat|client {clientId}".ParseSearchInfo(1, 0); - var result = await queryHelper.QueryResource(query); - - Assert.AreEqual(clientId, result.Results.First().ClientId); - - dbContext.Remove(msg); - await dbContext.SaveChangesAsync(); - } - - [Test] - public async Task Test_ChatResourceQueryHelper_Contains() - { - var msg = MessageGenerators.GenerateMessage(sent: DateTime.Now); - msg.Message = "this is a test"; - - dbContext.Set() - .Add(msg); - await dbContext.SaveChangesAsync(); - - var query = $"chat|contains {msg.Message}".ParseSearchInfo(1, 0); - var result = await queryHelper.QueryResource(query); - - Assert.AreEqual(msg.Message, result.Results.First().Message); - - dbContext.Remove(msg); - await dbContext.SaveChangesAsync(); - } - - [Test] - public async Task Test_ChatResourceQueryHelper_Sort() - { - var firstMessage = MessageGenerators.GenerateMessage(sent: DateTime.Now.AddHours(-1)); - var secondMessage = MessageGenerators.GenerateMessage(sent: DateTime.Now); - - dbContext.Set() - .Add(firstMessage); - dbContext.Set() - .Add(secondMessage); - await dbContext.SaveChangesAsync(); - - var query = $"chat|sort {SortDirection.Ascending}".ParseSearchInfo(2, 0); - var result = await queryHelper.QueryResource(query); - - Assert.AreEqual(firstMessage.TimeSent, result.Results.First().When); - Assert.AreEqual(secondMessage.TimeSent, result.Results.Last().When); - - query = $"chat|sort {SortDirection.Descending}".ParseSearchInfo(2, 0); - result = await queryHelper.QueryResource(query); - - Assert.AreEqual(firstMessage.TimeSent, result.Results.Last().When); - Assert.AreEqual(secondMessage.TimeSent, result.Results.First().When); - - dbContext.Remove(firstMessage); - dbContext.Remove(secondMessage); - await dbContext.SaveChangesAsync(); - } - #endregion - } -} diff --git a/Plugins/Web/StatsWeb/API/StatsController.cs b/WebfrontCore/Controllers/API/StatsController.cs similarity index 100% rename from Plugins/Web/StatsWeb/API/StatsController.cs rename to WebfrontCore/Controllers/API/StatsController.cs diff --git a/WebfrontCore/Controllers/API/Validation/FindClientRequestValidator.cs b/WebfrontCore/Controllers/API/Validation/FindClientRequestValidator.cs index c9d3fc86..968c653d 100644 --- a/WebfrontCore/Controllers/API/Validation/FindClientRequestValidator.cs +++ b/WebfrontCore/Controllers/API/Validation/FindClientRequestValidator.cs @@ -1,5 +1,5 @@ -using FluentValidation; -using SharedLibraryCore.Database.Models; +using Data.Models; +using FluentValidation; using SharedLibraryCore.Dtos; namespace WebfrontCore.Controllers.API.Validation diff --git a/WebfrontCore/Controllers/ActionController.cs b/WebfrontCore/Controllers/ActionController.cs index 774c1a3e..32e83c36 100644 --- a/WebfrontCore/Controllers/ActionController.cs +++ b/WebfrontCore/Controllers/ActionController.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading.Tasks; +using Data.Models.Client; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using SharedLibraryCore; @@ -10,7 +11,6 @@ using SharedLibraryCore.Commands; using SharedLibraryCore.Configuration; using SharedLibraryCore.Interfaces; using WebfrontCore.ViewModels; -using static SharedLibraryCore.Database.Models.EFClient; namespace WebfrontCore.Controllers { @@ -215,10 +215,10 @@ namespace WebfrontCore.Controllers Name = "level", Label = Localization["WEBFRONT_PROFILE_LEVEL"], Type = "select", - Values = Enum.GetValues(typeof(Permission)).OfType() + Values = Enum.GetValues(typeof(EFClient.Permission)).OfType() .Where(p => p <= Client.Level) - .Where(p => p != Permission.Banned) - .Where(p => p != Permission.Flagged) + .Where(p => p != EFClient.Permission.Banned) + .Where(p => p != EFClient.Permission.Flagged) .ToDictionary(p => p.ToString(), p => p.ToLocalizedLevelName()) }, }, diff --git a/WebfrontCore/Controllers/ClientController.cs b/WebfrontCore/Controllers/Client/ClientController.cs similarity index 86% rename from WebfrontCore/Controllers/ClientController.cs rename to WebfrontCore/Controllers/Client/ClientController.cs index 86a7e353..dc7f0760 100644 --- a/WebfrontCore/Controllers/ClientController.cs +++ b/WebfrontCore/Controllers/Client/ClientController.cs @@ -5,24 +5,26 @@ using SharedLibraryCore.Dtos; using SharedLibraryCore.Dtos.Meta.Responses; using SharedLibraryCore.Interfaces; using SharedLibraryCore.QueryHelper; -using SharedLibraryCore.Services; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Data.Models; +using IW4MAdmin.Plugins.Stats.Config; using WebfrontCore.ViewComponents; -using static SharedLibraryCore.Database.Models.EFClient; -using static SharedLibraryCore.Database.Models.EFPenalty; namespace WebfrontCore.Controllers { public class ClientController : BaseController { private readonly IMetaService _metaService; + private readonly IConfigurationHandler _configurationHandler; - public ClientController(IManager manager, IMetaService metaService) : base(manager) + public ClientController(IManager manager, IMetaService metaService, + IConfigurationHandler configurationHandler) : base(manager) { _metaService = metaService; + _configurationHandler = configurationHandler; } public async Task ProfileAsync(int id, MetaType? metaFilterType) @@ -42,13 +44,13 @@ namespace WebfrontCore.Controllers client.SetAdditionalProperty(EFMeta.ClientTag, tag.LinkedMeta.Value); } - int displayLevelInt = (int)client.Level; - string displayLevel = client.Level.ToLocalizedLevelName(); + var displayLevelInt = (int)client.Level; + var displayLevel = client.Level.ToLocalizedLevelName(); if (!Authorized && client.Level.ShouldHideLevel()) { - displayLevelInt = (int)Permission.User; - displayLevel = Permission.User.ToLocalizedLevelName(); + displayLevelInt = (int)Data.Models.Client.EFClient.Permission.User; + displayLevel = Data.Models.Client.EFClient.Permission.User.ToLocalizedLevelName(); } displayLevel = string.IsNullOrEmpty(client.Tag) ? displayLevel : $"{displayLevel} ({client.Tag})"; @@ -77,7 +79,7 @@ namespace WebfrontCore.Controllers .Prepend(client.CurrentAlias.IPAddress.ConvertIPtoString()) .Distinct() .ToList(), - HasActivePenalty = activePenalties.Any(_penalty => _penalty.Type != PenaltyType.Flag), + HasActivePenalty = activePenalties.Any(_penalty => _penalty.Type != EFPenalty.PenaltyType.Flag), Online = Manager.GetActiveClients().FirstOrDefault(c => c.ClientId == client.ClientId) != null, TimeOnline = (DateTime.UtcNow - client.LastConnection).HumanizeForCurrentCulture(), LinkedAccounts = client.LinkedAccounts, @@ -111,6 +113,7 @@ namespace WebfrontCore.Controllers ViewBag.Title += " " + Localization["WEBFRONT_CLIENT_PROFILE_TITLE"]; ViewBag.Description = $"Client information for {strippedName}"; ViewBag.Keywords = $"IW4MAdmin, client, profile, {strippedName}"; + ViewBag.UseNewStats = _configurationHandler.Configuration().EnableAdvancedMetrics; return View("Profile/Index", clientDto); } @@ -155,10 +158,10 @@ namespace WebfrontCore.Controllers foreach (var client in clientsDto) { - if (!Authorized && ((Permission)client.LevelInt).ShouldHideLevel()) + if (!Authorized && ((Data.Models.Client.EFClient.Permission)client.LevelInt).ShouldHideLevel()) { - client.LevelInt = (int)Permission.User; - client.Level = Permission.User.ToLocalizedLevelName(); + client.LevelInt = (int)Data.Models.Client.EFClient.Permission.User; + client.Level = Data.Models.Client.EFClient.Permission.User.ToLocalizedLevelName(); } } diff --git a/WebfrontCore/Controllers/Client/ClientStatisticsController.cs b/WebfrontCore/Controllers/Client/ClientStatisticsController.cs new file mode 100644 index 00000000..829c01f4 --- /dev/null +++ b/WebfrontCore/Controllers/Client/ClientStatisticsController.cs @@ -0,0 +1,38 @@ +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using SharedLibraryCore; +using SharedLibraryCore.Configuration; +using SharedLibraryCore.Interfaces; +using Stats.Dtos; + +namespace WebfrontCore.Controllers +{ + [Route("clientstatistics")] + public class ClientStatisticsController : BaseController + { + private IResourceQueryHelper _queryHelper; + private readonly DefaultSettings _defaultConfig; + + public ClientStatisticsController(IManager manager, + IResourceQueryHelper queryHelper, + IConfigurationHandler configurationHandler) : base(manager) + { + _queryHelper = queryHelper; + _defaultConfig = configurationHandler.Configuration(); + } + + [HttpGet("{id:int}/advanced")] + public async Task Advanced(int id, [FromQuery] string serverId) + { + ViewBag.Config = _defaultConfig.GameStrings; + var hitInfo = await _queryHelper.QueryResource(new StatsInfoRequest + { + ClientId = id, + ServerEndpoint = serverId + }); + + return View("~/Views/Client/Statistics/Advanced.cshtml", hitInfo.Results.First()); + } + } +} \ No newline at end of file diff --git a/Plugins/Web/StatsWeb/Controllers/StatsController.cs b/WebfrontCore/Controllers/Client/Legacy/StatsController.cs similarity index 78% rename from Plugins/Web/StatsWeb/Controllers/StatsController.cs rename to WebfrontCore/Controllers/Client/Legacy/StatsController.cs index a6dee0d7..0d998647 100644 --- a/Plugins/Web/StatsWeb/Controllers/StatsController.cs +++ b/WebfrontCore/Controllers/Client/Legacy/StatsController.cs @@ -8,13 +8,14 @@ using SharedLibraryCore.Dtos; using SharedLibraryCore.Dtos.Meta.Responses; using SharedLibraryCore.Interfaces; using Stats.Dtos; -using StatsWeb.Extensions; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using ILogger = Microsoft.Extensions.Logging.ILogger; +using Data.Abstractions; +using IW4MAdmin.Plugins.Stats.Config; namespace IW4MAdmin.Plugins.Web.StatsWeb.Controllers { @@ -25,16 +26,19 @@ namespace IW4MAdmin.Plugins.Web.StatsWeb.Controllers private readonly IResourceQueryHelper _chatResourceQueryHelper; private readonly ITranslationLookup _translationLookup; private readonly IDatabaseContextFactory _contextFactory; + private readonly IConfigurationHandler _configurationHandler; - public StatsController(ILogger logger, IManager manager, IResourceQueryHelper resourceQueryHelper, ITranslationLookup translationLookup, - IDatabaseContextFactory contextFactory) : base(manager) + public StatsController(ILogger logger, IManager manager, IResourceQueryHelper resourceQueryHelper, ITranslationLookup translationLookup, + IDatabaseContextFactory contextFactory, + IConfigurationHandler configurationHandler) : base(manager) { _logger = logger; _manager = manager; _chatResourceQueryHelper = resourceQueryHelper; _translationLookup = translationLookup; _contextFactory = contextFactory; + _configurationHandler = configurationHandler; } [HttpGet] @@ -42,10 +46,11 @@ namespace IW4MAdmin.Plugins.Web.StatsWeb.Controllers { ViewBag.Title = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_STATS_INDEX_TITLE"]; ViewBag.Description = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_STATS_INDEX_DESC"]; - ViewBag.Servers = _manager.GetServers().Select(_server => new ServerInfo() { Name = _server.Hostname, ID = _server.EndPoint }); + ViewBag.Servers = _manager.GetServers() + .Select(_server => new ServerInfo() {Name = _server.Hostname, ID = _server.EndPoint}); ViewBag.Localization = _translationLookup; - return View("Index"); + return View("~/Views/Client/Statistics/Index.cshtml"); } [HttpGet] @@ -64,7 +69,9 @@ namespace IW4MAdmin.Plugins.Web.StatsWeb.Controllers serverId = StatManager.GetIdForServer(server); } - var results = await Plugin.Manager.GetTopStats(offset, count, serverId); + var results = _configurationHandler.Configuration().EnableAdvancedMetrics + ? await Plugin.Manager.GetNewTopStats(offset, count, serverId) + : await Plugin.Manager.GetTopStats(offset, count, serverId); // this returns an empty result so we know to stale the loader if (results.Count == 0 && offset > 0) @@ -72,10 +79,8 @@ namespace IW4MAdmin.Plugins.Web.StatsWeb.Controllers return Ok(); } - else - { - return View("Components/TopPlayers/_List", results); - } + ViewBag.UseNewStats = _configurationHandler.Configuration().EnableAdvancedMetrics; + return View("~/Views/Client/Statistics/Components/TopPlayers/_List.cshtml", results); } [HttpGet] @@ -92,7 +97,7 @@ namespace IW4MAdmin.Plugins.Web.StatsWeb.Controllers SentAfter = whenLower }); - return View("_MessageContext", messages.Results.ToList()); + return View("~/Views/Client/_MessageContext.cshtml", messages.Results.ToList()); } [HttpGet("Message/Find")] @@ -125,11 +130,12 @@ namespace IW4MAdmin.Plugins.Web.StatsWeb.Controllers } var result = searchRequest != null ? await _chatResourceQueryHelper.QueryResource(searchRequest) : null; - return View("Message/Find", result); + return View("~/Views/Client/Message/Find.cshtml", result); } [HttpGet("Message/FindNext")] - public async Task FindNextMessages([FromQuery] string query, [FromQuery] int count, [FromQuery] int offset) + public async Task FindNextMessages([FromQuery] string query, [FromQuery] int count, + [FromQuery] int offset) { ChatSearchQuery searchRequest; @@ -151,7 +157,7 @@ namespace IW4MAdmin.Plugins.Web.StatsWeb.Controllers } var result = await _chatResourceQueryHelper.QueryResource(searchRequest); - return PartialView("Message/_Item", result.Results); + return PartialView("~/Views/Client/Message/_Item.cshtml", result.Results); } [HttpGet] @@ -159,9 +165,10 @@ namespace IW4MAdmin.Plugins.Web.StatsWeb.Controllers public async Task GetAutomatedPenaltyInfoAsync(int penaltyId) { await using var context = _contextFactory.CreateContext(false); - + var penalty = await context.Penalties - .Select(_penalty => new { _penalty.OffenderId, _penalty.PenaltyId, _penalty.When, _penalty.AutomatedOffense }) + .Select(_penalty => new + {_penalty.OffenderId, _penalty.PenaltyId, _penalty.When, _penalty.AutomatedOffense}) .FirstOrDefaultAsync(_penalty => _penalty.PenaltyId == penaltyId); if (penalty == null) @@ -170,7 +177,7 @@ namespace IW4MAdmin.Plugins.Web.StatsWeb.Controllers } // todo: this can be optimized - var iqSnapshotInfo = context.Set() + var iqSnapshotInfo = context.ACSnapshots .Where(s => s.ClientId == penalty.OffenderId) .Include(s => s.LastStrainAngle) .Include(s => s.HitOrigin) @@ -185,13 +192,13 @@ namespace IW4MAdmin.Plugins.Web.StatsWeb.Controllers if (penaltyInfo.Count > 0) { - return View("_PenaltyInfo", penaltyInfo); + return View("~/Views/Client/_PenaltyInfo.cshtml", penaltyInfo); } // we want to show anything related to the automated offense else { - return View("_MessageContext", new List + return View("~/Views/Client/_MessageContext.cshtml", new List { new MessageResponse() { @@ -203,4 +210,4 @@ namespace IW4MAdmin.Plugins.Web.StatsWeb.Controllers } } } -} +} \ No newline at end of file diff --git a/WebfrontCore/Controllers/ConsoleController.cs b/WebfrontCore/Controllers/ConsoleController.cs index 5d2bddad..910d8223 100644 --- a/WebfrontCore/Controllers/ConsoleController.cs +++ b/WebfrontCore/Controllers/ConsoleController.cs @@ -6,6 +6,7 @@ using SharedLibraryCore.Dtos; using SharedLibraryCore.Interfaces; using System.Linq; using System.Threading.Tasks; +using Data.Models; namespace WebfrontCore.Controllers { diff --git a/WebfrontCore/Controllers/HomeController.cs b/WebfrontCore/Controllers/HomeController.cs index d6d73bb9..595ac25f 100644 --- a/WebfrontCore/Controllers/HomeController.cs +++ b/WebfrontCore/Controllers/HomeController.cs @@ -1,10 +1,15 @@ -using Microsoft.AspNetCore.Diagnostics; +using System; +using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Mvc; using SharedLibraryCore; using SharedLibraryCore.Dtos; using SharedLibraryCore.Interfaces; using System.Linq; using System.Threading.Tasks; +using Data.Abstractions; +using Data.Models.Client; +using Data.Models.Client.Stats; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using static SharedLibraryCore.Server; using ILogger = Microsoft.Extensions.Logging.ILogger; @@ -15,11 +20,23 @@ namespace WebfrontCore.Controllers { private readonly ITranslationLookup _translationLookup; private readonly ILogger _logger; + private readonly IDataValueCache _serverStatsCache; + private const string ServerStatKey = nameof(ServerStatKey); - public HomeController(ILogger logger, IManager manager, ITranslationLookup translationLookup) : base(manager) + public HomeController(ILogger logger, IManager manager, ITranslationLookup translationLookup, + IDataValueCache serverStatsCache) : base(manager) { _logger = logger; _translationLookup = translationLookup; + _serverStatsCache = serverStatsCache; + + _serverStatsCache.SetCacheItem(async set => + { + var count = await set.CountAsync(); + var startOfPeriod = DateTime.UtcNow.AddHours(-24); + var recentCount = await set.CountAsync(client => client.LastConnection >= startOfPeriod); + return (count, recentCount); + }, ServerStatKey); } public async Task Index(Game? game = null) @@ -28,14 +45,15 @@ namespace WebfrontCore.Controllers ViewBag.Title = Localization["WEBFRONT_HOME_TITLE"]; ViewBag.Keywords = Localization["WEBFRONT_KEWORDS_HOME"]; - var servers = Manager.GetServers().Where(_server => !game.HasValue ? true : _server.GameName == game); + var servers = Manager.GetServers().Where(_server => !game.HasValue || _server.GameName == game); + var (count, recentCount) = await _serverStatsCache.GetCacheItem(ServerStatKey); var model = new IW4MAdminInfo() { TotalAvailableClientSlots = servers.Sum(_server => _server.MaxClients), TotalOccupiedClientSlots = servers.SelectMany(_server => _server.GetClientsAsList()).Count(), - TotalClientCount = await Manager.GetClientService().GetTotalClientsAsync(), - RecentClientCount = await Manager.GetClientService().GetRecentClientCount(), + TotalClientCount = count, + RecentClientCount = recentCount, Game = game, ActiveServerGames = Manager.GetServers().Select(_server => _server.GameName).Distinct().ToArray() }; @@ -46,7 +64,8 @@ namespace WebfrontCore.Controllers public IActionResult Error() { var exceptionFeature = HttpContext.Features.Get(); - _logger.LogError("[Webfront] {path} {message} {@exception}", exceptionFeature.Path, exceptionFeature.Error.Message, exceptionFeature.Error); + _logger.LogError("[Webfront] {path} {message} {@exception}", exceptionFeature.Path, + exceptionFeature.Error.Message, exceptionFeature.Error); ViewBag.Description = Localization["WEBFRONT_ERROR_DESC"]; ViewBag.Title = Localization["WEBFRONT_ERROR_TITLE"]; return View(exceptionFeature.Error); @@ -71,15 +90,16 @@ namespace WebfrontCore.Controllers .GroupBy(_cmd => { // we need the plugin type the command is defined in - var pluginType = _cmd.GetType().Assembly.GetTypes().FirstOrDefault(_type => _type.Assembly != excludedAssembly && typeof(IPlugin).IsAssignableFrom(_type)); - return pluginType == null ? - _translationLookup["WEBFRONT_HELP_COMMAND_NATIVE"] : + var pluginType = _cmd.GetType().Assembly.GetTypes().FirstOrDefault(_type => + _type.Assembly != excludedAssembly && typeof(IPlugin).IsAssignableFrom(_type)); + return pluginType == null ? _translationLookup["WEBFRONT_HELP_COMMAND_NATIVE"] : pluginType.Name == "ScriptPlugin" ? _translationLookup["WEBFRONT_HELP_SCRIPT_PLUGIN"] : - Manager.Plugins.First(_plugin => _plugin.GetType() == pluginType).Name; // for now we're just returning the name of the plugin, maybe later we'll include more info + Manager.Plugins.First(_plugin => _plugin.GetType() == pluginType) + .Name; // for now we're just returning the name of the plugin, maybe later we'll include more info }) .Select(_grp => (_grp.Key, _grp.AsEnumerable())); return View(commands); } } -} +} \ No newline at end of file diff --git a/WebfrontCore/Controllers/PenaltyController.cs b/WebfrontCore/Controllers/PenaltyController.cs index 7620a165..944cd88f 100644 --- a/WebfrontCore/Controllers/PenaltyController.cs +++ b/WebfrontCore/Controllers/PenaltyController.cs @@ -1,13 +1,13 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using SharedLibraryCore; -using SharedLibraryCore.Database; using SharedLibraryCore.Dtos; using SharedLibraryCore.Interfaces; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using static SharedLibraryCore.Database.Models.EFPenalty; +using Data.Abstractions; +using Data.Models; namespace WebfrontCore.Controllers { @@ -20,7 +20,7 @@ namespace WebfrontCore.Controllers _contextFactory = contextFactory; } - public IActionResult List(PenaltyType showOnly = PenaltyType.Any, bool hideAutomatedPenalties = true) + public IActionResult List(EFPenalty.PenaltyType showOnly = EFPenalty.PenaltyType.Any, bool hideAutomatedPenalties = true) { ViewBag.Description = Localization["WEBFRONT_DESCRIPTION_PENALTIES"]; ViewBag.Title = Localization["WEBFRONT_PENALTY_TITLE"]; @@ -30,7 +30,7 @@ namespace WebfrontCore.Controllers return View(showOnly); } - public async Task ListAsync(int offset = 0, PenaltyType showOnly = PenaltyType.Any, bool hideAutomatedPenalties = true) + public async Task ListAsync(int offset = 0, EFPenalty.PenaltyType showOnly = EFPenalty.PenaltyType.Any, bool hideAutomatedPenalties = true) { return await Task.FromResult(View("_List", new ViewModels.PenaltyFilterInfo() { @@ -52,7 +52,7 @@ namespace WebfrontCore.Controllers await using var ctx = _contextFactory.CreateContext(false); var iqPenalties = ctx.Penalties .AsNoTracking() - .Where(p => p.Type == PenaltyType.Ban && p.Active) + .Where(p => p.Type == EFPenalty.PenaltyType.Ban && p.Active) .OrderByDescending(_penalty => _penalty.When) .Select(p => new PenaltyInfo() { diff --git a/WebfrontCore/Middleware/ClaimsPermissionRemoval.cs b/WebfrontCore/Middleware/ClaimsPermissionRemoval.cs index bc8e4c81..3d9dfb17 100644 --- a/WebfrontCore/Middleware/ClaimsPermissionRemoval.cs +++ b/WebfrontCore/Middleware/ClaimsPermissionRemoval.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; -using static SharedLibraryCore.Database.Models.EFClient; +using Data.Models.Client; using static SharedLibraryCore.GameEvent; namespace WebfrontCore.Middleware @@ -36,10 +36,10 @@ namespace WebfrontCore.Middleware private void OnGameEvent(object sender, GameEvent gameEvent) { if (gameEvent.Type == EventType.ChangePermission && - gameEvent.Extra is Permission perm) + gameEvent.Extra is EFClient.Permission perm) { // we want to remove the claims when the client is demoted - if (perm < Permission.Trusted) + if (perm < EFClient.Permission.Trusted) { lock (_privilegedClientIds) { @@ -47,7 +47,7 @@ namespace WebfrontCore.Middleware } } // and add if promoted - else if (perm > Permission.Trusted && + else if (perm > EFClient.Permission.Trusted && !_privilegedClientIds.Contains(gameEvent.Target.ClientId)) { lock (_privilegedClientIds) diff --git a/WebfrontCore/Startup.cs b/WebfrontCore/Startup.cs index 1ec1205d..429636fd 100644 --- a/WebfrontCore/Startup.cs +++ b/WebfrontCore/Startup.cs @@ -4,27 +4,28 @@ using FluentValidation.AspNetCore; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.ApplicationParts; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using SharedLibraryCore; using SharedLibraryCore.Configuration; -using SharedLibraryCore.Database; using SharedLibraryCore.Dtos; using SharedLibraryCore.Dtos.Meta.Responses; using SharedLibraryCore.Interfaces; using SharedLibraryCore.Services; using Stats.Dtos; using Stats.Helpers; -using StatsWeb; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Reflection; using System.Threading.Tasks; +using Data.Abstractions; +using Data.Helpers; +using IW4MAdmin.Plugins.Stats.Config; +using Stats.Client.Abstractions; using WebfrontCore.Controllers.API.Validation; using WebfrontCore.Middleware; @@ -80,11 +81,14 @@ namespace WebfrontCore }); #if DEBUG - mvcBuilder = mvcBuilder.AddRazorRuntimeCompilation(); - services.Configure(_options => { - _options.ViewLocationFormats.Add(@"/Views/Plugins/{1}/{0}" + RazorViewEngine.ViewExtension); - }); + mvcBuilder = mvcBuilder.AddRazorRuntimeCompilation(); + services.Configure(_options => + { + _options.ViewLocationFormats.Add(@"/Views/Plugins/{1}/{0}" + RazorViewEngine.ViewExtension); + _options.ViewLocationFormats.Add("/Views/Plugins/Stats/Advanced.cshtml"); + }); + } #endif foreach (var asm in pluginAssemblies()) @@ -106,7 +110,8 @@ namespace WebfrontCore services.AddTransient, FindClientRequestValidator>(); services.AddSingleton, ClientService>(); services.AddSingleton, StatsResourceQueryHelper>(); - + services.AddSingleton, AdvancedClientStatsResourceQueryHelper>(); + services.AddSingleton(typeof(IDataValueCache<,>), typeof(DataValueCache<,>)); // todo: this needs to be handled more gracefully services.AddSingleton(Program.ApplicationServiceProvider.GetService()); services.AddSingleton(Program.ApplicationServiceProvider.GetService()); @@ -116,6 +121,12 @@ namespace WebfrontCore services.AddSingleton(Program.ApplicationServiceProvider.GetService()); services.AddSingleton(Program.ApplicationServiceProvider.GetService()); services.AddSingleton(Program.ApplicationServiceProvider.GetRequiredService()); + services.AddSingleton( + Program.ApplicationServiceProvider.GetRequiredService()); + services.AddSingleton(Program.ApplicationServiceProvider + .GetRequiredService>()); + services.AddSingleton(Program.ApplicationServiceProvider + .GetRequiredService>()); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. diff --git a/WebfrontCore/ViewComponents/PenaltyListViewComponent.cs b/WebfrontCore/ViewComponents/PenaltyListViewComponent.cs index ccb1ceae..829656d3 100644 --- a/WebfrontCore/ViewComponents/PenaltyListViewComponent.cs +++ b/WebfrontCore/ViewComponents/PenaltyListViewComponent.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Mvc; -using SharedLibraryCore.Database.Models; using System.Linq; using System.Threading.Tasks; +using Data.Models; namespace WebfrontCore.ViewComponents { diff --git a/WebfrontCore/ViewComponents/TopPlayersViewComponent.cs b/WebfrontCore/ViewComponents/TopPlayersViewComponent.cs new file mode 100644 index 00000000..6e92c5d5 --- /dev/null +++ b/WebfrontCore/ViewComponents/TopPlayersViewComponent.cs @@ -0,0 +1,42 @@ +using System.Linq; +using System.Threading.Tasks; +using IW4MAdmin.Plugins.Stats; +using IW4MAdmin.Plugins.Stats.Config; +using IW4MAdmin.Plugins.Stats.Helpers; +using Microsoft.AspNetCore.Mvc; +using SharedLibraryCore.Interfaces; + +namespace WebfrontCore.ViewComponents +{ + public class TopPlayersViewComponent : ViewComponent + { + private readonly IConfigurationHandler _configurationHandler; + + public TopPlayersViewComponent(IConfigurationHandler configurationHandler) + { + _configurationHandler = configurationHandler; + } + + public async Task InvokeAsync(int count, int offset, long? serverId = null) + { + if (serverId == 0) + { + serverId = null; + } + + var server = Plugin.ServerManager.GetServers().FirstOrDefault(_server => _server.EndPoint == serverId); + + if (server != null) + { + serverId = StatManager.GetIdForServer(server); + } + + + ViewBag.UseNewStats = _configurationHandler.Configuration().EnableAdvancedMetrics; + return View("~/Views/Client/Statistics/Components/TopPlayers/_List.cshtml", + _configurationHandler.Configuration().EnableAdvancedMetrics + ? await Plugin.Manager.GetNewTopStats(offset, count, serverId) + : await Plugin.Manager.GetTopStats(offset, count, serverId)); + } + } +} \ No newline at end of file diff --git a/WebfrontCore/ViewModels/PenaltyFilterInfo.cs b/WebfrontCore/ViewModels/PenaltyFilterInfo.cs index ad1d6436..81ef8a7c 100644 --- a/WebfrontCore/ViewModels/PenaltyFilterInfo.cs +++ b/WebfrontCore/ViewModels/PenaltyFilterInfo.cs @@ -1,4 +1,4 @@ -using static SharedLibraryCore.Database.Models.EFPenalty; +using Data.Models; namespace WebfrontCore.ViewModels { @@ -15,7 +15,7 @@ namespace WebfrontCore.ViewModels /// /// show only a certain type of penalty /// - public PenaltyType ShowOnly { get; set; } + public EFPenalty.PenaltyType ShowOnly { get; set; } /// /// ignore penalties that are automated diff --git a/WebfrontCore/Views/Client/Find/Index.cshtml b/WebfrontCore/Views/Client/Find/Index.cshtml index edcf8e1d..a0fc389e 100644 --- a/WebfrontCore/Views/Client/Find/Index.cshtml +++ b/WebfrontCore/Views/Client/Find/Index.cshtml @@ -1,6 +1,6 @@ @model IList @{ - var loc = SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex; + var loc = Utilities.CurrentLocalization.LocalizationIndex; }
diff --git a/Plugins/Web/StatsWeb/Views/Stats/Message/Find.cshtml b/WebfrontCore/Views/Client/Message/Find.cshtml similarity index 100% rename from Plugins/Web/StatsWeb/Views/Stats/Message/Find.cshtml rename to WebfrontCore/Views/Client/Message/Find.cshtml diff --git a/Plugins/Web/StatsWeb/Views/Stats/Message/_Item.cshtml b/WebfrontCore/Views/Client/Message/_Item.cshtml similarity index 100% rename from Plugins/Web/StatsWeb/Views/Stats/Message/_Item.cshtml rename to WebfrontCore/Views/Client/Message/_Item.cshtml diff --git a/WebfrontCore/Views/Client/Profile/Index.cshtml b/WebfrontCore/Views/Client/Profile/Index.cshtml index 8d967d06..2b538627 100644 --- a/WebfrontCore/Views/Client/Profile/Index.cshtml +++ b/WebfrontCore/Views/Client/Profile/Index.cshtml @@ -1,17 +1,16 @@ -@using SharedLibraryCore.Database.Models -@using SharedLibraryCore.Interfaces -@using SharedLibraryCore +@using SharedLibraryCore.Interfaces +@using Data.Models @model SharedLibraryCore.Dtos.PlayerInfo @{ string match = System.Text.RegularExpressions.Regex.Match(Model.Name.ToUpper(), "[A-Z]").Value; string shortCode = match == string.Empty ? "?" : match; var loc = SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex; string gravatarUrl = Model.Meta.FirstOrDefault(m => m.Key == "GravatarEmail")?.Value; - bool isFlagged = Model.LevelInt == (int)SharedLibraryCore.Database.Models.EFClient.Permission.Flagged; - bool isPermBanned = Model.LevelInt == (int)SharedLibraryCore.Database.Models.EFClient.Permission.Banned; + bool isFlagged = Model.LevelInt == (int) SharedLibraryCore.Database.Models.EFClient.Permission.Flagged; + bool isPermBanned = Model.LevelInt == (int) SharedLibraryCore.Database.Models.EFClient.Permission.Banned; bool isTempBanned = Model.ActivePenalty?.Type == EFPenalty.PenaltyType.TempBan; string translationKey = $"WEBFRONT_PROFILE_{Model.ActivePenalty?.Type.ToString().ToUpper()}_INFO"; - var ignoredMetaTypes = new[] { MetaType.Information, MetaType.Other, MetaType.QuickMessage }; + var ignoredMetaTypes = new[] {MetaType.Information, MetaType.Other, MetaType.QuickMessage}; }
@@ -25,7 +24,9 @@
-
+
+ +
@if (ViewBag.Authorized) {
@@ -37,16 +38,18 @@
@foreach (var linked in Model.LinkedAccounts) { - @Html.ActionLink(linked.Value.ToString("X"), "ProfileAsync", "Client", new { id = linked.Key }, new { @class = "link-inverse" })
+ @Html.ActionLink(linked.Value.ToString("X"), "ProfileAsync", "Client", new {id = linked.Key}, new {@class = "link-inverse"})
} - @foreach (string alias in Model.Aliases) + @foreach (var alias in Model.Aliases) { -
+ +
} @foreach (string ip in Model.IPs) { - @ip
+ @ip +
}
} @@ -62,7 +65,7 @@ break; case "time": - @Utilities.HumanizeForCurrentCulture(Model.ActivePenalty.Expires.Value - DateTime.UtcNow) + @((Model.ActivePenalty.Expires.Value - DateTime.UtcNow).HumanizeForCurrentCulture()) break; default: @@ -89,20 +92,21 @@ } }
- @if (ViewBag.Authorized) - { -
+ +
+ @if (ViewBag.Authorized) + { @if (!isPermBanned) { } - @if (Model.LevelInt < (int)ViewBag.User.Level && !Model.HasActivePenalty) + @if (Model.LevelInt < (int) ViewBag.User.Level && !Model.HasActivePenalty) { } - @if (Model.LevelInt < (int)ViewBag.User.Level && Model.HasActivePenalty) + @if (Model.LevelInt < (int) ViewBag.User.Level && Model.HasActivePenalty) { @if (isTempBanned) { @@ -120,12 +124,16 @@ { } -
- } + } + @if (ViewBag.UseNewStats) + { + + } +
- +
@@ -136,7 +144,9 @@
@ViewBag.Localization["META_TYPE_ALL_NAME"] + asp-route-id="@Model.ClientId"> + @ViewBag.Localization["META_TYPE_ALL_NAME"] + @foreach (MetaType type in Enum.GetValues(typeof(MetaType))) { @@ -146,7 +156,9 @@ class="nav-link p-2 pl-3 pr-3 text-center col-12 col-md-auto text-md-left @(Model.MetaFilterType.HasValue && Model.MetaFilterType.Value.ToString() == type.ToString() ? "btn-primary text-white" : "text-muted")" asp-route-id="@Model.ClientId" asp-route-metaFilterType="@type" - data-meta-type="@type">@type.ToTranslatedName() + data-meta-type="@type"> + @type.ToTranslatedName() + } }
@@ -166,7 +178,7 @@
@section targetid { - + } @section scripts { @@ -175,4 +187,4 @@ -} +} \ No newline at end of file diff --git a/WebfrontCore/Views/Client/Profile/Meta/_AdministeredPenaltyResponse.cshtml b/WebfrontCore/Views/Client/Profile/Meta/_AdministeredPenaltyResponse.cshtml index bb573a23..3023b51a 100644 --- a/WebfrontCore/Views/Client/Profile/Meta/_AdministeredPenaltyResponse.cshtml +++ b/WebfrontCore/Views/Client/Profile/Meta/_AdministeredPenaltyResponse.cshtml @@ -26,7 +26,7 @@ else if (match.MatchValue == "reason") { - @if (ViewBag.Authorized && !string.IsNullOrEmpty(Model.AutomatedOffense) && Model.PenaltyType != SharedLibraryCore.Database.Models.EFPenalty.PenaltyType.Warning) + @if (ViewBag.Authorized && !string.IsNullOrEmpty(Model.AutomatedOffense) && Model.PenaltyType != Data.Models.EFPenalty.PenaltyType.Warning) { @Utilities.FormatExt(ViewBag.Localization["WEBFRONT_PROFILE_ANTICHEAT_DETECTION"], Model.AutomatedOffense) diff --git a/WebfrontCore/Views/Client/Profile/Meta/_ReceivedPenaltyResponse.cshtml b/WebfrontCore/Views/Client/Profile/Meta/_ReceivedPenaltyResponse.cshtml index 205d9933..709bf63e 100644 --- a/WebfrontCore/Views/Client/Profile/Meta/_ReceivedPenaltyResponse.cshtml +++ b/WebfrontCore/Views/Client/Profile/Meta/_ReceivedPenaltyResponse.cshtml @@ -1,5 +1,4 @@ @using SharedLibraryCore.Dtos.Meta.Responses -@using SharedLibraryCore @model ReceivedPenaltyResponse @{ @@ -28,7 +27,7 @@ else if (match.MatchValue == "reason") { - @if (ViewBag.Authorized && !string.IsNullOrEmpty(Model.AutomatedOffense) && Model.PenaltyType != SharedLibraryCore.Database.Models.EFPenalty.PenaltyType.Warning && Model.PenaltyType != SharedLibraryCore.Database.Models.EFPenalty.PenaltyType.Kick) + @if (ViewBag.Authorized && !string.IsNullOrEmpty(Model.AutomatedOffense) && Model.PenaltyType != Data.Models.EFPenalty.PenaltyType.Warning && Model.PenaltyType != Data.Models.EFPenalty.PenaltyType.Kick) { @Utilities.FormatExt(ViewBag.Localization["WEBFRONT_PROFILE_ANTICHEAT_DETECTION"], Model.AutomatedOffense) diff --git a/WebfrontCore/Views/Client/Statistics/Advanced.cshtml b/WebfrontCore/Views/Client/Statistics/Advanced.cshtml new file mode 100644 index 00000000..f918c4cb --- /dev/null +++ b/WebfrontCore/Views/Client/Statistics/Advanced.cshtml @@ -0,0 +1,457 @@ +@using SharedLibraryCore.Configuration +@using Data.Models.Client.Stats +@using Stats.Helpers +@using Data.Models.Client +@using Data.Models.Client.Stats.Reference +@using Humanizer +@using Humanizer.Localisation +@using IW4MAdmin.Plugins.Stats +@model Stats.Dtos.AdvancedStatsInfo +@{ + ViewBag.Title = "Advanced Client Statistics"; + ViewBag.Description = Model.ClientName; + + const int maxItems = 5; + const string headshotKey = "MOD_HEAD_SHOT"; + const string meleeKey = "MOD_MELEE"; + + var suicideKeys = new[] {"MOD_SUICIDE", "MOD_FALLING"}; + var config = (GameStringConfiguration) ViewBag.Config; + + var headerClass = Model.Level == EFClient.Permission.Banned ? "bg-danger" : "bg-primary"; + var textClass = Model.Level == EFClient.Permission.Banned ? "text-danger" : "text-primary"; + var borderBottomClass = Model.Level == EFClient.Permission.Banned ? "border-bottom-danger border-top-danger" : "border-bottom border-top"; + var borderClass = Model.Level == EFClient.Permission.Banned ? "border-danger" : "border-primary"; + var buttonClass = Model.Level == EFClient.Permission.Banned ? "btn-danger" : "btn-primary"; + + string GetWeaponNameForHit(EFClientHitStatistic stat) + { + if (stat == null) + { + return null; + } + var rebuiltName = stat.RebuildWeaponName(); + var name = config.GetStringForGame(rebuiltName); + return !rebuiltName.Equals(name, StringComparison.InvariantCultureIgnoreCase) + ? name + : config.GetStringForGame(stat.Weapon.Name); + } + + string GetWeaponAttachmentName(EFWeaponAttachmentCombo attachment) + { + if (attachment == null) + { + return null; + } + + var attachmentText = string.Join('+', new[] + { + config.GetStringForGame(attachment.Attachment1.Name), + config.GetStringForGame(attachment.Attachment2?.Name), + config.GetStringForGame(attachment.Attachment3?.Name) + }.Where(attach => !string.IsNullOrWhiteSpace(attach))); + + return attachmentText; + } + + var weapons = Model.ByWeapon + .Where(hit => hit.DamageInflicted > 0) + .GroupBy(hit => new {hit.WeaponId}) + .Select(group => + { + var withoutAttachments = group.FirstOrDefault(hit => hit.WeaponAttachmentComboId == null); + var mostUsedAttachment = group.Except(new[] {withoutAttachments}) + .OrderByDescending(g => g.DamageInflicted) + .GroupBy(g => g.WeaponAttachmentComboId) + .FirstOrDefault() + ?.FirstOrDefault(); + + if (withoutAttachments == null || mostUsedAttachment == null) + { + return withoutAttachments; + } + + withoutAttachments.WeaponAttachmentComboId = mostUsedAttachment.WeaponAttachmentComboId; + withoutAttachments.WeaponAttachmentCombo = mostUsedAttachment.WeaponAttachmentCombo; + + return withoutAttachments; + }) + .Where(hit => hit != null) + .OrderByDescending(hit => hit.KillCount) + .ToList(); + + var allPerServer = Model.All.Where(hit => hit.ServerId == Model.ServerId).ToList(); + + // if the serverId is supplied we want all the entries with serverID but nothing else + var aggregate = Model.ServerId == null + ? Model.Aggregate + : allPerServer.Where(hit => hit.WeaponId == null) + .Where(hit => hit.HitLocation == null) + .Where(hit => hit.ServerId == Model.ServerId) + .Where(hit => hit.WeaponAttachmentComboId == null) + .FirstOrDefault(hit => hit.MeansOfDeathId == null); + + var filteredHitLocations = Model.ByHitLocation + .Where(hit => hit.HitCount > 0) + .Where(hit => hit.HitLocation.Name != "none") + .Where(hit => hit.HitLocation.Name != "neck") + .Where(hit => hit.ServerId == Model.ServerId) + .OrderByDescending(hit => hit.HitCount) + .ThenBy(hit => hit.HitLocationId) + .ToList(); + + var uniqueWeapons = allPerServer.Any() + ? Model.ByWeapon.Where(hit => hit.ServerId == Model.ServerId) + .Where(weapon => weapon.DamageInflicted > 0) + .GroupBy(weapon => weapon.WeaponId) + .Count() + : (int?) null; // want to default to -- in ui instead of 0 + + var activeTime = weapons.Any() + ? TimeSpan.FromSeconds(weapons.Sum(weapon => weapon.UsageSeconds ?? 0)) + : (TimeSpan?) null; // want to default to -- in ui instead of 0 + + var kdr = aggregate == null + ? null + : Math.Round(aggregate.KillCount / (float) aggregate.DeathCount, 2).ToString(Utilities.CurrentLocalization.Culture); + + var serverLegacyStat = Model.LegacyStats + .FirstOrDefault(stat => stat.ServerId == Model.ServerId); + + // legacy stats section + var performance = Model.Performance; + var skill = Model.ServerId != null ? serverLegacyStat?.Skill.ToNumericalString() : Model.LegacyStats.WeightValueByPlaytime(nameof(EFClientStatistics.Skill), 0).ToNumericalString(); + var elo = Model.ServerId != null ? serverLegacyStat?.EloRating.ToNumericalString() : Model.LegacyStats.WeightValueByPlaytime(nameof(EFClientStatistics.EloRating), 0).ToNumericalString(); + var spm = Model.ServerId != null ? serverLegacyStat?.SPM.ToNumericalString() : Model.LegacyStats.WeightValueByPlaytime(nameof(EFClientStatistics.SPM), 0).ToNumericalString(); + + var performanceHistory = Model.Ratings + .Select(rating => rating.PerformanceMetric); + + if (performance != null) + { + performanceHistory = performanceHistory.Append(performance.Value); + } + + var score = allPerServer.Any() + ? allPerServer.Sum(stat => stat.Score) + : null; + + var headShots = allPerServer.Any() + ? allPerServer.Where(hit => hit.MeansOfDeath?.Name == headshotKey).Sum(hit => hit.HitCount) + : (int?) null; // want to default to -- in ui instead of 0 + + var meleeKills = allPerServer.Any() + ? allPerServer.Where(hit => hit.MeansOfDeath?.Name == meleeKey).Sum(hit => hit.KillCount) + : (int?) null; + + var suicides = allPerServer.Any() + ? allPerServer.Where(hit => suicideKeys.Contains(hit.MeansOfDeath?.Name ?? "")).Sum(hit => hit.KillCount) + : (int?) null; + + var statCards = new[] + { + new + { + Name = (ViewBag.Localization["PLUGINS_STATS_TEXT_KILLS"] as string).Titleize(), + Value = aggregate?.KillCount.ToNumericalString() + }, + new + { + Name = (ViewBag.Localization["PLUGINS_STATS_TEXT_DEATHS"] as string).Titleize(), + Value = aggregate?.DeathCount.ToNumericalString() + }, + new + { + Name = (ViewBag.Localization["PLUGINS_STATS_TEXT_KDR"] as string).Titleize(), + Value = kdr + }, + new + { + Name = (ViewBag.Localization["WEBFRONT_ADV_STATS_SCORE"] as string).Titleize(), + Value = score.ToNumericalString() + }, + new + { + Name = (ViewBag.Localization["WEBFRONT_ADV_STATS_ZSCORE"] as string), + Value = Model.ZScore.ToNumericalString(2) + }, + new + { + Name = (ViewBag.Localization["PLUGINS_STATS_TEXT_SKILL"] as string).ToLower().Titleize(), + Value = skill + }, + new + { + Name = (ViewBag.Localization["WEBFRONT_ADV_STATS_ELO"] as string).Titleize(), + Value = elo + }, + new + { + Name = (ViewBag.Localization["PLUGINS_STATS_META_SPM"] as string).Titleize(), + Value = spm + }, + new + { + Name = ViewBag.Localization["WEBFRONT_ADV_STATS_TOTAL_DAMAGE"] as string, + Value = aggregate?.DamageInflicted.ToNumericalString() + }, + new + { + Name = ViewBag.Localization["WEBFRONT_ADV_STATS_SUICIDES"] as string, + Value = suicides.ToNumericalString() + }, + new + { + Name = ViewBag.Localization["WEBFRONT_ADV_STATS_HEADSHOTS"] as string, + Value = headShots.ToNumericalString() + }, + new + { + Name = ViewBag.Localization["WEBFRONT_ADV_STATS_MELEES"] as string, + Value = meleeKills.ToNumericalString() + }, + new + { + Name = ViewBag.Localization["WEBFRONT_ADV_STATS_FAV_WEAP"] as string, + Value = GetWeaponNameForHit(weapons.FirstOrDefault()) + }, + new + { + Name = ViewBag.Localization["WEBFRONT_ADV_STATS_FAV_ATTACHMENTS"] as string, + Value = GetWeaponAttachmentName(weapons.FirstOrDefault()?.WeaponAttachmentCombo) + }, + new + { + Name = ViewBag.Localization["WEBFRONT_ADV_STATS_TOTAL_WEAPONS_USED"] as string, + Value = uniqueWeapons.ToNumericalString() + }, + new + { + Name = ViewBag.Localization["WEBFRONT_ADV_STATS_TOTAL_ACTIVE_TIME"] as string, + Value = activeTime?.HumanizeForCurrentCulture() + } + }; +} + +
+ +
+
+ +
+
+ @performance +
+
+ + @if (Model.Level == EFClient.Permission.Banned) + { +
@ViewBag.Localization["GLOBAL_PERMISSION_BANNED"]
+ } + else if (Model.ZScore != null) + { + if (Model.ServerId != null) + { +
@((ViewBag.Localization["WEBFRONT_ADV_STATS_PERFORMANCE"] as string).FormatExt(performance.ToNumericalString()))
+ } + + else + { +
@((ViewBag.Localization["WEBFRONT_ADV_STATS_RATING"] as string).FormatExt(Model.Rating.ToNumericalString()))
+ } + + if (Model.Ranking > 0) + { +
@((ViewBag.Localization["WEBFRONT_ADV_STATS_RANKED"] as string).FormatExt(Model.Ranking.ToNumericalString()))
+ } + + else + { +
@ViewBag.Localization["WEBFRONT_ADV_STATS_EXPIRED"]
+ } + } + + else + { +
@ViewBag.Localization["WEBFRONT_STATS_INDEX_UNRANKED"]
+ } +
+
+
+ +
+ +
+ +
+ @foreach (var card in statCards) + { +
+ @if (string.IsNullOrWhiteSpace(card.Value)) + { +
+ } + else + { +
@card.Value
+ } +
@card.Name
+
+ } +
+
+ +
+
+
@ViewBag.Localization["WEBFRONT_ADV_STATS_WEAP_USAGE"]
+
+ + + + + + + + + + @foreach (var weaponHit in weapons.Take(maxItems)) + { + + + @{ var attachments = GetWeaponAttachmentName(weaponHit.WeaponAttachmentCombo); } + @if (string.IsNullOrWhiteSpace(attachments)) + { + + } + else + { + + } + + + + + + } + + @foreach (var weaponHit in weapons.Skip(maxItems)) + { + + + @{ var attachments = GetWeaponAttachmentName(weaponHit.WeaponAttachmentCombo); } + @if (string.IsNullOrWhiteSpace(attachments)) + { + + } + else + { + + } + + + + + + } + +
@ViewBag.Localization["WEBFRONT_ADV_STATS_WEAPON"]@ViewBag.Localization["WEBFRONT_ADV_STATS_FAV_ATTACHMENTS"]@ViewBag.Localization["WEBFRONT_ADV_STATS_KILLS"]@ViewBag.Localization["WEBFRONT_ADV_STATS_HITS"]@ViewBag.Localization["WEBFRONT_ADV_STATS_DAMAGE"]@ViewBag.Localization["WEBFRONT_ADV_STATS_USAGE"]
@GetWeaponNameForHit(weaponHit)@attachments@weaponHit.KillCount.ToNumericalString()@weaponHit.HitCount.ToNumericalString()@weaponHit.DamageInflicted.ToNumericalString()@TimeSpan.FromSeconds(weaponHit.UsageSeconds ?? 0).HumanizeForCurrentCulture(minUnit: TimeUnit.Second)
+ +
+
+
+ +
+
+
@ViewBag.Localization["WEBFRONT_ADV_STATS_HIT_LOCATIONS"]
+
+ + + + + + + + @{ + var totalHits = filteredHitLocations.Sum(hit => hit.HitCount); + } + @foreach (var hitLocation in filteredHitLocations.Take(8)) + { + + + + + + + } + + @foreach (var hitLocation in filteredHitLocations.Skip(8)) + { + + + + + + + } +
@ViewBag.Localization["WEBFRONT_ADV_STATS_LOCATION"]@ViewBag.Localization["WEBFRONT_ADV_STATS_HITS"]@ViewBag.Localization["WEBFRONT_ADV_STATS_PERCENTAGE"]@ViewBag.Localization["WEBFRONT_ADV_STATS_DAMAGE"]
@config.GetStringForGame(hitLocation.HitLocation.Name)@hitLocation.HitCount@Math.Round((hitLocation.HitCount / (float) totalHits) * 100.0).ToString(Utilities.CurrentLocalization.Culture)%@hitLocation.DamageInflicted.ToNumericalString()
+ +
+
+
+ + +
+
+
+ +@{ + var projection = filteredHitLocations.Select(loc => new + { + name = loc.HitLocation.Name, + // we want to count head and neck as the same + percentage = (loc.HitLocation.Name == "head" + ? filteredHitLocations.FirstOrDefault(c => c.HitLocation.Name == "neck")?.HitCount ?? 0 + loc.HitCount + : loc.HitCount) / (float) totalHits + }).ToList(); + var maxPercentage = projection.Any() ? projection.Max(p => p.percentage) : 0; +} + +@section scripts +{ + + + + + +} \ No newline at end of file diff --git a/WebfrontCore/Views/Client/Statistics/Components/TopPlayers/_List.cshtml b/WebfrontCore/Views/Client/Statistics/Components/TopPlayers/_List.cshtml new file mode 100644 index 00000000..b53759e4 --- /dev/null +++ b/WebfrontCore/Views/Client/Statistics/Components/TopPlayers/_List.cshtml @@ -0,0 +1,151 @@ +@using IW4MAdmin.Plugins.Stats +@model List +@{ + Layout = null; + var loc = Utilities.CurrentLocalization.LocalizationIndex.Set; + double getDeviation(double deviations) => Math.Pow(Math.E, 5.259 + (deviations * 0.812)); + string rankIcon(double? elo) + { + if (elo >= getDeviation(-0.75) && elo < getDeviation(1.25)) + { + return "0_no-place/menu_div_no_place.png"; + } + if (elo >= getDeviation(0.125) && elo < getDeviation(0.625)) + { + return "1_iron/menu_div_iron_sub03.png"; + } + if (elo >= getDeviation(0.625) && elo < getDeviation(1.0)) + { + return "2_bronze/menu_div_bronze_sub03.png"; + } + if (elo >= getDeviation(1.0) && elo < getDeviation(1.25)) + { + return "3_silver/menu_div_silver_sub03.png"; + } + if (elo >= getDeviation(1.25) && elo < getDeviation(1.5)) + { + return "4_gold/menu_div_gold_sub03.png"; + } + if (elo >= getDeviation(1.5) && elo < getDeviation(1.75)) + { + return "5_platinum/menu_div_platinum_sub03.png"; + } + if (elo >= getDeviation(1.75) && elo < getDeviation(2.0)) + { + return "6_semipro/menu_div_semipro_sub03.png"; + } + if (elo >= getDeviation(2.0)) + { + return "7_pro/menu_div_pro_sub03.png"; + } + + return "0_no-place/menu_div_no_place.png"; + } +} + +@if (Model.Count == 0) +{ +
@Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_NOQUALIFY"]
+} +@foreach (var stat in Model) +{ +
+ @if (ViewBag.UseNewStats) + { + @stat.Performance + } +
+
+
#@stat.Ranking
+ @if (stat.RatingChange > 0) + { +
+
+
@stat.RatingChange
+
+ } + @if (stat.RatingChange < 0) + { +
+
@Math.Abs(stat.RatingChange)
+
+
+ } + + @if (!ViewBag.UseNewStats) + { + + + + } + else + { + + + + } +
+ + @if (ViewBag.UseNewStats) + { +
+
+ + @stat.Performance.ToNumericalString() + + @if (stat.ServerId == null) + { + @loc["WEBFRONT_ADV_STATS_RATING"].FormatExt("").ToLower() + } + + else + { + @loc["WEBFRONT_ADV_STATS_PERFORMANCE"].FormatExt("").ToLower() + } +
+
+ @stat.Kills.ToNumericalString() @loc["PLUGINS_STATS_TEXT_KILLS"] +
+
+ @stat.Deaths.ToNumericalString() @loc["PLUGINS_STATS_TEXT_DEATHS"]
+
+
+ @stat.KDR @loc["PLUGINS_STATS_TEXT_KDR"] +
+
+ @stat.TimePlayedValue.HumanizeForCurrentCulture() @loc["WEBFRONT_PROFILE_PLAYER"] +
+
+ @stat.LastSeenValue.HumanizeForCurrentCulture() @loc["WEBFRONT_PROFILE_LSEEN"] +
+
+ } + else + { + @stat.Performance @loc["PLUGINS_STATS_COMMANDS_PERFORMANCE"] +
+ @stat.KDR @loc["PLUGINS_STATS_TEXT_KDR"] + @stat.Kills @loc["PLUGINS_STATS_TEXT_KILLS"] + @stat.Deaths @loc["PLUGINS_STATS_TEXT_DEATHS"]
+ @loc["WEBFRONT_PROFILE_PLAYER"] @stat.TimePlayed @loc["GLOBAL_TIME_HOURS"]
+ @loc["WEBFRONT_PROFILE_LSEEN"] @stat.LastSeen @loc["WEBFRONT_PENALTY_TEMPLATE_AGO"] + } +
+ +
+ +
+ +
+ @if (ViewBag.UseNewStats) + { + @stat.Performance + } + + else + { + + } +
+
+} diff --git a/Plugins/Web/StatsWeb/Views/Stats/Index.cshtml b/WebfrontCore/Views/Client/Statistics/Index.cshtml similarity index 97% rename from Plugins/Web/StatsWeb/Views/Stats/Index.cshtml rename to WebfrontCore/Views/Client/Statistics/Index.cshtml index 7d8ace74..64d931fe 100644 --- a/Plugins/Web/StatsWeb/Views/Stats/Index.cshtml +++ b/WebfrontCore/Views/Client/Statistics/Index.cshtml @@ -14,7 +14,7 @@
- @await Component.InvokeAsync("TopPlayers", new { count = 10, offset = 0 }) + @await Component.InvokeAsync("TopPlayers", new { count = 25, offset = 0 })
@foreach (var server in ViewBag.Servers) @@ -30,5 +30,5 @@ - + } diff --git a/Plugins/Web/StatsWeb/Views/Stats/_MessageContext.cshtml b/WebfrontCore/Views/Client/_MessageContext.cshtml similarity index 100% rename from Plugins/Web/StatsWeb/Views/Stats/_MessageContext.cshtml rename to WebfrontCore/Views/Client/_MessageContext.cshtml diff --git a/Plugins/Web/StatsWeb/Views/Stats/_PenaltyInfo.cshtml b/WebfrontCore/Views/Client/_PenaltyInfo.cshtml similarity index 91% rename from Plugins/Web/StatsWeb/Views/Stats/_PenaltyInfo.cshtml rename to WebfrontCore/Views/Client/_PenaltyInfo.cshtml index fe20c4be..fc4f9c5a 100644 --- a/Plugins/Web/StatsWeb/Views/Stats/_PenaltyInfo.cshtml +++ b/WebfrontCore/Views/Client/_PenaltyInfo.cshtml @@ -1,4 +1,4 @@ -@model IEnumerable +@model IEnumerable @{ Layout = null; } diff --git a/WebfrontCore/Views/Penalty/List.cshtml b/WebfrontCore/Views/Penalty/List.cshtml index 0966054c..1df43ff4 100644 --- a/WebfrontCore/Views/Penalty/List.cshtml +++ b/WebfrontCore/Views/Penalty/List.cshtml @@ -1,4 +1,4 @@ -@model SharedLibraryCore.Database.Models.EFPenalty.PenaltyType +@model Data.Models.EFPenalty.PenaltyType @{ var loc = SharedLibraryCore.Utilities.CurrentLocalization.LocalizationIndex; } @@ -7,11 +7,11 @@