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>
|
||||
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
|
||||
<PackageId>RaidMax.IW4MAdmin.Application</PackageId>
|
||||
<Version>2.1.9.1</Version>
|
||||
<Version>2.1.9.2</Version>
|
||||
<Authors>RaidMax</Authors>
|
||||
<Company>Forever None</Company>
|
||||
<Product>IW4MAdmin</Product>
|
||||
|
@ -23,9 +23,9 @@ namespace IW4MAdmin.Application
|
||||
|
||||
public void AddEvent(GameEvent gameEvent)
|
||||
{
|
||||
// IsProcessingEvent.Wait();
|
||||
//IsProcessingEvent.Wait();
|
||||
((Manager as ApplicationManager).OnServerEvent)(this, new GameEventArgs(null, false, gameEvent));
|
||||
// IsProcessingEvent.Release(1);
|
||||
//IsProcessingEvent.Release(1);
|
||||
//if (gameEvent.Type == GameEvent.EventType.Connect)
|
||||
//{
|
||||
// IsProcessingEvent.Wait();
|
||||
|
@ -39,6 +39,7 @@ namespace IW4MAdmin.Application
|
||||
// expose the event handler so we can execute the events
|
||||
public OnServerEventEventHandler OnServerEvent { get; set; }
|
||||
public DateTime StartTime { get; private set; }
|
||||
public string Version => Assembly.GetEntryAssembly().GetName().Version.ToString();
|
||||
|
||||
static ApplicationManager Instance;
|
||||
readonly List<AsyncStatus> TaskStatuses;
|
||||
@ -102,9 +103,12 @@ namespace IW4MAdmin.Application
|
||||
return;
|
||||
}
|
||||
|
||||
await newEvent.Owner.ExecuteEvent(newEvent);
|
||||
|
||||
// todo: this is a hacky mess
|
||||
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;
|
||||
|
||||
@ -144,8 +148,6 @@ namespace IW4MAdmin.Application
|
||||
}
|
||||
}
|
||||
|
||||
await newEvent.Owner.ExecuteEvent(newEvent);
|
||||
|
||||
#if DEBUG
|
||||
Logger.WriteDebug($"Processed event with id {newEvent.Id}");
|
||||
#endif
|
||||
@ -175,6 +177,9 @@ namespace IW4MAdmin.Application
|
||||
}
|
||||
// tell anyone waiting for the output that we're done
|
||||
newEvent.OnProcessed.Set();
|
||||
|
||||
var changeHistorySvc = new ChangeHistoryService();
|
||||
await changeHistorySvc.Add(args.Event);
|
||||
}
|
||||
|
||||
public IList<Server> GetServers()
|
||||
@ -263,7 +268,7 @@ namespace IW4MAdmin.Application
|
||||
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))
|
||||
.Select(c => new
|
||||
{
|
||||
|
@ -1,197 +1,197 @@
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
//using SharedLibraryCore;
|
||||
//using SharedLibraryCore.Objects;
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Text;
|
||||
//using System.Threading.Tasks;
|
||||
|
||||
namespace IW4ScriptCommands.Commands
|
||||
{
|
||||
class Balance : Command
|
||||
{
|
||||
private class TeamAssignment
|
||||
{
|
||||
public IW4MAdmin.Plugins.Stats.IW4Info.Team CurrentTeam { get; set; }
|
||||
public int Num { get; set; }
|
||||
public IW4MAdmin.Plugins.Stats.Models.EFClientStatistics Stats { get; set; }
|
||||
}
|
||||
public Balance() : base("balance", "balance teams", "bal", Player.Permission.Trusted, false, null)
|
||||
{
|
||||
}
|
||||
//namespace IW4ScriptCommands.Commands
|
||||
//{
|
||||
// class Balance : Command
|
||||
// {
|
||||
// private class TeamAssignment
|
||||
// {
|
||||
// public IW4MAdmin.Plugins.Stats.IW4Info.Team CurrentTeam { get; set; }
|
||||
// public int Num { get; set; }
|
||||
// public IW4MAdmin.Plugins.Stats.Models.EFClientStatistics Stats { get; set; }
|
||||
// }
|
||||
// public Balance() : base("balance", "balance teams", "bal", Player.Permission.Trusted, false, null)
|
||||
// {
|
||||
// }
|
||||
|
||||
public override async Task ExecuteAsync(GameEvent E)
|
||||
{
|
||||
string teamsString = (await E.Owner.GetDvarAsync<string>("sv_iw4madmin_teams")).Value;
|
||||
// public override async Task ExecuteAsync(GameEvent E)
|
||||
// {
|
||||
// string teamsString = (await E.Owner.GetDvarAsync<string>("sv_iw4madmin_teams")).Value;
|
||||
|
||||
var scriptClientTeams = teamsString.Split(';', StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(c => c.Split(','))
|
||||
.Select(c => new TeamAssignment()
|
||||
{
|
||||
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,
|
||||
Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(E.Owner.Players.FirstOrDefault(p => p?.NetworkId == c[0].ConvertLong()).ClientId, E.Owner.GetHashCode())
|
||||
})
|
||||
.ToList();
|
||||
// var scriptClientTeams = teamsString.Split(';', StringSplitOptions.RemoveEmptyEntries)
|
||||
// .Select(c => c.Split(','))
|
||||
// .Select(c => new TeamAssignment()
|
||||
// {
|
||||
// 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,
|
||||
// Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(E.Owner.Players.FirstOrDefault(p => p?.NetworkId == c[0].ConvertLong()).ClientId, E.Owner.GetHashCode())
|
||||
// })
|
||||
// .ToList();
|
||||
|
||||
// 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)
|
||||
|| 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"]);
|
||||
return;
|
||||
}
|
||||
// // 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)
|
||||
// || 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"]);
|
||||
// return;
|
||||
// }
|
||||
|
||||
List<string> teamAssignments = new List<string>();
|
||||
// List<string> teamAssignments = new List<string>();
|
||||
|
||||
var activeClients = E.Owner.GetPlayersAsList().Select(c => new TeamAssignment()
|
||||
{
|
||||
Num = c.ClientNumber,
|
||||
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
|
||||
})
|
||||
.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)
|
||||
.OrderByDescending(c => c.Stats.Performance)
|
||||
.ToList();
|
||||
// var activeClients = E.Owner.GetPlayersAsList().Select(c => new TeamAssignment()
|
||||
// {
|
||||
// Num = c.ClientNumber,
|
||||
// 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
|
||||
// })
|
||||
// .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)
|
||||
// .OrderByDescending(c => c.Stats.Performance)
|
||||
// .ToList();
|
||||
|
||||
var alliesTeam = scriptClientTeams
|
||||
.Where(c => c.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies)
|
||||
.Where(c => activeClients.Count(t => t.Num == c.Num) == 0)
|
||||
.ToList();
|
||||
// var alliesTeam = scriptClientTeams
|
||||
// .Where(c => c.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies)
|
||||
// .Where(c => activeClients.Count(t => t.Num == c.Num) == 0)
|
||||
// .ToList();
|
||||
|
||||
var axisTeam = scriptClientTeams
|
||||
.Where(c => c.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis)
|
||||
.Where(c => activeClients.Count(t => t.Num == c.Num) == 0)
|
||||
.ToList();
|
||||
// var axisTeam = scriptClientTeams
|
||||
// .Where(c => c.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis)
|
||||
// .Where(c => activeClients.Count(t => t.Num == c.Num) == 0)
|
||||
// .ToList();
|
||||
|
||||
while (activeClients.Count() > 0)
|
||||
{
|
||||
int teamSizeDifference = alliesTeam.Count - axisTeam.Count;
|
||||
double performanceDisparity = alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0 -
|
||||
axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0;
|
||||
// while (activeClients.Count() > 0)
|
||||
// {
|
||||
// int teamSizeDifference = alliesTeam.Count - axisTeam.Count;
|
||||
// double performanceDisparity = alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0 -
|
||||
// axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0;
|
||||
|
||||
if (teamSizeDifference == 0)
|
||||
{
|
||||
if (performanceDisparity == 0)
|
||||
{
|
||||
alliesTeam.Add(activeClients.First());
|
||||
activeClients.RemoveAt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (performanceDisparity > 0)
|
||||
{
|
||||
axisTeam.Add(activeClients.First());
|
||||
activeClients.RemoveAt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
alliesTeam.Add(activeClients.First());
|
||||
activeClients.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (teamSizeDifference > 0)
|
||||
{
|
||||
if (performanceDisparity > 0)
|
||||
{
|
||||
axisTeam.Add(activeClients.First());
|
||||
activeClients.RemoveAt(0);
|
||||
}
|
||||
// if (teamSizeDifference == 0)
|
||||
// {
|
||||
// if (performanceDisparity == 0)
|
||||
// {
|
||||
// alliesTeam.Add(activeClients.First());
|
||||
// activeClients.RemoveAt(0);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (performanceDisparity > 0)
|
||||
// {
|
||||
// axisTeam.Add(activeClients.First());
|
||||
// activeClients.RemoveAt(0);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// alliesTeam.Add(activeClients.First());
|
||||
// activeClients.RemoveAt(0);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else if (teamSizeDifference > 0)
|
||||
// {
|
||||
// if (performanceDisparity > 0)
|
||||
// {
|
||||
// axisTeam.Add(activeClients.First());
|
||||
// activeClients.RemoveAt(0);
|
||||
// }
|
||||
|
||||
else
|
||||
{
|
||||
axisTeam.Add(activeClients.Last());
|
||||
activeClients.RemoveAt(activeClients.Count - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (performanceDisparity > 0)
|
||||
{
|
||||
alliesTeam.Add(activeClients.First());
|
||||
activeClients.RemoveAt(0);
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// axisTeam.Add(activeClients.Last());
|
||||
// activeClients.RemoveAt(activeClients.Count - 1);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (performanceDisparity > 0)
|
||||
// {
|
||||
// alliesTeam.Add(activeClients.First());
|
||||
// activeClients.RemoveAt(0);
|
||||
// }
|
||||
|
||||
else
|
||||
{
|
||||
alliesTeam.Add(activeClients.Last());
|
||||
activeClients.RemoveAt(activeClients.Count - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// alliesTeam.Add(activeClients.Last());
|
||||
// activeClients.RemoveAt(activeClients.Count - 1);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
alliesTeam = alliesTeam.OrderByDescending(t => t.Stats.Performance)
|
||||
.ToList();
|
||||
// alliesTeam = alliesTeam.OrderByDescending(t => t.Stats.Performance)
|
||||
// .ToList();
|
||||
|
||||
axisTeam = axisTeam.OrderByDescending(t => t.Stats.Performance)
|
||||
.ToList();
|
||||
// axisTeam = axisTeam.OrderByDescending(t => t.Stats.Performance)
|
||||
// .ToList();
|
||||
|
||||
while (Math.Abs(alliesTeam.Count - axisTeam.Count) > 1)
|
||||
{
|
||||
int teamSizeDifference = alliesTeam.Count - axisTeam.Count;
|
||||
double performanceDisparity = alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0 -
|
||||
axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0;
|
||||
// while (Math.Abs(alliesTeam.Count - axisTeam.Count) > 1)
|
||||
// {
|
||||
// int teamSizeDifference = alliesTeam.Count - axisTeam.Count;
|
||||
// double performanceDisparity = alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0 -
|
||||
// axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0;
|
||||
|
||||
if (teamSizeDifference > 0)
|
||||
{
|
||||
if (performanceDisparity > 0)
|
||||
{
|
||||
axisTeam.Add(alliesTeam.First());
|
||||
alliesTeam.RemoveAt(0);
|
||||
}
|
||||
// if (teamSizeDifference > 0)
|
||||
// {
|
||||
// if (performanceDisparity > 0)
|
||||
// {
|
||||
// axisTeam.Add(alliesTeam.First());
|
||||
// alliesTeam.RemoveAt(0);
|
||||
// }
|
||||
|
||||
else
|
||||
{
|
||||
axisTeam.Add(alliesTeam.Last());
|
||||
alliesTeam.RemoveAt(axisTeam.Count - 1);
|
||||
}
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// axisTeam.Add(alliesTeam.Last());
|
||||
// alliesTeam.RemoveAt(axisTeam.Count - 1);
|
||||
// }
|
||||
// }
|
||||
|
||||
else
|
||||
{
|
||||
if (performanceDisparity > 0)
|
||||
{
|
||||
alliesTeam.Add(axisTeam.Last());
|
||||
axisTeam.RemoveAt(axisTeam.Count - 1);
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// if (performanceDisparity > 0)
|
||||
// {
|
||||
// alliesTeam.Add(axisTeam.Last());
|
||||
// axisTeam.RemoveAt(axisTeam.Count - 1);
|
||||
// }
|
||||
|
||||
else
|
||||
{
|
||||
alliesTeam.Add(axisTeam.First());
|
||||
axisTeam.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// alliesTeam.Add(axisTeam.First());
|
||||
// axisTeam.RemoveAt(0);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
foreach (var assignment in alliesTeam)
|
||||
{
|
||||
teamAssignments.Add($"{assignment.Num},2");
|
||||
assignment.Stats.Team = IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies;
|
||||
}
|
||||
foreach (var assignment in axisTeam)
|
||||
{
|
||||
teamAssignments.Add($"{assignment.Num},3");
|
||||
assignment.Stats.Team = IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis;
|
||||
}
|
||||
// foreach (var assignment in alliesTeam)
|
||||
// {
|
||||
// teamAssignments.Add($"{assignment.Num},2");
|
||||
// assignment.Stats.Team = IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies;
|
||||
// }
|
||||
// foreach (var assignment in axisTeam)
|
||||
// {
|
||||
// teamAssignments.Add($"{assignment.Num},3");
|
||||
// assignment.Stats.Team = IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis;
|
||||
// }
|
||||
|
||||
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)
|
||||
{
|
||||
await E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BALANCE_FAIL_BALANCED"]);
|
||||
return;
|
||||
}
|
||||
// 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)
|
||||
// {
|
||||
// await E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BALANCE_FAIL_BALANCED"]);
|
||||
// return;
|
||||
// }
|
||||
|
||||
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($"Axis Elo: {(axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0)}");
|
||||
}
|
||||
// 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($"Axis Elo: {(axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0)}");
|
||||
// }
|
||||
|
||||
string args = string.Join(",", teamAssignments);
|
||||
await E.Owner.ExecuteCommandAsync($"sv_iw4madmin_command \"balance:{args}\"");
|
||||
await E.Origin.Tell("Balance command sent");
|
||||
}
|
||||
}
|
||||
}
|
||||
// string args = string.Join(",", teamAssignments);
|
||||
// await E.Owner.ExecuteCommandAsync($"sv_iw4madmin_command \"balance:{args}\"");
|
||||
// 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> DeathstreakMessages { get; set; }
|
||||
public int TopPlayersMinPlayTime { get; set; }
|
||||
public bool StoreClientKills { get; set; }
|
||||
public string Name() => "Stats";
|
||||
public IBaseConfiguration Generate()
|
||||
{
|
||||
@ -49,6 +50,7 @@ namespace IW4MAdmin.Plugins.Stats.Config
|
||||
};
|
||||
|
||||
TopPlayersMinPlayTime = 3600 * 3;
|
||||
StoreClientKills = false;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -30,6 +30,9 @@ namespace Stats.Models
|
||||
builder.Entity<EFRating>()
|
||||
.HasIndex(p => p.When);
|
||||
|
||||
builder.Entity<EFClientMessage>()
|
||||
.HasIndex(p => p.TimeSent);
|
||||
|
||||
// force pluralization
|
||||
builder.Entity<EFClientKill>().ToTable("EFClientKills");
|
||||
builder.Entity<EFClientMessage>().ToTable("EFClientMessages");
|
||||
|
@ -40,11 +40,16 @@ namespace IW4MAdmin.Plugins.Stats.Web.Controllers
|
||||
where message.TimeSent <= whenUpper
|
||||
select new SharedLibraryCore.Dtos.ChatInfo()
|
||||
{
|
||||
ClientId = message.ClientId,
|
||||
Message = message.Message,
|
||||
Name = message.Client.CurrentAlias.Name,
|
||||
Time = message.TimeSent
|
||||
};
|
||||
|
||||
#if DEBUG == true
|
||||
var messagesSql = iqMessages.ToSql();
|
||||
#endif
|
||||
|
||||
var messages = await iqMessages.ToListAsync();
|
||||
|
||||
return View("_MessageContext", messages);
|
||||
|
@ -7,6 +7,6 @@
|
||||
<h5>@Model.First().Time.ToString()</h5>
|
||||
@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>
|
@ -8,6 +8,8 @@ using System.Linq;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
|
||||
namespace SharedLibraryCore.Database
|
||||
{
|
||||
@ -103,6 +105,13 @@ namespace SharedLibraryCore.Database
|
||||
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
|
||||
modelBuilder.Entity<EFClient>().ToTable("EFClients");
|
||||
modelBuilder.Entity<EFAlias>().ToTable("EFAlias");
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text;
|
||||
|
||||
namespace SharedLibraryCore.Database.Models
|
||||
@ -15,7 +16,7 @@ namespace SharedLibraryCore.Database.Models
|
||||
Permission,
|
||||
Ban
|
||||
}
|
||||
|
||||
|
||||
[Key]
|
||||
public int ChangeHistoryId { get; set; }
|
||||
public int OriginEntityId { get; set; }
|
||||
|
@ -4,6 +4,7 @@ namespace SharedLibraryCore.Dtos
|
||||
{
|
||||
public class ChatInfo
|
||||
{
|
||||
public int ClientId { get; set; }
|
||||
public string Message { get; set; }
|
||||
public DateTime Time { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
@ -25,92 +25,7 @@ namespace SharedLibraryCore.Events
|
||||
return eventList;
|
||||
}
|
||||
|
||||
private static async Task SaveChangeHistory(GameEvent e)
|
||||
{
|
||||
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)
|
||||
public static void OnGameEvent(object sender, GameEventArgs eventState)
|
||||
{
|
||||
var E = eventState.Event;
|
||||
// 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
|
||||
AddNewEvent(apiEvent);
|
||||
|
||||
await SaveChangeHistory(E);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -20,12 +20,23 @@ namespace SharedLibraryCore.Helpers
|
||||
|
||||
public void OnChange(T value)
|
||||
{
|
||||
// clear the first value when count max count reached
|
||||
if (Values.Count > 30)
|
||||
Values.RemoveAt(0);
|
||||
Values.Add(value);
|
||||
lock (value)
|
||||
{
|
||||
// clear the first value when count max count reached
|
||||
if (Values.Count > 30)
|
||||
Values.RemoveAt(0);
|
||||
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>
|
||||
{
|
||||
Task<T> CreateProxy();
|
||||
Task<T> Create(T entity);
|
||||
Task<T> Delete(T entity);
|
||||
Task<T> Update(T entity);
|
||||
|
@ -39,5 +39,6 @@ namespace SharedLibraryCore.Interfaces
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
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 Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using SharedLibraryCore.Database;
|
||||
|
||||
@ -155,6 +156,8 @@ namespace SharedLibraryCore.Migrations
|
||||
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.HasIndex("TimeSent");
|
||||
|
||||
b.ToTable("EFClientMessages");
|
||||
});
|
||||
|
||||
@ -349,7 +352,8 @@ namespace SharedLibraryCore.Migrations
|
||||
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFChangeHistory", b =>
|
||||
{
|
||||
b.Property<int>("ChangeHistoryId")
|
||||
.ValueGeneratedOnAdd();
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<bool>("Active");
|
||||
|
||||
|
@ -54,9 +54,10 @@ namespace SharedLibraryCore.Services
|
||||
|
||||
public async Task<IList<EFAlias>> Find(Func<EFAlias, bool> expression)
|
||||
{
|
||||
// todo: max better?
|
||||
return await Task.Run(() =>
|
||||
{
|
||||
using (var context = new DatabaseContext())
|
||||
using (var context = new DatabaseContext(true))
|
||||
return context.Aliases
|
||||
.AsNoTracking()
|
||||
.Include(a => a.Link.Children)
|
||||
@ -67,10 +68,9 @@ namespace SharedLibraryCore.Services
|
||||
|
||||
public async Task<EFAlias> Get(int entityID)
|
||||
{
|
||||
using (var context = new DatabaseContext())
|
||||
using (var context = new DatabaseContext(true))
|
||||
return await context.Aliases
|
||||
.AsNoTracking()
|
||||
.SingleOrDefaultAsync(e => e.AliasId == entityID);
|
||||
.FirstOrDefaultAsync(e => e.AliasId == entityID);
|
||||
}
|
||||
|
||||
public Task<EFAlias> GetUnique(long entityProperty)
|
||||
@ -81,23 +81,6 @@ namespace SharedLibraryCore.Services
|
||||
public async Task<EFAlias> Update(EFAlias entity)
|
||||
{
|
||||
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()
|
||||
{
|
||||
using (var context = new DatabaseContext())
|
||||
@ -262,7 +262,7 @@ namespace SharedLibraryCore.Services
|
||||
|
||||
name = name.ToLower();
|
||||
|
||||
using (var context = new DatabaseContext(true))
|
||||
using (var context = new DatabaseContext(disableTracking: true))
|
||||
{
|
||||
int asIP = name.ConvertToIP();
|
||||
// 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()
|
||||
{
|
||||
using (var context = new DatabaseContext())
|
||||
using (var context = new DatabaseContext(true))
|
||||
return await context.Clients
|
||||
.CountAsync();
|
||||
}
|
||||
@ -349,9 +301,9 @@ namespace SharedLibraryCore.Services
|
||||
|
||||
public async Task<int> GetTotalPlayTime()
|
||||
{
|
||||
using (var context = new DatabaseContext())
|
||||
using (var context = new DatabaseContext(true))
|
||||
return await context.Clients.SumAsync(c => c.TotalConnectionTime);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +66,28 @@ namespace SharedLibraryCore
|
||||
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)
|
||||
{
|
||||
String lookingFor = str.ToLower();
|
||||
|
@ -37,6 +37,8 @@ namespace WebfrontCore.Controllers
|
||||
SocialLink = Manager.GetApplicationSettings().Configuration().SocialLinkAddress;
|
||||
SocialTitle = Manager.GetApplicationSettings().Configuration().SocialLinkTitle;
|
||||
}
|
||||
|
||||
ViewBag.Version = Manager.Version;
|
||||
}
|
||||
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
|
@ -38,7 +38,7 @@
|
||||
<li class="nav-item text-center text-md-left">@Html.ActionLink(loc["WEBFRONT_NAV_HOME"], "Index", "Home", new { area = "" }, new { @class = "nav-link" })</li>
|
||||
<li class="nav-item text-center text-md-left">@Html.ActionLink(loc["WEBFRONT_NAV_PENALTIES"], "List", "Penalty", new { area = "" }, new { @class = "nav-link" })</li>
|
||||
<li class="nav-item text-center text-md-left">@Html.ActionLink(loc["WEBFRONT_NAV_PRIVILEGED"], "PrivilegedAsync", "Client", new { area = "" }, new { @class = "nav-link" })</li>
|
||||
@foreach (var _page in ViewBag.Pages)
|
||||
@foreach (var _page in ViewBag.Pages)
|
||||
{
|
||||
<li class="nav-item text-center text-md-left">
|
||||
<a class="nav-link" href="@_page.Location">@_page.Name</a>
|
||||
@ -56,20 +56,20 @@
|
||||
|
||||
<div class="dropdown-menu p-0" aria-labelledby="account_dropdown">
|
||||
@Html.ActionLink(loc["WEBFRONT_NAV_CONSOLE"], "Index", "Console", new { area = "" }, new
|
||||
{
|
||||
@class = "dropdown-item bg-dark text-muted text-center text-md-left",
|
||||
title = "Web Console"
|
||||
})
|
||||
{
|
||||
@class = "dropdown-item bg-dark text-muted text-center text-md-left",
|
||||
title = "Web Console"
|
||||
})
|
||||
@Html.ActionLink(loc["WEBFRONT_NAV_PROFILE"], "ProfileAsync", "Client", new { id = ViewBag.User.ClientId }, new
|
||||
{
|
||||
@class = "dropdown-item bg-dark text-muted text-center text-md-left",
|
||||
title = "Client Profile",
|
||||
})
|
||||
{
|
||||
@class = "dropdown-item bg-dark text-muted text-center text-md-left",
|
||||
title = "Client Profile",
|
||||
})
|
||||
@Html.ActionLink(loc["WEBFRONT_NAV_LOGOUT"], "LogoutAsync", "Account", new { area = "" }, new
|
||||
{
|
||||
@class = "dropdown-item bg-dark text-muted text-center text-md-left",
|
||||
title = "Logout of account"
|
||||
})
|
||||
{
|
||||
@class = "dropdown-item bg-dark text-muted text-center text-md-left",
|
||||
title = "Logout of account"
|
||||
})
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item text-center text-md-left"></li>
|
||||
@ -135,7 +135,22 @@
|
||||
|
||||
<div class="container p-4">
|
||||
@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>
|
||||
<environment include="Development">
|
||||
<script type="text/javascript" src="~/lib/jQuery/dist/jquery.js"></script>
|
||||
|
@ -6409,3 +6409,11 @@ form *, select {
|
||||
.client-message, .automated-penalty-info-detailed {
|
||||
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 {
|
||||
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 :(
|
||||
playerHistory.forEach(function (item, i) {
|
||||
@ -29,6 +29,7 @@
|
||||
lineThickness: 0,
|
||||
tickThickness: 0,
|
||||
minimum: 0,
|
||||
maximum: maxClients + 1,
|
||||
margin: 0,
|
||||
valueFormatString: " ",
|
||||
labelMaxWidth: 0
|
||||
@ -53,9 +54,10 @@ var charts = {};
|
||||
$('.server-history-row').each(function (index, element) {
|
||||
let clientHistory = $(this).data('clienthistory');
|
||||
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 width = $('.server-header').first().width();
|
||||
let historyChart = getPlayerHistoryChart(clientHistory, serverId, width, color);
|
||||
let historyChart = getPlayerHistoryChart(clientHistory, serverId, width, color, maxClients);
|
||||
historyChart.render();
|
||||
charts[serverId] = historyChart;
|
||||
});
|
||||
@ -82,7 +84,7 @@ function refreshClientActivity() {
|
||||
$('#server_clientactivity_' + serverId).html(response);
|
||||
})
|
||||
.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…
Reference in New Issue
Block a user