implement custom tag (descriptor) feature

allow override of level names through configuration
few small fixes/improvements
This commit is contained in:
RaidMax 2021-01-24 11:47:19 -06:00
parent c419d80b57
commit c4f19e94ef
40 changed files with 5576 additions and 184 deletions

View File

@ -300,6 +300,13 @@ namespace IW4MAdmin
Time = DateTime.UtcNow
});
var clientTag = await _metaService.GetPersistentMeta(EFMeta.ClientTag, E.Origin);
if (clientTag?.LinkedMeta != null)
{
E.Origin.Tag = clientTag.LinkedMeta.Value;
}
await E.Origin.OnJoin(E.Origin.IPAddress);
}
}

View File

@ -186,7 +186,7 @@ namespace IW4MAdmin.Application
await Task.WhenAll(tasks);
logger.LogInformation("Shutdown completed successfully");
Console.Write(Utilities.CurrentLocalization.LocalizationIndex["MANAGER_SHUTDOWN_SUCCESS"]);
Console.WriteLine(Utilities.CurrentLocalization.LocalizationIndex["MANAGER_SHUTDOWN_SUCCESS"]);
}
@ -319,6 +319,15 @@ namespace IW4MAdmin.Application
appConfigHandler.Save();
}
// register override level names
foreach (var (key, value) in appConfig.OverridePermissionLevelNames)
{
if (!Utilities.PermissionLevelOverrides.ContainsKey(key))
{
Utilities.PermissionLevelOverrides.Add(key, value);
}
}
// build the dependency list
HandlePluginRegistration(appConfig, serviceCollection, masterRestClient);

View File

@ -29,7 +29,7 @@ namespace IW4MAdmin.Application.Misc
_contextFactory = contextFactory;
}
public async Task AddPersistentMeta(string metaKey, string metaValue, EFClient client)
public async Task AddPersistentMeta(string metaKey, string metaValue, EFClient client, EFMeta linkedMeta = null)
{
// this seems to happen if the client disconnects before they've had time to authenticate and be added
if (client.ClientId < 1)
@ -48,6 +48,7 @@ namespace IW4MAdmin.Application.Misc
{
existingMeta.Value = metaValue;
existingMeta.Updated = DateTime.UtcNow;
existingMeta.LinkedMetaId = linkedMeta?.MetaId;
}
else
@ -57,13 +58,98 @@ namespace IW4MAdmin.Application.Misc
ClientId = client.ClientId,
Created = DateTime.UtcNow,
Key = metaKey,
Value = metaValue
Value = metaValue,
LinkedMetaId = linkedMeta?.MetaId
});
}
await ctx.SaveChangesAsync();
}
public async Task AddPersistentMeta(string metaKey, string metaValue)
{
await using var ctx = _contextFactory.CreateContext();
var existingMeta = await ctx.EFMeta
.Where(meta => meta.Key == metaKey)
.Where(meta => meta.ClientId == null)
.ToListAsync();
var matchValues = existingMeta
.Where(meta => meta.Value == metaValue)
.ToArray();
if (matchValues.Any())
{
foreach (var meta in matchValues)
{
_logger.LogDebug("Updating existing meta with key {key} and id {id}", meta.Key, meta.MetaId);
meta.Value = metaValue;
meta.Updated = DateTime.UtcNow;
}
await ctx.SaveChangesAsync();
}
else
{
_logger.LogDebug("Adding new meta with key {key}", metaKey);
ctx.EFMeta.Add(new EFMeta()
{
Created = DateTime.UtcNow,
Key = metaKey,
Value = metaValue
});
await ctx.SaveChangesAsync();
}
}
public async Task RemovePersistentMeta(string metaKey, EFClient client)
{
await using var context = _contextFactory.CreateContext();
var existingMeta = await context.EFMeta
.FirstOrDefaultAsync(meta => meta.Key == metaKey && meta.ClientId == client.ClientId);
if (existingMeta == null)
{
_logger.LogDebug("No meta with key {key} found for client id {id}", metaKey, client.ClientId);
return;
}
_logger.LogDebug("Removing meta for key {key} with id {id}", metaKey, existingMeta.MetaId);
context.EFMeta.Remove(existingMeta);
await context.SaveChangesAsync();
}
public async Task RemovePersistentMeta(string metaKey, string metaValue = null)
{
await using var context = _contextFactory.CreateContext(enableTracking: false);
var existingMeta = await context.EFMeta
.Where(meta => meta.Key == metaKey)
.Where(meta => meta.ClientId == null)
.ToListAsync();
if (metaValue == null)
{
_logger.LogDebug("Removing all meta for key {key} with ids [{ids}] ", metaKey, string.Join(", ", existingMeta.Select(meta => meta.MetaId)));
existingMeta.ForEach(meta => context.Remove(existingMeta));
await context.SaveChangesAsync();
return;
}
var foundMeta = existingMeta.FirstOrDefault(meta => meta.Value == metaValue);
if (foundMeta != null)
{
_logger.LogDebug("Removing meta for key {key} with id {id}", metaKey, foundMeta.MetaId);
context.Remove(foundMeta);
await context.SaveChangesAsync();
}
}
public async Task<EFMeta> GetPersistentMeta(string metaKey, EFClient client)
{
await using var ctx = _contextFactory.CreateContext(enableTracking: false);
@ -76,11 +162,34 @@ namespace IW4MAdmin.Application.Misc
MetaId = _meta.MetaId,
Key = _meta.Key,
ClientId = _meta.ClientId,
Value = _meta.Value
Value = _meta.Value,
LinkedMetaId = _meta.LinkedMetaId,
LinkedMeta = _meta.LinkedMetaId != null ? new EFMeta()
{
MetaId = _meta.LinkedMeta.MetaId,
Key = _meta.LinkedMeta.Key,
Value = _meta.LinkedMeta.Value
} : null
})
.FirstOrDefaultAsync();
}
public async Task<IEnumerable<EFMeta>> GetPersistentMeta(string metaKey)
{
await using var context = _contextFactory.CreateContext(enableTracking: false);
return await context.EFMeta
.Where(meta => meta.Key == metaKey)
.Where(meta => meta.ClientId == null)
.Select(meta => new EFMeta
{
MetaId = meta.MetaId,
Key = meta.Key,
ClientId = meta.ClientId,
Value = meta.Value,
})
.ToListAsync();
}
public void AddRuntimeMeta<T, V>(MetaType metaKey, Func<T, Task<IEnumerable<V>>> metaAction) where T : PaginationRequest where V : IClientMeta
{
if (!_metaActions.ContainsKey(metaKey))

View File

@ -13,51 +13,12 @@ using System.Net;
using Newtonsoft.Json.Linq;
using System.Text.RegularExpressions;
using static SharedLibraryCore.Database.Models.EFClient;
using Humanizer;
namespace IW4MAdmin.Plugins.Welcome
{
public class Plugin : IPlugin
{
String TimesConnected(EFClient P)
{
int connection = P.Connections;
String Prefix = String.Empty;
if (connection % 10 > 3 || connection % 10 == 0 || (connection % 100 > 9 && connection % 100 < 19))
Prefix = "th";
else
{
switch (connection % 10)
{
case 1:
Prefix = "st";
break;
case 2:
Prefix = "nd";
break;
case 3:
Prefix = "rd";
break;
}
}
switch (connection)
{
case 0:
case 1:
return "first";
case 2:
return "second";
case 3:
return "third";
case 4:
return "fourth";
case 5:
return "fifth";
default:
return connection.ToString() + Prefix;
}
}
public string Author => "RaidMax";
public float Version => 1.0f;
@ -91,7 +52,7 @@ namespace IW4MAdmin.Plugins.Welcome
if (E.Type == GameEvent.EventType.Join)
{
EFClient newPlayer = E.Origin;
if (newPlayer.Level >= Permission.Trusted && !E.Origin.Masked)
if (newPlayer.Level >= Permission.Trusted && !E.Origin.Masked || !string.IsNullOrEmpty(newPlayer.GetAdditionalProperty<string>("ClientTag")))
E.Owner.Broadcast(await ProcessAnnouncement(_configHandler.Configuration().PrivilegedAnnouncementMessage, newPlayer));
newPlayer.Tell(await ProcessAnnouncement(_configHandler.Configuration().UserWelcomeMessage, newPlayer));
@ -119,13 +80,13 @@ namespace IW4MAdmin.Plugins.Welcome
private async Task<string> ProcessAnnouncement(string msg, EFClient joining)
{
msg = msg.Replace("{{ClientName}}", joining.Name);
msg = msg.Replace("{{ClientLevel}}", Utilities.ConvertLevelToColor(joining.Level, joining.ClientPermission.Name));
msg = msg.Replace("{{ClientLevel}}", $"{Utilities.ConvertLevelToColor(joining.Level, joining.ClientPermission.Name)}{(string.IsNullOrEmpty(joining.GetAdditionalProperty<string>("ClientTag")) ? "" : $" ^7({joining.GetAdditionalProperty<string>("ClientTag")}^7)")}");
// this prevents it from trying to evaluate it every message
if (msg.Contains("{{ClientLocation}}"))
{
msg = msg.Replace("{{ClientLocation}}", await GetCountryName(joining.IPAddressString));
}
msg = msg.Replace("{{TimesConnected}}", TimesConnected(joining));
msg = msg.Replace("{{TimesConnected}}", joining.Connections.Ordinalize());
return msg;
}

View File

@ -28,9 +28,9 @@ namespace SharedLibraryCore
/// <summary>
/// Executes the command
/// </summary>
/// <param name="E"></param>
/// <param name="gameEvent"></param>
/// <returns></returns>
abstract public Task ExecuteAsync(GameEvent E);
abstract public Task ExecuteAsync(GameEvent gameEvent);
/// <summary>
/// Specifies the name and string that triggers the command

View File

@ -0,0 +1,37 @@
using SharedLibraryCore.Configuration;
using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Interfaces;
using System.Threading.Tasks;
namespace SharedLibraryCore.Commands
{
public class AddClientTagCommand : Command
{
private readonly IMetaService _metaService;
public AddClientTagCommand(CommandConfiguration config, ITranslationLookup layout, IMetaService metaService) : base(config, layout)
{
Name = "addclienttag";
Description = layout["COMMANDS_ADD_CLIENT_TAG_DESC"];
Alias = "act";
Permission = EFClient.Permission.Owner;
RequiresTarget = false;
Arguments = new[]
{
new CommandArgument()
{
Name = _translationLookup["COMMANDS_ARGUMENT_TAG"],
Required = true
}
};
_metaService = metaService;
}
public override async Task ExecuteAsync(GameEvent gameEvent)
{
await _metaService.AddPersistentMeta(EFMeta.ClientTagName, gameEvent.Data);
gameEvent.Origin.Tell(_translationLookup["COMMANDS_ADD_CLIENT_TAG_SUCCESS"].FormatExt(gameEvent.Data));
}
}
}

View File

@ -0,0 +1,33 @@
using SharedLibraryCore.Configuration;
using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SharedLibraryCore.Commands
{
public class ListClientTags : Command
{
private readonly IMetaService _metaService;
public ListClientTags(CommandConfiguration config, ITranslationLookup layout, IMetaService metaService) : base(config, layout)
{
Name = "listclienttags";
Description = layout["COMMANDS_LIST_CLIENT_TAGS_DESC"];
Alias = "lct";
Permission = EFClient.Permission.Owner;
RequiresTarget = false;
_metaService = metaService;
}
public override async Task ExecuteAsync(GameEvent gameEvent)
{
var tags = await _metaService.GetPersistentMeta(EFMeta.ClientTagName);
gameEvent.Origin.Tell(tags.Select(tag => tag.Value));
}
}
}

View File

@ -465,10 +465,11 @@ namespace SharedLibraryCore.Commands
RequiresTarget = false;
}
public override Task ExecuteAsync(GameEvent E)
public override Task ExecuteAsync(GameEvent gameEvent)
{
string you = string.Format("{0} [^3#{1}^7] {2} ^7[^3@{3}^7] ^7[{4}^7] IP: {5}", E.Origin.Name, E.Origin.ClientNumber, E.Origin.NetworkId, E.Origin.ClientId, Utilities.ConvertLevelToColor(E.Origin.Level, E.Origin.ClientPermission.Name), E.Origin.IPAddressString);
E.Origin.Tell(you);
var you = _translationLookup["COMMANDS_WHOAMI_FORMAT"].FormatExt(gameEvent.Origin.ClientNumber, gameEvent.Origin.ClientId, gameEvent.Origin.GuidString,
gameEvent.Origin.IPAddressString, gameEvent.Origin.ClientPermission.Name, string.IsNullOrEmpty(gameEvent.Origin.Tag) ? "" : $" {gameEvent.Origin.Tag}^7", gameEvent.Origin.Name);
gameEvent.Origin.Tell(you);
return Task.CompletedTask;
}
@ -488,46 +489,14 @@ namespace SharedLibraryCore.Commands
RequiresTarget = false;
}
public override Task ExecuteAsync(GameEvent E)
public override Task ExecuteAsync(GameEvent gameEvent)
{
StringBuilder playerList = new StringBuilder();
int count = 0;
for (int i = 0; i < E.Owner.Clients.Count; i++)
{
var P = E.Owner.Clients[i];
var clientList = gameEvent.Owner.GetClientsAsList()
.Select(client => _translationLookup["COMMANDS_LIST_FORMAT"]
.FormatExt(client.ClientPermission.Name, string.IsNullOrEmpty(client.Tag) ? "" : $" {client.Tag}^7", client.ClientNumber, client.Name))
.ToArray();
if (P == null)
{
continue;
}
// todo: fix spacing
// todo: make this better :)
if (P.Masked)
{
playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.ConvertLevelToColor(EFClient.Permission.User, P.ClientPermission.Name), P.ClientNumber, P.Name, Utilities.GetSpaces(EFClient.Permission.SeniorAdmin.ToString().Length - EFClient.Permission.User.ToString().Length));
}
else
{
playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.ConvertLevelToColor(P.Level, P.ClientPermission.Name), P.ClientNumber, P.Name, Utilities.GetSpaces(EFClient.Permission.SeniorAdmin.ToString().Length - P.Level.ToString().Length));
}
if (count == 2 || E.Owner.GetClientsAsList().Count == 1)
{
E.Origin.Tell(playerList.ToString());
count = 0;
playerList = new StringBuilder();
continue;
}
count++;
}
if (playerList.Length > 0)
{
E.Origin.Tell(playerList.ToString());
}
// todo: make no players response for webfront
gameEvent.Origin.Tell(clientList);
return Task.CompletedTask;
}
@ -737,7 +706,7 @@ namespace SharedLibraryCore.Commands
{
// can't promote a client to higher than your current perms
// or your peer
gameEvent.Origin.Tell(string.Format(_translationLookup["COMMANDS_SETLEVEL_LEVELTOOHIGH"], gameEvent.Target.Name, (gameEvent.Origin.Level - 1).ToString()));
gameEvent.Origin.Tell(string.Format(_translationLookup["COMMANDS_SETLEVEL_LEVELTOOHIGH"], gameEvent.Target.Name, (gameEvent.Origin.Level - 1).ToLocalizedLevelName()));
return;
}
@ -991,9 +960,14 @@ namespace SharedLibraryCore.Commands
rules.AddRange(E.Owner.ServerConfig.Rules);
}
foreach (string r in rules)
var ruleFomat = rules.Select(r => $"- {r}");
if (E.Message.IsBroadcastCommand(_config.BroadcastCommandPrefix))
{
var _ = E.Message.IsBroadcastCommand(_config.BroadcastCommandPrefix) ? E.Owner.Broadcast($"- {r}") : E.Origin.Tell($"- {r}");
E.Owner.Broadcast(ruleFomat);
}
else
{
E.Origin.Tell(ruleFomat);
}
}

View File

@ -0,0 +1,37 @@
using SharedLibraryCore.Configuration;
using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Interfaces;
using System.Threading.Tasks;
namespace SharedLibraryCore.Commands
{
public class RemoveClientTag : Command
{
private readonly IMetaService _metaService;
public RemoveClientTag(CommandConfiguration config, ITranslationLookup layout, IMetaService metaService) : base(config, layout)
{
Name = "removeclienttag";
Description = layout["COMMANDS_REMOVE_CLIENT_TAG_DESC"];
Alias = "rct";
Permission = EFClient.Permission.Owner;
RequiresTarget = false;
Arguments = new[]
{
new CommandArgument()
{
Name = _translationLookup["COMMANDS_ARGUMENT_TAG"],
Required = true
}
};
_metaService = metaService;
}
public override async Task ExecuteAsync(GameEvent gameEvent)
{
await _metaService.RemovePersistentMeta(EFMeta.ClientTagName, gameEvent.Data);
gameEvent.Origin.Tell(_translationLookup["COMMANDS_REMOVE_CLIENT_TAG_SUCCESS"].FormatExt(gameEvent.Data));
}
}
}

View File

@ -0,0 +1,49 @@
using SharedLibraryCore.Configuration;
using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Interfaces;
using System.Linq;
using System.Threading.Tasks;
namespace SharedLibraryCore.Commands
{
public class SetClientTagCommand : Command
{
private readonly IMetaService _metaService;
public SetClientTagCommand(CommandConfiguration config, ITranslationLookup layout, IMetaService metaService) : base(config, layout)
{
Name = "setclienttag";
Description = layout["COMMANDS_SET_CLIENT_TAG_DESC"];
Alias = "sct";
Permission = EFClient.Permission.Owner;
RequiresTarget = true;
Arguments = new[]
{
new CommandArgument()
{
Name = _translationLookup["COMMANDS_ARGUMENT_TAG"],
Required = true
}
};
_metaService = metaService;
}
public override async Task ExecuteAsync(GameEvent gameEvent)
{
var availableTags = await _metaService.GetPersistentMeta(EFMeta.ClientTagName);
var matchingTag = availableTags.FirstOrDefault(tag => tag.Value == gameEvent.Data);
if (matchingTag == null)
{
gameEvent.Origin.Tell(_translationLookup["COMMANDS_SET_CLIENT_TAG_FAIL"].FormatExt(gameEvent.Data));
return;
}
gameEvent.Target.Tag = matchingTag.Value;
await _metaService.AddPersistentMeta(EFMeta.ClientTag, string.Empty, gameEvent.Target, matchingTag);
gameEvent.Origin.Tell(_translationLookup["COMMANDS_SET_CLIENT_TAG_SUCCESS"].FormatExt(matchingTag.Value));
}
}
}

View File

@ -0,0 +1,40 @@
using SharedLibraryCore.Configuration;
using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Interfaces;
using System.Linq;
using System.Threading.Tasks;
namespace SharedLibraryCore.Commands
{
public class UnsetClientTagCommand : Command
{
private readonly IMetaService _metaService;
public UnsetClientTagCommand(CommandConfiguration config, ITranslationLookup layout, IMetaService metaService) : base(config, layout)
{
Name = "unsetclienttag";
Description = layout["COMMANDS_UNSET_CLIENT_TAG_DESC"];
Alias = "uct";
Permission = EFClient.Permission.Owner;
RequiresTarget = true;
Arguments = new[]
{
new CommandArgument()
{
Name = _translationLookup["COMMANDS_ARGUMENT_TAG"],
Required = true
}
};
_metaService = metaService;
}
public override async Task ExecuteAsync(GameEvent gameEvent)
{
gameEvent.Target.Tag = null;
await _metaService.RemovePersistentMeta(EFMeta.ClientTag, gameEvent.Target);
gameEvent.Origin.Tell(_translationLookup["COMMANDS_UNSET_CLIENT_TAG_SUCCESS"]);
}
}
}

View File

@ -3,6 +3,8 @@ using SharedLibraryCore.Interfaces;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using static SharedLibraryCore.Database.Models.EFClient;
namespace SharedLibraryCore.Configuration
{
@ -137,6 +139,10 @@ namespace SharedLibraryCore.Configuration
{{"afk", "Away from keyboard"}, {"ci", "Connection interrupted. Reconnect"}};
[LocalizedDisplayName(("WEBFRONT_CONFIGURATION_ENABLE_PRIVILEGED_USER_PRIVACY"))]
public bool EnablePrivilegedUserPrivacy { get; set; }
public Dictionary<Permission, string> OverridePermissionLevelNames { get; set; } = Enum
.GetValues(typeof(Permission))
.Cast<Permission>()
.ToDictionary(perm => perm, perm => perm.ToString());
[UIHint("ServerConfiguration")]
public ServerConfiguration[] Servers { get; set; }

View File

@ -123,6 +123,10 @@ namespace SharedLibraryCore.Database
modelBuilder.Entity<EFMeta>(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

View File

@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace SharedLibraryCore.Database.Models
{
@ -11,15 +9,18 @@ namespace SharedLibraryCore.Database.Models
/// </summary>
public class EFMeta : SharedEntity
{
public const string ClientTagName = nameof(ClientTagName);
public const string ClientTag = nameof(ClientTag);
[Key]
public int MetaId { get; set; }
[Required]
public DateTime Created { get; set; } = DateTime.UtcNow;
[Required]
public DateTime Updated { get; set; } = DateTime.UtcNow;
[Required]
public int ClientId { get; set; }
[ForeignKey("ClientId")] // this is the client that the meta belongs to
public int? ClientId { get; set; }
// this is the client that the meta could belong to
[ForeignKey(nameof(ClientId))]
public virtual EFClient Client { get; set; }
[Required]
[MinLength(3)]
@ -29,5 +30,9 @@ namespace SharedLibraryCore.Database.Models
[Required]
public string Value { get; set; }
public string Extra { get; set; }
public int? LinkedMetaId { get; set; }
[ForeignKey(nameof(LinkedMetaId))]
public virtual EFMeta LinkedMeta { get; set; }
}
}

View File

@ -11,6 +11,7 @@ namespace SharedLibraryCore.Dtos
public string Name { get; set; }
public int ClientId { get; set; }
public string Level { get; set; }
public string Tag { get; set; }
public int LevelInt { get; set; }
public string IPAddress { get; set; }
public long NetworkId { get; set; }

View File

@ -261,6 +261,11 @@ namespace SharedLibraryCore
_eventFinishedWaiter.Set();
}
public async Task<GameEvent> WaitAsync()
{
return await WaitAsync(Utilities.DefaultCommandTimeout, new CancellationToken());
}
/// <summary>
/// asynchronously wait for GameEvent to be processed
/// </summary>

View File

@ -16,7 +16,31 @@ namespace SharedLibraryCore.Interfaces
/// <param name="metaValue">value of the meta data</param>
/// <param name="client">client to save the meta for</param>
/// <returns></returns>
Task AddPersistentMeta(string metaKey, string metaValue, EFClient client);
Task AddPersistentMeta(string metaKey, string metaValue, EFClient client, EFMeta linkedMeta = null);
/// <summary>
/// adds or updates meta key and value to the database
/// </summary>
/// <param name="metaKey">key of meta data</param>
/// <param name="metaValue">value of the meta data</param>
/// <returns></returns>
Task AddPersistentMeta(string metaKey, string metaValue);
/// <summary>
/// removes meta key with given value
/// </summary>
/// <param name="metaKey">key of meta data</param>
/// <param name="client">client to delete the meta for</param>
/// <returns></returns>
Task RemovePersistentMeta(string metaKey, EFClient client);
/// <summary>
/// removes meta key with given value
/// </summary>
/// <param name="metaKey">key of the meta data</param>
/// <param name="metaValue">value of the meta data</param>
/// <returns></returns>
Task RemovePersistentMeta(string metaKey, string metaValue = null);
/// <summary>
/// retrieves meta data for given client and key
@ -26,6 +50,13 @@ namespace SharedLibraryCore.Interfaces
/// <returns></returns>
Task<EFMeta> GetPersistentMeta(string metaKey, EFClient client);
/// <summary>
/// retrieves collection of meta for given key
/// </summary>
/// <param name="metaKey">key to retrieve values for</param>
/// <returns></returns>
Task<IEnumerable<EFMeta>> GetPersistentMeta(string metaKey);
/// <summary>
/// adds a meta task to the runtime meta list
/// </summary>

View File

@ -0,0 +1,929 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using SharedLibraryCore.Database.MigrationContext;
namespace SharedLibraryCore.Migrations.MySql
{
[DbContext(typeof(MySqlDatabaseContext))]
[Migration("20210123023921_UpdateEFMetaToSupportNonClientMeta")]
partial class UpdateEFMetaToSupportNonClientMeta
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.10")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
{
b.Property<int>("SnapshotId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int>("ClientId")
.HasColumnType("int");
b.Property<int>("CurrentSessionLength")
.HasColumnType("int");
b.Property<double>("CurrentStrain")
.HasColumnType("double");
b.Property<int>("CurrentViewAngleId")
.HasColumnType("int");
b.Property<int>("Deaths")
.HasColumnType("int");
b.Property<double>("Distance")
.HasColumnType("double");
b.Property<double>("EloRating")
.HasColumnType("double");
b.Property<int>("HitDestinationId")
.HasColumnType("int");
b.Property<int>("HitLocation")
.HasColumnType("int");
b.Property<int>("HitOriginId")
.HasColumnType("int");
b.Property<int>("HitType")
.HasColumnType("int");
b.Property<int>("Hits")
.HasColumnType("int");
b.Property<int>("Kills")
.HasColumnType("int");
b.Property<int>("LastStrainAngleId")
.HasColumnType("int");
b.Property<double>("RecoilOffset")
.HasColumnType("double");
b.Property<double>("SessionAngleOffset")
.HasColumnType("double");
b.Property<double>("SessionAverageSnapValue")
.HasColumnType("double");
b.Property<double>("SessionSPM")
.HasColumnType("double");
b.Property<int>("SessionScore")
.HasColumnType("int");
b.Property<int>("SessionSnapHits")
.HasColumnType("int");
b.Property<double>("StrainAngleBetween")
.HasColumnType("double");
b.Property<int>("TimeSinceLastEvent")
.HasColumnType("int");
b.Property<int>("WeaponId")
.HasColumnType("int");
b.Property<DateTime>("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("IW4MAdmin.Plugins.Stats.Models.EFACSnapshotVector3", b =>
{
b.Property<int>("ACSnapshotVector3Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int>("SnapshotId")
.HasColumnType("int");
b.Property<int>("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<long>("KillId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int>("AttackerId")
.HasColumnType("int");
b.Property<int>("Damage")
.HasColumnType("int");
b.Property<int?>("DeathOriginVector3Id")
.HasColumnType("int");
b.Property<int>("DeathType")
.HasColumnType("int");
b.Property<double>("Fraction")
.HasColumnType("double");
b.Property<int>("HitLoc")
.HasColumnType("int");
b.Property<bool>("IsKill")
.HasColumnType("tinyint(1)");
b.Property<int?>("KillOriginVector3Id")
.HasColumnType("int");
b.Property<int>("Map")
.HasColumnType("int");
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<int>("VictimId")
.HasColumnType("int");
b.Property<int?>("ViewAnglesVector3Id")
.HasColumnType("int");
b.Property<double>("VisibilityPercentage")
.HasColumnType("double");
b.Property<int>("Weapon")
.HasColumnType("int");
b.Property<DateTime>("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<long>("MessageId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int>("ClientId")
.HasColumnType("int");
b.Property<string>("Message")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<bool>("SentIngame")
.HasColumnType("tinyint(1)");
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<DateTime>("TimeSent")
.HasColumnType("datetime(6)");
b.HasKey("MessageId");
b.HasIndex("ClientId");
b.HasIndex("ServerId");
b.HasIndex("TimeSent");
b.ToTable("EFClientMessages");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b =>
{
b.Property<int>("RatingHistoryId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int>("ClientId")
.HasColumnType("int");
b.HasKey("RatingHistoryId");
b.HasIndex("ClientId");
b.ToTable("EFClientRatingHistory");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
{
b.Property<int>("ClientId")
.HasColumnType("int");
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<double>("AverageRecoilOffset")
.HasColumnType("double");
b.Property<double>("AverageSnapValue")
.HasColumnType("double");
b.Property<int>("Deaths")
.HasColumnType("int");
b.Property<double>("EloRating")
.HasColumnType("double");
b.Property<int>("Kills")
.HasColumnType("int");
b.Property<double>("MaxStrain")
.HasColumnType("double");
b.Property<double>("RollingWeightedKDR")
.HasColumnType("double");
b.Property<double>("SPM")
.HasColumnType("double");
b.Property<double>("Skill")
.HasColumnType("double");
b.Property<int>("SnapHitCount")
.HasColumnType("int");
b.Property<int>("TimePlayed")
.HasColumnType("int");
b.Property<double>("VisionAverage")
.HasColumnType("double");
b.HasKey("ClientId", "ServerId");
b.HasIndex("ServerId");
b.ToTable("EFClientStatistics");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b =>
{
b.Property<int>("HitLocationCountId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int>("EFClientStatisticsClientId")
.HasColumnName("EFClientStatisticsClientId")
.HasColumnType("int");
b.Property<long>("EFClientStatisticsServerId")
.HasColumnName("EFClientStatisticsServerId")
.HasColumnType("bigint");
b.Property<int>("HitCount")
.HasColumnType("int");
b.Property<float>("HitOffsetAverage")
.HasColumnType("float");
b.Property<int>("Location")
.HasColumnType("int");
b.Property<float>("MaxAngleDistance")
.HasColumnType("float");
b.HasKey("HitLocationCountId");
b.HasIndex("EFClientStatisticsServerId");
b.HasIndex("EFClientStatisticsClientId", "EFClientStatisticsServerId");
b.ToTable("EFHitLocationCounts");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b =>
{
b.Property<int>("RatingId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int>("ActivityAmount")
.HasColumnType("int");
b.Property<bool>("Newest")
.HasColumnType("tinyint(1)");
b.Property<double>("Performance")
.HasColumnType("double");
b.Property<int>("Ranking")
.HasColumnType("int");
b.Property<int>("RatingHistoryId")
.HasColumnType("int");
b.Property<long?>("ServerId")
.HasColumnType("bigint");
b.Property<DateTime>("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("IW4MAdmin.Plugins.Stats.Models.EFServer", b =>
{
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<string>("EndPoint")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<int?>("GameName")
.HasColumnType("int");
b.Property<string>("HostName")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<bool>("IsPasswordProtected")
.HasColumnType("tinyint(1)");
b.Property<int>("Port")
.HasColumnType("int");
b.HasKey("ServerId");
b.ToTable("EFServers");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b =>
{
b.Property<int>("StatisticId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<long>("TotalKills")
.HasColumnType("bigint");
b.Property<long>("TotalPlayTime")
.HasColumnType("bigint");
b.HasKey("StatisticId");
b.HasIndex("ServerId");
b.ToTable("EFServerStatistics");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b =>
{
b.Property<int>("AliasId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<DateTime>("DateAdded")
.HasColumnType("datetime(6)");
b.Property<int?>("IPAddress")
.HasColumnType("int");
b.Property<int>("LinkId")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("varchar(24) CHARACTER SET utf8mb4")
.HasMaxLength(24);
b.Property<string>("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("SharedLibraryCore.Database.Models.EFAliasLink", b =>
{
b.Property<int>("AliasLinkId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.HasKey("AliasLinkId");
b.ToTable("EFAliasLinks");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFChangeHistory", b =>
{
b.Property<int>("ChangeHistoryId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<string>("Comment")
.HasColumnType("varchar(128) CHARACTER SET utf8mb4")
.HasMaxLength(128);
b.Property<string>("CurrentValue")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<int?>("ImpersonationEntityId")
.HasColumnType("int");
b.Property<int>("OriginEntityId")
.HasColumnType("int");
b.Property<string>("PreviousValue")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<int>("TargetEntityId")
.HasColumnType("int");
b.Property<DateTime>("TimeChanged")
.HasColumnType("datetime(6)");
b.Property<int>("TypeOfChange")
.HasColumnType("int");
b.HasKey("ChangeHistoryId");
b.ToTable("EFChangeHistory");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b =>
{
b.Property<int>("ClientId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int>("AliasLinkId")
.HasColumnType("int");
b.Property<int>("Connections")
.HasColumnType("int");
b.Property<int>("CurrentAliasId")
.HasColumnType("int");
b.Property<DateTime>("FirstConnection")
.HasColumnType("datetime(6)");
b.Property<DateTime>("LastConnection")
.HasColumnType("datetime(6)");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<bool>("Masked")
.HasColumnType("tinyint(1)");
b.Property<long>("NetworkId")
.HasColumnType("bigint");
b.Property<string>("Password")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<string>("PasswordSalt")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<int>("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 =>
{
b.Property<int>("MetaId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int?>("ClientId")
.HasColumnType("int");
b.Property<DateTime>("Created")
.HasColumnType("datetime(6)");
b.Property<string>("Extra")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<string>("Key")
.IsRequired()
.HasColumnType("varchar(32) CHARACTER SET utf8mb4")
.HasMaxLength(32);
b.Property<DateTime>("Updated")
.HasColumnType("datetime(6)");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.HasKey("MetaId");
b.HasIndex("ClientId");
b.HasIndex("Key");
b.ToTable("EFMeta");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
{
b.Property<int>("PenaltyId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<string>("AutomatedOffense")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<DateTime?>("Expires")
.HasColumnType("datetime(6)");
b.Property<bool>("IsEvadedOffense")
.HasColumnType("tinyint(1)");
b.Property<int>("LinkId")
.HasColumnType("int");
b.Property<int>("OffenderId")
.HasColumnType("int");
b.Property<string>("Offense")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<int>("PunisherId")
.HasColumnType("int");
b.Property<int>("Type")
.HasColumnType("int");
b.Property<DateTime>("When")
.HasColumnType("datetime(6)");
b.HasKey("PenaltyId");
b.HasIndex("LinkId");
b.HasIndex("OffenderId");
b.HasIndex("PunisherId");
b.ToTable("EFPenalties");
});
modelBuilder.Entity("SharedLibraryCore.Helpers.Vector3", b =>
{
b.Property<int>("Vector3Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<float>("X")
.HasColumnType("float");
b.Property<float>("Y")
.HasColumnType("float");
b.Property<float>("Z")
.HasColumnType("float");
b.HasKey("Vector3Id");
b.ToTable("Vector3");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", 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")
.WithMany("PredictedViewAngles")
.HasForeignKey("SnapshotId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SharedLibraryCore.Helpers.Vector3", "Vector")
.WithMany()
.HasForeignKey("Vector3Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", 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")
.WithMany()
.HasForeignKey("AliasLinkId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SharedLibraryCore.Database.Models.EFAlias", "CurrentAlias")
.WithMany()
.HasForeignKey("CurrentAliasId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFMeta", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
.WithMany("Meta")
.HasForeignKey("ClientId");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link")
.WithMany("ReceivedPenalties")
.HasForeignKey("LinkId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Offender")
.WithMany("ReceivedPenalties")
.HasForeignKey("OffenderId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Punisher")
.WithMany("AdministeredPenalties")
.HasForeignKey("PunisherId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,52 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace SharedLibraryCore.Migrations.MySql
{
public partial class UpdateEFMetaToSupportNonClientMeta : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_EFMeta_EFClients_ClientId",
table: "EFMeta");
migrationBuilder.AlterColumn<int>(
name: "ClientId",
table: "EFMeta",
nullable: true,
oldClrType: typeof(int),
oldType: "int");
migrationBuilder.AddForeignKey(
name: "FK_EFMeta_EFClients_ClientId",
table: "EFMeta",
column: "ClientId",
principalTable: "EFClients",
principalColumn: "ClientId",
onDelete: ReferentialAction.Restrict);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_EFMeta_EFClients_ClientId",
table: "EFMeta");
migrationBuilder.AlterColumn<int>(
name: "ClientId",
table: "EFMeta",
type: "int",
nullable: false,
oldClrType: typeof(int),
oldNullable: true);
migrationBuilder.AddForeignKey(
name: "FK_EFMeta_EFClients_ClientId",
table: "EFMeta",
column: "ClientId",
principalTable: "EFClients",
principalColumn: "ClientId",
onDelete: ReferentialAction.Cascade);
}
}
}

View File

@ -0,0 +1,939 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using SharedLibraryCore.Database.MigrationContext;
namespace SharedLibraryCore.Migrations.MySql
{
[DbContext(typeof(MySqlDatabaseContext))]
[Migration("20210124170830_UpdateEFMetaToSupportLinkedMeta")]
partial class UpdateEFMetaToSupportLinkedMeta
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.10")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
{
b.Property<int>("SnapshotId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int>("ClientId")
.HasColumnType("int");
b.Property<int>("CurrentSessionLength")
.HasColumnType("int");
b.Property<double>("CurrentStrain")
.HasColumnType("double");
b.Property<int>("CurrentViewAngleId")
.HasColumnType("int");
b.Property<int>("Deaths")
.HasColumnType("int");
b.Property<double>("Distance")
.HasColumnType("double");
b.Property<double>("EloRating")
.HasColumnType("double");
b.Property<int>("HitDestinationId")
.HasColumnType("int");
b.Property<int>("HitLocation")
.HasColumnType("int");
b.Property<int>("HitOriginId")
.HasColumnType("int");
b.Property<int>("HitType")
.HasColumnType("int");
b.Property<int>("Hits")
.HasColumnType("int");
b.Property<int>("Kills")
.HasColumnType("int");
b.Property<int>("LastStrainAngleId")
.HasColumnType("int");
b.Property<double>("RecoilOffset")
.HasColumnType("double");
b.Property<double>("SessionAngleOffset")
.HasColumnType("double");
b.Property<double>("SessionAverageSnapValue")
.HasColumnType("double");
b.Property<double>("SessionSPM")
.HasColumnType("double");
b.Property<int>("SessionScore")
.HasColumnType("int");
b.Property<int>("SessionSnapHits")
.HasColumnType("int");
b.Property<double>("StrainAngleBetween")
.HasColumnType("double");
b.Property<int>("TimeSinceLastEvent")
.HasColumnType("int");
b.Property<int>("WeaponId")
.HasColumnType("int");
b.Property<DateTime>("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("IW4MAdmin.Plugins.Stats.Models.EFACSnapshotVector3", b =>
{
b.Property<int>("ACSnapshotVector3Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int>("SnapshotId")
.HasColumnType("int");
b.Property<int>("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<long>("KillId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int>("AttackerId")
.HasColumnType("int");
b.Property<int>("Damage")
.HasColumnType("int");
b.Property<int?>("DeathOriginVector3Id")
.HasColumnType("int");
b.Property<int>("DeathType")
.HasColumnType("int");
b.Property<double>("Fraction")
.HasColumnType("double");
b.Property<int>("HitLoc")
.HasColumnType("int");
b.Property<bool>("IsKill")
.HasColumnType("tinyint(1)");
b.Property<int?>("KillOriginVector3Id")
.HasColumnType("int");
b.Property<int>("Map")
.HasColumnType("int");
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<int>("VictimId")
.HasColumnType("int");
b.Property<int?>("ViewAnglesVector3Id")
.HasColumnType("int");
b.Property<double>("VisibilityPercentage")
.HasColumnType("double");
b.Property<int>("Weapon")
.HasColumnType("int");
b.Property<DateTime>("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<long>("MessageId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int>("ClientId")
.HasColumnType("int");
b.Property<string>("Message")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<bool>("SentIngame")
.HasColumnType("tinyint(1)");
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<DateTime>("TimeSent")
.HasColumnType("datetime(6)");
b.HasKey("MessageId");
b.HasIndex("ClientId");
b.HasIndex("ServerId");
b.HasIndex("TimeSent");
b.ToTable("EFClientMessages");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b =>
{
b.Property<int>("RatingHistoryId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int>("ClientId")
.HasColumnType("int");
b.HasKey("RatingHistoryId");
b.HasIndex("ClientId");
b.ToTable("EFClientRatingHistory");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
{
b.Property<int>("ClientId")
.HasColumnType("int");
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<double>("AverageRecoilOffset")
.HasColumnType("double");
b.Property<double>("AverageSnapValue")
.HasColumnType("double");
b.Property<int>("Deaths")
.HasColumnType("int");
b.Property<double>("EloRating")
.HasColumnType("double");
b.Property<int>("Kills")
.HasColumnType("int");
b.Property<double>("MaxStrain")
.HasColumnType("double");
b.Property<double>("RollingWeightedKDR")
.HasColumnType("double");
b.Property<double>("SPM")
.HasColumnType("double");
b.Property<double>("Skill")
.HasColumnType("double");
b.Property<int>("SnapHitCount")
.HasColumnType("int");
b.Property<int>("TimePlayed")
.HasColumnType("int");
b.Property<double>("VisionAverage")
.HasColumnType("double");
b.HasKey("ClientId", "ServerId");
b.HasIndex("ServerId");
b.ToTable("EFClientStatistics");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b =>
{
b.Property<int>("HitLocationCountId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int>("EFClientStatisticsClientId")
.HasColumnName("EFClientStatisticsClientId")
.HasColumnType("int");
b.Property<long>("EFClientStatisticsServerId")
.HasColumnName("EFClientStatisticsServerId")
.HasColumnType("bigint");
b.Property<int>("HitCount")
.HasColumnType("int");
b.Property<float>("HitOffsetAverage")
.HasColumnType("float");
b.Property<int>("Location")
.HasColumnType("int");
b.Property<float>("MaxAngleDistance")
.HasColumnType("float");
b.HasKey("HitLocationCountId");
b.HasIndex("EFClientStatisticsServerId");
b.HasIndex("EFClientStatisticsClientId", "EFClientStatisticsServerId");
b.ToTable("EFHitLocationCounts");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b =>
{
b.Property<int>("RatingId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int>("ActivityAmount")
.HasColumnType("int");
b.Property<bool>("Newest")
.HasColumnType("tinyint(1)");
b.Property<double>("Performance")
.HasColumnType("double");
b.Property<int>("Ranking")
.HasColumnType("int");
b.Property<int>("RatingHistoryId")
.HasColumnType("int");
b.Property<long?>("ServerId")
.HasColumnType("bigint");
b.Property<DateTime>("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("IW4MAdmin.Plugins.Stats.Models.EFServer", b =>
{
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<string>("EndPoint")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<int?>("GameName")
.HasColumnType("int");
b.Property<string>("HostName")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<bool>("IsPasswordProtected")
.HasColumnType("tinyint(1)");
b.Property<int>("Port")
.HasColumnType("int");
b.HasKey("ServerId");
b.ToTable("EFServers");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b =>
{
b.Property<int>("StatisticId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<long>("TotalKills")
.HasColumnType("bigint");
b.Property<long>("TotalPlayTime")
.HasColumnType("bigint");
b.HasKey("StatisticId");
b.HasIndex("ServerId");
b.ToTable("EFServerStatistics");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b =>
{
b.Property<int>("AliasId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<DateTime>("DateAdded")
.HasColumnType("datetime(6)");
b.Property<int?>("IPAddress")
.HasColumnType("int");
b.Property<int>("LinkId")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("varchar(24) CHARACTER SET utf8mb4")
.HasMaxLength(24);
b.Property<string>("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("SharedLibraryCore.Database.Models.EFAliasLink", b =>
{
b.Property<int>("AliasLinkId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.HasKey("AliasLinkId");
b.ToTable("EFAliasLinks");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFChangeHistory", b =>
{
b.Property<int>("ChangeHistoryId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<string>("Comment")
.HasColumnType("varchar(128) CHARACTER SET utf8mb4")
.HasMaxLength(128);
b.Property<string>("CurrentValue")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<int?>("ImpersonationEntityId")
.HasColumnType("int");
b.Property<int>("OriginEntityId")
.HasColumnType("int");
b.Property<string>("PreviousValue")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<int>("TargetEntityId")
.HasColumnType("int");
b.Property<DateTime>("TimeChanged")
.HasColumnType("datetime(6)");
b.Property<int>("TypeOfChange")
.HasColumnType("int");
b.HasKey("ChangeHistoryId");
b.ToTable("EFChangeHistory");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b =>
{
b.Property<int>("ClientId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int>("AliasLinkId")
.HasColumnType("int");
b.Property<int>("Connections")
.HasColumnType("int");
b.Property<int>("CurrentAliasId")
.HasColumnType("int");
b.Property<DateTime>("FirstConnection")
.HasColumnType("datetime(6)");
b.Property<DateTime>("LastConnection")
.HasColumnType("datetime(6)");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<bool>("Masked")
.HasColumnType("tinyint(1)");
b.Property<long>("NetworkId")
.HasColumnType("bigint");
b.Property<string>("Password")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<string>("PasswordSalt")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<int>("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 =>
{
b.Property<int>("MetaId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int?>("ClientId")
.HasColumnType("int");
b.Property<DateTime>("Created")
.HasColumnType("datetime(6)");
b.Property<string>("Extra")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<string>("Key")
.IsRequired()
.HasColumnType("varchar(32) CHARACTER SET utf8mb4")
.HasMaxLength(32);
b.Property<int?>("LinkedMetaId")
.HasColumnType("int");
b.Property<DateTime>("Updated")
.HasColumnType("datetime(6)");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.HasKey("MetaId");
b.HasIndex("ClientId");
b.HasIndex("Key");
b.HasIndex("LinkedMetaId");
b.ToTable("EFMeta");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
{
b.Property<int>("PenaltyId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<string>("AutomatedOffense")
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<DateTime?>("Expires")
.HasColumnType("datetime(6)");
b.Property<bool>("IsEvadedOffense")
.HasColumnType("tinyint(1)");
b.Property<int>("LinkId")
.HasColumnType("int");
b.Property<int>("OffenderId")
.HasColumnType("int");
b.Property<string>("Offense")
.IsRequired()
.HasColumnType("longtext CHARACTER SET utf8mb4");
b.Property<int>("PunisherId")
.HasColumnType("int");
b.Property<int>("Type")
.HasColumnType("int");
b.Property<DateTime>("When")
.HasColumnType("datetime(6)");
b.HasKey("PenaltyId");
b.HasIndex("LinkId");
b.HasIndex("OffenderId");
b.HasIndex("PunisherId");
b.ToTable("EFPenalties");
});
modelBuilder.Entity("SharedLibraryCore.Helpers.Vector3", b =>
{
b.Property<int>("Vector3Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<float>("X")
.HasColumnType("float");
b.Property<float>("Y")
.HasColumnType("float");
b.Property<float>("Z")
.HasColumnType("float");
b.HasKey("Vector3Id");
b.ToTable("Vector3");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", 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")
.WithMany("PredictedViewAngles")
.HasForeignKey("SnapshotId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SharedLibraryCore.Helpers.Vector3", "Vector")
.WithMany()
.HasForeignKey("Vector3Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", 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")
.WithMany()
.HasForeignKey("AliasLinkId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SharedLibraryCore.Database.Models.EFAlias", "CurrentAlias")
.WithMany()
.HasForeignKey("CurrentAliasId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFMeta", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
.WithMany("Meta")
.HasForeignKey("ClientId");
b.HasOne("SharedLibraryCore.Database.Models.EFMeta", "LinkedMeta")
.WithMany()
.HasForeignKey("LinkedMetaId")
.OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link")
.WithMany("ReceivedPenalties")
.HasForeignKey("LinkId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Offender")
.WithMany("ReceivedPenalties")
.HasForeignKey("OffenderId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Punisher")
.WithMany("AdministeredPenalties")
.HasForeignKey("PunisherId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,43 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace SharedLibraryCore.Migrations.MySql
{
public partial class UpdateEFMetaToSupportLinkedMeta : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "LinkedMetaId",
table: "EFMeta",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_EFMeta_LinkedMetaId",
table: "EFMeta",
column: "LinkedMetaId");
migrationBuilder.AddForeignKey(
name: "FK_EFMeta_EFMeta_LinkedMetaId",
table: "EFMeta",
column: "LinkedMetaId",
principalTable: "EFMeta",
principalColumn: "MetaId",
onDelete: ReferentialAction.SetNull);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_EFMeta_EFMeta_LinkedMetaId",
table: "EFMeta");
migrationBuilder.DropIndex(
name: "IX_EFMeta_LinkedMetaId",
table: "EFMeta");
migrationBuilder.DropColumn(
name: "LinkedMetaId",
table: "EFMeta");
}
}
}

View File

@ -14,7 +14,7 @@ namespace SharedLibraryCore.Migrations.MySql
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.7")
.HasAnnotation("ProductVersion", "3.1.10")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
@ -470,11 +470,11 @@ namespace SharedLibraryCore.Migrations.MySql
b.Property<string>("Name")
.IsRequired()
.HasColumnType("varchar(24) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin")
.HasColumnType("varchar(24) CHARACTER SET utf8mb4")
.HasMaxLength(24);
b.Property<string>("SearchableName")
.HasColumnType("varchar(24) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin")
.HasColumnType("varchar(24) CHARACTER SET utf8mb4")
.HasMaxLength(24);
b.HasKey("AliasId");
@ -609,7 +609,7 @@ namespace SharedLibraryCore.Migrations.MySql
b.Property<bool>("Active")
.HasColumnType("tinyint(1)");
b.Property<int>("ClientId")
b.Property<int?>("ClientId")
.HasColumnType("int");
b.Property<DateTime>("Created")
@ -623,6 +623,9 @@ namespace SharedLibraryCore.Migrations.MySql
.HasColumnType("varchar(32) CHARACTER SET utf8mb4")
.HasMaxLength(32);
b.Property<int?>("LinkedMetaId")
.HasColumnType("int");
b.Property<DateTime>("Updated")
.HasColumnType("datetime(6)");
@ -636,6 +639,8 @@ namespace SharedLibraryCore.Migrations.MySql
b.HasIndex("Key");
b.HasIndex("LinkedMetaId");
b.ToTable("EFMeta");
});
@ -898,9 +903,12 @@ namespace SharedLibraryCore.Migrations.MySql
{
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
.WithMany("Meta")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
.HasForeignKey("ClientId");
b.HasOne("SharedLibraryCore.Database.Models.EFMeta", "LinkedMeta")
.WithMany()
.HasForeignKey("LinkedMetaId")
.OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>

View File

@ -0,0 +1,946 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using SharedLibraryCore.Database.MigrationContext;
namespace SharedLibraryCore.Migrations.Postgresql
{
[DbContext(typeof(PostgresqlDatabaseContext))]
[Migration("20210123024304_UpdateEFMetaToSupportNonClientMeta")]
partial class UpdateEFMetaToSupportNonClientMeta
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.HasAnnotation("ProductVersion", "3.1.10")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
{
b.Property<int>("SnapshotId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int>("ClientId")
.HasColumnType("integer");
b.Property<int>("CurrentSessionLength")
.HasColumnType("integer");
b.Property<double>("CurrentStrain")
.HasColumnType("double precision");
b.Property<int>("CurrentViewAngleId")
.HasColumnType("integer");
b.Property<int>("Deaths")
.HasColumnType("integer");
b.Property<double>("Distance")
.HasColumnType("double precision");
b.Property<double>("EloRating")
.HasColumnType("double precision");
b.Property<int>("HitDestinationId")
.HasColumnType("integer");
b.Property<int>("HitLocation")
.HasColumnType("integer");
b.Property<int>("HitOriginId")
.HasColumnType("integer");
b.Property<int>("HitType")
.HasColumnType("integer");
b.Property<int>("Hits")
.HasColumnType("integer");
b.Property<int>("Kills")
.HasColumnType("integer");
b.Property<int>("LastStrainAngleId")
.HasColumnType("integer");
b.Property<double>("RecoilOffset")
.HasColumnType("double precision");
b.Property<double>("SessionAngleOffset")
.HasColumnType("double precision");
b.Property<double>("SessionAverageSnapValue")
.HasColumnType("double precision");
b.Property<double>("SessionSPM")
.HasColumnType("double precision");
b.Property<int>("SessionScore")
.HasColumnType("integer");
b.Property<int>("SessionSnapHits")
.HasColumnType("integer");
b.Property<double>("StrainAngleBetween")
.HasColumnType("double precision");
b.Property<int>("TimeSinceLastEvent")
.HasColumnType("integer");
b.Property<int>("WeaponId")
.HasColumnType("integer");
b.Property<DateTime>("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("IW4MAdmin.Plugins.Stats.Models.EFACSnapshotVector3", b =>
{
b.Property<int>("ACSnapshotVector3Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int>("SnapshotId")
.HasColumnType("integer");
b.Property<int>("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<long>("KillId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int>("AttackerId")
.HasColumnType("integer");
b.Property<int>("Damage")
.HasColumnType("integer");
b.Property<int?>("DeathOriginVector3Id")
.HasColumnType("integer");
b.Property<int>("DeathType")
.HasColumnType("integer");
b.Property<double>("Fraction")
.HasColumnType("double precision");
b.Property<int>("HitLoc")
.HasColumnType("integer");
b.Property<bool>("IsKill")
.HasColumnType("boolean");
b.Property<int?>("KillOriginVector3Id")
.HasColumnType("integer");
b.Property<int>("Map")
.HasColumnType("integer");
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<int>("VictimId")
.HasColumnType("integer");
b.Property<int?>("ViewAnglesVector3Id")
.HasColumnType("integer");
b.Property<double>("VisibilityPercentage")
.HasColumnType("double precision");
b.Property<int>("Weapon")
.HasColumnType("integer");
b.Property<DateTime>("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<long>("MessageId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int>("ClientId")
.HasColumnType("integer");
b.Property<string>("Message")
.HasColumnType("text");
b.Property<bool>("SentIngame")
.HasColumnType("boolean");
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<DateTime>("TimeSent")
.HasColumnType("timestamp without time zone");
b.HasKey("MessageId");
b.HasIndex("ClientId");
b.HasIndex("ServerId");
b.HasIndex("TimeSent");
b.ToTable("EFClientMessages");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b =>
{
b.Property<int>("RatingHistoryId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int>("ClientId")
.HasColumnType("integer");
b.HasKey("RatingHistoryId");
b.HasIndex("ClientId");
b.ToTable("EFClientRatingHistory");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
{
b.Property<int>("ClientId")
.HasColumnType("integer");
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<double>("AverageRecoilOffset")
.HasColumnType("double precision");
b.Property<double>("AverageSnapValue")
.HasColumnType("double precision");
b.Property<int>("Deaths")
.HasColumnType("integer");
b.Property<double>("EloRating")
.HasColumnType("double precision");
b.Property<int>("Kills")
.HasColumnType("integer");
b.Property<double>("MaxStrain")
.HasColumnType("double precision");
b.Property<double>("RollingWeightedKDR")
.HasColumnType("double precision");
b.Property<double>("SPM")
.HasColumnType("double precision");
b.Property<double>("Skill")
.HasColumnType("double precision");
b.Property<int>("SnapHitCount")
.HasColumnType("integer");
b.Property<int>("TimePlayed")
.HasColumnType("integer");
b.Property<double>("VisionAverage")
.HasColumnType("double precision");
b.HasKey("ClientId", "ServerId");
b.HasIndex("ServerId");
b.ToTable("EFClientStatistics");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b =>
{
b.Property<int>("HitLocationCountId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int>("EFClientStatisticsClientId")
.HasColumnName("EFClientStatisticsClientId")
.HasColumnType("integer");
b.Property<long>("EFClientStatisticsServerId")
.HasColumnName("EFClientStatisticsServerId")
.HasColumnType("bigint");
b.Property<int>("HitCount")
.HasColumnType("integer");
b.Property<float>("HitOffsetAverage")
.HasColumnType("real");
b.Property<int>("Location")
.HasColumnType("integer");
b.Property<float>("MaxAngleDistance")
.HasColumnType("real");
b.HasKey("HitLocationCountId");
b.HasIndex("EFClientStatisticsServerId");
b.HasIndex("EFClientStatisticsClientId", "EFClientStatisticsServerId");
b.ToTable("EFHitLocationCounts");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b =>
{
b.Property<int>("RatingId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int>("ActivityAmount")
.HasColumnType("integer");
b.Property<bool>("Newest")
.HasColumnType("boolean");
b.Property<double>("Performance")
.HasColumnType("double precision");
b.Property<int>("Ranking")
.HasColumnType("integer");
b.Property<int>("RatingHistoryId")
.HasColumnType("integer");
b.Property<long?>("ServerId")
.HasColumnType("bigint");
b.Property<DateTime>("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("IW4MAdmin.Plugins.Stats.Models.EFServer", b =>
{
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<string>("EndPoint")
.HasColumnType("text");
b.Property<int?>("GameName")
.HasColumnType("integer");
b.Property<string>("HostName")
.HasColumnType("text");
b.Property<bool>("IsPasswordProtected")
.HasColumnType("boolean");
b.Property<int>("Port")
.HasColumnType("integer");
b.HasKey("ServerId");
b.ToTable("EFServers");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b =>
{
b.Property<int>("StatisticId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<long>("TotalKills")
.HasColumnType("bigint");
b.Property<long>("TotalPlayTime")
.HasColumnType("bigint");
b.HasKey("StatisticId");
b.HasIndex("ServerId");
b.ToTable("EFServerStatistics");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b =>
{
b.Property<int>("AliasId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<DateTime>("DateAdded")
.HasColumnType("timestamp without time zone");
b.Property<int?>("IPAddress")
.HasColumnType("integer");
b.Property<int>("LinkId")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("character varying(24)")
.HasMaxLength(24);
b.Property<string>("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("SharedLibraryCore.Database.Models.EFAliasLink", b =>
{
b.Property<int>("AliasLinkId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.HasKey("AliasLinkId");
b.ToTable("EFAliasLinks");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFChangeHistory", b =>
{
b.Property<int>("ChangeHistoryId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<string>("Comment")
.HasColumnType("character varying(128)")
.HasMaxLength(128);
b.Property<string>("CurrentValue")
.HasColumnType("text");
b.Property<int?>("ImpersonationEntityId")
.HasColumnType("integer");
b.Property<int>("OriginEntityId")
.HasColumnType("integer");
b.Property<string>("PreviousValue")
.HasColumnType("text");
b.Property<int>("TargetEntityId")
.HasColumnType("integer");
b.Property<DateTime>("TimeChanged")
.HasColumnType("timestamp without time zone");
b.Property<int>("TypeOfChange")
.HasColumnType("integer");
b.HasKey("ChangeHistoryId");
b.ToTable("EFChangeHistory");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b =>
{
b.Property<int>("ClientId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int>("AliasLinkId")
.HasColumnType("integer");
b.Property<int>("Connections")
.HasColumnType("integer");
b.Property<int>("CurrentAliasId")
.HasColumnType("integer");
b.Property<DateTime>("FirstConnection")
.HasColumnType("timestamp without time zone");
b.Property<DateTime>("LastConnection")
.HasColumnType("timestamp without time zone");
b.Property<int>("Level")
.HasColumnType("integer");
b.Property<bool>("Masked")
.HasColumnType("boolean");
b.Property<long>("NetworkId")
.HasColumnType("bigint");
b.Property<string>("Password")
.HasColumnType("text");
b.Property<string>("PasswordSalt")
.HasColumnType("text");
b.Property<int>("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 =>
{
b.Property<int>("MetaId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int?>("ClientId")
.HasColumnType("integer");
b.Property<DateTime>("Created")
.HasColumnType("timestamp without time zone");
b.Property<string>("Extra")
.HasColumnType("text");
b.Property<string>("Key")
.IsRequired()
.HasColumnType("character varying(32)")
.HasMaxLength(32);
b.Property<DateTime>("Updated")
.HasColumnType("timestamp without time zone");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("MetaId");
b.HasIndex("ClientId");
b.HasIndex("Key");
b.ToTable("EFMeta");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
{
b.Property<int>("PenaltyId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<string>("AutomatedOffense")
.HasColumnType("text");
b.Property<DateTime?>("Expires")
.HasColumnType("timestamp without time zone");
b.Property<bool>("IsEvadedOffense")
.HasColumnType("boolean");
b.Property<int>("LinkId")
.HasColumnType("integer");
b.Property<int>("OffenderId")
.HasColumnType("integer");
b.Property<string>("Offense")
.IsRequired()
.HasColumnType("text");
b.Property<int>("PunisherId")
.HasColumnType("integer");
b.Property<int>("Type")
.HasColumnType("integer");
b.Property<DateTime>("When")
.HasColumnType("timestamp without time zone");
b.HasKey("PenaltyId");
b.HasIndex("LinkId");
b.HasIndex("OffenderId");
b.HasIndex("PunisherId");
b.ToTable("EFPenalties");
});
modelBuilder.Entity("SharedLibraryCore.Helpers.Vector3", b =>
{
b.Property<int>("Vector3Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<float>("X")
.HasColumnType("real");
b.Property<float>("Y")
.HasColumnType("real");
b.Property<float>("Z")
.HasColumnType("real");
b.HasKey("Vector3Id");
b.ToTable("Vector3");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", 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")
.WithMany("PredictedViewAngles")
.HasForeignKey("SnapshotId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SharedLibraryCore.Helpers.Vector3", "Vector")
.WithMany()
.HasForeignKey("Vector3Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", 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")
.WithMany()
.HasForeignKey("AliasLinkId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SharedLibraryCore.Database.Models.EFAlias", "CurrentAlias")
.WithMany()
.HasForeignKey("CurrentAliasId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFMeta", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
.WithMany("Meta")
.HasForeignKey("ClientId");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link")
.WithMany("ReceivedPenalties")
.HasForeignKey("LinkId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Offender")
.WithMany("ReceivedPenalties")
.HasForeignKey("OffenderId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Punisher")
.WithMany("AdministeredPenalties")
.HasForeignKey("PunisherId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,52 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace SharedLibraryCore.Migrations.Postgresql
{
public partial class UpdateEFMetaToSupportNonClientMeta : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_EFMeta_EFClients_ClientId",
table: "EFMeta");
migrationBuilder.AlterColumn<int>(
name: "ClientId",
table: "EFMeta",
nullable: true,
oldClrType: typeof(int),
oldType: "integer");
migrationBuilder.AddForeignKey(
name: "FK_EFMeta_EFClients_ClientId",
table: "EFMeta",
column: "ClientId",
principalTable: "EFClients",
principalColumn: "ClientId",
onDelete: ReferentialAction.Restrict);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_EFMeta_EFClients_ClientId",
table: "EFMeta");
migrationBuilder.AlterColumn<int>(
name: "ClientId",
table: "EFMeta",
type: "integer",
nullable: false,
oldClrType: typeof(int),
oldNullable: true);
migrationBuilder.AddForeignKey(
name: "FK_EFMeta_EFClients_ClientId",
table: "EFMeta",
column: "ClientId",
principalTable: "EFClients",
principalColumn: "ClientId",
onDelete: ReferentialAction.Cascade);
}
}
}

View File

@ -0,0 +1,956 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using SharedLibraryCore.Database.MigrationContext;
namespace SharedLibraryCore.Migrations.Postgresql
{
[DbContext(typeof(PostgresqlDatabaseContext))]
[Migration("20210124170956_UpdateEFMetaToSupportLinkedMeta")]
partial class UpdateEFMetaToSupportLinkedMeta
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.HasAnnotation("ProductVersion", "3.1.10")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
{
b.Property<int>("SnapshotId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int>("ClientId")
.HasColumnType("integer");
b.Property<int>("CurrentSessionLength")
.HasColumnType("integer");
b.Property<double>("CurrentStrain")
.HasColumnType("double precision");
b.Property<int>("CurrentViewAngleId")
.HasColumnType("integer");
b.Property<int>("Deaths")
.HasColumnType("integer");
b.Property<double>("Distance")
.HasColumnType("double precision");
b.Property<double>("EloRating")
.HasColumnType("double precision");
b.Property<int>("HitDestinationId")
.HasColumnType("integer");
b.Property<int>("HitLocation")
.HasColumnType("integer");
b.Property<int>("HitOriginId")
.HasColumnType("integer");
b.Property<int>("HitType")
.HasColumnType("integer");
b.Property<int>("Hits")
.HasColumnType("integer");
b.Property<int>("Kills")
.HasColumnType("integer");
b.Property<int>("LastStrainAngleId")
.HasColumnType("integer");
b.Property<double>("RecoilOffset")
.HasColumnType("double precision");
b.Property<double>("SessionAngleOffset")
.HasColumnType("double precision");
b.Property<double>("SessionAverageSnapValue")
.HasColumnType("double precision");
b.Property<double>("SessionSPM")
.HasColumnType("double precision");
b.Property<int>("SessionScore")
.HasColumnType("integer");
b.Property<int>("SessionSnapHits")
.HasColumnType("integer");
b.Property<double>("StrainAngleBetween")
.HasColumnType("double precision");
b.Property<int>("TimeSinceLastEvent")
.HasColumnType("integer");
b.Property<int>("WeaponId")
.HasColumnType("integer");
b.Property<DateTime>("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("IW4MAdmin.Plugins.Stats.Models.EFACSnapshotVector3", b =>
{
b.Property<int>("ACSnapshotVector3Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int>("SnapshotId")
.HasColumnType("integer");
b.Property<int>("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<long>("KillId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int>("AttackerId")
.HasColumnType("integer");
b.Property<int>("Damage")
.HasColumnType("integer");
b.Property<int?>("DeathOriginVector3Id")
.HasColumnType("integer");
b.Property<int>("DeathType")
.HasColumnType("integer");
b.Property<double>("Fraction")
.HasColumnType("double precision");
b.Property<int>("HitLoc")
.HasColumnType("integer");
b.Property<bool>("IsKill")
.HasColumnType("boolean");
b.Property<int?>("KillOriginVector3Id")
.HasColumnType("integer");
b.Property<int>("Map")
.HasColumnType("integer");
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<int>("VictimId")
.HasColumnType("integer");
b.Property<int?>("ViewAnglesVector3Id")
.HasColumnType("integer");
b.Property<double>("VisibilityPercentage")
.HasColumnType("double precision");
b.Property<int>("Weapon")
.HasColumnType("integer");
b.Property<DateTime>("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<long>("MessageId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int>("ClientId")
.HasColumnType("integer");
b.Property<string>("Message")
.HasColumnType("text");
b.Property<bool>("SentIngame")
.HasColumnType("boolean");
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<DateTime>("TimeSent")
.HasColumnType("timestamp without time zone");
b.HasKey("MessageId");
b.HasIndex("ClientId");
b.HasIndex("ServerId");
b.HasIndex("TimeSent");
b.ToTable("EFClientMessages");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b =>
{
b.Property<int>("RatingHistoryId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int>("ClientId")
.HasColumnType("integer");
b.HasKey("RatingHistoryId");
b.HasIndex("ClientId");
b.ToTable("EFClientRatingHistory");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
{
b.Property<int>("ClientId")
.HasColumnType("integer");
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<double>("AverageRecoilOffset")
.HasColumnType("double precision");
b.Property<double>("AverageSnapValue")
.HasColumnType("double precision");
b.Property<int>("Deaths")
.HasColumnType("integer");
b.Property<double>("EloRating")
.HasColumnType("double precision");
b.Property<int>("Kills")
.HasColumnType("integer");
b.Property<double>("MaxStrain")
.HasColumnType("double precision");
b.Property<double>("RollingWeightedKDR")
.HasColumnType("double precision");
b.Property<double>("SPM")
.HasColumnType("double precision");
b.Property<double>("Skill")
.HasColumnType("double precision");
b.Property<int>("SnapHitCount")
.HasColumnType("integer");
b.Property<int>("TimePlayed")
.HasColumnType("integer");
b.Property<double>("VisionAverage")
.HasColumnType("double precision");
b.HasKey("ClientId", "ServerId");
b.HasIndex("ServerId");
b.ToTable("EFClientStatistics");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b =>
{
b.Property<int>("HitLocationCountId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int>("EFClientStatisticsClientId")
.HasColumnName("EFClientStatisticsClientId")
.HasColumnType("integer");
b.Property<long>("EFClientStatisticsServerId")
.HasColumnName("EFClientStatisticsServerId")
.HasColumnType("bigint");
b.Property<int>("HitCount")
.HasColumnType("integer");
b.Property<float>("HitOffsetAverage")
.HasColumnType("real");
b.Property<int>("Location")
.HasColumnType("integer");
b.Property<float>("MaxAngleDistance")
.HasColumnType("real");
b.HasKey("HitLocationCountId");
b.HasIndex("EFClientStatisticsServerId");
b.HasIndex("EFClientStatisticsClientId", "EFClientStatisticsServerId");
b.ToTable("EFHitLocationCounts");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b =>
{
b.Property<int>("RatingId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int>("ActivityAmount")
.HasColumnType("integer");
b.Property<bool>("Newest")
.HasColumnType("boolean");
b.Property<double>("Performance")
.HasColumnType("double precision");
b.Property<int>("Ranking")
.HasColumnType("integer");
b.Property<int>("RatingHistoryId")
.HasColumnType("integer");
b.Property<long?>("ServerId")
.HasColumnType("bigint");
b.Property<DateTime>("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("IW4MAdmin.Plugins.Stats.Models.EFServer", b =>
{
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<string>("EndPoint")
.HasColumnType("text");
b.Property<int?>("GameName")
.HasColumnType("integer");
b.Property<string>("HostName")
.HasColumnType("text");
b.Property<bool>("IsPasswordProtected")
.HasColumnType("boolean");
b.Property<int>("Port")
.HasColumnType("integer");
b.HasKey("ServerId");
b.ToTable("EFServers");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b =>
{
b.Property<int>("StatisticId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<long>("ServerId")
.HasColumnType("bigint");
b.Property<long>("TotalKills")
.HasColumnType("bigint");
b.Property<long>("TotalPlayTime")
.HasColumnType("bigint");
b.HasKey("StatisticId");
b.HasIndex("ServerId");
b.ToTable("EFServerStatistics");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b =>
{
b.Property<int>("AliasId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<DateTime>("DateAdded")
.HasColumnType("timestamp without time zone");
b.Property<int?>("IPAddress")
.HasColumnType("integer");
b.Property<int>("LinkId")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("character varying(24)")
.HasMaxLength(24);
b.Property<string>("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("SharedLibraryCore.Database.Models.EFAliasLink", b =>
{
b.Property<int>("AliasLinkId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.HasKey("AliasLinkId");
b.ToTable("EFAliasLinks");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFChangeHistory", b =>
{
b.Property<int>("ChangeHistoryId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<string>("Comment")
.HasColumnType("character varying(128)")
.HasMaxLength(128);
b.Property<string>("CurrentValue")
.HasColumnType("text");
b.Property<int?>("ImpersonationEntityId")
.HasColumnType("integer");
b.Property<int>("OriginEntityId")
.HasColumnType("integer");
b.Property<string>("PreviousValue")
.HasColumnType("text");
b.Property<int>("TargetEntityId")
.HasColumnType("integer");
b.Property<DateTime>("TimeChanged")
.HasColumnType("timestamp without time zone");
b.Property<int>("TypeOfChange")
.HasColumnType("integer");
b.HasKey("ChangeHistoryId");
b.ToTable("EFChangeHistory");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b =>
{
b.Property<int>("ClientId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int>("AliasLinkId")
.HasColumnType("integer");
b.Property<int>("Connections")
.HasColumnType("integer");
b.Property<int>("CurrentAliasId")
.HasColumnType("integer");
b.Property<DateTime>("FirstConnection")
.HasColumnType("timestamp without time zone");
b.Property<DateTime>("LastConnection")
.HasColumnType("timestamp without time zone");
b.Property<int>("Level")
.HasColumnType("integer");
b.Property<bool>("Masked")
.HasColumnType("boolean");
b.Property<long>("NetworkId")
.HasColumnType("bigint");
b.Property<string>("Password")
.HasColumnType("text");
b.Property<string>("PasswordSalt")
.HasColumnType("text");
b.Property<int>("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 =>
{
b.Property<int>("MetaId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int?>("ClientId")
.HasColumnType("integer");
b.Property<DateTime>("Created")
.HasColumnType("timestamp without time zone");
b.Property<string>("Extra")
.HasColumnType("text");
b.Property<string>("Key")
.IsRequired()
.HasColumnType("character varying(32)")
.HasMaxLength(32);
b.Property<int?>("LinkedMetaId")
.HasColumnType("integer");
b.Property<DateTime>("Updated")
.HasColumnType("timestamp without time zone");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("MetaId");
b.HasIndex("ClientId");
b.HasIndex("Key");
b.HasIndex("LinkedMetaId");
b.ToTable("EFMeta");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
{
b.Property<int>("PenaltyId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<string>("AutomatedOffense")
.HasColumnType("text");
b.Property<DateTime?>("Expires")
.HasColumnType("timestamp without time zone");
b.Property<bool>("IsEvadedOffense")
.HasColumnType("boolean");
b.Property<int>("LinkId")
.HasColumnType("integer");
b.Property<int>("OffenderId")
.HasColumnType("integer");
b.Property<string>("Offense")
.IsRequired()
.HasColumnType("text");
b.Property<int>("PunisherId")
.HasColumnType("integer");
b.Property<int>("Type")
.HasColumnType("integer");
b.Property<DateTime>("When")
.HasColumnType("timestamp without time zone");
b.HasKey("PenaltyId");
b.HasIndex("LinkId");
b.HasIndex("OffenderId");
b.HasIndex("PunisherId");
b.ToTable("EFPenalties");
});
modelBuilder.Entity("SharedLibraryCore.Helpers.Vector3", b =>
{
b.Property<int>("Vector3Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<float>("X")
.HasColumnType("real");
b.Property<float>("Y")
.HasColumnType("real");
b.Property<float>("Z")
.HasColumnType("real");
b.HasKey("Vector3Id");
b.ToTable("Vector3");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", 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")
.WithMany("PredictedViewAngles")
.HasForeignKey("SnapshotId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SharedLibraryCore.Helpers.Vector3", "Vector")
.WithMany()
.HasForeignKey("Vector3Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", 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")
.WithMany()
.HasForeignKey("AliasLinkId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SharedLibraryCore.Database.Models.EFAlias", "CurrentAlias")
.WithMany()
.HasForeignKey("CurrentAliasId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFMeta", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
.WithMany("Meta")
.HasForeignKey("ClientId");
b.HasOne("SharedLibraryCore.Database.Models.EFMeta", "LinkedMeta")
.WithMany()
.HasForeignKey("LinkedMetaId")
.OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link")
.WithMany("ReceivedPenalties")
.HasForeignKey("LinkId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Offender")
.WithMany("ReceivedPenalties")
.HasForeignKey("OffenderId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Punisher")
.WithMany("AdministeredPenalties")
.HasForeignKey("PunisherId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,43 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace SharedLibraryCore.Migrations.Postgresql
{
public partial class UpdateEFMetaToSupportLinkedMeta : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "LinkedMetaId",
table: "EFMeta",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_EFMeta_LinkedMetaId",
table: "EFMeta",
column: "LinkedMetaId");
migrationBuilder.AddForeignKey(
name: "FK_EFMeta_EFMeta_LinkedMetaId",
table: "EFMeta",
column: "LinkedMetaId",
principalTable: "EFMeta",
principalColumn: "MetaId",
onDelete: ReferentialAction.SetNull);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_EFMeta_EFMeta_LinkedMetaId",
table: "EFMeta");
migrationBuilder.DropIndex(
name: "IX_EFMeta_LinkedMetaId",
table: "EFMeta");
migrationBuilder.DropColumn(
name: "LinkedMetaId",
table: "EFMeta");
}
}
}

View File

@ -15,8 +15,8 @@ namespace SharedLibraryCore.Migrations.Postgresql
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
.HasAnnotation("ProductVersion", "3.1.7")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.HasAnnotation("ProductVersion", "3.1.10")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
@ -24,7 +24,7 @@ namespace SharedLibraryCore.Migrations.Postgresql
b.Property<int>("SnapshotId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn);
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
@ -121,7 +121,7 @@ namespace SharedLibraryCore.Migrations.Postgresql
b.Property<int>("ACSnapshotVector3Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn);
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
@ -146,7 +146,7 @@ namespace SharedLibraryCore.Migrations.Postgresql
b.Property<long>("KillId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn);
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
@ -218,7 +218,7 @@ namespace SharedLibraryCore.Migrations.Postgresql
b.Property<long>("MessageId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn);
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
@ -254,7 +254,7 @@ namespace SharedLibraryCore.Migrations.Postgresql
b.Property<int>("RatingHistoryId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn);
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
@ -328,7 +328,7 @@ namespace SharedLibraryCore.Migrations.Postgresql
b.Property<int>("HitLocationCountId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn);
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
@ -367,7 +367,7 @@ namespace SharedLibraryCore.Migrations.Postgresql
b.Property<int>("RatingId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn);
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
@ -439,7 +439,7 @@ namespace SharedLibraryCore.Migrations.Postgresql
b.Property<int>("StatisticId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn);
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
@ -465,7 +465,7 @@ namespace SharedLibraryCore.Migrations.Postgresql
b.Property<int>("AliasId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn);
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
@ -509,7 +509,7 @@ namespace SharedLibraryCore.Migrations.Postgresql
b.Property<int>("AliasLinkId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn);
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
@ -524,7 +524,7 @@ namespace SharedLibraryCore.Migrations.Postgresql
b.Property<int>("ChangeHistoryId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn);
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
@ -564,7 +564,7 @@ namespace SharedLibraryCore.Migrations.Postgresql
b.Property<int>("ClientId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn);
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
@ -619,12 +619,12 @@ namespace SharedLibraryCore.Migrations.Postgresql
b.Property<int>("MetaId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn);
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
b.Property<int>("ClientId")
b.Property<int?>("ClientId")
.HasColumnType("integer");
b.Property<DateTime>("Created")
@ -638,6 +638,9 @@ namespace SharedLibraryCore.Migrations.Postgresql
.HasColumnType("character varying(32)")
.HasMaxLength(32);
b.Property<int?>("LinkedMetaId")
.HasColumnType("integer");
b.Property<DateTime>("Updated")
.HasColumnType("timestamp without time zone");
@ -651,6 +654,8 @@ namespace SharedLibraryCore.Migrations.Postgresql
b.HasIndex("Key");
b.HasIndex("LinkedMetaId");
b.ToTable("EFMeta");
});
@ -659,7 +664,7 @@ namespace SharedLibraryCore.Migrations.Postgresql
b.Property<int>("PenaltyId")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn);
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<bool>("Active")
.HasColumnType("boolean");
@ -708,7 +713,7 @@ namespace SharedLibraryCore.Migrations.Postgresql
b.Property<int>("Vector3Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn);
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<float>("X")
.HasColumnType("real");
@ -915,9 +920,12 @@ namespace SharedLibraryCore.Migrations.Postgresql
{
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
.WithMany("Meta")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
.HasForeignKey("ClientId");
b.HasOne("SharedLibraryCore.Database.Models.EFMeta", "LinkedMeta")
.WithMany()
.HasForeignKey("LinkedMetaId")
.OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>

View File

@ -0,0 +1,938 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using SharedLibraryCore.Database.MigrationContext;
namespace SharedLibraryCore.Migrations.Sqlite
{
[DbContext(typeof(SqliteDatabaseContext))]
[Migration("20210124164906_UpdateEFMetaToSupportNonClientMetaAndLinkedMeta")]
partial class UpdateEFMetaToSupportNonClientMetaAndLinkedMeta
{
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 =>
{
b.Property<int>("SnapshotId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Active")
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<int>("CurrentSessionLength")
.HasColumnType("INTEGER");
b.Property<double>("CurrentStrain")
.HasColumnType("REAL");
b.Property<int>("CurrentViewAngleId")
.HasColumnType("INTEGER");
b.Property<int>("Deaths")
.HasColumnType("INTEGER");
b.Property<double>("Distance")
.HasColumnType("REAL");
b.Property<double>("EloRating")
.HasColumnType("REAL");
b.Property<int>("HitDestinationId")
.HasColumnType("INTEGER");
b.Property<int>("HitLocation")
.HasColumnType("INTEGER");
b.Property<int>("HitOriginId")
.HasColumnType("INTEGER");
b.Property<int>("HitType")
.HasColumnType("INTEGER");
b.Property<int>("Hits")
.HasColumnType("INTEGER");
b.Property<int>("Kills")
.HasColumnType("INTEGER");
b.Property<int>("LastStrainAngleId")
.HasColumnType("INTEGER");
b.Property<double>("RecoilOffset")
.HasColumnType("REAL");
b.Property<double>("SessionAngleOffset")
.HasColumnType("REAL");
b.Property<double>("SessionAverageSnapValue")
.HasColumnType("REAL");
b.Property<double>("SessionSPM")
.HasColumnType("REAL");
b.Property<int>("SessionScore")
.HasColumnType("INTEGER");
b.Property<int>("SessionSnapHits")
.HasColumnType("INTEGER");
b.Property<double>("StrainAngleBetween")
.HasColumnType("REAL");
b.Property<int>("TimeSinceLastEvent")
.HasColumnType("INTEGER");
b.Property<int>("WeaponId")
.HasColumnType("INTEGER");
b.Property<DateTime>("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("IW4MAdmin.Plugins.Stats.Models.EFACSnapshotVector3", b =>
{
b.Property<int>("ACSnapshotVector3Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Active")
.HasColumnType("INTEGER");
b.Property<int>("SnapshotId")
.HasColumnType("INTEGER");
b.Property<int>("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<long>("KillId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Active")
.HasColumnType("INTEGER");
b.Property<int>("AttackerId")
.HasColumnType("INTEGER");
b.Property<int>("Damage")
.HasColumnType("INTEGER");
b.Property<int?>("DeathOriginVector3Id")
.HasColumnType("INTEGER");
b.Property<int>("DeathType")
.HasColumnType("INTEGER");
b.Property<double>("Fraction")
.HasColumnType("REAL");
b.Property<int>("HitLoc")
.HasColumnType("INTEGER");
b.Property<bool>("IsKill")
.HasColumnType("INTEGER");
b.Property<int?>("KillOriginVector3Id")
.HasColumnType("INTEGER");
b.Property<int>("Map")
.HasColumnType("INTEGER");
b.Property<long>("ServerId")
.HasColumnType("INTEGER");
b.Property<int>("VictimId")
.HasColumnType("INTEGER");
b.Property<int?>("ViewAnglesVector3Id")
.HasColumnType("INTEGER");
b.Property<double>("VisibilityPercentage")
.HasColumnType("REAL");
b.Property<int>("Weapon")
.HasColumnType("INTEGER");
b.Property<DateTime>("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<long>("MessageId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Active")
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<string>("Message")
.HasColumnType("TEXT");
b.Property<bool>("SentIngame")
.HasColumnType("INTEGER");
b.Property<long>("ServerId")
.HasColumnType("INTEGER");
b.Property<DateTime>("TimeSent")
.HasColumnType("TEXT");
b.HasKey("MessageId");
b.HasIndex("ClientId");
b.HasIndex("ServerId");
b.HasIndex("TimeSent");
b.ToTable("EFClientMessages");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b =>
{
b.Property<int>("RatingHistoryId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Active")
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.HasKey("RatingHistoryId");
b.HasIndex("ClientId");
b.ToTable("EFClientRatingHistory");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
{
b.Property<int>("ClientId")
.HasColumnType("INTEGER");
b.Property<long>("ServerId")
.HasColumnType("INTEGER");
b.Property<bool>("Active")
.HasColumnType("INTEGER");
b.Property<double>("AverageRecoilOffset")
.HasColumnType("REAL");
b.Property<double>("AverageSnapValue")
.HasColumnType("REAL");
b.Property<int>("Deaths")
.HasColumnType("INTEGER");
b.Property<double>("EloRating")
.HasColumnType("REAL");
b.Property<int>("Kills")
.HasColumnType("INTEGER");
b.Property<double>("MaxStrain")
.HasColumnType("REAL");
b.Property<double>("RollingWeightedKDR")
.HasColumnType("REAL");
b.Property<double>("SPM")
.HasColumnType("REAL");
b.Property<double>("Skill")
.HasColumnType("REAL");
b.Property<int>("SnapHitCount")
.HasColumnType("INTEGER");
b.Property<int>("TimePlayed")
.HasColumnType("INTEGER");
b.Property<double>("VisionAverage")
.HasColumnType("REAL");
b.HasKey("ClientId", "ServerId");
b.HasIndex("ServerId");
b.ToTable("EFClientStatistics");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b =>
{
b.Property<int>("HitLocationCountId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Active")
.HasColumnType("INTEGER");
b.Property<int>("EFClientStatisticsClientId")
.HasColumnName("EFClientStatisticsClientId")
.HasColumnType("INTEGER");
b.Property<long>("EFClientStatisticsServerId")
.HasColumnName("EFClientStatisticsServerId")
.HasColumnType("INTEGER");
b.Property<int>("HitCount")
.HasColumnType("INTEGER");
b.Property<float>("HitOffsetAverage")
.HasColumnType("REAL");
b.Property<int>("Location")
.HasColumnType("INTEGER");
b.Property<float>("MaxAngleDistance")
.HasColumnType("REAL");
b.HasKey("HitLocationCountId");
b.HasIndex("EFClientStatisticsServerId");
b.HasIndex("EFClientStatisticsClientId", "EFClientStatisticsServerId");
b.ToTable("EFHitLocationCounts");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b =>
{
b.Property<int>("RatingId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Active")
.HasColumnType("INTEGER");
b.Property<int>("ActivityAmount")
.HasColumnType("INTEGER");
b.Property<bool>("Newest")
.HasColumnType("INTEGER");
b.Property<double>("Performance")
.HasColumnType("REAL");
b.Property<int>("Ranking")
.HasColumnType("INTEGER");
b.Property<int>("RatingHistoryId")
.HasColumnType("INTEGER");
b.Property<long?>("ServerId")
.HasColumnType("INTEGER");
b.Property<DateTime>("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("IW4MAdmin.Plugins.Stats.Models.EFServer", b =>
{
b.Property<long>("ServerId")
.HasColumnType("INTEGER");
b.Property<bool>("Active")
.HasColumnType("INTEGER");
b.Property<string>("EndPoint")
.HasColumnType("TEXT");
b.Property<int?>("GameName")
.HasColumnType("INTEGER");
b.Property<string>("HostName")
.HasColumnType("TEXT");
b.Property<bool>("IsPasswordProtected")
.HasColumnType("INTEGER");
b.Property<int>("Port")
.HasColumnType("INTEGER");
b.HasKey("ServerId");
b.ToTable("EFServers");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b =>
{
b.Property<int>("StatisticId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Active")
.HasColumnType("INTEGER");
b.Property<long>("ServerId")
.HasColumnType("INTEGER");
b.Property<long>("TotalKills")
.HasColumnType("INTEGER");
b.Property<long>("TotalPlayTime")
.HasColumnType("INTEGER");
b.HasKey("StatisticId");
b.HasIndex("ServerId");
b.ToTable("EFServerStatistics");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b =>
{
b.Property<int>("AliasId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Active")
.HasColumnType("INTEGER");
b.Property<DateTime>("DateAdded")
.HasColumnType("TEXT");
b.Property<int?>("IPAddress")
.HasColumnType("INTEGER");
b.Property<int>("LinkId")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(24);
b.Property<string>("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("SharedLibraryCore.Database.Models.EFAliasLink", b =>
{
b.Property<int>("AliasLinkId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Active")
.HasColumnType("INTEGER");
b.HasKey("AliasLinkId");
b.ToTable("EFAliasLinks");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFChangeHistory", b =>
{
b.Property<int>("ChangeHistoryId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Active")
.HasColumnType("INTEGER");
b.Property<string>("Comment")
.HasColumnType("TEXT")
.HasMaxLength(128);
b.Property<string>("CurrentValue")
.HasColumnType("TEXT");
b.Property<int?>("ImpersonationEntityId")
.HasColumnType("INTEGER");
b.Property<int>("OriginEntityId")
.HasColumnType("INTEGER");
b.Property<string>("PreviousValue")
.HasColumnType("TEXT");
b.Property<int>("TargetEntityId")
.HasColumnType("INTEGER");
b.Property<DateTime>("TimeChanged")
.HasColumnType("TEXT");
b.Property<int>("TypeOfChange")
.HasColumnType("INTEGER");
b.HasKey("ChangeHistoryId");
b.ToTable("EFChangeHistory");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b =>
{
b.Property<int>("ClientId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Active")
.HasColumnType("INTEGER");
b.Property<int>("AliasLinkId")
.HasColumnType("INTEGER");
b.Property<int>("Connections")
.HasColumnType("INTEGER");
b.Property<int>("CurrentAliasId")
.HasColumnType("INTEGER");
b.Property<DateTime>("FirstConnection")
.HasColumnType("TEXT");
b.Property<DateTime>("LastConnection")
.HasColumnType("TEXT");
b.Property<int>("Level")
.HasColumnType("INTEGER");
b.Property<bool>("Masked")
.HasColumnType("INTEGER");
b.Property<long>("NetworkId")
.HasColumnType("INTEGER");
b.Property<string>("Password")
.HasColumnType("TEXT");
b.Property<string>("PasswordSalt")
.HasColumnType("TEXT");
b.Property<int>("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 =>
{
b.Property<int>("MetaId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Active")
.HasColumnType("INTEGER");
b.Property<int?>("ClientId")
.HasColumnType("INTEGER");
b.Property<DateTime>("Created")
.HasColumnType("TEXT");
b.Property<string>("Extra")
.HasColumnType("TEXT");
b.Property<string>("Key")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(32);
b.Property<int?>("LinkedMetaId")
.HasColumnType("INTEGER");
b.Property<DateTime>("Updated")
.HasColumnType("TEXT");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("MetaId");
b.HasIndex("ClientId");
b.HasIndex("Key");
b.HasIndex("LinkedMetaId");
b.ToTable("EFMeta");
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
{
b.Property<int>("PenaltyId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Active")
.HasColumnType("INTEGER");
b.Property<string>("AutomatedOffense")
.HasColumnType("TEXT");
b.Property<DateTime?>("Expires")
.HasColumnType("TEXT");
b.Property<bool>("IsEvadedOffense")
.HasColumnType("INTEGER");
b.Property<int>("LinkId")
.HasColumnType("INTEGER");
b.Property<int>("OffenderId")
.HasColumnType("INTEGER");
b.Property<string>("Offense")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("PunisherId")
.HasColumnType("INTEGER");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.Property<DateTime>("When")
.HasColumnType("TEXT");
b.HasKey("PenaltyId");
b.HasIndex("LinkId");
b.HasIndex("OffenderId");
b.HasIndex("PunisherId");
b.ToTable("EFPenalties");
});
modelBuilder.Entity("SharedLibraryCore.Helpers.Vector3", b =>
{
b.Property<int>("Vector3Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<float>("X")
.HasColumnType("REAL");
b.Property<float>("Y")
.HasColumnType("REAL");
b.Property<float>("Z")
.HasColumnType("REAL");
b.HasKey("Vector3Id");
b.ToTable("Vector3");
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", 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")
.WithMany("PredictedViewAngles")
.HasForeignKey("SnapshotId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SharedLibraryCore.Helpers.Vector3", "Vector")
.WithMany()
.HasForeignKey("Vector3Id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", 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")
.WithMany()
.HasForeignKey("AliasLinkId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SharedLibraryCore.Database.Models.EFAlias", "CurrentAlias")
.WithMany()
.HasForeignKey("CurrentAliasId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFMeta", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
.WithMany("Meta")
.HasForeignKey("ClientId");
b.HasOne("SharedLibraryCore.Database.Models.EFMeta", "LinkedMeta")
.WithMany()
.HasForeignKey("LinkedMetaId")
.OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
{
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link")
.WithMany("ReceivedPenalties")
.HasForeignKey("LinkId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Offender")
.WithMany("ReceivedPenalties")
.HasForeignKey("OffenderId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Punisher")
.WithMany("AdministeredPenalties")
.HasForeignKey("PunisherId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,128 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace SharedLibraryCore.Migrations.Sqlite
{
public partial class UpdateEFMetaToSupportNonClientMetaAndLinkedMeta : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(@"PRAGMA foreign_keys = 0;
CREATE TABLE sqlitestudio_temp_table AS SELECT *
FROM EFMeta;
DROP TABLE EFMeta;
CREATE TABLE EFMeta (
MetaId INTEGER NOT NULL
CONSTRAINT PK_EFMeta PRIMARY KEY AUTOINCREMENT,
Active INTEGER NOT NULL,
ClientId INTEGER,
Created TEXT NOT NULL,
Extra TEXT,
[Key] TEXT NOT NULL,
Updated TEXT NOT NULL,
Value TEXT NOT NULL,
LinkedMetaId INTEGER CONSTRAINT IX_EFMeta_LinkedMetaId REFERENCES EFMeta (MetaId) ON DELETE SET NULL,
CONSTRAINT FK_EFMeta_EFClients_ClientId FOREIGN KEY (
ClientId
)
REFERENCES EFClients (ClientId) ON DELETE CASCADE
);
INSERT INTO EFMeta (
MetaId,
Active,
ClientId,
Created,
Extra,
[Key],
Updated,
Value
)
SELECT MetaId,
Active,
ClientId,
Created,
Extra,
""Key"",
Updated,
Value
FROM sqlitestudio_temp_table;
DROP TABLE sqlitestudio_temp_table;
CREATE INDEX IX_EFMeta_ClientId ON EFMeta(
""ClientId""
);
CREATE INDEX IX_EFMeta_Key ON EFMeta (
""Key""
);
CREATE INDEX IX_EFMeta_LinkedMetaId ON EFMeta (
LinkedMetaId
);
PRAGMA foreign_keys = 1;");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(@"PRAGMA foreign_keys = 0;
CREATE TABLE sqlitestudio_temp_table AS SELECT *
FROM EFMeta;
DROP TABLE EFMeta;
CREATE TABLE EFMeta (
MetaId INTEGER NOT NULL
CONSTRAINT PK_EFMeta PRIMARY KEY AUTOINCREMENT,
Active INTEGER NOT NULL,
ClientId INTEGER NOT NULL,
Created TEXT NOT NULL,
Extra TEXT,
[Key] TEXT NOT NULL,
Updated TEXT NOT NULL,
Value TEXT NOT NULL,
CONSTRAINT FK_EFMeta_EFClients_ClientId FOREIGN KEY (
ClientId
)
REFERENCES EFClients (ClientId) ON DELETE CASCADE
);
INSERT INTO EFMeta (
MetaId,
Active,
ClientId,
Created,
Extra,
[Key],
Updated,
Value
)
SELECT MetaId,
Active,
ClientId,
Created,
Extra,
""Key"",
Updated,
Value
FROM sqlitestudio_temp_table;
DROP TABLE sqlitestudio_temp_table;
CREATE INDEX IX_EFMeta_ClientId ON EFMeta(
""ClientId""
);
CREATE INDEX IX_EFMeta_Key ON EFMeta(
""Key""
);
PRAGMA foreign_keys = 1;");
}
}
}

View File

@ -14,7 +14,7 @@ namespace SharedLibraryCore.Migrations.Sqlite
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.7");
.HasAnnotation("ProductVersion", "3.1.10");
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
{
@ -608,7 +608,7 @@ namespace SharedLibraryCore.Migrations.Sqlite
b.Property<bool>("Active")
.HasColumnType("INTEGER");
b.Property<int>("ClientId")
b.Property<int?>("ClientId")
.HasColumnType("INTEGER");
b.Property<DateTime>("Created")
@ -622,6 +622,9 @@ namespace SharedLibraryCore.Migrations.Sqlite
.HasColumnType("TEXT")
.HasMaxLength(32);
b.Property<int?>("LinkedMetaId")
.HasColumnType("INTEGER");
b.Property<DateTime>("Updated")
.HasColumnType("TEXT");
@ -635,6 +638,8 @@ namespace SharedLibraryCore.Migrations.Sqlite
b.HasIndex("Key");
b.HasIndex("LinkedMetaId");
b.ToTable("EFMeta");
});
@ -897,9 +902,12 @@ namespace SharedLibraryCore.Migrations.Sqlite
{
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
.WithMany("Meta")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
.HasForeignKey("ClientId");
b.HasOne("SharedLibraryCore.Database.Models.EFMeta", "LinkedMeta")
.WithMany()
.HasForeignKey("LinkedMetaId")
.OnDelete(DeleteBehavior.SetNull);
});
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>

View File

@ -152,6 +152,16 @@ namespace SharedLibraryCore.Database.Models
return e;
}
public void Tell(IEnumerable<string> messages)
{
foreach(var message in messages)
{
#pragma warning disable 4014
Tell(message).WaitAsync();
#pragma warning restore 4014
}
}
/// <summary>
/// warn a client with given reason
/// </summary>
@ -706,10 +716,16 @@ namespace SharedLibraryCore.Database.Models
public ClientPermission ClientPermission => new ClientPermission()
{
Level = Level,
Name = Utilities.CurrentLocalization
.LocalizationIndex[$"GLOBAL_PERMISSION_{Level.ToString().ToUpper()}"]
Name = Level.ToLocalizedLevelName()
};
[NotMapped]
public string Tag
{
get => GetAdditionalProperty<string>(EFMeta.ClientTag);
set => SetAdditionalProperty(EFMeta.ClientTag, value);
}
[NotMapped]
private readonly SemaphoreSlim _processingEvent;

View File

@ -141,6 +141,17 @@ namespace SharedLibraryCore
return e;
}
public void Broadcast(IEnumerable<string> messages, EFClient sender = null)
{
foreach (var message in messages)
{
#pragma warning disable 4014
Broadcast(message, sender).WaitAsync();
#pragma warning restore 4014
}
}
/// <summary>
/// Send a message to a particular players
/// </summary>

View File

@ -59,6 +59,12 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.10" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Migrations\MySql\20210123023212_UpdateEFMetaToSupportNonClientMeta.cs" />
<Compile Remove="Migrations\MySql\20210123165535_UpdateEFMetaToSupportLinkedMeta.cs" />
<Compile Remove="Migrations\MySql\20210123165535_UpdateEFMetaToSupportLinkedMeta.Designer.cs" />
</ItemGroup>
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command="if not exist &quot;$(ProjectDir)..\BUILD&quot; (&#xD;&#xA;if $(ConfigurationName) == Debug (&#xD;&#xA;md &quot;$(ProjectDir)..\BUILD&quot;&#xD;&#xA;)&#xD;&#xA;)&#xD;&#xA;if not exist &quot;$(ProjectDir)..\BUILD\Plugins&quot; (&#xD;&#xA;if $(ConfigurationName) == Debug (&#xD;&#xA;md &quot;$(ProjectDir)..\BUILD\Plugins&quot;&#xD;&#xA;)&#xD;&#xA;)" />
</Target>

View File

@ -59,6 +59,7 @@ namespace SharedLibraryCore
/// fallback id for world events
/// </summary>
public const long WORLD_ID = -1;
public static Dictionary<Permission, string> PermissionLevelOverrides { get; } = new Dictionary<Permission, string>();
public static string HttpRequest(string location, string header, string headerValue)
{
@ -219,9 +220,12 @@ namespace SharedLibraryCore
return $"^{colorCode}{localizedLevel ?? level.ToString()}";
}
public static string ToLocalizedLevelName(this EFClient.Permission perm)
public static string ToLocalizedLevelName(this Permission permission)
{
return CurrentLocalization.LocalizationIndex[$"GLOBAL_PERMISSION_{perm.ToString().ToUpper()}"];
var localized = CurrentLocalization.LocalizationIndex[$"GLOBAL_PERMISSION_{permission.ToString().ToUpper()}"];
return PermissionLevelOverrides.ContainsKey(permission) && PermissionLevelOverrides[permission] != localized
? PermissionLevelOverrides[permission]
: localized;
}
public async static Task<string> ProcessMessageToken(this Server server, IList<Helpers.MessageToken> tokens, String str)

View File

@ -88,8 +88,6 @@ namespace WebfrontCore.Controllers.API
return Unauthorized();
}
HttpContext.Request.Cookies.TryGetValue(".AspNetCore.Cookies", out var cookie);
if (Authorized)
{
return Ok();

View File

@ -439,7 +439,7 @@ namespace WebfrontCore.Controllers
private Dictionary<string, string> GetPresetPenaltyReasons() => _appConfig.PresetPenaltyReasons.Values
.Concat(_appConfig.GlobalRules)
.Concat(_appConfig.Servers.SelectMany(server => server.Rules))
.Concat(_appConfig.Servers.SelectMany(server => server.Rules ?? new string[0]))
.Distinct()
.Select((value, index) => new
{

View File

@ -36,6 +36,11 @@ namespace WebfrontCore.Controllers
var activePenalties = (await Manager.GetPenaltyService().GetActivePenaltiesAsync(client.AliasLinkId, client.IPAddress));
var tag = await _metaService.GetPersistentMeta(EFMeta.ClientTag, client);
if (tag?.LinkedMeta != null)
{
client.SetAdditionalProperty(EFMeta.ClientTag, tag.LinkedMeta.Value);
}
int displayLevelInt = (int)client.Level;
string displayLevel = client.Level.ToLocalizedLevelName();
@ -46,6 +51,8 @@ namespace WebfrontCore.Controllers
displayLevel = Permission.User.ToLocalizedLevelName();
}
displayLevel = string.IsNullOrEmpty(client.Tag) ? displayLevel : $"{displayLevel} ({client.Tag})";
var clientDto = new PlayerInfo()
{
Name = client.Name,

View File

@ -29,7 +29,8 @@ namespace WebfrontCore.ViewComponents
Name = p.Name,
ClientId = p.ClientId,
Level = p.Level.ToLocalizedLevelName(),
LevelInt = (int)p.Level
LevelInt = (int)p.Level,
Tag = p.Tag
}).ToList(),
ChatHistory = s.ChatHistory.ToList(),
Online = !s.Throttled,

View File

@ -7,7 +7,7 @@
foreach (var key in Model.Keys)
{
<div class="col-12 bg-primary pt-2 pb-2">
@key.ToString()
@Utilities.ToLocalizedLevelName(key)
</div>
<div class="col-12 bg-dark pt-2 pb-2">

View File

@ -45,57 +45,48 @@
}
</div>
<div class="col-md-5">
<div class="row" style="overflow-wrap: anywhere">
<div class="col-6 text-left text-md-right">
@{
for (int i = 0; i < half; i++)
<div class="row">
<div class="text-left w-50" >
@for (var i = 0; i < half; i++)
{
if (i > Model.Players.Count - 1)
{
continue;
}
string levelColorClass = !ViewBag.Authorized ? "" : $"level-color-{Model.Players[i].LevelInt}";
<div class="d-inline-flex">
@if (ViewBag.Authorized)
{
<div class="oi oi-circle-x ml-0 mr-1 profile-action action-kick-button d-inline d-md-none" data-action="kick" data-action-id="@Model.Players[i].ClientId" aria-hidden="true"></div>
}
//Model.Players[i].Name = string.Join("", "DankMememachine12".Take(new Random().Next(14, 17)));
<a asp-controller="Client" asp-action="ProfileAsync" asp-route-id="@Model.Players[i].ClientId" class="@levelColorClass">
string levelColorClass = !ViewBag.Authorized ? "" : $"level-color-{Model.Players[i].LevelInt}";
<a asp-controller="Client" asp-action="ProfileAsync" asp-route-id="@Model.Players[i].ClientId" class="@levelColorClass" style="overflow-wrap: break-word;">
<color-code value="@Model.Players[i].Name" allow="@ViewBag.EnableColorCodes"></color-code>
</a>
@if (ViewBag.Authorized)
{
<div class="oi oi-circle-x ml-1 profile-action action-kick-button d-none d-md-inline" data-action="kick" data-action-id="@Model.Players[i].ClientId" aria-hidden="true"></div>
}
</div>
<br />
<div class="oi oi-circle-x ml-1 profile-action action-kick-button" data-action="kick" data-action-id="@Model.Players[i].ClientId" aria-hidden="true"></div>
}
}
</div>
<div class="col-6 text-right w-50">
@{
for (int i = half; i < Math.Min(Model.ClientCount, Model.Players.Count); i++)
<div class="text-right w-50">
@for (var i = half; i < Math.Min(Model.ClientCount, Model.Players.Count); i++)
{
if (i > Model.Players.Count - 1)
{
continue;
}
//Model.Players[i].Name = string.Join("", "DankMememachine12".Take(new Random().Next(14, 17)));
string levelColorClass = !ViewBag.Authorized ? "" : $"level-color-{Model.Players[i].LevelInt}";
<div>
<a asp-controller="Client" asp-action="ProfileAsync" asp-route-id="@Model.Players[i].ClientId" class="@levelColorClass">
<a asp-controller="Client" asp-action="ProfileAsync" asp-route-id="@Model.Players[i].ClientId" class="@levelColorClass" style="overflow-wrap: break-word;">
<color-code value="@Model.Players[i].Name" allow="@ViewBag.EnableColorCodes"></color-code>
</a>
@if (ViewBag.Authorized)
{
<span class="oi oi-circle-x ml-1 profile-action align-baseline action-kick-button flex-column" data-action="kick" data-action-id="@Model.Players[i].ClientId" aria-hidden="true"></span>
}
<br />
</div>
<div class="oi oi-circle-x ml-1 profile-action action-kick-button" data-action="kick" data-action-id="@Model.Players[i].ClientId" aria-hidden="true"></div>
}
}
</div>