change penalty expiration datetime to null for perm bans
add tempban max time allow searching for GUID stats returns ranking as well fix for promotion/demotion text
This commit is contained in:
parent
a58726d872
commit
d50e6c8030
@ -197,7 +197,8 @@ namespace IW4MAdmin
|
||||
Players[player.ClientNumber] = player;
|
||||
|
||||
var activePenalties = await Manager.GetPenaltyService().GetActivePenaltiesAsync(player.AliasLinkId, player.IPAddress);
|
||||
var currentBan = activePenalties.FirstOrDefault(b => b.Expires > DateTime.UtcNow);
|
||||
var currentBan = activePenalties.FirstOrDefault(p => p.Type == Penalty.PenaltyType.Ban || p.Type == Penalty.PenaltyType.TempBan);
|
||||
|
||||
var currentAutoFlag = activePenalties.Where(p => p.Type == Penalty.PenaltyType.Flag && p.PunisherId == 1)
|
||||
.Where(p => p.Active)
|
||||
.OrderByDescending(p => p.When)
|
||||
@ -232,7 +233,7 @@ namespace IW4MAdmin
|
||||
string formattedKick = String.Format(
|
||||
RconParser.GetCommandPrefixes().Kick,
|
||||
polledPlayer.ClientNumber,
|
||||
$"{loc["SERVER_TB_REMAIN"]} ({(currentBan.Expires - DateTime.UtcNow).TimeSpanText()} {loc["WEBFRONT_PENALTY_TEMPLATE_REMAINING"]})");
|
||||
$"{loc["SERVER_TB_REMAIN"]} ({(currentBan.Expires.Value - DateTime.UtcNow).TimeSpanText()} {loc["WEBFRONT_PENALTY_TEMPLATE_REMAINING"]})");
|
||||
await this.ExecuteCommandAsync(formattedKick);
|
||||
}
|
||||
|
||||
@ -1060,7 +1061,7 @@ namespace IW4MAdmin
|
||||
Penalty newPenalty = new Penalty()
|
||||
{
|
||||
Type = Penalty.PenaltyType.Ban,
|
||||
Expires = DateTime.MaxValue,
|
||||
Expires = null,
|
||||
Offender = Target,
|
||||
Offense = Message,
|
||||
Punisher = Origin,
|
||||
@ -1080,7 +1081,7 @@ namespace IW4MAdmin
|
||||
var unbanPenalty = new Penalty()
|
||||
{
|
||||
Type = Penalty.PenaltyType.Unban,
|
||||
Expires = DateTime.UtcNow,
|
||||
Expires = null,
|
||||
Offender = Target,
|
||||
Offense = reason,
|
||||
Punisher = Origin,
|
||||
|
@ -1,197 +1,193 @@
|
||||
//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
|
||||
{
|
||||
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 override async Task ExecuteAsync(GameEvent E)
|
||||
// {
|
||||
// string teamsString = (await E.Owner.GetDvarAsync<string>("sv_iw4madmin_teams")).Value;
|
||||
public static string GetTeamAssignments(Player client, string teamsString = "")
|
||||
{
|
||||
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 = client.CurrentServer.GetPlayersAsList().FirstOrDefault(p => p.ClientNumber== Int32.Parse(c[0]))?.ClientNumber ?? -1,
|
||||
Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(client.CurrentServer.Players.FirstOrDefault(p => p.ClientNumber == Int32.Parse(c[0])).ClientId, client.CurrentServer.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(client.CurrentServer.MaxClients / 2.0)
|
||||
|| scriptClientTeams.Count(ct => ct.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies) >= Math.Floor(client.CurrentServer.MaxClients / 2.0))
|
||||
{
|
||||
// E.Origin?.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BALANCE_FAIL"]);
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
// // 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 = client.CurrentServer.GetPlayersAsList().Select(c => new TeamAssignment()
|
||||
{
|
||||
Num = c.ClientNumber,
|
||||
Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(c.ClientId, client.CurrentServer.GetHashCode()),
|
||||
CurrentTeam = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(c.ClientId, client.CurrentServer.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 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 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;
|
||||
// //E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BALANCE_FAIL_BALANCED"]);
|
||||
// return string.Empty;
|
||||
//}
|
||||
|
||||
//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)}");
|
||||
// E.Origin.Tell($"Allies Elo: {(alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0)}");
|
||||
// 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");
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//E.Origin.Tell("Balance command sent");
|
||||
string args = string.Join(",", teamAssignments);
|
||||
return args;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using IW4ScriptCommands.Commands;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Objects;
|
||||
using System;
|
||||
@ -32,5 +33,18 @@ namespace WebfrontCore.Controllers.API
|
||||
|
||||
return Content("");
|
||||
}
|
||||
|
||||
[HttpGet("{networkId}")]
|
||||
public IActionResult GetTeamAssignments(string networkId, string teams = "")
|
||||
{
|
||||
var client = Manager.GetActiveClients()
|
||||
.First(c => c.NetworkId == networkId.ConvertLong());
|
||||
|
||||
teams = teams ?? string.Empty;
|
||||
|
||||
string assignments = Balance.GetTeamAssignments(client, teams);
|
||||
|
||||
return Content(assignments);
|
||||
}
|
||||
}
|
||||
}
|
@ -14,7 +14,6 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
{
|
||||
class TopStats : Command
|
||||
{
|
||||
|
||||
public static async Task<List<string>> GetTopStats(Server s)
|
||||
{
|
||||
int serverId = s.GetHashCode();
|
||||
|
@ -9,6 +9,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SharedLibraryCore.Database;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using IW4MAdmin.Plugins.Stats.Helpers;
|
||||
|
||||
namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
{
|
||||
@ -47,14 +48,20 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
{
|
||||
if (E.Target != null)
|
||||
{
|
||||
int performanceRanking = await StatManager.GetClientOverallRanking(E.Target.ClientId);
|
||||
string performanceRankingString = performanceRanking == 0 ? loc["WEBFRONT_STATS_INDEX_UNRANKED"] : $"{loc["WEBFRONT_STATS_INDEX_RANKED"]} #{performanceRanking}";
|
||||
|
||||
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()}";
|
||||
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()} | {performanceRankingString}";
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
int performanceRanking = await StatManager.GetClientOverallRanking(E.Origin.ClientId);
|
||||
string performanceRankingString = performanceRanking == 0 ? loc["WEBFRONT_STATS_INDEX_UNRANKED"] : $"{loc["WEBFRONT_STATS_INDEX_RANKED"]} #{performanceRanking}";
|
||||
|
||||
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()} | {performanceRankingString}";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
/// </summary>
|
||||
/// <param name="clientId">client id of the player</param>
|
||||
/// <returns></returns>
|
||||
public async Task<int> GetClientOverallRanking(int clientId)
|
||||
public static async Task<int> GetClientOverallRanking(int clientId)
|
||||
{
|
||||
using (var context = new DatabaseContext(true))
|
||||
{
|
||||
|
@ -143,7 +143,7 @@ namespace IW4MAdmin.Plugins.Stats
|
||||
new ProfileMeta()
|
||||
{
|
||||
Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_RANKING"],
|
||||
Value = "#" + await Manager.GetClientOverallRanking(clientId),
|
||||
Value = "#" + await StatManager.GetClientOverallRanking(clientId),
|
||||
},
|
||||
new ProfileMeta()
|
||||
{
|
||||
|
@ -113,6 +113,9 @@ If you wish to further customize your experience of **IW4MAdmin**, the following
|
||||
* Possible values — `sqlite`, `mysql`, `postgresql`
|
||||
* Default — `sqlite`
|
||||
|
||||
`Ignore Bots`
|
||||
* Disables bots from being registered by **IW4MAdmin**
|
||||
|
||||
`RConPollRate`
|
||||
* Specifies (in milliseconds) how often to poll each server for updates
|
||||
* Default — `5000`
|
||||
|
@ -183,12 +183,20 @@ namespace SharedLibraryCore.Commands
|
||||
string tempbanReason = match.Groups[2].ToString();
|
||||
var length = match.Groups[1].ToString().ParseTimespan();
|
||||
|
||||
if (length > E.Owner.Manager.GetApplicationSettings().Configuration().MaximumTempBanTime)
|
||||
{
|
||||
E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_TEMPBAN_FAIL_TOOLONG"]);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
var _ = !(await E.Target.TempBan(tempbanReason, length, E.Origin).WaitAsync()).Failed ?
|
||||
E.Origin.Tell($"^5{E.Target} ^7{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_TEMPBAN_SUCCESS"]} ^5{length.TimeSpanText()}") :
|
||||
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_TEMPBAN_FAIL"]} {E.Target.Name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CBan : Command
|
||||
{
|
||||
@ -468,8 +476,12 @@ namespace SharedLibraryCore.Commands
|
||||
{
|
||||
ActiveClient.Level = newPerm;
|
||||
await E.Owner.Manager.GetClientService().Update(ActiveClient);
|
||||
|
||||
if (newPerm > oldPerm)
|
||||
{
|
||||
ActiveClient.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_SETLEVEL_SUCCESS_TARGET"]} {newPerm}");
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
@ -503,6 +515,8 @@ namespace SharedLibraryCore.Commands
|
||||
|
||||
E.Owner.Manager.GetEventHandler().AddEvent(e);
|
||||
|
||||
var _ = newPerm < oldPerm ?
|
||||
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_SETLEVEL_DEMOTE_SUCCESS"]} {E.Target.Name}") :
|
||||
E.Origin.Tell($"{E.Target.Name} {Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_SETLEVEL_SUCCESS"]}");
|
||||
}
|
||||
|
||||
@ -625,7 +639,7 @@ namespace SharedLibraryCore.Commands
|
||||
}
|
||||
|
||||
IList<EFClient> db_players = (await (E.Owner.Manager.GetClientService() as ClientService)
|
||||
.GetClientByName(E.Data))
|
||||
.FindClientsByIdentifier(E.Data))
|
||||
.OrderByDescending(p => p.LastConnection)
|
||||
.ToList();
|
||||
|
||||
@ -935,7 +949,8 @@ namespace SharedLibraryCore.Commands
|
||||
{
|
||||
var B = await E.Owner.Manager.GetPenaltyService().GetClientPenaltiesAsync(E.Target.ClientId);
|
||||
|
||||
var penalty = B.FirstOrDefault(b => b.Type > Penalty.PenaltyType.Kick && b.Expires > DateTime.UtcNow);
|
||||
var penalty = B.FirstOrDefault(b => b.Type > Penalty.PenaltyType.Kick &&
|
||||
(b.Expires == null || b.Expires > DateTime.UtcNow));
|
||||
|
||||
if (penalty == null)
|
||||
{
|
||||
@ -943,7 +958,7 @@ namespace SharedLibraryCore.Commands
|
||||
return;
|
||||
}
|
||||
|
||||
string timeRemaining = penalty.Type == Penalty.PenaltyType.TempBan ? $"({(penalty.Expires - DateTime.UtcNow).TimeSpanText()} remaining)" : "";
|
||||
string timeRemaining = penalty.Type == Penalty.PenaltyType.TempBan ? $"({(penalty.Expires.Value - DateTime.UtcNow).TimeSpanText()} remaining)" : "";
|
||||
string success = Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BANINFO_SUCCESS"];
|
||||
|
||||
E.Origin.Tell($"^1{E.Target.Name} ^7{string.Format(success, penalty.Punisher.Name)} {penalty.Punisher.Name} {timeRemaining}");
|
||||
|
@ -22,6 +22,7 @@ namespace SharedLibraryCore.Configuration
|
||||
public string ConnectionString { get; set; }
|
||||
public int RConPollRate { get; set; } = 5000;
|
||||
public bool IgnoreBots { get; set; }
|
||||
public TimeSpan MaximumTempBanTime { get; set; } = new TimeSpan(24 * 30, 0, 0);
|
||||
public string Id { get; set; }
|
||||
public List<ServerConfiguration> Servers { get; set; }
|
||||
public int AutoMessagePeriod { get; set; }
|
||||
|
@ -98,6 +98,9 @@ namespace SharedLibraryCore.Database
|
||||
.WithMany(p => p.AdministeredPenalties)
|
||||
.HasForeignKey(c => c.PunisherId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
entity.Property(p => p.Expires)
|
||||
.IsRequired(false);
|
||||
});
|
||||
|
||||
modelBuilder.Entity<EFAliasLink>(entity =>
|
||||
|
@ -27,7 +27,7 @@ namespace SharedLibraryCore.Database.Models
|
||||
[Required]
|
||||
public DateTime When { get; set; }
|
||||
[Required]
|
||||
public DateTime Expires { get; set; }
|
||||
public DateTime? Expires { get; set; }
|
||||
[Required]
|
||||
public string Offense { get; set; }
|
||||
public string AutomatedOffense { get; set; }
|
||||
|
690
SharedLibraryCore/Migrations/20181014171848_MakePenaltyExpirationNullable.Designer.cs
generated
Normal file
690
SharedLibraryCore/Migrations/20181014171848_MakePenaltyExpirationNullable.Designer.cs
generated
Normal file
@ -0,0 +1,690 @@
|
||||
// <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("20181014171848_MakePenaltyExpirationNullable")]
|
||||
partial class MakePenaltyExpirationNullable
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.1.4-rtm-31024");
|
||||
|
||||
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>("CurrentViewAngleId");
|
||||
|
||||
b.Property<int>("Deaths");
|
||||
|
||||
b.Property<double>("Distance");
|
||||
|
||||
b.Property<double>("EloRating");
|
||||
|
||||
b.Property<int>("HitDestinationId");
|
||||
|
||||
b.Property<int>("HitLocation");
|
||||
|
||||
b.Property<int>("HitOriginId");
|
||||
|
||||
b.Property<int>("HitType");
|
||||
|
||||
b.Property<int>("Hits");
|
||||
|
||||
b.Property<int>("Kills");
|
||||
|
||||
b.Property<int>("LastStrainAngleId");
|
||||
|
||||
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("CurrentViewAngleId");
|
||||
|
||||
b.HasIndex("HitDestinationId");
|
||||
|
||||
b.HasIndex("HitOriginId");
|
||||
|
||||
b.HasIndex("LastStrainAngleId");
|
||||
|
||||
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("CurrentViewAngleId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("SharedLibraryCore.Helpers.Vector3", "HitDestination")
|
||||
.WithMany()
|
||||
.HasForeignKey("HitDestinationId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("SharedLibraryCore.Helpers.Vector3", "HitOrigin")
|
||||
.WithMany()
|
||||
.HasForeignKey("HitOriginId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("SharedLibraryCore.Helpers.Vector3", "LastStrainAngle")
|
||||
.WithMany()
|
||||
.HasForeignKey("LastStrainAngleId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
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,105 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace SharedLibraryCore.Migrations
|
||||
{
|
||||
public partial class MakePenaltyExpirationNullable : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
if (migrationBuilder.ActiveProvider == "Microsoft.EntityFrameworkCore.Sqlite")
|
||||
{
|
||||
migrationBuilder.Sql(@"PRAGMA foreign_keys = 0;
|
||||
|
||||
CREATE TABLE sqlitestudio_temp_table AS SELECT *
|
||||
FROM EFPenalties;
|
||||
|
||||
DROP TABLE EFPenalties;
|
||||
|
||||
CREATE TABLE EFPenalties (
|
||||
PenaltyId INTEGER NOT NULL
|
||||
CONSTRAINT PK_EFPenalties PRIMARY KEY AUTOINCREMENT,
|
||||
Active INTEGER NOT NULL,
|
||||
Expires TEXT,
|
||||
LinkId INTEGER NOT NULL,
|
||||
OffenderId INTEGER NOT NULL,
|
||||
Offense TEXT NOT NULL,
|
||||
PunisherId INTEGER NOT NULL,
|
||||
Type INTEGER NOT NULL,
|
||||
[When] TEXT NOT NULL,
|
||||
AutomatedOffense TEXT,
|
||||
CONSTRAINT FK_EFPenalties_EFAliasLinks_LinkId FOREIGN KEY (
|
||||
LinkId
|
||||
)
|
||||
REFERENCES EFAliasLinks (AliasLinkId) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_EFPenalties_EFClients_OffenderId FOREIGN KEY (
|
||||
OffenderId
|
||||
)
|
||||
REFERENCES EFClients (ClientId) ON DELETE RESTRICT,
|
||||
CONSTRAINT FK_EFPenalties_EFClients_PunisherId FOREIGN KEY (
|
||||
PunisherId
|
||||
)
|
||||
REFERENCES EFClients (ClientId) ON DELETE RESTRICT
|
||||
);
|
||||
|
||||
INSERT INTO EFPenalties (
|
||||
PenaltyId,
|
||||
Active,
|
||||
Expires,
|
||||
LinkId,
|
||||
OffenderId,
|
||||
Offense,
|
||||
PunisherId,
|
||||
Type,
|
||||
[When],
|
||||
AutomatedOffense
|
||||
)
|
||||
SELECT PenaltyId,
|
||||
Active,
|
||||
Expires,
|
||||
LinkId,
|
||||
OffenderId,
|
||||
Offense,
|
||||
PunisherId,
|
||||
Type,
|
||||
""When"",
|
||||
AutomatedOffense
|
||||
FROM sqlitestudio_temp_table;
|
||||
|
||||
DROP TABLE sqlitestudio_temp_table;
|
||||
|
||||
CREATE INDEX IX_EFPenalties_LinkId ON EFPenalties(
|
||||
""LinkId""
|
||||
);
|
||||
|
||||
CREATE INDEX IX_EFPenalties_OffenderId ON EFPenalties(
|
||||
""OffenderId""
|
||||
);
|
||||
|
||||
CREATE INDEX IX_EFPenalties_PunisherId ON EFPenalties(
|
||||
""PunisherId""
|
||||
);
|
||||
|
||||
PRAGMA foreign_keys = 1; ");
|
||||
}
|
||||
else
|
||||
{
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "Expires",
|
||||
table: "EFPenalties",
|
||||
nullable: true,
|
||||
oldClrType: typeof(DateTime));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<DateTime>(
|
||||
name: "Expires",
|
||||
table: "EFPenalties",
|
||||
nullable: false,
|
||||
oldClrType: typeof(DateTime),
|
||||
oldNullable: true);
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@ using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
using SharedLibraryCore.Database;
|
||||
|
||||
namespace SharedLibraryCore.Migrations
|
||||
@ -15,9 +14,7 @@ namespace SharedLibraryCore.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
|
||||
.HasAnnotation("ProductVersion", "2.1.3-rtm-32065")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
.HasAnnotation("ProductVersion", "2.1.4-rtm-31024");
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
|
||||
{
|
||||
@ -456,7 +453,7 @@ namespace SharedLibraryCore.Migrations
|
||||
|
||||
b.Property<string>("AutomatedOffense");
|
||||
|
||||
b.Property<DateTime>("Expires");
|
||||
b.Property<DateTime?>("Expires");
|
||||
|
||||
b.Property<int>("LinkId");
|
||||
|
||||
|
@ -255,27 +255,30 @@ namespace SharedLibraryCore.Services
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IList<EFClient>> GetClientByName(string name)
|
||||
public async Task<IList<EFClient>> FindClientsByIdentifier(string identifier)
|
||||
{
|
||||
if (identifier.Length < 3)
|
||||
{
|
||||
if (name.Length < 3)
|
||||
return new List<EFClient>();
|
||||
}
|
||||
|
||||
name = name.ToLower();
|
||||
identifier = identifier.ToLower();
|
||||
|
||||
using (var context = new DatabaseContext(disableTracking: true))
|
||||
{
|
||||
int asIP = name.ConvertToIP();
|
||||
// hack: so IW4MAdmin and bots don't show up in search results
|
||||
asIP = asIP == 0 ? int.MaxValue : asIP;
|
||||
long networkId = identifier.ConvertLong();
|
||||
int ipAddress = identifier.ConvertToIP();
|
||||
|
||||
var iqLinkIds = (from alias in context.Aliases
|
||||
where asIP != int.MaxValue ? alias.IPAddress == asIP : alias.Name.ToLower().Contains(name)
|
||||
select alias.LinkId);
|
||||
where alias.IPAddress == ipAddress ||
|
||||
alias.Name.ToLower().Contains(identifier)
|
||||
select alias.LinkId).Distinct();
|
||||
|
||||
var linkIds = iqLinkIds.ToList();
|
||||
|
||||
var iqClients = context.Clients
|
||||
.Where(c => linkIds.Contains(c.AliasLinkId))
|
||||
.Where(c => linkIds.Contains(c.AliasLinkId) ||
|
||||
networkId == c.NetworkId)
|
||||
.Include(c => c.CurrentAlias)
|
||||
.Include(c => c.AliasLink.Children);
|
||||
|
||||
|
@ -30,9 +30,6 @@ namespace SharedLibraryCore.Services
|
||||
AutomatedOffense = newEntity.AutomatedOffense
|
||||
};
|
||||
|
||||
if (addedEntity.Expires == DateTime.MaxValue)
|
||||
addedEntity.Expires = DateTime.Parse(System.Data.SqlTypes.SqlDateTime.MaxValue.ToString());
|
||||
|
||||
// make bans propogate to all aliases
|
||||
if (addedEntity.Type == Objects.Penalty.PenaltyType.Ban)
|
||||
{
|
||||
@ -225,7 +222,7 @@ namespace SharedLibraryCore.Services
|
||||
.Where(p => p.LinkId == linkId ||
|
||||
p.Link.Children.Any(a => a.IPAddress == ip))
|
||||
.Where(p => p.Active)
|
||||
.Where(p => p.Expires > now);
|
||||
.Where(p => p.Expires == null || p.Expires > now);
|
||||
|
||||
|
||||
#if DEBUG == true
|
||||
@ -246,7 +243,7 @@ namespace SharedLibraryCore.Services
|
||||
var penalties = await context.Penalties
|
||||
.Include(p => p.Link.Children)
|
||||
.Where(p => p.LinkId == aliasLinkId)
|
||||
.Where(p => p.Expires > now)
|
||||
.Where(p => p.Expires > now || p.Expires == null)
|
||||
.ToListAsync();
|
||||
|
||||
penalties.ForEach(async p =>
|
||||
|
@ -248,14 +248,14 @@ namespace SharedLibraryCore
|
||||
if (!string.IsNullOrEmpty(bot))
|
||||
// should set their GUID to the negation of their 1 based index (-1 - -18)
|
||||
return -(Convert.ToInt64(bot.Substring(3)) + 1);
|
||||
return 0;
|
||||
return long.MinValue;
|
||||
}
|
||||
|
||||
public static int ConvertToIP(this string str)
|
||||
{
|
||||
System.Net.IPAddress.TryParse(str, out System.Net.IPAddress ip);
|
||||
|
||||
return ip == null ? 0 : BitConverter.ToInt32(ip.GetAddressBytes(), 0);
|
||||
return ip == null ? int.MaxValue : BitConverter.ToInt32(ip.GetAddressBytes(), 0);
|
||||
}
|
||||
|
||||
public static string ConvertIPtoString(this int ip)
|
||||
|
@ -146,7 +146,7 @@ namespace WebfrontCore.Controllers
|
||||
|
||||
public async Task<IActionResult> FindAsync(string clientName)
|
||||
{
|
||||
var clients = (await Manager.GetClientService().GetClientByName(clientName))
|
||||
var clients = (await Manager.GetClientService().FindClientsByIdentifier(clientName))
|
||||
.OrderByDescending(c => c.LastConnection);
|
||||
|
||||
var clientsDto = clients.Select(c => new PlayerInfo()
|
||||
|
@ -30,7 +30,7 @@ namespace WebfrontCore.ViewComponents
|
||||
Type = p.Type.ToString(),
|
||||
TimePunished = Utilities.GetTimePassed(p.When, false),
|
||||
// show time passed if ban
|
||||
TimeRemaining = DateTime.UtcNow > p.Expires ? "" : $"{(p.Expires.Year == DateTime.MaxValue.Year ? Utilities.GetTimePassed(p.When, true) : Utilities.TimeSpanText(p.Expires - DateTime.UtcNow))}",
|
||||
TimeRemaining = DateTime.UtcNow > p.Expires ? "" : $"{(p.Expires.Value.Year == DateTime.MaxValue.Year ? Utilities.GetTimePassed(p.When, true) : Utilities.TimeSpanText(p.Expires.Value - DateTime.UtcNow))}",
|
||||
Sensitive = p.Type == Penalty.PenaltyType.Flag,
|
||||
AutomatedOffense = p.AutomatedOffense
|
||||
});
|
||||
|
@ -1,3 +1,6 @@
|
||||
Version 2.3:
|
||||
-added configuration option to ignore bots
|
||||
|
||||
Version 2.2:
|
||||
-upgraded projects to .NET 2.1
|
||||
-added top player stats page
|
||||
|
Loading…
Reference in New Issue
Block a user