1
0
mirror of https://github.com/RaidMax/IW4M-Admin.git synced 2025-06-11 15:52:25 -05:00

fix bug with player not getting updated on disconnect (related to issue #24)

jint version downgraded for better stability (also locked the engine instance as it's not thread safe)
updated readme
remove vpn detection from application configuration as it's now in a seperate plugin
defaulted webfront bind URl to all interfaces
readd the custom say name
added visibility percentage to AC
This commit is contained in:
RaidMax
2018-09-04 12:40:29 -05:00
parent 270be7ad99
commit 8868f98dc5
22 changed files with 1126 additions and 313 deletions

View File

@ -1,197 +1,197 @@
//using SharedLibraryCore;
//using SharedLibraryCore.Objects;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;
using SharedLibraryCore;
using SharedLibraryCore.Objects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//namespace IW4ScriptCommands.Commands
//{
// class Balance : Command
// {
// private class TeamAssignment
// {
// public IW4MAdmin.Plugins.Stats.IW4Info.Team CurrentTeam { get; set; }
// public int Num { get; set; }
// public IW4MAdmin.Plugins.Stats.Models.EFClientStatistics Stats { get; set; }
// }
// public Balance() : base("balance", "balance teams", "bal", Player.Permission.Trusted, false, null)
// {
// }
namespace IW4ScriptCommands.Commands
{
class Balance : Command
{
private class TeamAssignment
{
public IW4MAdmin.Plugins.Stats.IW4Info.Team CurrentTeam { get; set; }
public int Num { get; set; }
public IW4MAdmin.Plugins.Stats.Models.EFClientStatistics Stats { get; set; }
}
public Balance() : base("balance", "balance teams", "bal", Player.Permission.Trusted, false, null)
{
}
// public override async Task ExecuteAsync(GameEvent E)
// {
// string teamsString = (await E.Owner.GetDvarAsync<string>("sv_iw4madmin_teams")).Value;
public override async Task ExecuteAsync(GameEvent E)
{
string teamsString = (await E.Owner.GetDvarAsync<string>("sv_iw4madmin_teams")).Value;
// var scriptClientTeams = teamsString.Split(';', StringSplitOptions.RemoveEmptyEntries)
// .Select(c => c.Split(','))
// .Select(c => new TeamAssignment()
// {
// CurrentTeam = (IW4MAdmin.Plugins.Stats.IW4Info.Team)Enum.Parse(typeof(IW4MAdmin.Plugins.Stats.IW4Info.Team), c[1]),
// Num = E.Owner.Players.FirstOrDefault(p => p?.NetworkId == c[0].ConvertLong())?.ClientNumber ?? -1,
// Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(E.Owner.Players.FirstOrDefault(p => p?.NetworkId == c[0].ConvertLong()).ClientId, E.Owner.GetHashCode())
// })
// .ToList();
var scriptClientTeams = teamsString.Split(';', StringSplitOptions.RemoveEmptyEntries)
.Select(c => c.Split(','))
.Select(c => new TeamAssignment()
{
CurrentTeam = (IW4MAdmin.Plugins.Stats.IW4Info.Team)Enum.Parse(typeof(IW4MAdmin.Plugins.Stats.IW4Info.Team), c[1]),
Num = E.Owner.Players.FirstOrDefault(p => p?.NetworkId == c[0].ConvertLong())?.ClientNumber ?? -1,
Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(E.Owner.Players.FirstOrDefault(p => p?.NetworkId == c[0].ConvertLong()).ClientId, E.Owner.GetHashCode())
})
.ToList();
// // at least one team is full so we can't balance
// if (scriptClientTeams.Count(ct => ct.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis) >= Math.Floor(E.Owner.MaxClients / 2.0)
// || scriptClientTeams.Count(ct => ct.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies) >= Math.Floor(E.Owner.MaxClients / 2.0))
// {
// await E.Origin?.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BALANCE_FAIL"]);
// return;
// }
// at least one team is full so we can't balance
if (scriptClientTeams.Count(ct => ct.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis) >= Math.Floor(E.Owner.MaxClients / 2.0)
|| scriptClientTeams.Count(ct => ct.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies) >= Math.Floor(E.Owner.MaxClients / 2.0))
{
await E.Origin?.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BALANCE_FAIL"]);
return;
}
// List<string> teamAssignments = new List<string>();
List<string> teamAssignments = new List<string>();
// var activeClients = E.Owner.GetPlayersAsList().Select(c => new TeamAssignment()
// {
// Num = c.ClientNumber,
// Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(c.ClientId, E.Owner.GetHashCode()),
// CurrentTeam = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(c.ClientId, E.Owner.GetHashCode()).Team
// })
// .Where(c => scriptClientTeams.FirstOrDefault(sc => sc.Num == c.Num)?.CurrentTeam != IW4MAdmin.Plugins.Stats.IW4Info.Team.Spectator)
// .Where(c => c.CurrentTeam != scriptClientTeams.FirstOrDefault(p => p.Num == c.Num)?.CurrentTeam)
// .OrderByDescending(c => c.Stats.Performance)
// .ToList();
var activeClients = E.Owner.GetPlayersAsList().Select(c => new TeamAssignment()
{
Num = c.ClientNumber,
Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(c.ClientId, E.Owner.GetHashCode()),
CurrentTeam = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(c.ClientId, E.Owner.GetHashCode()).Team
})
.Where(c => scriptClientTeams.FirstOrDefault(sc => sc.Num == c.Num)?.CurrentTeam != IW4MAdmin.Plugins.Stats.IW4Info.Team.Spectator)
.Where(c => c.CurrentTeam != scriptClientTeams.FirstOrDefault(p => p.Num == c.Num)?.CurrentTeam)
.OrderByDescending(c => c.Stats.Performance)
.ToList();
// var alliesTeam = scriptClientTeams
// .Where(c => c.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies)
// .Where(c => activeClients.Count(t => t.Num == c.Num) == 0)
// .ToList();
var alliesTeam = scriptClientTeams
.Where(c => c.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies)
.Where(c => activeClients.Count(t => t.Num == c.Num) == 0)
.ToList();
// var axisTeam = scriptClientTeams
// .Where(c => c.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis)
// .Where(c => activeClients.Count(t => t.Num == c.Num) == 0)
// .ToList();
var axisTeam = scriptClientTeams
.Where(c => c.CurrentTeam == IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis)
.Where(c => activeClients.Count(t => t.Num == c.Num) == 0)
.ToList();
// while (activeClients.Count() > 0)
// {
// int teamSizeDifference = alliesTeam.Count - axisTeam.Count;
// double performanceDisparity = alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0 -
// axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0;
while (activeClients.Count() > 0)
{
int teamSizeDifference = alliesTeam.Count - axisTeam.Count;
double performanceDisparity = alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0 -
axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0;
// if (teamSizeDifference == 0)
// {
// if (performanceDisparity == 0)
// {
// alliesTeam.Add(activeClients.First());
// activeClients.RemoveAt(0);
// }
// else
// {
// if (performanceDisparity > 0)
// {
// axisTeam.Add(activeClients.First());
// activeClients.RemoveAt(0);
// }
// else
// {
// alliesTeam.Add(activeClients.First());
// activeClients.RemoveAt(0);
// }
// }
// }
// else if (teamSizeDifference > 0)
// {
// if (performanceDisparity > 0)
// {
// axisTeam.Add(activeClients.First());
// activeClients.RemoveAt(0);
// }
if (teamSizeDifference == 0)
{
if (performanceDisparity == 0)
{
alliesTeam.Add(activeClients.First());
activeClients.RemoveAt(0);
}
else
{
if (performanceDisparity > 0)
{
axisTeam.Add(activeClients.First());
activeClients.RemoveAt(0);
}
else
{
alliesTeam.Add(activeClients.First());
activeClients.RemoveAt(0);
}
}
}
else if (teamSizeDifference > 0)
{
if (performanceDisparity > 0)
{
axisTeam.Add(activeClients.First());
activeClients.RemoveAt(0);
}
// else
// {
// axisTeam.Add(activeClients.Last());
// activeClients.RemoveAt(activeClients.Count - 1);
// }
// }
// else
// {
// if (performanceDisparity > 0)
// {
// alliesTeam.Add(activeClients.First());
// activeClients.RemoveAt(0);
// }
else
{
axisTeam.Add(activeClients.Last());
activeClients.RemoveAt(activeClients.Count - 1);
}
}
else
{
if (performanceDisparity > 0)
{
alliesTeam.Add(activeClients.First());
activeClients.RemoveAt(0);
}
// else
// {
// alliesTeam.Add(activeClients.Last());
// activeClients.RemoveAt(activeClients.Count - 1);
// }
// }
// }
else
{
alliesTeam.Add(activeClients.Last());
activeClients.RemoveAt(activeClients.Count - 1);
}
}
}
// alliesTeam = alliesTeam.OrderByDescending(t => t.Stats.Performance)
// .ToList();
alliesTeam = alliesTeam.OrderByDescending(t => t.Stats.Performance)
.ToList();
// axisTeam = axisTeam.OrderByDescending(t => t.Stats.Performance)
// .ToList();
axisTeam = axisTeam.OrderByDescending(t => t.Stats.Performance)
.ToList();
// while (Math.Abs(alliesTeam.Count - axisTeam.Count) > 1)
// {
// int teamSizeDifference = alliesTeam.Count - axisTeam.Count;
// double performanceDisparity = alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0 -
// axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0;
while (Math.Abs(alliesTeam.Count - axisTeam.Count) > 1)
{
int teamSizeDifference = alliesTeam.Count - axisTeam.Count;
double performanceDisparity = alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0 -
axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0;
// if (teamSizeDifference > 0)
// {
// if (performanceDisparity > 0)
// {
// axisTeam.Add(alliesTeam.First());
// alliesTeam.RemoveAt(0);
// }
if (teamSizeDifference > 0)
{
if (performanceDisparity > 0)
{
axisTeam.Add(alliesTeam.First());
alliesTeam.RemoveAt(0);
}
// else
// {
// axisTeam.Add(alliesTeam.Last());
// alliesTeam.RemoveAt(axisTeam.Count - 1);
// }
// }
else
{
axisTeam.Add(alliesTeam.Last());
alliesTeam.RemoveAt(axisTeam.Count - 1);
}
}
// else
// {
// if (performanceDisparity > 0)
// {
// alliesTeam.Add(axisTeam.Last());
// axisTeam.RemoveAt(axisTeam.Count - 1);
// }
else
{
if (performanceDisparity > 0)
{
alliesTeam.Add(axisTeam.Last());
axisTeam.RemoveAt(axisTeam.Count - 1);
}
// else
// {
// alliesTeam.Add(axisTeam.First());
// axisTeam.RemoveAt(0);
// }
// }
// }
else
{
alliesTeam.Add(axisTeam.First());
axisTeam.RemoveAt(0);
}
}
}
// foreach (var assignment in alliesTeam)
// {
// teamAssignments.Add($"{assignment.Num},2");
// assignment.Stats.Team = IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies;
// }
// foreach (var assignment in axisTeam)
// {
// teamAssignments.Add($"{assignment.Num},3");
// assignment.Stats.Team = IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis;
// }
foreach (var assignment in alliesTeam)
{
teamAssignments.Add($"{assignment.Num},2");
assignment.Stats.Team = IW4MAdmin.Plugins.Stats.IW4Info.Team.Allies;
}
foreach (var assignment in axisTeam)
{
teamAssignments.Add($"{assignment.Num},3");
assignment.Stats.Team = IW4MAdmin.Plugins.Stats.IW4Info.Team.Axis;
}
// if (alliesTeam.Count(ac => scriptClientTeams.First(sc => sc.Num == ac.Num).CurrentTeam != ac.CurrentTeam) == 0 &&
// axisTeam.Count(ac => scriptClientTeams.First(sc => sc.Num == ac.Num).CurrentTeam != ac.CurrentTeam) == 0)
// {
// await E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BALANCE_FAIL_BALANCED"]);
// return;
// }
if (alliesTeam.Count(ac => scriptClientTeams.First(sc => sc.Num == ac.Num).CurrentTeam != ac.CurrentTeam) == 0 &&
axisTeam.Count(ac => scriptClientTeams.First(sc => sc.Num == ac.Num).CurrentTeam != ac.CurrentTeam) == 0)
{
await E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BALANCE_FAIL_BALANCED"]);
return;
}
// if (E.Origin?.Level > Player.Permission.Administrator)
// {
// await E.Origin.Tell($"Allies Elo: {(alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0)}");
// await E.Origin.Tell($"Axis Elo: {(axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0)}");
// }
if (E.Origin?.Level > Player.Permission.Administrator)
{
await E.Origin.Tell($"Allies Elo: {(alliesTeam.Count > 0 ? alliesTeam.Average(t => t.Stats.Performance) : 0)}");
await E.Origin.Tell($"Axis Elo: {(axisTeam.Count > 0 ? axisTeam.Average(t => t.Stats.Performance) : 0)}");
}
// string args = string.Join(",", teamAssignments);
// await E.Owner.ExecuteCommandAsync($"sv_iw4madmin_command \"balance:{args}\"");
// await E.Origin.Tell("Balance command sent");
// }
// }
//}
string args = string.Join(",", teamAssignments);
await E.Owner.ExecuteCommandAsync($"sv_iw4madmin_command \"balance:{args}\"");
await E.Origin.Tell("Balance command sent");
}
}
}

View File

@ -1,6 +1,7 @@
using System.Collections.Concurrent;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using SharedLibraryCore;
using SharedLibraryCore.Configuration;
@ -36,6 +37,15 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment
var objectionalWords = Settings.Configuration().OffensiveWords;
bool containsObjectionalWord = objectionalWords.FirstOrDefault(w => E.Origin.Name.ToLower().Contains(w)) != null;
// we want to run regex against it just incase
if (!containsObjectionalWord)
{
foreach (string word in objectionalWords)
{
containsObjectionalWord |= Regex.IsMatch(E.Origin.Name.ToLower(), word);
}
}
if (containsObjectionalWord)
{
await E.Origin.Kick(Settings.Configuration().ProfanityKickMessage, new Player()
@ -56,7 +66,18 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment
if (E.Type == GameEvent.EventType.Say)
{
var objectionalWords = Settings.Configuration().OffensiveWords;
bool containsObjectionalWord = objectionalWords.FirstOrDefault(w => E.Data.ToLower().Contains(w)) != null;
bool containsObjectionalWord = false;
foreach (string word in objectionalWords)
{
containsObjectionalWord |= Regex.IsMatch(E.Origin.Name.ToLower(), word);
// break out early because there's at least one objectional word
if (containsObjectionalWord)
{
break;
}
}
if (containsObjectionalWord)
{

View File

@ -1,14 +1,14 @@
const plugin = {
var plugin = {
author: 'RaidMax',
version: 1.0,
name: 'VPN Kick Plugin',
name: 'VPN Detection Plugin',
manager: null,
logger: null,
vpnExceptionIds: [],
checkForVpn(origin) {
let exempt = false;
checkForVpn: function (origin) {
var exempt = false;
// prevent players that are exempt from being kicked
this.vpnExceptionIds.forEach(function (id) {
if (id === origin.ClientId) {
@ -21,43 +21,46 @@ const plugin = {
return;
}
let usingVPN = false;
var usingVPN = false;
try {
let cl = new System.Net.Http.HttpClient();
let re = cl.GetAsync('https://api.xdefcon.com/proxy/check/?ip=' + origin.IPAddressString).Result;
let co = re.Content;
let parsedJSON = JSON.parse(co.ReadAsStringAsync().Result);
//co.Dispose();
//re.Dispose();
//cl.Dispose();
usingVPN = parsedJSON['success'] && parsedJSON['proxy'];
var cl = new System.Net.Http.HttpClient();
var re = cl.GetAsync('https://api.xdefcon.com/proxy/check/?ip=' + origin.IPAddressString).Result;
var co = re.Content;
var parsedJSON = JSON.parse(co.ReadAsStringAsync().Result);
// todo: does this work as expected now?
co.Dispose();
re.Dispose();
cl.Dispose();
usingVPN = parsedJSON.success && parsedJSON.proxy;
} catch (e) {
this.logger.WriteError(e.message);
}
if (usingVPN) {
this.logger.WriteInfo(origin + ' is using a VPN (' + origin.IPAddressString + ')');
let library = importNamespace('SharedLibraryCore');
let kickOrigin = new library.Objects.Player();
var library = importNamespace('SharedLibraryCore');
var kickOrigin = new library.Objects.Player();
kickOrigin.ClientId = 1;
origin.Kick(_localization.LocalizationIndex["SERVER_KICK_VPNS_NOTALLOWED"], kickOrigin);
}
},
onEventAsync(gameEvent, server) {
onEventAsync: function (gameEvent, server) {
// connect event
if (gameEvent.Type === 3) {
this.checkForVpn(gameEvent.Origin);
}
},
onLoadAsync(manager) {
onLoadAsync: function (manager) {
this.manager = manager;
this.logger = manager.GetLogger();
},
onUnloadAsync() { },
onUnloadAsync: function () {
},
onTickAsync(server) { }
onTickAsync: function (server) {
}
};

View File

@ -43,15 +43,13 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
context.ChangeTracker.AutoDetectChangesEnabled = false;
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var thirtyDaysAgo = DateTime.UtcNow.AddMonths(-1);
var fifteenDaysAgo = DateTime.UtcNow.AddDays(-15);
var iqClientRatings = (from rating in context.Set<EFRating>()
#if DEBUG == false
where rating.ActivityAmount >= Plugin.Config.Configuration().TopPlayersMinPlayTime
#endif
where rating.RatingHistory.Client.Level != Player.Permission.Banned
where rating.RatingHistory.Client.LastConnection > thirtyDaysAgo
where rating.Newest
where rating.ServerId == null
where rating.RatingHistory.Client.LastConnection > fifteenDaysAgo
where rating.RatingHistory.Client.Level != Player.Permission.Banned
where rating.Newest
where rating.ActivityAmount >= Plugin.Config.Configuration().TopPlayersMinPlayTime
orderby rating.Performance descending
select new
{
@ -67,7 +65,10 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
var clientRatings = await iqClientRatings.ToListAsync();
var clientIds = clientRatings.GroupBy(r => r.ClientId).Select(r => r.First().ClientId).ToList();
var clientIds = clientRatings
.GroupBy(r => r.ClientId)
.Select(r => r.First().ClientId)
.ToList();
var iqStatsInfo = (from stat in context.Set<EFClientStatistics>()
where clientIds.Contains(stat.ClientId)
@ -101,8 +102,8 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
Performance = Math.Round(clientRatingsDict[s.ClientId].Performance, 2),
RatingChange = clientRatingsDict[s.ClientId].Ratings.First().Ranking - clientRatingsDict[s.ClientId].Ratings.Last().Ranking,
PerformanceHistory = clientRatingsDict[s.ClientId].Ratings.Count() > 1 ?
clientRatingsDict[s.ClientId].Ratings.Select(r => r.Performance).ToList() :
new List<double>() { clientRatingsDict[s.ClientId].Performance, clientRatingsDict[s.ClientId].Performance },
clientRatingsDict[s.ClientId].Ratings.Select(r => r.Performance).ToList() :
new List<double>() { clientRatingsDict[s.ClientId].Performance, clientRatingsDict[s.ClientId].Performance },
TimePlayed = Math.Round(clientRatingsDict[s.ClientId].TotalConnectionTime / 3600.0, 1).ToString("#,##0"),
})
.OrderByDescending(r => r.Performance)
@ -324,7 +325,8 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
/// </summary>
/// <returns></returns>
public async Task AddScriptHit(bool isDamage, DateTime time, Player attacker, Player victim, int serverId, string map, string hitLoc, string type,
string damage, string weapon, string killOrigin, string deathOrigin, string viewAngles, string offset, string isKillstreakKill, string Ads, string fraction, string snapAngles)
string damage, string weapon, string killOrigin, string deathOrigin, string viewAngles, string offset, string isKillstreakKill, string Ads,
string fraction, string visibilityPercentage, string snapAngles)
{
var statsSvc = ContextThreads[serverId];
Vector3 vDeathOrigin = null;
@ -381,6 +383,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
IsKillstreakKill = isKillstreakKill[0] != '0',
AdsPercent = float.Parse(Ads),
Fraction = double.Parse(fraction),
VisibilityPercentage = double.Parse(visibilityPercentage),
IsKill = !isDamage,
AnglesList = snapshotAngles
};
@ -569,9 +572,9 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
}
// update their performance
//#if !DEBUG
#if !DEBUG
if ((DateTime.UtcNow - attackerStats.LastStatHistoryUpdate).TotalMinutes >= 2.5)
//#endif
#endif
{
await UpdateStatHistory(attacker, attackerStats);
attackerStats.LastStatHistoryUpdate = DateTime.UtcNow;
@ -631,13 +634,13 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
ctx.Update(clientHistory);
}
var thirtyDaysAgo = DateTime.UtcNow.AddMonths(-1);
var fifteenDaysAgo = DateTime.UtcNow.AddDays(-15);
// get the client ranking for the current server
int individualClientRanking = await ctx.Set<EFRating>()
.Where(c => c.ServerId == clientStats.ServerId)
.Where(r => r.RatingHistory.Client.LastConnection > fifteenDaysAgo)
.Where(r => r.RatingHistory.Client.Level != Player.Permission.Banned)
.Where(r => r.ActivityAmount > Plugin.Config.Configuration().TopPlayersMinPlayTime)
.Where(r => r.RatingHistory.Client.LastConnection > thirtyDaysAgo)
.Where(c => c.RatingHistory.ClientId != client.ClientId)
.Where(r => r.Newest)
.Where(c => c.Performance > clientStats.Performance)
@ -689,11 +692,11 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
}
int overallClientRanking = await ctx.Set<EFRating>()
.Where(r => r.RatingHistory.Client.Level != Player.Permission.Banned)
.Where(r => r.ServerId == null)
.Where(r => r.RatingHistory.ClientId != client.ClientId)
.Where(r => r.RatingHistory.Client.LastConnection > fifteenDaysAgo)
.Where(r => r.RatingHistory.Client.Level != Player.Permission.Banned)
.Where(r => r.ActivityAmount > Plugin.Config.Configuration().TopPlayersMinPlayTime)
.Where(r => r.RatingHistory.Client.LastConnection > thirtyDaysAgo)
.Where(r => r.RatingHistory.ClientId != client.ClientId)
.Where(r => r.ServerId == null)
.Where(r => r.Newest)
.Where(r => r.Performance > performanceAverage)
.CountAsync() + 1;
@ -730,9 +733,10 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
{
await ctx.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException e)
// this can happen when the client disconnects without any stat changes
catch (DbUpdateConcurrencyException)
{
}
}
}

View File

@ -31,6 +31,7 @@ namespace IW4MAdmin.Plugins.Stats.Models
public DateTime When { get; set; }
public double Fraction { get; set; }
public bool IsKill { get; set; }
public double VisibilityPercentage { get; set; }
// http://wiki.modsrepository.com/index.php?title=Call_of_Duty_5:_Gameplay_standards for conversion to meters
[NotMapped]
public double Distance => Vector3.Distance(KillOrigin, DeathOrigin) * 0.0254;

View File

@ -76,7 +76,7 @@ namespace IW4MAdmin.Plugins.Stats
if (killInfo.Length >= 14)
{
await Manager.AddScriptHit(false, E.Time, E.Origin, E.Target, S.GetHashCode(), S.CurrentMap.Name, killInfo[7], killInfo[8],
killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13], killInfo[14]);
killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13], killInfo[14], killInfo[15]);
}
break;
case GameEvent.EventType.Kill:
@ -92,7 +92,7 @@ namespace IW4MAdmin.Plugins.Stats
if (killInfo.Length >= 14)
{
await Manager.AddScriptHit(true, E.Time, E.Origin, E.Target, S.GetHashCode(), S.CurrentMap.Name, killInfo[7], killInfo[8],
killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13], killInfo[14]);
killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13], killInfo[14], killInfo[15]);
}
break;
}

View File

@ -0,0 +1,55 @@
using IW4MAdmin.Application;
using SharedLibraryCore;
using SharedLibraryCore.Objects;
using System;
using System.Collections.Generic;
using System.Text;
using Xunit;
namespace Tests
{
[Collection("ManagerCollection")]
public class PluginTests
{
readonly ApplicationManager Manager;
public PluginTests(ManagerFixture fixture)
{
Manager = fixture.Manager;
}
[Fact]
public void ClientSayObjectionalWordShouldWarn()
{
var e = new GameEvent()
{
Type = GameEvent.EventType.Connect,
Origin = new Player()
{
Name = $"Player1",
NetworkId = 1,
ClientNumber = 1
},
Owner = Manager.GetServers()[0]
};
Manager.GetEventHandler().AddEvent(e);
e.OnProcessed.Wait();
var client = Manager.GetServers()[0].Players[0];
e = new GameEvent()
{
Type = GameEvent.EventType.Say,
Origin = client,
Data = "nigger",
Owner = client.CurrentServer
};
Manager.GetEventHandler().AddEvent(e);
e.OnProcessed.Wait();
Assert.True(client.Warnings == 1, "client wasn't warned for objectional language");
}
}
}