update project to .net core 2.1.5
got rid of "threadsafe" stats service in stats plugin
This commit is contained in:
parent
c8366a22e5
commit
b289917319
@ -3,9 +3,10 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>2.1.5</RuntimeFrameworkVersion>
|
||||||
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
|
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
|
||||||
<PackageId>RaidMax.IW4MAdmin.Application</PackageId>
|
<PackageId>RaidMax.IW4MAdmin.Application</PackageId>
|
||||||
<Version>2.1.9.4</Version>
|
<Version>2.1.9.5</Version>
|
||||||
<Authors>RaidMax</Authors>
|
<Authors>RaidMax</Authors>
|
||||||
<Company>Forever None</Company>
|
<Company>Forever None</Company>
|
||||||
<Product>IW4MAdmin</Product>
|
<Product>IW4MAdmin</Product>
|
||||||
@ -30,8 +31,8 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ServerGarbageCollection>true</ServerGarbageCollection>
|
<ServerGarbageCollection>true</ServerGarbageCollection>
|
||||||
<TieredCompilation>true</TieredCompilation>
|
<TieredCompilation>true</TieredCompilation>
|
||||||
<AssemblyVersion>2.1.9.4</AssemblyVersion>
|
<AssemblyVersion>2.1.9.5</AssemblyVersion>
|
||||||
<FileVersion>2.1.9.4</FileVersion>
|
<FileVersion>2.1.9.5</FileVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -78,7 +79,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Update="Microsoft.NETCore.App" />
|
<PackageReference Update="Microsoft.NETCore.App" Version="2.1.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
|
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
|
||||||
|
@ -20,11 +20,37 @@ namespace IW4MAdmin.Application
|
|||||||
|
|
||||||
readonly string FileName;
|
readonly string FileName;
|
||||||
readonly SemaphoreSlim OnLogWriting;
|
readonly SemaphoreSlim OnLogWriting;
|
||||||
|
static readonly short MAX_LOG_FILES = 10;
|
||||||
|
|
||||||
public Logger(string fn)
|
public Logger(string fn)
|
||||||
{
|
{
|
||||||
FileName = Path.Join("Log", $"{fn}-{DateTime.Now.ToString("yyyyMMddHHmmssffff")}.log");
|
FileName = Path.Join("Log", $"{fn}.log");
|
||||||
OnLogWriting = new SemaphoreSlim(1,1);
|
OnLogWriting = new SemaphoreSlim(1, 1);
|
||||||
|
RotateLogs();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// rotates logs when log is initialized
|
||||||
|
/// </summary>
|
||||||
|
private void RotateLogs()
|
||||||
|
{
|
||||||
|
string maxLog = FileName + MAX_LOG_FILES;
|
||||||
|
|
||||||
|
if (File.Exists(maxLog))
|
||||||
|
{
|
||||||
|
File.Delete(maxLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = MAX_LOG_FILES - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
string logToMove = i == 0 ? FileName : FileName + i;
|
||||||
|
string movedLogName = FileName + (i + 1);
|
||||||
|
|
||||||
|
if (File.Exists(logToMove))
|
||||||
|
{
|
||||||
|
File.Move(logToMove, movedLogName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Write(string msg, LogType type)
|
void Write(string msg, LogType type)
|
||||||
@ -41,17 +67,25 @@ namespace IW4MAdmin.Application
|
|||||||
catch (Exception) { }
|
catch (Exception) { }
|
||||||
|
|
||||||
string LogLine = $"[{DateTime.Now.ToString("MM.dd.yyy HH:mm:ss.fff")}] - {stringType}: {msg}";
|
string LogLine = $"[{DateTime.Now.ToString("MM.dd.yyy HH:mm:ss.fff")}] - {stringType}: {msg}";
|
||||||
|
try
|
||||||
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
// lets keep it simple and dispose of everything quickly as logging wont be that much (relatively)
|
// lets keep it simple and dispose of everything quickly as logging wont be that much (relatively)
|
||||||
|
Console.WriteLine(LogLine);
|
||||||
Console.WriteLine(LogLine);
|
File.AppendAllText(FileName, LogLine + Environment.NewLine);
|
||||||
File.AppendAllText(FileName, LogLine + Environment.NewLine);
|
|
||||||
#else
|
#else
|
||||||
if (type == LogType.Error || type == LogType.Verbose)
|
if (type == LogType.Error || type == LogType.Verbose)
|
||||||
Console.WriteLine(LogLine);
|
Console.WriteLine(LogLine);
|
||||||
//if (type != LogType.Debug)
|
//if (type != LogType.Debug)
|
||||||
File.AppendAllText(FileName, $"{LogLine}{Environment.NewLine}");
|
File.AppendAllText(FileName, $"{LogLine}{Environment.NewLine}");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Well.. It looks like your machine can't event write to the log file. That's something else...");
|
||||||
|
Console.WriteLine(ex.GetExceptionInfo());
|
||||||
|
}
|
||||||
|
|
||||||
OnLogWriting.Release(1);
|
OnLogWriting.Release(1);
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ namespace IW4MAdmin.Application
|
|||||||
var consoleTask = Task.Run(async () =>
|
var consoleTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
String userInput;
|
String userInput;
|
||||||
Player Origin = Utilities.IW4MAdminClient;
|
Player Origin = Utilities.IW4MAdminClient(ServerManager.Servers[0]);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -123,7 +123,6 @@ namespace IW4MAdmin.Application
|
|||||||
|
|
||||||
if (userInput?.Length > 0)
|
if (userInput?.Length > 0)
|
||||||
{
|
{
|
||||||
Origin.CurrentServer = ServerManager.Servers[0];
|
|
||||||
GameEvent E = new GameEvent()
|
GameEvent E = new GameEvent()
|
||||||
{
|
{
|
||||||
Type = GameEvent.EventType.Command,
|
Type = GameEvent.EventType.Command,
|
||||||
|
@ -205,8 +205,7 @@ namespace IW4MAdmin
|
|||||||
if (currentBan != null)
|
if (currentBan != null)
|
||||||
{
|
{
|
||||||
Logger.WriteInfo($"Banned client {player} trying to connect...");
|
Logger.WriteInfo($"Banned client {player} trying to connect...");
|
||||||
var autoKickClient = Utilities.IW4MAdminClient;
|
var autoKickClient = Utilities.IW4MAdminClient(this);
|
||||||
autoKickClient.CurrentServer = this;
|
|
||||||
|
|
||||||
// the player is permanently banned
|
// the player is permanently banned
|
||||||
if (currentBan.Type == Penalty.PenaltyType.Ban)
|
if (currentBan.Type == Penalty.PenaltyType.Ban)
|
||||||
@ -911,7 +910,7 @@ namespace IW4MAdmin
|
|||||||
{
|
{
|
||||||
if (Target.Warnings >= 4)
|
if (Target.Warnings >= 4)
|
||||||
{
|
{
|
||||||
Target.Kick(loc["SERVER_WARNLIMT_REACHED"], Utilities.IW4MAdminClient);
|
Target.Kick(loc["SERVER_WARNLIMT_REACHED"], Utilities.IW4MAdminClient(this));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>2.1.5</RuntimeFrameworkVersion>
|
||||||
<ApplicationIcon />
|
<ApplicationIcon />
|
||||||
<StartupObject />
|
<StartupObject />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@ -17,7 +18,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Update="Microsoft.NETCore.App"/>
|
<PackageReference Update="Microsoft.NETCore.App" Version="2.1.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>2.1.5</RuntimeFrameworkVersion>
|
||||||
<ApplicationIcon />
|
<ApplicationIcon />
|
||||||
<StartupObject />
|
<StartupObject />
|
||||||
<PackageId>RaidMax.IW4MAdmin.Plugins.Login</PackageId>
|
<PackageId>RaidMax.IW4MAdmin.Plugins.Login</PackageId>
|
||||||
@ -21,7 +22,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Update="Microsoft.NETCore.App"/>
|
<PackageReference Update="Microsoft.NETCore.App" Version="2.1.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>2.1.5</RuntimeFrameworkVersion>
|
||||||
<ApplicationIcon />
|
<ApplicationIcon />
|
||||||
<StartupObject />
|
<StartupObject />
|
||||||
<PackageId>RaidMax.IW4MAdmin.Plugins.ProfanityDeterment</PackageId>
|
<PackageId>RaidMax.IW4MAdmin.Plugins.ProfanityDeterment</PackageId>
|
||||||
@ -19,7 +20,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Update="Microsoft.NETCore.App"/>
|
<PackageReference Update="Microsoft.NETCore.App" Version="2.1.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
@ -28,7 +28,6 @@ var plugin = {
|
|||||||
var re = cl.GetAsync('https://api.xdefcon.com/proxy/check/?ip=' + origin.IPAddressString).Result;
|
var re = cl.GetAsync('https://api.xdefcon.com/proxy/check/?ip=' + origin.IPAddressString).Result;
|
||||||
var co = re.Content;
|
var co = re.Content;
|
||||||
var parsedJSON = JSON.parse(co.ReadAsStringAsync().Result);
|
var parsedJSON = JSON.parse(co.ReadAsStringAsync().Result);
|
||||||
// todo: does this work as expected now?
|
|
||||||
co.Dispose();
|
co.Dispose();
|
||||||
re.Dispose();
|
re.Dispose();
|
||||||
cl.Dispose();
|
cl.Dispose();
|
||||||
@ -39,11 +38,7 @@ var plugin = {
|
|||||||
|
|
||||||
if (usingVPN) {
|
if (usingVPN) {
|
||||||
this.logger.WriteInfo(origin + ' is using a VPN (' + origin.IPAddressString + ')');
|
this.logger.WriteInfo(origin + ' is using a VPN (' + origin.IPAddressString + ')');
|
||||||
var library = importNamespace('SharedLibraryCore');
|
origin.Kick(_localization.LocalizationIndex["SERVER_KICK_VPNS_NOTALLOWED"], _IW4MAdminClient);
|
||||||
var kickOrigin = new library.Objects.Player();
|
|
||||||
kickOrigin.ClientId = 1;
|
|
||||||
kickOrigin.CurrentServer = origin.CurrentServer;
|
|
||||||
origin.Kick(_localization.LocalizationIndex["SERVER_KICK_VPNS_NOTALLOWED"], kickOrigin);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using SharedLibraryCore.Database;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace IW4MAdmin.Plugins.Stats.Commands
|
namespace IW4MAdmin.Plugins.Stats.Commands
|
||||||
{
|
{
|
||||||
@ -17,23 +19,30 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
|||||||
{
|
{
|
||||||
if (E.Origin.ClientNumber >= 0)
|
if (E.Origin.ClientNumber >= 0)
|
||||||
{
|
{
|
||||||
var svc = new SharedLibraryCore.Services.GenericRepository<EFClientStatistics>();
|
|
||||||
int serverId = E.Owner.GetHashCode();
|
int serverId = E.Owner.GetHashCode();
|
||||||
var stats = svc.Find(s => s.ClientId == E.Origin.ClientId && s.ServerId == serverId).First();
|
|
||||||
|
|
||||||
stats.Deaths = 0;
|
EFClientStatistics clientStats;
|
||||||
stats.Kills = 0;
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
stats.SPM = 0.0;
|
{
|
||||||
stats.Skill = 0.0;
|
clientStats = await ctx.Set<EFClientStatistics>()
|
||||||
stats.TimePlayed = 0;
|
.Where(s => s.ClientId == E.Origin.ClientId && s.ServerId == serverId)
|
||||||
// todo: make this more dynamic
|
.FirstAsync();
|
||||||
stats.EloRating = 200.0;
|
|
||||||
|
|
||||||
// reset the cached version
|
clientStats.Deaths = 0;
|
||||||
Plugin.Manager.ResetStats(E.Origin.ClientId, E.Owner.GetHashCode());
|
clientStats.Kills = 0;
|
||||||
|
clientStats.SPM = 0.0;
|
||||||
|
clientStats.Skill = 0.0;
|
||||||
|
clientStats.TimePlayed = 0;
|
||||||
|
// todo: make this more dynamic
|
||||||
|
clientStats.EloRating = 200.0;
|
||||||
|
|
||||||
// fixme: this doesn't work properly when another context exists
|
// reset the cached version
|
||||||
await svc.SaveChangesAsync();
|
Plugin.Manager.ResetStats(E.Origin.ClientId, E.Owner.GetHashCode());
|
||||||
|
|
||||||
|
// fixme: this doesn't work properly when another context exists
|
||||||
|
await ctx.SaveChangesAsync();
|
||||||
|
}
|
||||||
E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_RESET_SUCCESS"]);
|
E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_RESET_SUCCESS"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using SharedLibraryCore.Database;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace IW4MAdmin.Plugins.Stats.Commands
|
namespace IW4MAdmin.Plugins.Stats.Commands
|
||||||
{
|
{
|
||||||
@ -39,19 +41,21 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var clientStats = new GenericRepository<EFClientStatistics>();
|
|
||||||
int serverId = E.Owner.GetHashCode();
|
int serverId = E.Owner.GetHashCode();
|
||||||
|
|
||||||
if (E.Target != null)
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
{
|
{
|
||||||
pStats = (await clientStats.FindAsync(c => c.ServerId == serverId && c.ClientId == E.Target.ClientId)).First();
|
if (E.Target != null)
|
||||||
statLine = $"^5{pStats.Kills} ^7{loc["PLUGINS_STATS_TEXT_KILLS"]} | ^5{pStats.Deaths} ^7{loc["PLUGINS_STATS_TEXT_DEATHS"]} | ^5{pStats.KDR} ^7KDR | ^5{pStats.Performance} ^7{loc["PLUGINS_STATS_COMMANDS_PERFORMANCE"].ToUpper()}";
|
{
|
||||||
}
|
pStats = (await ctx.Set<EFClientStatistics>().FirstAsync(c => c.ServerId == serverId && c.ClientId == E.Target.ClientId));
|
||||||
|
statLine = $"^5{pStats.Kills} ^7{loc["PLUGINS_STATS_TEXT_KILLS"]} | ^5{pStats.Deaths} ^7{loc["PLUGINS_STATS_TEXT_DEATHS"]} | ^5{pStats.KDR} ^7KDR | ^5{pStats.Performance} ^7{loc["PLUGINS_STATS_COMMANDS_PERFORMANCE"].ToUpper()}";
|
||||||
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pStats = (await clientStats.FindAsync(c => c.ServerId == serverId && c.ClientId == E.Origin.ClientId)).First();
|
pStats = (await ctx.Set<EFClientStatistics>().FirstAsync((c => c.ServerId == serverId && c.ClientId == E.Origin.ClientId)));
|
||||||
statLine = $"^5{pStats.Kills} ^7{loc["PLUGINS_STATS_TEXT_KILLS"]} | ^5{pStats.Deaths} ^7{loc["PLUGINS_STATS_TEXT_DEATHS"]} | ^5{pStats.KDR} ^7KDR | ^5{pStats.Performance} ^7{loc["PLUGINS_STATS_COMMANDS_PERFORMANCE"].ToUpper()}";
|
statLine = $"^5{pStats.Kills} ^7{loc["PLUGINS_STATS_TEXT_KILLS"]} | ^5{pStats.Deaths} ^7{loc["PLUGINS_STATS_TEXT_DEATHS"]} | ^5{pStats.KDR} ^7KDR | ^5{pStats.Performance} ^7{loc["PLUGINS_STATS_COMMANDS_PERFORMANCE"].ToUpper()}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (E.Message.IsBroadcastCommand())
|
if (E.Message.IsBroadcastCommand())
|
||||||
|
@ -24,20 +24,20 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
public class StatManager
|
public class StatManager
|
||||||
{
|
{
|
||||||
private ConcurrentDictionary<int, ServerStats> Servers;
|
private ConcurrentDictionary<int, ServerStats> Servers;
|
||||||
private ConcurrentDictionary<int, ThreadSafeStatsService> ContextThreads;
|
|
||||||
private ILogger Log;
|
private ILogger Log;
|
||||||
private IManager Manager;
|
private readonly IManager Manager;
|
||||||
|
|
||||||
|
|
||||||
private readonly SemaphoreSlim OnProcessingPenalty;
|
private readonly SemaphoreSlim OnProcessingPenalty;
|
||||||
|
private readonly SemaphoreSlim OnProcessingSensitive;
|
||||||
|
|
||||||
public StatManager(IManager mgr)
|
public StatManager(IManager mgr)
|
||||||
{
|
{
|
||||||
Servers = new ConcurrentDictionary<int, ServerStats>();
|
Servers = new ConcurrentDictionary<int, ServerStats>();
|
||||||
ContextThreads = new ConcurrentDictionary<int, ThreadSafeStatsService>();
|
|
||||||
Log = mgr.GetLogger(0);
|
Log = mgr.GetLogger(0);
|
||||||
Manager = mgr;
|
Manager = mgr;
|
||||||
OnProcessingPenalty = new SemaphoreSlim(1, 1);
|
OnProcessingPenalty = new SemaphoreSlim(1, 1);
|
||||||
|
OnProcessingSensitive = new SemaphoreSlim(1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EFClientStatistics GetClientStats(int clientId, int serverId) => Servers[serverId].PlayerStats[clientId];
|
public EFClientStatistics GetClientStats(int clientId, int serverId) => Servers[serverId].PlayerStats[clientId];
|
||||||
@ -188,36 +188,36 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
/// <param name="sv"></param>
|
/// <param name="sv"></param>
|
||||||
public void AddServer(Server sv)
|
public void AddServer(Server sv)
|
||||||
{
|
{
|
||||||
|
// insert the server if it does not exist
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int serverId = sv.GetHashCode();
|
int serverId = sv.GetHashCode();
|
||||||
var statsSvc = new ThreadSafeStatsService();
|
EFServer server;
|
||||||
ContextThreads.TryAdd(serverId, statsSvc);
|
|
||||||
|
|
||||||
var serverSvc = statsSvc.ServerSvc;
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
|
|
||||||
// get the server from the database if it exists, otherwise create and insert a new one
|
|
||||||
var server = statsSvc.ServerSvc.Find(c => c.ServerId == serverId).FirstOrDefault();
|
|
||||||
|
|
||||||
if (server == null)
|
|
||||||
{
|
{
|
||||||
server = new EFServer()
|
var serverSet = ctx.Set<EFServer>();
|
||||||
{
|
// get the server from the database if it exists, otherwise create and insert a new one
|
||||||
Port = sv.GetPort(),
|
server = serverSet.FirstOrDefault(c => c.ServerId == serverId);
|
||||||
Active = true,
|
|
||||||
ServerId = serverId
|
|
||||||
};
|
|
||||||
|
|
||||||
serverSvc.Insert(server);
|
if (server == null)
|
||||||
|
{
|
||||||
|
server = new EFServer()
|
||||||
|
{
|
||||||
|
Port = sv.GetPort(),
|
||||||
|
Active = true,
|
||||||
|
ServerId = serverId
|
||||||
|
};
|
||||||
|
|
||||||
|
server = serverSet.Add(server).Entity;
|
||||||
|
// this doesn't need to be async as it's during initialization
|
||||||
|
ctx.SaveChanges();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this doesn't need to be async as it's during initialization
|
|
||||||
serverSvc.SaveChanges();
|
|
||||||
// check to see if the stats have ever been initialized
|
// check to see if the stats have ever been initialized
|
||||||
InitializeServerStats(sv);
|
var serverStats = InitializeServerStats(sv);
|
||||||
statsSvc.ServerStatsSvc.SaveChanges();
|
|
||||||
|
|
||||||
var serverStats = statsSvc.ServerStatsSvc.Find(c => c.ServerId == serverId).FirstOrDefault();
|
|
||||||
Servers.TryAdd(serverId, new ServerStats(server, serverStats)
|
Servers.TryAdd(serverId, new ServerStats(server, serverStats)
|
||||||
{
|
{
|
||||||
IsTeamBased = sv.Gametype != "dm"
|
IsTeamBased = sv.Gametype != "dm"
|
||||||
@ -237,106 +237,134 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
/// <returns>EFClientStatistic of specified player</returns>
|
/// <returns>EFClientStatistic of specified player</returns>
|
||||||
public async Task<EFClientStatistics> AddPlayer(Player pl)
|
public async Task<EFClientStatistics> AddPlayer(Player pl)
|
||||||
{
|
{
|
||||||
int serverId = pl.CurrentServer.GetHashCode();
|
await OnProcessingSensitive.WaitAsync();
|
||||||
|
|
||||||
if (!Servers.ContainsKey(serverId))
|
try
|
||||||
{
|
{
|
||||||
Log.WriteError($"[Stats::AddPlayer] Server with id {serverId} could not be found");
|
int serverId = pl.CurrentServer.GetHashCode();
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var playerStats = Servers[serverId].PlayerStats;
|
|
||||||
var detectionStats = Servers[serverId].PlayerDetections;
|
|
||||||
var statsSvc = ContextThreads[serverId];
|
|
||||||
|
|
||||||
if (playerStats.ContainsKey(pl.ClientId))
|
if (!Servers.ContainsKey(serverId))
|
||||||
{
|
|
||||||
Log.WriteWarning($"Duplicate ClientId in stats {pl.ClientId}");
|
|
||||||
return playerStats[pl.ClientId];
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the client's stats from the database if it exists, otherwise create and attach a new one
|
|
||||||
// if this fails we want to throw an exception
|
|
||||||
var clientStatsSvc = statsSvc.ClientStatSvc;
|
|
||||||
var clientStats = clientStatsSvc.Find(c => c.ClientId == pl.ClientId && c.ServerId == serverId).FirstOrDefault();
|
|
||||||
|
|
||||||
if (clientStats == null)
|
|
||||||
{
|
|
||||||
clientStats = new EFClientStatistics()
|
|
||||||
{
|
{
|
||||||
Active = true,
|
Log.WriteError($"[Stats::AddPlayer] Server with id {serverId} could not be found");
|
||||||
ClientId = pl.ClientId,
|
return null;
|
||||||
Deaths = 0,
|
|
||||||
Kills = 0,
|
|
||||||
ServerId = serverId,
|
|
||||||
Skill = 0.0,
|
|
||||||
SPM = 0.0,
|
|
||||||
EloRating = 200.0,
|
|
||||||
HitLocations = Enum.GetValues(typeof(IW4Info.HitLocation)).OfType<IW4Info.HitLocation>().Select(hl => new EFHitLocationCount()
|
|
||||||
{
|
|
||||||
Active = true,
|
|
||||||
HitCount = 0,
|
|
||||||
Location = hl
|
|
||||||
}).ToList()
|
|
||||||
};
|
|
||||||
|
|
||||||
// insert if they've not been added
|
|
||||||
clientStats = clientStatsSvc.Insert(clientStats);
|
|
||||||
|
|
||||||
if (!playerStats.TryAdd(clientStats.ClientId, clientStats))
|
|
||||||
{
|
|
||||||
Log.WriteWarning("Adding new client to stats failed");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await clientStatsSvc.SaveChangesAsync();
|
var playerStats = Servers[serverId].PlayerStats;
|
||||||
}
|
var detectionStats = Servers[serverId].PlayerDetections;
|
||||||
|
|
||||||
else
|
if (playerStats.ContainsKey(pl.ClientId))
|
||||||
{
|
|
||||||
if (!playerStats.TryAdd(clientStats.ClientId, clientStats))
|
|
||||||
{
|
{
|
||||||
Log.WriteWarning("Adding pre-existing client to stats failed");
|
Log.WriteWarning($"Duplicate ClientId in stats {pl.ClientId}");
|
||||||
|
return playerStats[pl.ClientId];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// migration for previous existing stats
|
// get the client's stats from the database if it exists, otherwise create and attach a new one
|
||||||
if (clientStats.HitLocations.Count == 0)
|
// if this fails we want to throw an exception
|
||||||
{
|
|
||||||
clientStats.HitLocations = Enum.GetValues(typeof(IW4Info.HitLocation)).OfType<IW4Info.HitLocation>()
|
EFClientStatistics clientStats;
|
||||||
.Select(hl => new EFHitLocationCount()
|
|
||||||
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
|
{
|
||||||
|
var clientStatsSet = ctx.Set<EFClientStatistics>();
|
||||||
|
clientStats = clientStatsSet
|
||||||
|
.Include(cl => cl.HitLocations)
|
||||||
|
.FirstOrDefault(c => c.ClientId == pl.ClientId && c.ServerId == serverId);
|
||||||
|
|
||||||
|
if (clientStats == null)
|
||||||
{
|
{
|
||||||
Active = true,
|
clientStats = new EFClientStatistics()
|
||||||
HitCount = 0,
|
{
|
||||||
Location = hl
|
Active = true,
|
||||||
})
|
ClientId = pl.ClientId,
|
||||||
.ToList();
|
Deaths = 0,
|
||||||
await statsSvc.ClientStatSvc.SaveChangesAsync();
|
Kills = 0,
|
||||||
|
ServerId = serverId,
|
||||||
|
Skill = 0.0,
|
||||||
|
SPM = 0.0,
|
||||||
|
EloRating = 200.0,
|
||||||
|
HitLocations = Enum.GetValues(typeof(IW4Info.HitLocation)).OfType<IW4Info.HitLocation>().Select(hl => new EFHitLocationCount()
|
||||||
|
{
|
||||||
|
Active = true,
|
||||||
|
HitCount = 0,
|
||||||
|
Location = hl
|
||||||
|
}).ToList()
|
||||||
|
};
|
||||||
|
|
||||||
|
// insert if they've not been added
|
||||||
|
clientStats = clientStatsSet.Add(clientStats).Entity;
|
||||||
|
await ctx.SaveChangesAsync();
|
||||||
|
|
||||||
|
if (!playerStats.TryAdd(clientStats.ClientId, clientStats))
|
||||||
|
{
|
||||||
|
Log.WriteWarning("Adding new client to stats failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!playerStats.TryAdd(clientStats.ClientId, clientStats))
|
||||||
|
{
|
||||||
|
Log.WriteWarning("Adding pre-existing client to stats failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// migration for previous existing stats
|
||||||
|
if (clientStats.HitLocations.Count == 0)
|
||||||
|
{
|
||||||
|
clientStats.HitLocations = Enum.GetValues(typeof(IW4Info.HitLocation)).OfType<IW4Info.HitLocation>()
|
||||||
|
.Select(hl => new EFHitLocationCount()
|
||||||
|
{
|
||||||
|
Active = true,
|
||||||
|
HitCount = 0,
|
||||||
|
Location = hl
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
ctx.Update(clientStats);
|
||||||
|
await ctx.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
// for stats before rating
|
||||||
|
if (clientStats.EloRating == 0.0)
|
||||||
|
{
|
||||||
|
clientStats.EloRating = clientStats.Skill;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clientStats.RollingWeightedKDR == 0)
|
||||||
|
{
|
||||||
|
clientStats.RollingWeightedKDR = clientStats.KDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set these on connecting
|
||||||
|
clientStats.LastActive = DateTime.UtcNow;
|
||||||
|
clientStats.LastStatCalculation = DateTime.UtcNow;
|
||||||
|
clientStats.SessionScore = pl.Score;
|
||||||
|
clientStats.LastScore = pl.Score;
|
||||||
|
|
||||||
|
if (!detectionStats.TryAdd(pl.ClientId, new Cheat.Detection(Log, clientStats)))
|
||||||
|
{
|
||||||
|
Log.WriteWarning("Could not add client to detection");
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.WriteInfo($"Adding {pl} to stats");
|
||||||
|
}
|
||||||
|
|
||||||
|
return clientStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for stats before rating
|
catch (Exception ex)
|
||||||
if (clientStats.EloRating == 0.0)
|
|
||||||
{
|
{
|
||||||
clientStats.EloRating = clientStats.Skill;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clientStats.RollingWeightedKDR == 0)
|
finally
|
||||||
{
|
{
|
||||||
clientStats.RollingWeightedKDR = clientStats.KDR;
|
OnProcessingSensitive.Release(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set these on connecting
|
return null;
|
||||||
clientStats.LastActive = DateTime.UtcNow;
|
|
||||||
clientStats.LastStatCalculation = DateTime.UtcNow;
|
|
||||||
clientStats.SessionScore = pl.Score;
|
|
||||||
clientStats.LastScore = pl.Score;
|
|
||||||
|
|
||||||
if (!detectionStats.TryAdd(pl.ClientId, new Cheat.Detection(Log, clientStats)))
|
|
||||||
{
|
|
||||||
Log.WriteWarning("Could not add client to detection");
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.WriteInfo($"Adding {pl} to stats");
|
|
||||||
return clientStats;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -352,7 +380,6 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
var playerStats = Servers[serverId].PlayerStats;
|
var playerStats = Servers[serverId].PlayerStats;
|
||||||
var detectionStats = Servers[serverId].PlayerDetections;
|
var detectionStats = Servers[serverId].PlayerDetections;
|
||||||
var serverStats = Servers[serverId].ServerStatistics;
|
var serverStats = Servers[serverId].ServerStatistics;
|
||||||
var statsSvc = ContextThreads[serverId];
|
|
||||||
|
|
||||||
if (!playerStats.ContainsKey(pl.ClientId))
|
if (!playerStats.ContainsKey(pl.ClientId))
|
||||||
{
|
{
|
||||||
@ -371,10 +398,13 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
detectionStats.TryRemove(pl.ClientId, out Cheat.Detection removedValue4);
|
detectionStats.TryRemove(pl.ClientId, out Cheat.Detection removedValue4);
|
||||||
|
|
||||||
// sync their stats before they leave
|
// sync their stats before they leave
|
||||||
var clientStatsSvc = statsSvc.ClientStatSvc;
|
|
||||||
clientStats = UpdateStats(clientStats);
|
clientStats = UpdateStats(clientStats);
|
||||||
clientStatsSvc.Update(clientStats);
|
|
||||||
await clientStatsSvc.SaveChangesAsync();
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
|
{
|
||||||
|
ctx.Update(clientStats);
|
||||||
|
await ctx.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
// increment the total play time
|
// increment the total play time
|
||||||
serverStats.TotalPlayTime += (int)(DateTime.UtcNow - pl.LastConnection).TotalSeconds;
|
serverStats.TotalPlayTime += (int)(DateTime.UtcNow - pl.LastConnection).TotalSeconds;
|
||||||
@ -405,15 +435,6 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
string damage, string weapon, string killOrigin, string deathOrigin, string viewAngles, string offset, string isKillstreakKill, string Ads,
|
string damage, string weapon, string killOrigin, string deathOrigin, string viewAngles, string offset, string isKillstreakKill, string Ads,
|
||||||
string fraction, string visibilityPercentage, string snapAngles)
|
string fraction, string visibilityPercentage, string snapAngles)
|
||||||
{
|
{
|
||||||
var statsSvc = ContextThreads[serverId];
|
|
||||||
|
|
||||||
// incase the add palyer event get delayed
|
|
||||||
if (!Servers[serverId].PlayerStats.ContainsKey(attacker.ClientId))
|
|
||||||
{
|
|
||||||
await AddPlayer(attacker);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Vector3 vDeathOrigin = null;
|
Vector3 vDeathOrigin = null;
|
||||||
Vector3 vKillOrigin = null;
|
Vector3 vKillOrigin = null;
|
||||||
Vector3 vViewAngles = null;
|
Vector3 vViewAngles = null;
|
||||||
@ -490,10 +511,20 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// incase the add palyer event get delayed
|
||||||
|
if (!Servers[serverId].PlayerStats.ContainsKey(attacker.ClientId))
|
||||||
|
{
|
||||||
|
await AddPlayer(attacker);
|
||||||
|
}
|
||||||
|
|
||||||
var clientDetection = Servers[serverId].PlayerDetections[attacker.ClientId];
|
var clientDetection = Servers[serverId].PlayerDetections[attacker.ClientId];
|
||||||
var clientStats = Servers[serverId].PlayerStats[attacker.ClientId];
|
var clientStats = Servers[serverId].PlayerStats[attacker.ClientId];
|
||||||
var clientStatsSvc = statsSvc.ClientStatSvc;
|
|
||||||
clientStatsSvc.Update(clientStats);
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
|
{
|
||||||
|
ctx.Set<EFClientStatistics>().Update(clientStats);
|
||||||
|
await ctx.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
// increment their hit count
|
// increment their hit count
|
||||||
if (hit.DeathType == IW4Info.MeansOfDeath.MOD_PISTOL_BULLET ||
|
if (hit.DeathType == IW4Info.MeansOfDeath.MOD_PISTOL_BULLET ||
|
||||||
@ -531,17 +562,6 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
Log.WriteDebug(ex.GetExceptionInfo());
|
Log.WriteDebug(ex.GetExceptionInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await clientStatsSvc.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.WriteError("Could save save client stats");
|
|
||||||
Log.WriteDebug(ex.GetExceptionInfo());
|
|
||||||
}
|
|
||||||
|
|
||||||
OnProcessingPenalty.Release(1);
|
OnProcessingPenalty.Release(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -743,10 +763,14 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// todo: do we want to save this immediately?
|
// todo: do we want to save this immediately?
|
||||||
var clientStatsSvc = ContextThreads[serverId].ClientStatSvc;
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
clientStatsSvc.Update(attackerStats);
|
{
|
||||||
clientStatsSvc.Update(victimStats);
|
var clientStatsSet = ctx.Set<EFClientStatistics>();
|
||||||
await clientStatsSvc.SaveChangesAsync();
|
|
||||||
|
clientStatsSet.Update(attackerStats);
|
||||||
|
clientStatsSet.Update(victimStats);
|
||||||
|
await ctx.SaveChangesAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1079,39 +1103,43 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
return clientStats;
|
return clientStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitializeServerStats(Server sv)
|
public EFServerStatistics InitializeServerStats(Server sv)
|
||||||
{
|
{
|
||||||
int serverId = sv.GetHashCode();
|
int serverId = sv.GetHashCode();
|
||||||
var statsSvc = ContextThreads[serverId];
|
EFServerStatistics serverStats;
|
||||||
|
|
||||||
var serverStats = statsSvc.ServerStatsSvc.Find(s => s.ServerId == serverId).FirstOrDefault();
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
if (serverStats == null)
|
|
||||||
{
|
{
|
||||||
Log.WriteDebug($"Initializing server stats for {sv}");
|
var serverStatsSet = ctx.Set<EFServerStatistics>();
|
||||||
// server stats have never been generated before
|
serverStats = serverStatsSet.FirstOrDefault(s => s.ServerId == serverId);
|
||||||
serverStats = new EFServerStatistics()
|
|
||||||
|
if (serverStats == null)
|
||||||
{
|
{
|
||||||
Active = true,
|
Log.WriteDebug($"Initializing server stats for {sv}");
|
||||||
ServerId = serverId,
|
// server stats have never been generated before
|
||||||
TotalKills = 0,
|
serverStats = new EFServerStatistics()
|
||||||
TotalPlayTime = 0,
|
{
|
||||||
};
|
ServerId = serverId,
|
||||||
|
TotalKills = 0,
|
||||||
|
TotalPlayTime = 0,
|
||||||
|
};
|
||||||
|
|
||||||
var ieClientStats = statsSvc.ClientStatSvc.Find(cs => cs.ServerId == serverId);
|
serverStats = serverStatsSet.Add(serverStats).Entity;
|
||||||
|
ctx.SaveChanges();
|
||||||
// set these incase we've imported settings
|
}
|
||||||
serverStats.TotalKills = ieClientStats.Sum(cs => cs.Kills);
|
|
||||||
serverStats.TotalPlayTime = Manager.GetClientService().GetTotalPlayTime().Result;
|
|
||||||
|
|
||||||
statsSvc.ServerStatsSvc.Insert(serverStats);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return serverStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetKillstreaks(int serverId)
|
public void ResetKillstreaks(int serverId)
|
||||||
{
|
{
|
||||||
var serverStats = Servers[serverId];
|
var serverStats = Servers[serverId];
|
||||||
|
|
||||||
foreach (var stat in serverStats.PlayerStats.Values)
|
foreach (var stat in serverStats.PlayerStats.Values)
|
||||||
|
{
|
||||||
stat.StartNewSession();
|
stat.StartNewSession();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetStats(int clientId, int serverId)
|
public void ResetStats(int clientId, int serverId)
|
||||||
@ -1131,33 +1159,30 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
if (clientId < 1)
|
if (clientId < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var messageSvc = ContextThreads[serverId].MessageSvc;
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
messageSvc.Insert(new EFClientMessage()
|
|
||||||
{
|
{
|
||||||
Active = true,
|
ctx.Set<EFClientMessage>().Add(new EFClientMessage()
|
||||||
ClientId = clientId,
|
{
|
||||||
Message = message,
|
ClientId = clientId,
|
||||||
ServerId = serverId,
|
Message = message,
|
||||||
TimeSent = DateTime.UtcNow
|
ServerId = serverId,
|
||||||
});
|
TimeSent = DateTime.UtcNow
|
||||||
await messageSvc.SaveChangesAsync();
|
});
|
||||||
|
|
||||||
|
await ctx.SaveChangesAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Sync(Server sv)
|
public async Task Sync(Server sv)
|
||||||
{
|
{
|
||||||
int serverId = sv.GetHashCode();
|
int serverId = sv.GetHashCode();
|
||||||
var statsSvc = ContextThreads[serverId];
|
|
||||||
var serverSvc = statsSvc.ServerSvc;
|
|
||||||
|
|
||||||
serverSvc.Update(Servers[serverId].Server);
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
await serverSvc.SaveChangesAsync();
|
{
|
||||||
|
var serverSet = ctx.Set<EFServer>();
|
||||||
await statsSvc.KillStatsSvc.SaveChangesAsync();
|
serverSet.Update(Servers[serverId].Server);
|
||||||
await statsSvc.ServerSvc.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
|
}
|
||||||
statsSvc = null;
|
|
||||||
// this should prevent the gunk from having a long lasting context.
|
|
||||||
ContextThreads[serverId] = new ThreadSafeStatsService();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetTeamBased(int serverId, bool isTeamBased)
|
public void SetTeamBased(int serverId, bool isTeamBased)
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
using SharedLibraryCore.Services;
|
|
||||||
using IW4MAdmin.Plugins.Stats.Models;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace IW4MAdmin.Plugins.Stats.Helpers
|
|
||||||
{
|
|
||||||
public class ThreadSafeStatsService
|
|
||||||
{
|
|
||||||
public GenericRepository<EFClientStatistics> ClientStatSvc
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return new GenericRepository<EFClientStatistics>(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public GenericRepository<EFServer> ServerSvc
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return new GenericRepository<EFServer>(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public GenericRepository<EFClientKill> KillStatsSvc { get; private set; }
|
|
||||||
public GenericRepository<EFServerStatistics> ServerStatsSvc { get; private set; }
|
|
||||||
public GenericRepository<EFClientMessage> MessageSvc
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return new GenericRepository<EFClientMessage>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ThreadSafeStatsService()
|
|
||||||
{
|
|
||||||
KillStatsSvc = new GenericRepository<EFClientKill>();
|
|
||||||
ServerStatsSvc = new GenericRepository<EFServerStatistics>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,6 +13,8 @@ using SharedLibraryCore.Services;
|
|||||||
using IW4MAdmin.Plugins.Stats.Config;
|
using IW4MAdmin.Plugins.Stats.Config;
|
||||||
using IW4MAdmin.Plugins.Stats.Helpers;
|
using IW4MAdmin.Plugins.Stats.Helpers;
|
||||||
using IW4MAdmin.Plugins.Stats.Models;
|
using IW4MAdmin.Plugins.Stats.Models;
|
||||||
|
using SharedLibraryCore.Database;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace IW4MAdmin.Plugins.Stats
|
namespace IW4MAdmin.Plugins.Stats
|
||||||
{
|
{
|
||||||
@ -122,8 +124,11 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
// meta data info
|
// meta data info
|
||||||
async Task<List<ProfileMeta>> getStats(int clientId)
|
async Task<List<ProfileMeta>> getStats(int clientId)
|
||||||
{
|
{
|
||||||
var statsSvc = new GenericRepository<EFClientStatistics>();
|
IList<EFClientStatistics> clientStats;
|
||||||
var clientStats = await statsSvc.FindAsync(c => c.ClientId == clientId);
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
|
{
|
||||||
|
clientStats = await ctx.Set<EFClientStatistics>().Where(c => c.ClientId == clientId).ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
int kills = clientStats.Sum(c => c.Kills);
|
int kills = clientStats.Sum(c => c.Kills);
|
||||||
int deaths = clientStats.Sum(c => c.Deaths);
|
int deaths = clientStats.Sum(c => c.Deaths);
|
||||||
@ -170,8 +175,14 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
|
|
||||||
async Task<List<ProfileMeta>> getAnticheatInfo(int clientId)
|
async Task<List<ProfileMeta>> getAnticheatInfo(int clientId)
|
||||||
{
|
{
|
||||||
var statsSvc = new GenericRepository<EFClientStatistics>();
|
IList<EFClientStatistics> clientStats;
|
||||||
var clientStats = await statsSvc.FindAsync(c => c.ClientId == clientId);
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
|
{
|
||||||
|
clientStats = await ctx.Set<EFClientStatistics>()
|
||||||
|
.Include(c => c.HitLocations)
|
||||||
|
.Where(c => c.ClientId == clientId)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
double headRatio = 0;
|
double headRatio = 0;
|
||||||
double chestRatio = 0;
|
double chestRatio = 0;
|
||||||
@ -246,19 +257,24 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
|
|
||||||
async Task<List<ProfileMeta>> getMessages(int clientId)
|
async Task<List<ProfileMeta>> getMessages(int clientId)
|
||||||
{
|
{
|
||||||
var messageSvc = new GenericRepository<EFClientMessage>();
|
List<ProfileMeta> messageMeta;
|
||||||
var messages = await messageSvc.FindAsync(m => m.ClientId == clientId);
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
var messageMeta = messages.Select(m => new ProfileMeta()
|
|
||||||
{
|
{
|
||||||
Key = "EventMessage",
|
var messages = ctx.Set<EFClientMessage>().Where(m => m.ClientId == clientId);
|
||||||
Value = m.Message,
|
|
||||||
When = m.TimeSent,
|
messageMeta = await messages.Select(m => new ProfileMeta()
|
||||||
Extra = m.ServerId.ToString()
|
{
|
||||||
}).ToList();
|
Key = "EventMessage",
|
||||||
|
Value = m.Message,
|
||||||
|
When = m.TimeSent,
|
||||||
|
Extra = m.ServerId.ToString()
|
||||||
|
}).ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
messageMeta.Add(new ProfileMeta()
|
messageMeta.Add(new ProfileMeta()
|
||||||
{
|
{
|
||||||
Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_MESSAGES"],
|
Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_MESSAGES"],
|
||||||
Value = messages.Count
|
Value = messageMeta.Count
|
||||||
});
|
});
|
||||||
|
|
||||||
return messageMeta;
|
return messageMeta;
|
||||||
@ -275,16 +291,20 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
|
|
||||||
string totalKills(Server server)
|
string totalKills(Server server)
|
||||||
{
|
{
|
||||||
var serverStats = new GenericRepository<EFServerStatistics>();
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
return serverStats.Find(s => s.Active)
|
{
|
||||||
.Sum(c => c.TotalKills).ToString("#,##0");
|
long kills = ctx.Set<EFServerStatistics>().Where(s => s.Active).Sum(s => s.TotalKills);
|
||||||
|
return kills.ToString("#,##0");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string totalPlayTime(Server server)
|
string totalPlayTime(Server server)
|
||||||
{
|
{
|
||||||
var serverStats = new GenericRepository<EFServerStatistics>();
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
return Math.Ceiling((serverStats.GetQuery(s => s.Active)
|
{
|
||||||
.Sum(c => c.TotalPlayTime) / 3600.0)).ToString("#,##0");
|
long playTime = ctx.Set<EFServerStatistics>().Where(s => s.Active).Sum(s => s.TotalPlayTime);
|
||||||
|
return (playTime / 3600.0).ToString("#,##0");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string topStats(Server s)
|
string topStats(Server s)
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>2.1.5</RuntimeFrameworkVersion>
|
||||||
<ApplicationIcon />
|
<ApplicationIcon />
|
||||||
<StartupObject />
|
<StartupObject />
|
||||||
<PackageId>RaidMax.IW4MAdmin.Plugins.Stats</PackageId>
|
<PackageId>RaidMax.IW4MAdmin.Plugins.Stats</PackageId>
|
||||||
@ -26,7 +27,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Update="Microsoft.NETCore.App" />
|
<PackageReference Update="Microsoft.NETCore.App" Version="2.1.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>2.1.5</RuntimeFrameworkVersion>
|
||||||
<ApplicationIcon />
|
<ApplicationIcon />
|
||||||
<StartupObject />
|
<StartupObject />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@ -22,7 +23,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Update="Microsoft.NETCore.App" />
|
<PackageReference Update="Microsoft.NETCore.App" Version="2.1.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -8,6 +8,8 @@ using SharedLibraryCore.Configuration;
|
|||||||
using SharedLibraryCore.Services;
|
using SharedLibraryCore.Services;
|
||||||
using SharedLibraryCore.Database.Models;
|
using SharedLibraryCore.Database.Models;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using SharedLibraryCore.Database;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace IW4MAdmin.Plugins.Welcome
|
namespace IW4MAdmin.Plugins.Welcome
|
||||||
{
|
{
|
||||||
@ -88,8 +90,18 @@ namespace IW4MAdmin.Plugins.Welcome
|
|||||||
|
|
||||||
if (newPlayer.Level == Player.Permission.Flagged)
|
if (newPlayer.Level == Player.Permission.Flagged)
|
||||||
{
|
{
|
||||||
var penalty = await new GenericRepository<EFPenalty>().FindAsync(p => p.OffenderId == newPlayer.ClientId && p.Type == Penalty.PenaltyType.Flag);
|
string penaltyReason;
|
||||||
E.Owner.ToAdmins($"^1NOTICE: ^7Flagged player ^5{newPlayer.Name} ^7({penalty.FirstOrDefault()?.Offense}) has joined!");
|
|
||||||
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
|
{
|
||||||
|
penaltyReason = await ctx.Penalties
|
||||||
|
.Where(p => p.OffenderId == newPlayer.ClientId && p.Type == Penalty.PenaltyType.Flag)
|
||||||
|
.OrderByDescending(p => p.When)
|
||||||
|
.Select(p => p.AutomatedOffense ?? p.Offense)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
E.Owner.ToAdmins($"^1NOTICE: ^7Flagged player ^5{newPlayer.Name} ^7({penaltyReason}) has joined!");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
E.Owner.Broadcast(ProcessAnnouncement(Config.Configuration().UserAnnouncementMessage, newPlayer));
|
E.Owner.Broadcast(ProcessAnnouncement(Config.Configuration().UserAnnouncementMessage, newPlayer));
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>2.1.5</RuntimeFrameworkVersion>
|
||||||
<ApplicationIcon />
|
<ApplicationIcon />
|
||||||
<StartupObject />
|
<StartupObject />
|
||||||
<PackageId>RaidMax.IW4MAdmin.Plugins.Welcome</PackageId>
|
<PackageId>RaidMax.IW4MAdmin.Plugins.Welcome</PackageId>
|
||||||
@ -25,7 +26,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Update="Microsoft.NETCore.App" />
|
<PackageReference Update="Microsoft.NETCore.App" Version="2.1.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
@ -68,7 +68,6 @@ namespace SharedLibraryCore
|
|||||||
|
|
||||||
ScriptEngine.Execute(script);
|
ScriptEngine.Execute(script);
|
||||||
ScriptEngine.SetValue("_localization", Utilities.CurrentLocalization);
|
ScriptEngine.SetValue("_localization", Utilities.CurrentLocalization);
|
||||||
ScriptEngine.SetValue("_IW4MAdminClient", Utilities.IW4MAdminClient);
|
|
||||||
dynamic pluginObject = ScriptEngine.GetValue("plugin").ToObject();
|
dynamic pluginObject = ScriptEngine.GetValue("plugin").ToObject();
|
||||||
|
|
||||||
this.Author = pluginObject.author;
|
this.Author = pluginObject.author;
|
||||||
@ -87,6 +86,7 @@ namespace SharedLibraryCore
|
|||||||
{
|
{
|
||||||
ScriptEngine.SetValue("_gameEvent", E);
|
ScriptEngine.SetValue("_gameEvent", E);
|
||||||
ScriptEngine.SetValue("_server", S);
|
ScriptEngine.SetValue("_server", S);
|
||||||
|
ScriptEngine.SetValue("_IW4MAdminClient", Utilities.IW4MAdminClient(S));
|
||||||
return Task.FromResult(ScriptEngine.Execute("plugin.onEventAsync(_gameEvent, _server)").GetCompletionValue());
|
return Task.FromResult(ScriptEngine.Execute("plugin.onEventAsync(_gameEvent, _server)").GetCompletionValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ namespace SharedLibraryCore
|
|||||||
Port = config.Port;
|
Port = config.Port;
|
||||||
Manager = mgr;
|
Manager = mgr;
|
||||||
Logger = Manager.GetLogger(this.GetHashCode());
|
Logger = Manager.GetLogger(this.GetHashCode());
|
||||||
|
Logger.WriteInfo(this.ToString());
|
||||||
ServerConfig = config;
|
ServerConfig = config;
|
||||||
RemoteConnection = new RCon.Connection(IP, Port, Password, Logger);
|
RemoteConnection = new RCon.Connection(IP, Port, Password, Logger);
|
||||||
|
|
||||||
@ -263,7 +264,7 @@ namespace SharedLibraryCore
|
|||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"{IP}_{Port}";
|
return $"{IP}-{Port}";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task<bool> ScriptLoaded()
|
protected async Task<bool> ScriptLoaded()
|
||||||
|
@ -1,154 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using SharedLibraryCore.Database;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace SharedLibraryCore.Services
|
|
||||||
{
|
|
||||||
// https://stackoverflow.com/questions/43677906/crud-operations-with-entityframework-using-generic-type
|
|
||||||
public class GenericRepository<TEntity> where TEntity : class
|
|
||||||
{
|
|
||||||
private DatabaseContext _context;
|
|
||||||
private DbSet<TEntity> _dbSet;
|
|
||||||
private readonly bool ShouldTrack;
|
|
||||||
|
|
||||||
public GenericRepository(bool shouldTrack)
|
|
||||||
{
|
|
||||||
this.ShouldTrack = shouldTrack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GenericRepository() { }
|
|
||||||
|
|
||||||
protected DbContext Context
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_context == null)
|
|
||||||
{
|
|
||||||
_context = new DatabaseContext(!ShouldTrack);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _context;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected DbSet<TEntity> DBSet
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_dbSet == null)
|
|
||||||
{
|
|
||||||
_dbSet = this.Context.Set<TEntity>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _dbSet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<IList<TEntity>> FindAsync(Expression<Func<TEntity, bool>> predicate, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderExpression = null)
|
|
||||||
{
|
|
||||||
return await this.GetQuery(predicate, orderExpression).ToListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderExpression = null)
|
|
||||||
{
|
|
||||||
return this.GetQuery(predicate, orderExpression).AsEnumerable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual IQueryable<TEntity> GetQuery(Expression<Func<TEntity, bool>> predicate = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderExpression = null)
|
|
||||||
{
|
|
||||||
IQueryable<TEntity> qry = this.DBSet;
|
|
||||||
|
|
||||||
foreach (var property in this.Context.Model.FindEntityType(typeof(TEntity)).GetNavigations())
|
|
||||||
qry = qry.Include(property.Name);
|
|
||||||
|
|
||||||
|
|
||||||
if (predicate != null)
|
|
||||||
qry = qry.Where(predicate);
|
|
||||||
|
|
||||||
if (orderExpression != null)
|
|
||||||
return orderExpression(qry);
|
|
||||||
|
|
||||||
|
|
||||||
return qry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Insert<T>(T entity) where T : class
|
|
||||||
{
|
|
||||||
DbSet<T> dbSet = this.Context.Set<T>();
|
|
||||||
dbSet.Add(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual TEntity Insert(TEntity entity)
|
|
||||||
{
|
|
||||||
return DBSet.Add(entity).Entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Update<T>(T entity) where T : class
|
|
||||||
{
|
|
||||||
DbSet<T> dbSet = this.Context.Set<T>();
|
|
||||||
dbSet.Attach(entity);
|
|
||||||
this.Context.Entry(entity).State = EntityState.Modified;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Update(TEntity entity)
|
|
||||||
{
|
|
||||||
this.Attach(entity);
|
|
||||||
this.Context.Entry(entity).State = EntityState.Modified;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Delete<T>(T entity) where T : class
|
|
||||||
{
|
|
||||||
DbSet<T> dbSet = this.Context.Set<T>();
|
|
||||||
|
|
||||||
if (this.Context.Entry(entity).State == EntityState.Detached)
|
|
||||||
dbSet.Attach(entity);
|
|
||||||
|
|
||||||
dbSet.Remove(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Delete(TEntity entity)
|
|
||||||
{
|
|
||||||
if (this.Context.Entry(entity).State == EntityState.Detached)
|
|
||||||
this.Attach(entity);
|
|
||||||
|
|
||||||
this.DBSet.Remove(entity);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Delete<T>(object[] id) where T : class
|
|
||||||
{
|
|
||||||
DbSet<T> dbSet = this.Context.Set<T>();
|
|
||||||
T entity = dbSet.Find(id);
|
|
||||||
dbSet.Attach(entity);
|
|
||||||
dbSet.Remove(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Delete(object id)
|
|
||||||
{
|
|
||||||
TEntity entity = this.DBSet.Find(id);
|
|
||||||
this.Delete(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public virtual void Attach(TEntity entity)
|
|
||||||
{
|
|
||||||
if (this.Context.Entry(entity).State == EntityState.Detached)
|
|
||||||
this.DBSet.Attach(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void SaveChanges()
|
|
||||||
{
|
|
||||||
this.Context.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual Task SaveChangesAsync()
|
|
||||||
{
|
|
||||||
return this.Context.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,6 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>2.1.5</RuntimeFrameworkVersion>
|
||||||
<ApplicationIcon />
|
<ApplicationIcon />
|
||||||
<StartupObject />
|
<StartupObject />
|
||||||
<PackageId>RaidMax.IW4MAdmin.SharedLibraryCore</PackageId>
|
<PackageId>RaidMax.IW4MAdmin.SharedLibraryCore</PackageId>
|
||||||
@ -12,15 +13,6 @@
|
|||||||
<Configurations>Debug;Release;Prerelease</Configurations>
|
<Configurations>Debug;Release;Prerelease</Configurations>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Remove="Migrations\20180502195240_Update.cs" />
|
|
||||||
<Compile Remove="Migrations\20180923025324_FixForPostgreSQL.cs" />
|
|
||||||
<Compile Remove="Migrations\20180923025702_FixForPostgreSQL.cs" />
|
|
||||||
<Compile Remove="Migrations\20180923030248_FixForPostgreSQL.cs" />
|
|
||||||
<Compile Remove="Migrations\20180923030426_FixForPostgreSQL.cs" />
|
|
||||||
<Compile Remove="Migrations\20180923030528_FixForPostgreSQL.cs" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Jint" Version="2.11.58" />
|
<PackageReference Include="Jint" Version="2.11.58" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.4" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.4" />
|
||||||
@ -39,7 +31,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Update="Microsoft.NETCore.App" />
|
<PackageReference Update="Microsoft.NETCore.App" Version="2.1.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
|
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
|
||||||
|
@ -27,7 +27,7 @@ namespace SharedLibraryCore
|
|||||||
#endif
|
#endif
|
||||||
public static Encoding EncodingType;
|
public static Encoding EncodingType;
|
||||||
public static Localization.Layout CurrentLocalization = new Localization.Layout(new Dictionary<string, string>());
|
public static Localization.Layout CurrentLocalization = new Localization.Layout(new Dictionary<string, string>());
|
||||||
public static Player IW4MAdminClient = new Player() { ClientId = 1, Level = Player.Permission.Console };
|
public static Player IW4MAdminClient(Server server = null) => new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = server };
|
||||||
|
|
||||||
public static string HttpRequest(string location, string header, string headerValue)
|
public static string HttpRequest(string location, string header, string headerValue)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Database;
|
||||||
using SharedLibraryCore.Database.Models;
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Dtos;
|
using SharedLibraryCore.Dtos;
|
||||||
using SharedLibraryCore.Services;
|
using SharedLibraryCore.Services;
|
||||||
@ -33,8 +35,14 @@ namespace WebfrontCore.Controllers
|
|||||||
|
|
||||||
public async Task<IActionResult> PublicAsync()
|
public async Task<IActionResult> PublicAsync()
|
||||||
{
|
{
|
||||||
var penalties = await (new GenericRepository<EFPenalty>())
|
IList<EFPenalty> penalties;
|
||||||
.FindAsync(p => p.Type == SharedLibraryCore.Objects.Penalty.PenaltyType.Ban && p.Active);
|
|
||||||
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
|
{
|
||||||
|
penalties = await ctx.Penalties
|
||||||
|
.Where(p => p.Type == SharedLibraryCore.Objects.Penalty.PenaltyType.Ban && p.Active)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
var penaltiesDto = penalties.Select(p => new PenaltyInfo()
|
var penaltiesDto = penalties.Select(p => new PenaltyInfo()
|
||||||
{
|
{
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
|
<RuntimeFrameworkVersion>2.1.5</RuntimeFrameworkVersion>
|
||||||
<RazorCompileOnBuild>false</RazorCompileOnBuild>
|
<RazorCompileOnBuild>false</RazorCompileOnBuild>
|
||||||
<RazorCompileOnPublish>false</RazorCompileOnPublish>
|
<RazorCompileOnPublish>false</RazorCompileOnPublish>
|
||||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||||
@ -63,7 +64,7 @@
|
|||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.1.2" />
|
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.1.2" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.1" />
|
||||||
<PackageReference Update="Microsoft.NETCore.App" />
|
<PackageReference Update="Microsoft.NETCore.App" Version="2.1.5" />
|
||||||
<PackageReference Update="Microsoft.AspNetCore" Version="2.1.2" />
|
<PackageReference Update="Microsoft.AspNetCore" Version="2.1.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user