add index to time sent in EFCLientMessage, so we can retrieve faster in context view
set the maximum height of the add link to profile on client chat move change history into a seperate service move around AC penalty processing
This commit is contained in:
parent
7c708f06f3
commit
4a46abc46d
@ -5,7 +5,7 @@
|
|||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
|
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
|
||||||
<PackageId>RaidMax.IW4MAdmin.Application</PackageId>
|
<PackageId>RaidMax.IW4MAdmin.Application</PackageId>
|
||||||
<Version>2.1.9.1</Version>
|
<Version>2.1.9.2</Version>
|
||||||
<Authors>RaidMax</Authors>
|
<Authors>RaidMax</Authors>
|
||||||
<Company>Forever None</Company>
|
<Company>Forever None</Company>
|
||||||
<Product>IW4MAdmin</Product>
|
<Product>IW4MAdmin</Product>
|
||||||
|
@ -23,9 +23,9 @@ namespace IW4MAdmin.Application
|
|||||||
|
|
||||||
public void AddEvent(GameEvent gameEvent)
|
public void AddEvent(GameEvent gameEvent)
|
||||||
{
|
{
|
||||||
// IsProcessingEvent.Wait();
|
//IsProcessingEvent.Wait();
|
||||||
((Manager as ApplicationManager).OnServerEvent)(this, new GameEventArgs(null, false, gameEvent));
|
((Manager as ApplicationManager).OnServerEvent)(this, new GameEventArgs(null, false, gameEvent));
|
||||||
// IsProcessingEvent.Release(1);
|
//IsProcessingEvent.Release(1);
|
||||||
//if (gameEvent.Type == GameEvent.EventType.Connect)
|
//if (gameEvent.Type == GameEvent.EventType.Connect)
|
||||||
//{
|
//{
|
||||||
// IsProcessingEvent.Wait();
|
// IsProcessingEvent.Wait();
|
||||||
|
@ -39,6 +39,7 @@ namespace IW4MAdmin.Application
|
|||||||
// expose the event handler so we can execute the events
|
// expose the event handler so we can execute the events
|
||||||
public OnServerEventEventHandler OnServerEvent { get; set; }
|
public OnServerEventEventHandler OnServerEvent { get; set; }
|
||||||
public DateTime StartTime { get; private set; }
|
public DateTime StartTime { get; private set; }
|
||||||
|
public string Version => Assembly.GetEntryAssembly().GetName().Version.ToString();
|
||||||
|
|
||||||
static ApplicationManager Instance;
|
static ApplicationManager Instance;
|
||||||
readonly List<AsyncStatus> TaskStatuses;
|
readonly List<AsyncStatus> TaskStatuses;
|
||||||
@ -102,9 +103,12 @@ namespace IW4MAdmin.Application
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await newEvent.Owner.ExecuteEvent(newEvent);
|
||||||
|
|
||||||
// todo: this is a hacky mess
|
// todo: this is a hacky mess
|
||||||
if (newEvent.Origin?.DelayedEvents.Count > 0 &&
|
if (newEvent.Origin?.DelayedEvents.Count > 0 &&
|
||||||
newEvent.Origin?.State == Player.ClientState.Connected)
|
(newEvent.Origin?.State == Player.ClientState.Connected ||
|
||||||
|
newEvent.Type == GameEvent.EventType.Connect))
|
||||||
{
|
{
|
||||||
var events = newEvent.Origin.DelayedEvents;
|
var events = newEvent.Origin.DelayedEvents;
|
||||||
|
|
||||||
@ -144,8 +148,6 @@ namespace IW4MAdmin.Application
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await newEvent.Owner.ExecuteEvent(newEvent);
|
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
Logger.WriteDebug($"Processed event with id {newEvent.Id}");
|
Logger.WriteDebug($"Processed event with id {newEvent.Id}");
|
||||||
#endif
|
#endif
|
||||||
@ -175,6 +177,9 @@ namespace IW4MAdmin.Application
|
|||||||
}
|
}
|
||||||
// tell anyone waiting for the output that we're done
|
// tell anyone waiting for the output that we're done
|
||||||
newEvent.OnProcessed.Set();
|
newEvent.OnProcessed.Set();
|
||||||
|
|
||||||
|
var changeHistorySvc = new ChangeHistoryService();
|
||||||
|
await changeHistorySvc.Add(args.Event);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IList<Server> GetServers()
|
public IList<Server> GetServers()
|
||||||
@ -263,7 +268,7 @@ namespace IW4MAdmin.Application
|
|||||||
await new ContextSeed(db).Seed();
|
await new ContextSeed(db).Seed();
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: optimize this
|
// todo: optimize this (or replace it)
|
||||||
var ipList = (await ClientSvc.Find(c => c.Level > Player.Permission.Trusted))
|
var ipList = (await ClientSvc.Find(c => c.Level > Player.Permission.Trusted))
|
||||||
.Select(c => new
|
.Select(c => new
|
||||||
{
|
{
|
||||||
|
@ -1,197 +1,197 @@
|
|||||||
using SharedLibraryCore;
|
//using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Objects;
|
//using SharedLibraryCore.Objects;
|
||||||
using System;
|
//using System;
|
||||||
using System.Collections.Generic;
|
//using System.Collections.Generic;
|
||||||
using System.Linq;
|
//using System.Linq;
|
||||||
using System.Text;
|
//using System.Text;
|
||||||
using System.Threading.Tasks;
|
//using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace IW4ScriptCommands.Commands
|
//namespace IW4ScriptCommands.Commands
|
||||||
{
|
//{
|
||||||
class Balance : Command
|
// class Balance : Command
|
||||||
{
|
// {
|
||||||
private class TeamAssignment
|
// private class TeamAssignment
|
||||||
{
|
// {
|
||||||
public IW4MAdmin.Plugins.Stats.IW4Info.Team CurrentTeam { get; set; }
|
// public IW4MAdmin.Plugins.Stats.IW4Info.Team CurrentTeam { get; set; }
|
||||||
public int Num { get; set; }
|
// public int Num { get; set; }
|
||||||
public IW4MAdmin.Plugins.Stats.Models.EFClientStatistics Stats { get; set; }
|
// public IW4MAdmin.Plugins.Stats.Models.EFClientStatistics Stats { get; set; }
|
||||||
}
|
// }
|
||||||
public Balance() : base("balance", "balance teams", "bal", Player.Permission.Trusted, false, null)
|
// public Balance() : base("balance", "balance teams", "bal", Player.Permission.Trusted, false, null)
|
||||||
{
|
// {
|
||||||
}
|
// }
|
||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent E)
|
// public override async Task ExecuteAsync(GameEvent E)
|
||||||
{
|
// {
|
||||||
string teamsString = (await E.Owner.GetDvarAsync<string>("sv_iw4madmin_teams")).Value;
|
// string teamsString = (await E.Owner.GetDvarAsync<string>("sv_iw4madmin_teams")).Value;
|
||||||
|
|
||||||
var scriptClientTeams = teamsString.Split(';', StringSplitOptions.RemoveEmptyEntries)
|
// var scriptClientTeams = teamsString.Split(';', StringSplitOptions.RemoveEmptyEntries)
|
||||||
.Select(c => c.Split(','))
|
// .Select(c => c.Split(','))
|
||||||
.Select(c => new TeamAssignment()
|
// .Select(c => new TeamAssignment()
|
||||||
{
|
// {
|
||||||
CurrentTeam = (IW4MAdmin.Plugins.Stats.IW4Info.Team)Enum.Parse(typeof(IW4MAdmin.Plugins.Stats.IW4Info.Team), c[1]),
|
// CurrentTeam = (IW4MAdmin.Plugins.Stats.IW4Info.Team)Enum.Parse(typeof(IW4MAdmin.Plugins.Stats.IW4Info.Team), c[1]),
|
||||||
Num = E.Owner.Players.FirstOrDefault(p => p?.NetworkId == c[0].ConvertLong())?.ClientNumber ?? -1,
|
// Num = E.Owner.Players.FirstOrDefault(p => p?.NetworkId == c[0].ConvertLong())?.ClientNumber ?? -1,
|
||||||
Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(E.Owner.Players.FirstOrDefault(p => p?.NetworkId == c[0].ConvertLong()).ClientId, E.Owner.GetHashCode())
|
// Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(E.Owner.Players.FirstOrDefault(p => p?.NetworkId == c[0].ConvertLong()).ClientId, E.Owner.GetHashCode())
|
||||||
})
|
// })
|
||||||
.ToList();
|
// .ToList();
|
||||||
|
|
||||||
// at least one team is full so we can't balance
|
// // at least one team is full so we can't balance
|
||||||
if (scriptClientTeams.Count(ct => ct.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis) >= Math.Floor(E.Owner.MaxClients / 2.0)
|
// if (scriptClientTeams.Count(ct => ct.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis) >= Math.Floor(E.Owner.MaxClients / 2.0)
|
||||||
|| scriptClientTeams.Count(ct => ct.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies) >= Math.Floor(E.Owner.MaxClients / 2.0))
|
// || scriptClientTeams.Count(ct => ct.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies) >= Math.Floor(E.Owner.MaxClients / 2.0))
|
||||||
{
|
// {
|
||||||
await E.Origin?.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BALANCE_FAIL"]);
|
// await E.Origin?.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BALANCE_FAIL"]);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
List<string> teamAssignments = new List<string>();
|
// List<string> teamAssignments = new List<string>();
|
||||||
|
|
||||||
var activeClients = E.Owner.GetPlayersAsList().Select(c => new TeamAssignment()
|
// var activeClients = E.Owner.GetPlayersAsList().Select(c => new TeamAssignment()
|
||||||
{
|
// {
|
||||||
Num = c.ClientNumber,
|
// Num = c.ClientNumber,
|
||||||
Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(c.ClientId, E.Owner.GetHashCode()),
|
// Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(c.ClientId, E.Owner.GetHashCode()),
|
||||||
CurrentTeam = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(c.ClientId, E.Owner.GetHashCode()).Team
|
// CurrentTeam = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(c.ClientId, E.Owner.GetHashCode()).Team
|
||||||
})
|
// })
|
||||||
.Where(c => scriptClientTeams.FirstOrDefault(sc => sc.Num == c.Num)?.CurrentTeam != IW4MAdmin.Plugins.Stats.IW4Info.Team.Spectator)
|
// .Where(c => scriptClientTeams.FirstOrDefault(sc => sc.Num == c.Num)?.CurrentTeam != IW4MAdmin.Plugins.Stats.IW4Info.Team.Spectator)
|
||||||
.Where(c => c.CurrentTeam != scriptClientTeams.FirstOrDefault(p => p.Num == c.Num)?.CurrentTeam)
|
// .Where(c => c.CurrentTeam != scriptClientTeams.FirstOrDefault(p => p.Num == c.Num)?.CurrentTeam)
|
||||||
.OrderByDescending(c => c.Stats.Performance)
|
// .OrderByDescending(c => c.Stats.Performance)
|
||||||
.ToList();
|
// .ToList();
|
||||||
|
|
||||||
var alliesTeam = scriptClientTeams
|
// var alliesTeam = scriptClientTeams
|
||||||
.Where(c => c.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies)
|
// .Where(c => c.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies)
|
||||||
.Where(c => activeClients.Count(t => t.Num == c.Num) == 0)
|
// .Where(c => activeClients.Count(t => t.Num == c.Num) == 0)
|
||||||
.ToList();
|
// .ToList();
|
||||||
|
|
||||||
var axisTeam = scriptClientTeams
|
// var axisTeam = scriptClientTeams
|
||||||
.Where(c => c.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis)
|
// .Where(c => c.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis)
|
||||||
.Where(c => activeClients.Count(t => t.Num == c.Num) == 0)
|
// .Where(c => activeClients.Count(t => t.Num == c.Num) == 0)
|
||||||
.ToList();
|
// .ToList();
|
||||||
|
|
||||||
while (activeClients.Count() > 0)
|
// while (activeClients.Count() > 0)
|
||||||
{
|
// {
|
||||||
int teamSizeDifference = alliesTeam.Count - axisTeam.Count;
|
// int teamSizeDifference = alliesTeam.Count - axisTeam.Count;
|
||||||
double performanceDisparity = alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0 -
|
// double performanceDisparity = alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0 -
|
||||||
axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0;
|
// axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0;
|
||||||
|
|
||||||
if (teamSizeDifference == 0)
|
// if (teamSizeDifference == 0)
|
||||||
{
|
// {
|
||||||
if (performanceDisparity == 0)
|
// if (performanceDisparity == 0)
|
||||||
{
|
// {
|
||||||
alliesTeam.Add(activeClients.First());
|
// alliesTeam.Add(activeClients.First());
|
||||||
activeClients.RemoveAt(0);
|
// activeClients.RemoveAt(0);
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
if (performanceDisparity > 0)
|
// if (performanceDisparity > 0)
|
||||||
{
|
// {
|
||||||
axisTeam.Add(activeClients.First());
|
// axisTeam.Add(activeClients.First());
|
||||||
activeClients.RemoveAt(0);
|
// activeClients.RemoveAt(0);
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
alliesTeam.Add(activeClients.First());
|
// alliesTeam.Add(activeClients.First());
|
||||||
activeClients.RemoveAt(0);
|
// activeClients.RemoveAt(0);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else if (teamSizeDifference > 0)
|
// else if (teamSizeDifference > 0)
|
||||||
{
|
// {
|
||||||
if (performanceDisparity > 0)
|
// if (performanceDisparity > 0)
|
||||||
{
|
// {
|
||||||
axisTeam.Add(activeClients.First());
|
// axisTeam.Add(activeClients.First());
|
||||||
activeClients.RemoveAt(0);
|
// activeClients.RemoveAt(0);
|
||||||
}
|
// }
|
||||||
|
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
axisTeam.Add(activeClients.Last());
|
// axisTeam.Add(activeClients.Last());
|
||||||
activeClients.RemoveAt(activeClients.Count - 1);
|
// activeClients.RemoveAt(activeClients.Count - 1);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
if (performanceDisparity > 0)
|
// if (performanceDisparity > 0)
|
||||||
{
|
// {
|
||||||
alliesTeam.Add(activeClients.First());
|
// alliesTeam.Add(activeClients.First());
|
||||||
activeClients.RemoveAt(0);
|
// activeClients.RemoveAt(0);
|
||||||
}
|
// }
|
||||||
|
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
alliesTeam.Add(activeClients.Last());
|
// alliesTeam.Add(activeClients.Last());
|
||||||
activeClients.RemoveAt(activeClients.Count - 1);
|
// activeClients.RemoveAt(activeClients.Count - 1);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
alliesTeam = alliesTeam.OrderByDescending(t => t.Stats.Performance)
|
// alliesTeam = alliesTeam.OrderByDescending(t => t.Stats.Performance)
|
||||||
.ToList();
|
// .ToList();
|
||||||
|
|
||||||
axisTeam = axisTeam.OrderByDescending(t => t.Stats.Performance)
|
// axisTeam = axisTeam.OrderByDescending(t => t.Stats.Performance)
|
||||||
.ToList();
|
// .ToList();
|
||||||
|
|
||||||
while (Math.Abs(alliesTeam.Count - axisTeam.Count) > 1)
|
// while (Math.Abs(alliesTeam.Count - axisTeam.Count) > 1)
|
||||||
{
|
// {
|
||||||
int teamSizeDifference = alliesTeam.Count - axisTeam.Count;
|
// int teamSizeDifference = alliesTeam.Count - axisTeam.Count;
|
||||||
double performanceDisparity = alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0 -
|
// double performanceDisparity = alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0 -
|
||||||
axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0;
|
// axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0;
|
||||||
|
|
||||||
if (teamSizeDifference > 0)
|
// if (teamSizeDifference > 0)
|
||||||
{
|
// {
|
||||||
if (performanceDisparity > 0)
|
// if (performanceDisparity > 0)
|
||||||
{
|
// {
|
||||||
axisTeam.Add(alliesTeam.First());
|
// axisTeam.Add(alliesTeam.First());
|
||||||
alliesTeam.RemoveAt(0);
|
// alliesTeam.RemoveAt(0);
|
||||||
}
|
// }
|
||||||
|
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
axisTeam.Add(alliesTeam.Last());
|
// axisTeam.Add(alliesTeam.Last());
|
||||||
alliesTeam.RemoveAt(axisTeam.Count - 1);
|
// alliesTeam.RemoveAt(axisTeam.Count - 1);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
if (performanceDisparity > 0)
|
// if (performanceDisparity > 0)
|
||||||
{
|
// {
|
||||||
alliesTeam.Add(axisTeam.Last());
|
// alliesTeam.Add(axisTeam.Last());
|
||||||
axisTeam.RemoveAt(axisTeam.Count - 1);
|
// axisTeam.RemoveAt(axisTeam.Count - 1);
|
||||||
}
|
// }
|
||||||
|
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
alliesTeam.Add(axisTeam.First());
|
// alliesTeam.Add(axisTeam.First());
|
||||||
axisTeam.RemoveAt(0);
|
// axisTeam.RemoveAt(0);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
foreach (var assignment in alliesTeam)
|
// foreach (var assignment in alliesTeam)
|
||||||
{
|
// {
|
||||||
teamAssignments.Add($"{assignment.Num},2");
|
// teamAssignments.Add($"{assignment.Num},2");
|
||||||
assignment.Stats.Team = IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies;
|
// assignment.Stats.Team = IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies;
|
||||||
}
|
// }
|
||||||
foreach (var assignment in axisTeam)
|
// foreach (var assignment in axisTeam)
|
||||||
{
|
// {
|
||||||
teamAssignments.Add($"{assignment.Num},3");
|
// teamAssignments.Add($"{assignment.Num},3");
|
||||||
assignment.Stats.Team = IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis;
|
// assignment.Stats.Team = IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (alliesTeam.Count(ac => scriptClientTeams.First(sc => sc.Num == ac.Num).CurrentTeam != ac.CurrentTeam) == 0 &&
|
// if (alliesTeam.Count(ac => scriptClientTeams.First(sc => sc.Num == ac.Num).CurrentTeam != ac.CurrentTeam) == 0 &&
|
||||||
axisTeam.Count(ac => scriptClientTeams.First(sc => sc.Num == ac.Num).CurrentTeam != ac.CurrentTeam) == 0)
|
// axisTeam.Count(ac => scriptClientTeams.First(sc => sc.Num == ac.Num).CurrentTeam != ac.CurrentTeam) == 0)
|
||||||
{
|
// {
|
||||||
await E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BALANCE_FAIL_BALANCED"]);
|
// await E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BALANCE_FAIL_BALANCED"]);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (E.Origin?.Level > Player.Permission.Administrator)
|
// if (E.Origin?.Level > Player.Permission.Administrator)
|
||||||
{
|
// {
|
||||||
await E.Origin.Tell($"Allies Elo: {(alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0)}");
|
// await E.Origin.Tell($"Allies Elo: {(alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0)}");
|
||||||
await E.Origin.Tell($"Axis Elo: {(axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0)}");
|
// await E.Origin.Tell($"Axis Elo: {(axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0)}");
|
||||||
}
|
// }
|
||||||
|
|
||||||
string args = string.Join(",", teamAssignments);
|
// string args = string.Join(",", teamAssignments);
|
||||||
await E.Owner.ExecuteCommandAsync($"sv_iw4madmin_command \"balance:{args}\"");
|
// await E.Owner.ExecuteCommandAsync($"sv_iw4madmin_command \"balance:{args}\"");
|
||||||
await E.Origin.Tell("Balance command sent");
|
// await E.Origin.Tell("Balance command sent");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
@ -10,6 +10,7 @@ namespace IW4MAdmin.Plugins.Stats.Config
|
|||||||
public List<StreakMessageConfiguration> KillstreakMessages { get; set; }
|
public List<StreakMessageConfiguration> KillstreakMessages { get; set; }
|
||||||
public List<StreakMessageConfiguration> DeathstreakMessages { get; set; }
|
public List<StreakMessageConfiguration> DeathstreakMessages { get; set; }
|
||||||
public int TopPlayersMinPlayTime { get; set; }
|
public int TopPlayersMinPlayTime { get; set; }
|
||||||
|
public bool StoreClientKills { get; set; }
|
||||||
public string Name() => "Stats";
|
public string Name() => "Stats";
|
||||||
public IBaseConfiguration Generate()
|
public IBaseConfiguration Generate()
|
||||||
{
|
{
|
||||||
@ -49,6 +50,7 @@ namespace IW4MAdmin.Plugins.Stats.Config
|
|||||||
};
|
};
|
||||||
|
|
||||||
TopPlayersMinPlayTime = 3600 * 3;
|
TopPlayersMinPlayTime = 3600 * 3;
|
||||||
|
StoreClientKills = false;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -486,21 +486,24 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
|
|
||||||
if (Plugin.Config.Configuration().EnableAntiCheat)
|
if (Plugin.Config.Configuration().EnableAntiCheat)
|
||||||
{
|
{
|
||||||
async Task executePenalty(Cheat.DetectionPenaltyResult penalty)
|
await ApplyPenalty(clientDetection.ProcessKill(hit, isDamage), clientDetection, attacker);
|
||||||
|
await ApplyPenalty(clientDetection.ProcessTotalRatio(clientStats), clientDetection, attacker);
|
||||||
|
|
||||||
|
await clientStatsSvc.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Plugin.Config.Configuration().StoreClientKills)
|
||||||
{
|
{
|
||||||
async Task saveLog()
|
using (var ctx = new DatabaseContext())
|
||||||
{
|
{
|
||||||
using (var ctx = new DatabaseContext(false))
|
ctx.Set<EFClientKill>().Add(hit);
|
||||||
{
|
|
||||||
// todo: why does this cause duplicate primary key
|
|
||||||
foreach (var change in clientDetection.Tracker.GetChanges().Distinct())
|
|
||||||
{
|
|
||||||
ctx.Add(change);
|
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async Task ApplyPenalty(Cheat.DetectionPenaltyResult penalty, Cheat.Detection clientDetection, Player attacker)
|
||||||
|
{
|
||||||
await OnProcessingPenalty.WaitAsync();
|
await OnProcessingPenalty.WaitAsync();
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -509,7 +512,13 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
{
|
{
|
||||||
case Penalty.PenaltyType.Ban:
|
case Penalty.PenaltyType.Ban:
|
||||||
if (attacker.Level == Player.Permission.Banned)
|
if (attacker.Level == Player.Permission.Banned)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
if (clientDetection.Tracker.HasChanges)
|
||||||
|
{
|
||||||
|
await SaveTrackedSnapshots(clientDetection);
|
||||||
|
}
|
||||||
await attacker.Ban(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_CHEAT_DETECTED"], new Player()
|
await attacker.Ban(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_CHEAT_DETECTED"], new Player()
|
||||||
{
|
{
|
||||||
ClientId = 1,
|
ClientId = 1,
|
||||||
@ -523,11 +532,16 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await saveLog();
|
|
||||||
break;
|
break;
|
||||||
case Penalty.PenaltyType.Flag:
|
case Penalty.PenaltyType.Flag:
|
||||||
if (attacker.Level != Player.Permission.User)
|
if (attacker.Level != Player.Permission.User)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
if (clientDetection.Tracker.HasChanges)
|
||||||
|
{
|
||||||
|
await SaveTrackedSnapshots(clientDetection);
|
||||||
|
}
|
||||||
var e = new GameEvent()
|
var e = new GameEvent()
|
||||||
{
|
{
|
||||||
Data = penalty.Type == Cheat.Detection.DetectionType.Bone ?
|
Data = penalty.Type == Cheat.Detection.DetectionType.Bone ?
|
||||||
@ -544,32 +558,42 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
Owner = attacker.CurrentServer,
|
Owner = attacker.CurrentServer,
|
||||||
Type = GameEvent.EventType.Flag
|
Type = GameEvent.EventType.Flag
|
||||||
};
|
};
|
||||||
await saveLog();
|
|
||||||
// because we created an event it must be processed by the manager
|
// because we created an event it must be processed by the manager
|
||||||
// even if it didn't really do anything
|
// even if it didn't really do anything
|
||||||
Manager.GetEventHandler().AddEvent(e);
|
Manager.GetEventHandler().AddEvent(e);
|
||||||
await new CFlag().ExecuteAsync(e);
|
await new CFlag().ExecuteAsync(e);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
OnProcessingPenalty.Release();
|
OnProcessingPenalty.Release(1);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
OnProcessingPenalty.Release();
|
OnProcessingPenalty.Release(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
async Task SaveTrackedSnapshots(Cheat.Detection clientDetection)
|
||||||
|
{
|
||||||
await executePenalty(clientDetection.ProcessKill(hit, isDamage));
|
using (var ctx = new DatabaseContext(true))
|
||||||
await executePenalty(clientDetection.ProcessTotalRatio(clientStats));
|
{
|
||||||
|
// todo: why does this cause duplicate primary key
|
||||||
await clientStatsSvc.SaveChangesAsync();
|
foreach (var change in clientDetection.Tracker
|
||||||
}
|
.GetChanges()
|
||||||
|
.Where(c => c.SnapshotId == 0))
|
||||||
using (var ctx = new DatabaseContext())
|
{
|
||||||
|
ctx.Add(change);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
ctx.Set<EFClientKill>().Add(hit);
|
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
|
clientDetection.Tracker.ClearChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.WriteWarning(ex.GetExceptionInfo());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1096,5 +1120,5 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
{
|
{
|
||||||
Servers[serverId].IsTeamBased = isTeamBased;
|
Servers[serverId].IsTeamBased = isTeamBased;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,9 @@ namespace Stats.Models
|
|||||||
builder.Entity<EFRating>()
|
builder.Entity<EFRating>()
|
||||||
.HasIndex(p => p.When);
|
.HasIndex(p => p.When);
|
||||||
|
|
||||||
|
builder.Entity<EFClientMessage>()
|
||||||
|
.HasIndex(p => p.TimeSent);
|
||||||
|
|
||||||
// force pluralization
|
// force pluralization
|
||||||
builder.Entity<EFClientKill>().ToTable("EFClientKills");
|
builder.Entity<EFClientKill>().ToTable("EFClientKills");
|
||||||
builder.Entity<EFClientMessage>().ToTable("EFClientMessages");
|
builder.Entity<EFClientMessage>().ToTable("EFClientMessages");
|
||||||
|
@ -40,11 +40,16 @@ namespace IW4MAdmin.Plugins.Stats.Web.Controllers
|
|||||||
where message.TimeSent <= whenUpper
|
where message.TimeSent <= whenUpper
|
||||||
select new SharedLibraryCore.Dtos.ChatInfo()
|
select new SharedLibraryCore.Dtos.ChatInfo()
|
||||||
{
|
{
|
||||||
|
ClientId = message.ClientId,
|
||||||
Message = message.Message,
|
Message = message.Message,
|
||||||
Name = message.Client.CurrentAlias.Name,
|
Name = message.Client.CurrentAlias.Name,
|
||||||
Time = message.TimeSent
|
Time = message.TimeSent
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if DEBUG == true
|
||||||
|
var messagesSql = iqMessages.ToSql();
|
||||||
|
#endif
|
||||||
|
|
||||||
var messages = await iqMessages.ToListAsync();
|
var messages = await iqMessages.ToListAsync();
|
||||||
|
|
||||||
return View("_MessageContext", messages);
|
return View("_MessageContext", messages);
|
||||||
|
@ -7,6 +7,6 @@
|
|||||||
<h5>@Model.First().Time.ToString()</h5>
|
<h5>@Model.First().Time.ToString()</h5>
|
||||||
@foreach (var message in Model)
|
@foreach (var message in Model)
|
||||||
{
|
{
|
||||||
<span class="text-white">@message.Name</span><span> — @message.Message</span><br />
|
<span class="text-white">@Html.ActionLink(@message.Name, "ProfileAsync", "Client", new { id = message.ClientId})</span><span> — @message.Message</span><br />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
@ -8,6 +8,8 @@ using System.Linq;
|
|||||||
using Microsoft.Data.Sqlite;
|
using Microsoft.Data.Sqlite;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
|
||||||
namespace SharedLibraryCore.Database
|
namespace SharedLibraryCore.Database
|
||||||
{
|
{
|
||||||
@ -103,6 +105,13 @@ namespace SharedLibraryCore.Database
|
|||||||
ent.HasIndex(a => a.Name);
|
ent.HasIndex(a => a.Name);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<EFChangeHistory>(ent =>
|
||||||
|
{
|
||||||
|
ent.Property(c => c.ChangeHistoryId)
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn);
|
||||||
|
});
|
||||||
|
|
||||||
// force full name for database conversion
|
// force full name for database conversion
|
||||||
modelBuilder.Entity<EFClient>().ToTable("EFClients");
|
modelBuilder.Entity<EFClient>().ToTable("EFClients");
|
||||||
modelBuilder.Entity<EFAlias>().ToTable("EFAlias");
|
modelBuilder.Entity<EFAlias>().ToTable("EFAlias");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace SharedLibraryCore.Database.Models
|
namespace SharedLibraryCore.Database.Models
|
||||||
|
@ -4,6 +4,7 @@ namespace SharedLibraryCore.Dtos
|
|||||||
{
|
{
|
||||||
public class ChatInfo
|
public class ChatInfo
|
||||||
{
|
{
|
||||||
|
public int ClientId { get; set; }
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
public DateTime Time { get; set; }
|
public DateTime Time { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
@ -25,92 +25,7 @@ namespace SharedLibraryCore.Events
|
|||||||
return eventList;
|
return eventList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task SaveChangeHistory(GameEvent e)
|
public static void OnGameEvent(object sender, GameEventArgs eventState)
|
||||||
{
|
|
||||||
EFChangeHistory change = null;
|
|
||||||
|
|
||||||
switch (e.Type)
|
|
||||||
{
|
|
||||||
case GameEvent.EventType.Unknown:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Start:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Stop:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Connect:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Join:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Quit:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Disconnect:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.MapEnd:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.MapChange:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Say:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Warn:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Report:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Flag:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Unflag:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Kick:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.TempBan:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Ban:
|
|
||||||
change = new EFChangeHistory()
|
|
||||||
{
|
|
||||||
OriginEntityId = e.Origin.ClientId,
|
|
||||||
TargetEntityId = e.Target.ClientId,
|
|
||||||
TypeOfChange = EFChangeHistory.ChangeType.Ban,
|
|
||||||
Comment = e.Data
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Command:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.ChangePermission:
|
|
||||||
change = new EFChangeHistory()
|
|
||||||
{
|
|
||||||
OriginEntityId = e.Origin.ClientId,
|
|
||||||
TargetEntityId = e.Target.ClientId,
|
|
||||||
TypeOfChange = EFChangeHistory.ChangeType.Permission,
|
|
||||||
PreviousValue = ((Change)e.Extra).PreviousValue,
|
|
||||||
CurrentValue = ((Change)e.Extra).NewValue
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Broadcast:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Tell:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.ScriptDamage:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.ScriptKill:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Damage:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.Kill:
|
|
||||||
break;
|
|
||||||
case GameEvent.EventType.JoinTeam:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (change != null)
|
|
||||||
{
|
|
||||||
using (var ctx = new DatabaseContext(true))
|
|
||||||
{
|
|
||||||
ctx.EFChangeHistory.Add(change);
|
|
||||||
await ctx.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async void OnGameEvent(object sender, GameEventArgs eventState)
|
|
||||||
{
|
{
|
||||||
var E = eventState.Event;
|
var E = eventState.Event;
|
||||||
// don't want to clog up the api with unknown events
|
// don't want to clog up the api with unknown events
|
||||||
@ -150,8 +65,6 @@ namespace SharedLibraryCore.Events
|
|||||||
|
|
||||||
// add the new event to the list
|
// add the new event to the list
|
||||||
AddNewEvent(apiEvent);
|
AddNewEvent(apiEvent);
|
||||||
|
|
||||||
await SaveChangeHistory(E);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -19,13 +19,24 @@ namespace SharedLibraryCore.Helpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void OnChange(T value)
|
public void OnChange(T value)
|
||||||
|
{
|
||||||
|
lock (value)
|
||||||
{
|
{
|
||||||
// clear the first value when count max count reached
|
// clear the first value when count max count reached
|
||||||
if (Values.Count > 30)
|
if (Values.Count > 30)
|
||||||
Values.RemoveAt(0);
|
Values.RemoveAt(0);
|
||||||
Values.Add(value);
|
Values.Add(value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public List<T> GetChanges() => Values;
|
public T[] GetChanges() => Values.ToArray();
|
||||||
|
|
||||||
|
public bool HasChanges => Values.Count > 0;
|
||||||
|
|
||||||
|
public void ClearChanges()
|
||||||
|
{
|
||||||
|
lock (Values)
|
||||||
|
Values.Clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ namespace SharedLibraryCore.Interfaces
|
|||||||
{
|
{
|
||||||
public interface IEntityService<T>
|
public interface IEntityService<T>
|
||||||
{
|
{
|
||||||
Task<T> CreateProxy();
|
|
||||||
Task<T> Create(T entity);
|
Task<T> Create(T entity);
|
||||||
Task<T> Delete(T entity);
|
Task<T> Delete(T entity);
|
||||||
Task<T> Update(T entity);
|
Task<T> Update(T entity);
|
||||||
|
@ -39,5 +39,6 @@ namespace SharedLibraryCore.Interfaces
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IPageList GetPageList();
|
IPageList GetPageList();
|
||||||
|
string Version { get;}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
686
SharedLibraryCore/Migrations/20180915163111_AddIndexToMessageTimeSent.Designer.cs
generated
Normal file
686
SharedLibraryCore/Migrations/20180915163111_AddIndexToMessageTimeSent.Designer.cs
generated
Normal file
@ -0,0 +1,686 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using SharedLibraryCore.Database;
|
||||||
|
|
||||||
|
namespace SharedLibraryCore.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(DatabaseContext))]
|
||||||
|
[Migration("20180915163111_AddIndexToMessageTimeSent")]
|
||||||
|
partial class AddIndexToMessageTimeSent
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.1.2-rtm-30932");
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("SnapshotId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("ClientId");
|
||||||
|
|
||||||
|
b.Property<int>("CurrentSessionLength");
|
||||||
|
|
||||||
|
b.Property<double>("CurrentStrain");
|
||||||
|
|
||||||
|
b.Property<int?>("CurrentViewAngleVector3Id");
|
||||||
|
|
||||||
|
b.Property<int>("Deaths");
|
||||||
|
|
||||||
|
b.Property<double>("Distance");
|
||||||
|
|
||||||
|
b.Property<double>("EloRating");
|
||||||
|
|
||||||
|
b.Property<int?>("HitDestinationVector3Id");
|
||||||
|
|
||||||
|
b.Property<int>("HitLocation");
|
||||||
|
|
||||||
|
b.Property<int?>("HitOriginVector3Id");
|
||||||
|
|
||||||
|
b.Property<int>("HitType");
|
||||||
|
|
||||||
|
b.Property<int>("Hits");
|
||||||
|
|
||||||
|
b.Property<int>("Kills");
|
||||||
|
|
||||||
|
b.Property<int?>("LastStrainAngleVector3Id");
|
||||||
|
|
||||||
|
b.Property<double>("SessionAngleOffset");
|
||||||
|
|
||||||
|
b.Property<double>("SessionSPM");
|
||||||
|
|
||||||
|
b.Property<int>("SessionScore");
|
||||||
|
|
||||||
|
b.Property<double>("StrainAngleBetween");
|
||||||
|
|
||||||
|
b.Property<int>("TimeSinceLastEvent");
|
||||||
|
|
||||||
|
b.Property<int>("WeaponId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("When");
|
||||||
|
|
||||||
|
b.HasKey("SnapshotId");
|
||||||
|
|
||||||
|
b.HasIndex("ClientId");
|
||||||
|
|
||||||
|
b.HasIndex("CurrentViewAngleVector3Id");
|
||||||
|
|
||||||
|
b.HasIndex("HitDestinationVector3Id");
|
||||||
|
|
||||||
|
b.HasIndex("HitOriginVector3Id");
|
||||||
|
|
||||||
|
b.HasIndex("LastStrainAngleVector3Id");
|
||||||
|
|
||||||
|
b.ToTable("EFACSnapshot");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("KillId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("AttackerId");
|
||||||
|
|
||||||
|
b.Property<int>("Damage");
|
||||||
|
|
||||||
|
b.Property<int?>("DeathOriginVector3Id");
|
||||||
|
|
||||||
|
b.Property<int>("DeathType");
|
||||||
|
|
||||||
|
b.Property<double>("Fraction");
|
||||||
|
|
||||||
|
b.Property<int>("HitLoc");
|
||||||
|
|
||||||
|
b.Property<bool>("IsKill");
|
||||||
|
|
||||||
|
b.Property<int?>("KillOriginVector3Id");
|
||||||
|
|
||||||
|
b.Property<int>("Map");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId");
|
||||||
|
|
||||||
|
b.Property<int>("VictimId");
|
||||||
|
|
||||||
|
b.Property<int?>("ViewAnglesVector3Id");
|
||||||
|
|
||||||
|
b.Property<double>("VisibilityPercentage");
|
||||||
|
|
||||||
|
b.Property<int>("Weapon");
|
||||||
|
|
||||||
|
b.Property<DateTime>("When");
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("ClientId");
|
||||||
|
|
||||||
|
b.Property<string>("Message");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("TimeSent");
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("ClientId");
|
||||||
|
|
||||||
|
b.HasKey("RatingHistoryId");
|
||||||
|
|
||||||
|
b.HasIndex("ClientId");
|
||||||
|
|
||||||
|
b.ToTable("EFClientRatingHistory");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ClientId");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId");
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("Deaths");
|
||||||
|
|
||||||
|
b.Property<double>("EloRating");
|
||||||
|
|
||||||
|
b.Property<int>("Kills");
|
||||||
|
|
||||||
|
b.Property<double>("MaxStrain");
|
||||||
|
|
||||||
|
b.Property<double>("RollingWeightedKDR");
|
||||||
|
|
||||||
|
b.Property<double>("SPM");
|
||||||
|
|
||||||
|
b.Property<double>("Skill");
|
||||||
|
|
||||||
|
b.Property<int>("TimePlayed");
|
||||||
|
|
||||||
|
b.Property<double>("VisionAverage");
|
||||||
|
|
||||||
|
b.HasKey("ClientId", "ServerId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("EFClientStatistics");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("HitLocationCountId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("ClientId")
|
||||||
|
.HasColumnName("EFClientStatistics_ClientId");
|
||||||
|
|
||||||
|
b.Property<int>("HitCount");
|
||||||
|
|
||||||
|
b.Property<float>("HitOffsetAverage");
|
||||||
|
|
||||||
|
b.Property<int>("Location");
|
||||||
|
|
||||||
|
b.Property<float>("MaxAngleDistance");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId")
|
||||||
|
.HasColumnName("EFClientStatistics_ServerId");
|
||||||
|
|
||||||
|
b.HasKey("HitLocationCountId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.HasIndex("ClientId", "ServerId");
|
||||||
|
|
||||||
|
b.ToTable("EFHitLocationCounts");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("RatingId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("ActivityAmount");
|
||||||
|
|
||||||
|
b.Property<bool>("Newest");
|
||||||
|
|
||||||
|
b.Property<double>("Performance");
|
||||||
|
|
||||||
|
b.Property<int>("Ranking");
|
||||||
|
|
||||||
|
b.Property<int>("RatingHistoryId");
|
||||||
|
|
||||||
|
b.Property<int?>("ServerId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("When");
|
||||||
|
|
||||||
|
b.HasKey("RatingId");
|
||||||
|
|
||||||
|
b.HasIndex("Performance");
|
||||||
|
|
||||||
|
b.HasIndex("Ranking");
|
||||||
|
|
||||||
|
b.HasIndex("RatingHistoryId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.HasIndex("When");
|
||||||
|
|
||||||
|
b.ToTable("EFRating");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServer", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ServerId");
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("Port");
|
||||||
|
|
||||||
|
b.HasKey("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("EFServers");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("StatisticId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId");
|
||||||
|
|
||||||
|
b.Property<long>("TotalKills");
|
||||||
|
|
||||||
|
b.Property<long>("TotalPlayTime");
|
||||||
|
|
||||||
|
b.HasKey("StatisticId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("EFServerStatistics");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("AliasId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<DateTime>("DateAdded");
|
||||||
|
|
||||||
|
b.Property<int>("IPAddress");
|
||||||
|
|
||||||
|
b.Property<int>("LinkId");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(24);
|
||||||
|
|
||||||
|
b.HasKey("AliasId");
|
||||||
|
|
||||||
|
b.HasIndex("IPAddress");
|
||||||
|
|
||||||
|
b.HasIndex("LinkId");
|
||||||
|
|
||||||
|
b.HasIndex("Name");
|
||||||
|
|
||||||
|
b.ToTable("EFAlias");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAliasLink", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("AliasLinkId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.HasKey("AliasLinkId");
|
||||||
|
|
||||||
|
b.ToTable("EFAliasLinks");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFChangeHistory", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ChangeHistoryId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<string>("Comment")
|
||||||
|
.HasMaxLength(128);
|
||||||
|
|
||||||
|
b.Property<string>("CurrentValue");
|
||||||
|
|
||||||
|
b.Property<int>("OriginEntityId");
|
||||||
|
|
||||||
|
b.Property<string>("PreviousValue");
|
||||||
|
|
||||||
|
b.Property<int>("TargetEntityId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("TimeChanged");
|
||||||
|
|
||||||
|
b.Property<int>("TypeOfChange");
|
||||||
|
|
||||||
|
b.HasKey("ChangeHistoryId");
|
||||||
|
|
||||||
|
b.ToTable("EFChangeHistory");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ClientId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("AliasLinkId");
|
||||||
|
|
||||||
|
b.Property<int>("Connections");
|
||||||
|
|
||||||
|
b.Property<int>("CurrentAliasId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("FirstConnection");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastConnection");
|
||||||
|
|
||||||
|
b.Property<int>("Level");
|
||||||
|
|
||||||
|
b.Property<bool>("Masked");
|
||||||
|
|
||||||
|
b.Property<long>("NetworkId");
|
||||||
|
|
||||||
|
b.Property<string>("Password");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordSalt");
|
||||||
|
|
||||||
|
b.Property<int>("TotalConnectionTime");
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("ClientId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Created");
|
||||||
|
|
||||||
|
b.Property<string>("Extra");
|
||||||
|
|
||||||
|
b.Property<string>("Key")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Property<DateTime>("Updated");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("MetaId");
|
||||||
|
|
||||||
|
b.HasIndex("ClientId");
|
||||||
|
|
||||||
|
b.ToTable("EFMeta");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("PenaltyId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<string>("AutomatedOffense");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Expires");
|
||||||
|
|
||||||
|
b.Property<int>("LinkId");
|
||||||
|
|
||||||
|
b.Property<int>("OffenderId");
|
||||||
|
|
||||||
|
b.Property<string>("Offense")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Property<int>("PunisherId");
|
||||||
|
|
||||||
|
b.Property<int>("Type");
|
||||||
|
|
||||||
|
b.Property<DateTime>("When");
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
b.Property<int?>("EFACSnapshotSnapshotId");
|
||||||
|
|
||||||
|
b.Property<float>("X");
|
||||||
|
|
||||||
|
b.Property<float>("Y");
|
||||||
|
|
||||||
|
b.Property<float>("Z");
|
||||||
|
|
||||||
|
b.HasKey("Vector3Id");
|
||||||
|
|
||||||
|
b.HasIndex("EFACSnapshotSnapshotId");
|
||||||
|
|
||||||
|
b.ToTable("Vector3");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "CurrentViewAngle")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CurrentViewAngleVector3Id");
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "HitDestination")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("HitDestinationVector3Id");
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "HitOrigin")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("HitOriginVector3Id");
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "LastStrainAngle")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("LastStrainAngleVector3Id");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Attacker")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AttackerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Victim")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("VictimId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics")
|
||||||
|
.WithMany("HitLocations")
|
||||||
|
.HasForeignKey("ClientId", "ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", "RatingHistory")
|
||||||
|
.WithMany("Ratings")
|
||||||
|
.HasForeignKey("RatingHistoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link")
|
||||||
|
.WithMany("Children")
|
||||||
|
.HasForeignKey("LinkId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "AliasLink")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AliasLinkId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFAlias", "CurrentAlias")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CurrentAliasId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFMeta", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany("Meta")
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link")
|
||||||
|
.WithMany("ReceivedPenalties")
|
||||||
|
.HasForeignKey("LinkId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Offender")
|
||||||
|
.WithMany("ReceivedPenalties")
|
||||||
|
.HasForeignKey("OffenderId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Punisher")
|
||||||
|
.WithMany("AdministeredPenalties")
|
||||||
|
.HasForeignKey("PunisherId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Helpers.Vector3", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot")
|
||||||
|
.WithMany("PredictedViewAngles")
|
||||||
|
.HasForeignKey("EFACSnapshotSnapshotId");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace SharedLibraryCore.Migrations
|
||||||
|
{
|
||||||
|
public partial class AddIndexToMessageTimeSent : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_EFClientMessages_TimeSent",
|
||||||
|
table: "EFClientMessages",
|
||||||
|
column: "TimeSent");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_EFClientMessages_TimeSent",
|
||||||
|
table: "EFClientMessages");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
688
SharedLibraryCore/Migrations/20180915164118_ForceAutoIncrementChangeHistory.Designer.cs
generated
Normal file
688
SharedLibraryCore/Migrations/20180915164118_ForceAutoIncrementChangeHistory.Designer.cs
generated
Normal file
@ -0,0 +1,688 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using SharedLibraryCore.Database;
|
||||||
|
|
||||||
|
namespace SharedLibraryCore.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(DatabaseContext))]
|
||||||
|
[Migration("20180915164118_ForceAutoIncrementChangeHistory")]
|
||||||
|
partial class ForceAutoIncrementChangeHistory
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.1.2-rtm-30932");
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("SnapshotId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("ClientId");
|
||||||
|
|
||||||
|
b.Property<int>("CurrentSessionLength");
|
||||||
|
|
||||||
|
b.Property<double>("CurrentStrain");
|
||||||
|
|
||||||
|
b.Property<int?>("CurrentViewAngleVector3Id");
|
||||||
|
|
||||||
|
b.Property<int>("Deaths");
|
||||||
|
|
||||||
|
b.Property<double>("Distance");
|
||||||
|
|
||||||
|
b.Property<double>("EloRating");
|
||||||
|
|
||||||
|
b.Property<int?>("HitDestinationVector3Id");
|
||||||
|
|
||||||
|
b.Property<int>("HitLocation");
|
||||||
|
|
||||||
|
b.Property<int?>("HitOriginVector3Id");
|
||||||
|
|
||||||
|
b.Property<int>("HitType");
|
||||||
|
|
||||||
|
b.Property<int>("Hits");
|
||||||
|
|
||||||
|
b.Property<int>("Kills");
|
||||||
|
|
||||||
|
b.Property<int?>("LastStrainAngleVector3Id");
|
||||||
|
|
||||||
|
b.Property<double>("SessionAngleOffset");
|
||||||
|
|
||||||
|
b.Property<double>("SessionSPM");
|
||||||
|
|
||||||
|
b.Property<int>("SessionScore");
|
||||||
|
|
||||||
|
b.Property<double>("StrainAngleBetween");
|
||||||
|
|
||||||
|
b.Property<int>("TimeSinceLastEvent");
|
||||||
|
|
||||||
|
b.Property<int>("WeaponId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("When");
|
||||||
|
|
||||||
|
b.HasKey("SnapshotId");
|
||||||
|
|
||||||
|
b.HasIndex("ClientId");
|
||||||
|
|
||||||
|
b.HasIndex("CurrentViewAngleVector3Id");
|
||||||
|
|
||||||
|
b.HasIndex("HitDestinationVector3Id");
|
||||||
|
|
||||||
|
b.HasIndex("HitOriginVector3Id");
|
||||||
|
|
||||||
|
b.HasIndex("LastStrainAngleVector3Id");
|
||||||
|
|
||||||
|
b.ToTable("EFACSnapshot");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("KillId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("AttackerId");
|
||||||
|
|
||||||
|
b.Property<int>("Damage");
|
||||||
|
|
||||||
|
b.Property<int?>("DeathOriginVector3Id");
|
||||||
|
|
||||||
|
b.Property<int>("DeathType");
|
||||||
|
|
||||||
|
b.Property<double>("Fraction");
|
||||||
|
|
||||||
|
b.Property<int>("HitLoc");
|
||||||
|
|
||||||
|
b.Property<bool>("IsKill");
|
||||||
|
|
||||||
|
b.Property<int?>("KillOriginVector3Id");
|
||||||
|
|
||||||
|
b.Property<int>("Map");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId");
|
||||||
|
|
||||||
|
b.Property<int>("VictimId");
|
||||||
|
|
||||||
|
b.Property<int?>("ViewAnglesVector3Id");
|
||||||
|
|
||||||
|
b.Property<double>("VisibilityPercentage");
|
||||||
|
|
||||||
|
b.Property<int>("Weapon");
|
||||||
|
|
||||||
|
b.Property<DateTime>("When");
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("ClientId");
|
||||||
|
|
||||||
|
b.Property<string>("Message");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("TimeSent");
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("ClientId");
|
||||||
|
|
||||||
|
b.HasKey("RatingHistoryId");
|
||||||
|
|
||||||
|
b.HasIndex("ClientId");
|
||||||
|
|
||||||
|
b.ToTable("EFClientRatingHistory");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ClientId");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId");
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("Deaths");
|
||||||
|
|
||||||
|
b.Property<double>("EloRating");
|
||||||
|
|
||||||
|
b.Property<int>("Kills");
|
||||||
|
|
||||||
|
b.Property<double>("MaxStrain");
|
||||||
|
|
||||||
|
b.Property<double>("RollingWeightedKDR");
|
||||||
|
|
||||||
|
b.Property<double>("SPM");
|
||||||
|
|
||||||
|
b.Property<double>("Skill");
|
||||||
|
|
||||||
|
b.Property<int>("TimePlayed");
|
||||||
|
|
||||||
|
b.Property<double>("VisionAverage");
|
||||||
|
|
||||||
|
b.HasKey("ClientId", "ServerId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("EFClientStatistics");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("HitLocationCountId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("ClientId")
|
||||||
|
.HasColumnName("EFClientStatistics_ClientId");
|
||||||
|
|
||||||
|
b.Property<int>("HitCount");
|
||||||
|
|
||||||
|
b.Property<float>("HitOffsetAverage");
|
||||||
|
|
||||||
|
b.Property<int>("Location");
|
||||||
|
|
||||||
|
b.Property<float>("MaxAngleDistance");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId")
|
||||||
|
.HasColumnName("EFClientStatistics_ServerId");
|
||||||
|
|
||||||
|
b.HasKey("HitLocationCountId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.HasIndex("ClientId", "ServerId");
|
||||||
|
|
||||||
|
b.ToTable("EFHitLocationCounts");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("RatingId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("ActivityAmount");
|
||||||
|
|
||||||
|
b.Property<bool>("Newest");
|
||||||
|
|
||||||
|
b.Property<double>("Performance");
|
||||||
|
|
||||||
|
b.Property<int>("Ranking");
|
||||||
|
|
||||||
|
b.Property<int>("RatingHistoryId");
|
||||||
|
|
||||||
|
b.Property<int?>("ServerId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("When");
|
||||||
|
|
||||||
|
b.HasKey("RatingId");
|
||||||
|
|
||||||
|
b.HasIndex("Performance");
|
||||||
|
|
||||||
|
b.HasIndex("Ranking");
|
||||||
|
|
||||||
|
b.HasIndex("RatingHistoryId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.HasIndex("When");
|
||||||
|
|
||||||
|
b.ToTable("EFRating");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServer", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ServerId");
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("Port");
|
||||||
|
|
||||||
|
b.HasKey("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("EFServers");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("StatisticId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("ServerId");
|
||||||
|
|
||||||
|
b.Property<long>("TotalKills");
|
||||||
|
|
||||||
|
b.Property<long>("TotalPlayTime");
|
||||||
|
|
||||||
|
b.HasKey("StatisticId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("EFServerStatistics");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("AliasId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<DateTime>("DateAdded");
|
||||||
|
|
||||||
|
b.Property<int>("IPAddress");
|
||||||
|
|
||||||
|
b.Property<int>("LinkId");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(24);
|
||||||
|
|
||||||
|
b.HasKey("AliasId");
|
||||||
|
|
||||||
|
b.HasIndex("IPAddress");
|
||||||
|
|
||||||
|
b.HasIndex("LinkId");
|
||||||
|
|
||||||
|
b.HasIndex("Name");
|
||||||
|
|
||||||
|
b.ToTable("EFAlias");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAliasLink", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("AliasLinkId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.HasKey("AliasLinkId");
|
||||||
|
|
||||||
|
b.ToTable("EFAliasLinks");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFChangeHistory", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ChangeHistoryId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<string>("Comment")
|
||||||
|
.HasMaxLength(128);
|
||||||
|
|
||||||
|
b.Property<string>("CurrentValue");
|
||||||
|
|
||||||
|
b.Property<int>("OriginEntityId");
|
||||||
|
|
||||||
|
b.Property<string>("PreviousValue");
|
||||||
|
|
||||||
|
b.Property<int>("TargetEntityId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("TimeChanged");
|
||||||
|
|
||||||
|
b.Property<int>("TypeOfChange");
|
||||||
|
|
||||||
|
b.HasKey("ChangeHistoryId");
|
||||||
|
|
||||||
|
b.ToTable("EFChangeHistory");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ClientId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("AliasLinkId");
|
||||||
|
|
||||||
|
b.Property<int>("Connections");
|
||||||
|
|
||||||
|
b.Property<int>("CurrentAliasId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("FirstConnection");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastConnection");
|
||||||
|
|
||||||
|
b.Property<int>("Level");
|
||||||
|
|
||||||
|
b.Property<bool>("Masked");
|
||||||
|
|
||||||
|
b.Property<long>("NetworkId");
|
||||||
|
|
||||||
|
b.Property<string>("Password");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordSalt");
|
||||||
|
|
||||||
|
b.Property<int>("TotalConnectionTime");
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<int>("ClientId");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Created");
|
||||||
|
|
||||||
|
b.Property<string>("Extra");
|
||||||
|
|
||||||
|
b.Property<string>("Key")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Property<DateTime>("Updated");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("MetaId");
|
||||||
|
|
||||||
|
b.HasIndex("ClientId");
|
||||||
|
|
||||||
|
b.ToTable("EFMeta");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("PenaltyId")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
b.Property<string>("AutomatedOffense");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Expires");
|
||||||
|
|
||||||
|
b.Property<int>("LinkId");
|
||||||
|
|
||||||
|
b.Property<int>("OffenderId");
|
||||||
|
|
||||||
|
b.Property<string>("Offense")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Property<int>("PunisherId");
|
||||||
|
|
||||||
|
b.Property<int>("Type");
|
||||||
|
|
||||||
|
b.Property<DateTime>("When");
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
b.Property<int?>("EFACSnapshotSnapshotId");
|
||||||
|
|
||||||
|
b.Property<float>("X");
|
||||||
|
|
||||||
|
b.Property<float>("Y");
|
||||||
|
|
||||||
|
b.Property<float>("Z");
|
||||||
|
|
||||||
|
b.HasKey("Vector3Id");
|
||||||
|
|
||||||
|
b.HasIndex("EFACSnapshotSnapshotId");
|
||||||
|
|
||||||
|
b.ToTable("Vector3");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "CurrentViewAngle")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CurrentViewAngleVector3Id");
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "HitDestination")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("HitDestinationVector3Id");
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "HitOrigin")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("HitOriginVector3Id");
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "LastStrainAngle")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("LastStrainAngleVector3Id");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Attacker")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AttackerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Victim")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("VictimId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics")
|
||||||
|
.WithMany("HitLocations")
|
||||||
|
.HasForeignKey("ClientId", "ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", "RatingHistory")
|
||||||
|
.WithMany("Ratings")
|
||||||
|
.HasForeignKey("RatingHistoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link")
|
||||||
|
.WithMany("Children")
|
||||||
|
.HasForeignKey("LinkId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "AliasLink")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AliasLinkId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFAlias", "CurrentAlias")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CurrentAliasId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFMeta", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany("Meta")
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link")
|
||||||
|
.WithMany("ReceivedPenalties")
|
||||||
|
.HasForeignKey("LinkId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Offender")
|
||||||
|
.WithMany("ReceivedPenalties")
|
||||||
|
.HasForeignKey("OffenderId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Punisher")
|
||||||
|
.WithMany("AdministeredPenalties")
|
||||||
|
.HasForeignKey("PunisherId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Helpers.Vector3", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot")
|
||||||
|
.WithMany("PredictedViewAngles")
|
||||||
|
.HasForeignKey("EFACSnapshotSnapshotId");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace SharedLibraryCore.Migrations
|
||||||
|
{
|
||||||
|
public partial class ForceAutoIncrementChangeHistory : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
// hack: we can't alter the column on SQLite, but we need max length limit for the Index in MySQL etc
|
||||||
|
if (migrationBuilder.ActiveProvider != "Microsoft.EntityFrameworkCore.Sqlite")
|
||||||
|
{
|
||||||
|
migrationBuilder.AlterColumn<int>(
|
||||||
|
name: "ChangeHistoryId",
|
||||||
|
table: "EFChangeHistory"
|
||||||
|
).Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
using SharedLibraryCore.Database;
|
using SharedLibraryCore.Database;
|
||||||
|
|
||||||
@ -155,6 +156,8 @@ namespace SharedLibraryCore.Migrations
|
|||||||
|
|
||||||
b.HasIndex("ServerId");
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.HasIndex("TimeSent");
|
||||||
|
|
||||||
b.ToTable("EFClientMessages");
|
b.ToTable("EFClientMessages");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -349,7 +352,8 @@ namespace SharedLibraryCore.Migrations
|
|||||||
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFChangeHistory", b =>
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFChangeHistory", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("ChangeHistoryId")
|
b.Property<int>("ChangeHistoryId")
|
||||||
.ValueGeneratedOnAdd();
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn);
|
||||||
|
|
||||||
b.Property<bool>("Active");
|
b.Property<bool>("Active");
|
||||||
|
|
||||||
|
@ -54,9 +54,10 @@ namespace SharedLibraryCore.Services
|
|||||||
|
|
||||||
public async Task<IList<EFAlias>> Find(Func<EFAlias, bool> expression)
|
public async Task<IList<EFAlias>> Find(Func<EFAlias, bool> expression)
|
||||||
{
|
{
|
||||||
|
// todo: max better?
|
||||||
return await Task.Run(() =>
|
return await Task.Run(() =>
|
||||||
{
|
{
|
||||||
using (var context = new DatabaseContext())
|
using (var context = new DatabaseContext(true))
|
||||||
return context.Aliases
|
return context.Aliases
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Include(a => a.Link.Children)
|
.Include(a => a.Link.Children)
|
||||||
@ -67,10 +68,9 @@ namespace SharedLibraryCore.Services
|
|||||||
|
|
||||||
public async Task<EFAlias> Get(int entityID)
|
public async Task<EFAlias> Get(int entityID)
|
||||||
{
|
{
|
||||||
using (var context = new DatabaseContext())
|
using (var context = new DatabaseContext(true))
|
||||||
return await context.Aliases
|
return await context.Aliases
|
||||||
.AsNoTracking()
|
.FirstOrDefaultAsync(e => e.AliasId == entityID);
|
||||||
.SingleOrDefaultAsync(e => e.AliasId == entityID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<EFAlias> GetUnique(long entityProperty)
|
public Task<EFAlias> GetUnique(long entityProperty)
|
||||||
@ -81,23 +81,6 @@ namespace SharedLibraryCore.Services
|
|||||||
public async Task<EFAlias> Update(EFAlias entity)
|
public async Task<EFAlias> Update(EFAlias entity)
|
||||||
{
|
{
|
||||||
throw await Task.FromResult(new Exception());
|
throw await Task.FromResult(new Exception());
|
||||||
/*using (var context = new DatabaseContext())
|
|
||||||
{
|
|
||||||
entity = context.Aliases.Attach(entity);
|
|
||||||
context.Entry(entity).State = EntityState.Modified;
|
|
||||||
await context.SaveChangesAsync();
|
|
||||||
return entity;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<EFAliasLink> CreateLink(EFAliasLink link)
|
|
||||||
{
|
|
||||||
using (var context = new DatabaseContext())
|
|
||||||
{
|
|
||||||
context.AliasLinks.Add(link);
|
|
||||||
await context.SaveChangesAsync();
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
95
SharedLibraryCore/Services/ChangeHistoryService.cs
Normal file
95
SharedLibraryCore/Services/ChangeHistoryService.cs
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
using SharedLibraryCore.Database;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
|
using SharedLibraryCore.Events;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SharedLibraryCore.Services
|
||||||
|
{
|
||||||
|
public class ChangeHistoryService : IEntityService<EFChangeHistory>
|
||||||
|
{
|
||||||
|
public Task<EFChangeHistory> Create(EFChangeHistory entity)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<EFChangeHistory> Add(GameEvent e)
|
||||||
|
{
|
||||||
|
EFChangeHistory change = null;
|
||||||
|
|
||||||
|
switch (e.Type)
|
||||||
|
{
|
||||||
|
case GameEvent.EventType.Ban:
|
||||||
|
change = new EFChangeHistory()
|
||||||
|
{
|
||||||
|
OriginEntityId = e.Origin.ClientId,
|
||||||
|
TargetEntityId = e.Target.ClientId,
|
||||||
|
TypeOfChange = EFChangeHistory.ChangeType.Ban,
|
||||||
|
Comment = e.Data
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case GameEvent.EventType.Command:
|
||||||
|
break;
|
||||||
|
case GameEvent.EventType.ChangePermission:
|
||||||
|
change = new EFChangeHistory()
|
||||||
|
{
|
||||||
|
OriginEntityId = e.Origin.ClientId,
|
||||||
|
TargetEntityId = e.Target.ClientId,
|
||||||
|
TypeOfChange = EFChangeHistory.ChangeType.Permission,
|
||||||
|
PreviousValue = ((Change)e.Extra).PreviousValue,
|
||||||
|
CurrentValue = ((Change)e.Extra).NewValue
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (change != null)
|
||||||
|
{
|
||||||
|
using (var ctx = new DatabaseContext(true))
|
||||||
|
{
|
||||||
|
ctx.EFChangeHistory.Add(change);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await ctx.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
e.Owner.Logger.WriteDebug(ex.GetExceptionInfo());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return change;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<EFChangeHistory> Delete(EFChangeHistory entity)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<IList<EFChangeHistory>> Find(Func<EFChangeHistory, bool> expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<EFChangeHistory> Get(int entityID)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<EFChangeHistory> GetUnique(long entityProperty)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<EFChangeHistory> Update(EFChangeHistory entity)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -223,7 +223,7 @@ namespace SharedLibraryCore.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region ServiceSpecific
|
#region ServiceSpecific
|
||||||
public async Task<IList<EFClient>> GetOwners()
|
public async Task<IList<EFClient>> GetOwners()
|
||||||
{
|
{
|
||||||
using (var context = new DatabaseContext())
|
using (var context = new DatabaseContext())
|
||||||
@ -262,7 +262,7 @@ namespace SharedLibraryCore.Services
|
|||||||
|
|
||||||
name = name.ToLower();
|
name = name.ToLower();
|
||||||
|
|
||||||
using (var context = new DatabaseContext(true))
|
using (var context = new DatabaseContext(disableTracking: true))
|
||||||
{
|
{
|
||||||
int asIP = name.ConvertToIP();
|
int asIP = name.ConvertToIP();
|
||||||
// hack: so IW4MAdmin and bots don't show up in search results
|
// hack: so IW4MAdmin and bots don't show up in search results
|
||||||
@ -287,57 +287,9 @@ namespace SharedLibraryCore.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IList<EFClient>> GetClientByIP(int ipAddress)
|
|
||||||
{
|
|
||||||
using (var context = new DatabaseContext(true))
|
|
||||||
{
|
|
||||||
var iqClients = (from alias in context.Aliases
|
|
||||||
.AsNoTracking()
|
|
||||||
where alias.IPAddress == ipAddress
|
|
||||||
join link in context.AliasLinks
|
|
||||||
on alias.LinkId equals link.AliasLinkId
|
|
||||||
join client in context.Clients
|
|
||||||
.AsNoTracking()
|
|
||||||
on alias.LinkId equals client.AliasLinkId
|
|
||||||
select client)
|
|
||||||
.Distinct()
|
|
||||||
.Include(c => c.CurrentAlias)
|
|
||||||
.Include(c => c.AliasLink.Children);
|
|
||||||
|
|
||||||
return await iqClients.ToListAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IList<EFClient>> GetRecentClients(int offset, int count)
|
|
||||||
{
|
|
||||||
using (var context = new DatabaseContext())
|
|
||||||
return await context.Clients
|
|
||||||
.AsNoTracking()
|
|
||||||
.Include(c => c.CurrentAlias)
|
|
||||||
.Include(p => p.AliasLink)
|
|
||||||
.OrderByDescending(p => p.ClientId)
|
|
||||||
.Skip(offset)
|
|
||||||
.Take(count)
|
|
||||||
.ToListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IList<EFClient>> PruneInactivePrivilegedClients(int inactiveDays)
|
|
||||||
{
|
|
||||||
using (var context = new DatabaseContext())
|
|
||||||
{
|
|
||||||
var inactive = await context.Clients.Where(c => c.Level > Objects.Player.Permission.Flagged)
|
|
||||||
.AsNoTracking()
|
|
||||||
.Where(c => (DateTime.UtcNow - c.LastConnection).TotalDays >= inactiveDays)
|
|
||||||
.ToListAsync();
|
|
||||||
inactive.ForEach(c => c.Level = Player.Permission.User);
|
|
||||||
await context.SaveChangesAsync();
|
|
||||||
return inactive;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> GetTotalClientsAsync()
|
public async Task<int> GetTotalClientsAsync()
|
||||||
{
|
{
|
||||||
using (var context = new DatabaseContext())
|
using (var context = new DatabaseContext(true))
|
||||||
return await context.Clients
|
return await context.Clients
|
||||||
.CountAsync();
|
.CountAsync();
|
||||||
}
|
}
|
||||||
@ -349,9 +301,9 @@ namespace SharedLibraryCore.Services
|
|||||||
|
|
||||||
public async Task<int> GetTotalPlayTime()
|
public async Task<int> GetTotalPlayTime()
|
||||||
{
|
{
|
||||||
using (var context = new DatabaseContext())
|
using (var context = new DatabaseContext(true))
|
||||||
return await context.Clients.SumAsync(c => c.TotalConnectionTime);
|
return await context.Clients.SumAsync(c => c.TotalConnectionTime);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,28 @@ namespace SharedLibraryCore
|
|||||||
return newStr;
|
return newStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// helper method to get the information about an exception and inner exceptions
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ex"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string GetExceptionInfo(this Exception ex)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
int depth = 0;
|
||||||
|
while (ex != null)
|
||||||
|
{
|
||||||
|
sb.AppendLine($"Exception[{depth}] Name: {ex.GetType().FullName}");
|
||||||
|
sb.AppendLine($"Exception[{depth}] Message: {ex.Message}");
|
||||||
|
sb.AppendLine($"Exception[{depth}] Call Stack: {ex.StackTrace}");
|
||||||
|
sb.AppendLine($"Exception[{depth}] Source: {ex.Source}");
|
||||||
|
depth++;
|
||||||
|
ex = ex.InnerException;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
public static Player.Permission MatchPermission(String str)
|
public static Player.Permission MatchPermission(String str)
|
||||||
{
|
{
|
||||||
String lookingFor = str.ToLower();
|
String lookingFor = str.ToLower();
|
||||||
|
@ -37,6 +37,8 @@ namespace WebfrontCore.Controllers
|
|||||||
SocialLink = Manager.GetApplicationSettings().Configuration().SocialLinkAddress;
|
SocialLink = Manager.GetApplicationSettings().Configuration().SocialLinkAddress;
|
||||||
SocialTitle = Manager.GetApplicationSettings().Configuration().SocialLinkTitle;
|
SocialTitle = Manager.GetApplicationSettings().Configuration().SocialLinkTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ViewBag.Version = Manager.Version;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnActionExecuting(ActionExecutingContext context)
|
public override void OnActionExecuting(ActionExecutingContext context)
|
||||||
|
@ -135,7 +135,22 @@
|
|||||||
|
|
||||||
<div class="container p-4">
|
<div class="container p-4">
|
||||||
@RenderBody()
|
@RenderBody()
|
||||||
<footer></footer>
|
<footer id="footer_text">
|
||||||
|
<div class="d-lg-none d-block text-center pt-4 pb-4">
|
||||||
|
<a href="https://github.com/RaidMax/IW4M-Admin/releases" target="_blank">
|
||||||
|
@Program.Manager.Version
|
||||||
|
</a>
|
||||||
|
<br />
|
||||||
|
<span class="text-muted">Developed by RaidMax</span>
|
||||||
|
</div>
|
||||||
|
<div class="footer-mobile d-lg-block d-none text-center">
|
||||||
|
<a href="https://github.com/RaidMax/IW4M-Admin/releases" target="_blank">
|
||||||
|
@Program.Manager.Version
|
||||||
|
</a>
|
||||||
|
<br />
|
||||||
|
<span class="text-muted">Developed by RaidMax</span>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
<environment include="Development">
|
<environment include="Development">
|
||||||
<script type="text/javascript" src="~/lib/jQuery/dist/jquery.js"></script>
|
<script type="text/javascript" src="~/lib/jQuery/dist/jquery.js"></script>
|
||||||
|
@ -6409,3 +6409,11 @@ form *, select {
|
|||||||
.client-message, .automated-penalty-info-detailed {
|
.client-message, .automated-penalty-info-detailed {
|
||||||
cursor: pointer; }
|
cursor: pointer; }
|
||||||
|
|
||||||
|
#footer_text {
|
||||||
|
font-size: 0.85rem; }
|
||||||
|
|
||||||
|
.footer-mobile {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 1em;
|
||||||
|
right: 1em; }
|
||||||
|
|
||||||
|
10
WebfrontCore/wwwroot/css/bootstrap-custom.scss
vendored
10
WebfrontCore/wwwroot/css/bootstrap-custom.scss
vendored
@ -209,3 +209,13 @@ form *, select {
|
|||||||
.client-message, .automated-penalty-info-detailed {
|
.client-message, .automated-penalty-info-detailed {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#footer_text {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-mobile {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 1em;
|
||||||
|
right: 1em;
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
function getPlayerHistoryChart(playerHistory, i, width, color) {
|
function getPlayerHistoryChart(playerHistory, i, width, color, maxClients) {
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// thanks to canvasjs :(
|
// thanks to canvasjs :(
|
||||||
playerHistory.forEach(function (item, i) {
|
playerHistory.forEach(function (item, i) {
|
||||||
@ -29,6 +29,7 @@
|
|||||||
lineThickness: 0,
|
lineThickness: 0,
|
||||||
tickThickness: 0,
|
tickThickness: 0,
|
||||||
minimum: 0,
|
minimum: 0,
|
||||||
|
maximum: maxClients + 1,
|
||||||
margin: 0,
|
margin: 0,
|
||||||
valueFormatString: " ",
|
valueFormatString: " ",
|
||||||
labelMaxWidth: 0
|
labelMaxWidth: 0
|
||||||
@ -53,9 +54,10 @@ var charts = {};
|
|||||||
$('.server-history-row').each(function (index, element) {
|
$('.server-history-row').each(function (index, element) {
|
||||||
let clientHistory = $(this).data('clienthistory');
|
let clientHistory = $(this).data('clienthistory');
|
||||||
let serverId = $(this).data('serverid');
|
let serverId = $(this).data('serverid');
|
||||||
|
let maxClients = parseInt($('#server_header_' + serverId + ' .server-maxclients').text());
|
||||||
let color = $(this).data('online') === 'True' ? 'rgba(0, 122, 204, 0.432)' : '#ff6060'
|
let color = $(this).data('online') === 'True' ? 'rgba(0, 122, 204, 0.432)' : '#ff6060'
|
||||||
let width = $('.server-header').first().width();
|
let width = $('.server-header').first().width();
|
||||||
let historyChart = getPlayerHistoryChart(clientHistory, serverId, width, color);
|
let historyChart = getPlayerHistoryChart(clientHistory, serverId, width, color, maxClients);
|
||||||
historyChart.render();
|
historyChart.render();
|
||||||
charts[serverId] = historyChart;
|
charts[serverId] = historyChart;
|
||||||
});
|
});
|
||||||
@ -82,7 +84,7 @@ function refreshClientActivity() {
|
|||||||
$('#server_clientactivity_' + serverId).html(response);
|
$('#server_clientactivity_' + serverId).html(response);
|
||||||
})
|
})
|
||||||
.fail(function (jqxhr, textStatus, error) {
|
.fail(function (jqxhr, textStatus, error) {
|
||||||
$('#server_clientactivity_' + serverId).html("Could not load client activity - " + error);
|
$('#server_clientactivity_' + serverId).html(" Could not load client activity - " + error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user