1
0
mirror of https://github.com/RaidMax/IW4M-Admin.git synced 2025-07-09 21:39:56 -05:00

-reconfigured solution and projects to be correct debug/release and files copy properly

-started working on more advanced statistics
This commit is contained in:
RaidMax
2017-09-29 21:42:24 -05:00
parent 8d52d7ddc5
commit 4cddefd542
26 changed files with 1824 additions and 334 deletions

File diff suppressed because it is too large Load Diff

View File

@ -96,6 +96,35 @@ namespace StatsPlugin
/// </summary>
public class Stats : SharedLibrary.Interfaces.IPlugin
{
private class KillEvent
{
public IW4Info.HitLocation HitLoc { get; set; }
public IW4Info.MeansOfDeath DeathType { get; set; }
public int Damage { get; set; }
public IW4Info.WeaponName Weapon { get; set; }
public Vector3 KillOrigin { get; set; }
public Vector3 DeathOrigin { get; set; }
public KillEvent(string hit, string type, string damage, string weapon, string kOrigin, string dOrigin)
{
HitLoc = (IW4Info.HitLocation)Enum.Parse(typeof(IW4Info.HitLocation), hit);
DeathType = (IW4Info.MeansOfDeath)Enum.Parse(typeof(IW4Info.MeansOfDeath), type);
Damage = Int32.Parse(damage);
try
{
Weapon = (IW4Info.WeaponName)Enum.Parse(typeof(IW4Info.WeaponName), weapon);
}
catch (Exception)
{
Weapon = IW4Info.WeaponName.defaultweapon_mp;
}
KillOrigin = Vector3.Parse(kOrigin);
DeathOrigin = Vector3.Parse(dOrigin);
}
}
public static List<StatTracking> statLists;
public struct StatTracking
@ -187,7 +216,7 @@ namespace StatsPlugin
if (P == null)
continue;
CalculateAndSaveSkill(P, statLists.Find(x =>x.Port == S.GetPort()));
CalculateAndSaveSkill(P, statLists.Find(x => x.Port == S.GetPort()));
ResetCounters(P.ClientID, S.GetPort());
E.Owner.Logger.WriteInfo("Updated skill for client #" + P.DatabaseID);
@ -197,7 +226,7 @@ namespace StatsPlugin
if (E.Type == Event.GType.Disconnect)
{
CalculateAndSaveSkill(E.Origin, statLists.Find(x=>x.Port == S.GetPort()));
CalculateAndSaveSkill(E.Origin, statLists.Find(x => x.Port == S.GetPort()));
ResetCounters(E.Origin.ClientID, S.GetPort());
E.Owner.Logger.WriteInfo("Updated skill for disconnecting client #" + E.Origin.DatabaseID);
}
@ -207,6 +236,12 @@ namespace StatsPlugin
if (E.Origin == E.Target || E.Origin == null)
return;
string[] killInfo = E.Data.Split(';');
var killEvent = new KillEvent(killInfo[7], killInfo[8], killInfo[5], killInfo[6], killInfo[3], killInfo[4]);
S.Logger.WriteInfo($"{E.Origin.Name} killed {E.Target.Name} with a {killEvent.Weapon} from a distance of {Vector3.Distance(killEvent.KillOrigin, killEvent.DeathOrigin)} with {killEvent.Damage} damage, at {killEvent.HitLoc}");
Player Killer = E.Origin;
StatTracking curServer = statLists.Find(x => x.Port == S.GetPort());
PlayerStats killerStats = curServer.playerStats.GetStats(Killer);
@ -217,11 +252,11 @@ namespace StatsPlugin
if ((DateTime.Now - curServer.lastKill[E.Origin.ClientID]).TotalSeconds > 120)
curServer.inactiveMinutes[E.Origin.ClientID] += 2;
killerStats.Kills++;
killerStats.KDR = (killerStats.Deaths == 0) ? killerStats.Kills : killerStats.KDR = Math.Round((double)killerStats.Kills / (double)killerStats.Deaths, 2);
curServer.playerStats.UpdateStats(Killer, killerStats);
@ -239,7 +274,7 @@ namespace StatsPlugin
Player Victim = E.Origin;
StatTracking curServer = statLists.Find(x => x.Port == S.GetPort());
PlayerStats victimStats = curServer.playerStats.GetStats(Victim);
victimStats.Deaths++;
victimStats.KDR = Math.Round(victimStats.Kills / (double)victimStats.Deaths, 2);
@ -252,7 +287,7 @@ namespace StatsPlugin
}
}
public static string GetTotalKills()
public static string GetTotalKills()
{
long Kills = 0;
foreach (var S in statLists)
@ -284,7 +319,7 @@ namespace StatsPlugin
if (newPlayTime < 2)
return;
// calculate the players Score Per Minute for the current session
double SessionSPM = curServer.Kills[P.ClientID] * 100 / Math.Max(1, newPlayTime);
// calculate how much the KDR should way
@ -293,7 +328,7 @@ namespace StatsPlugin
double SPMWeightAgainstAverage;
// if no SPM, weight is 1 else the weight is the current sessions spm / lifetime average score per minute
SPMWeightAgainstAverage = (DisconnectingPlayerStats.scorePerMinute == 1) ? 1 : SessionSPM / DisconnectingPlayerStats.scorePerMinute;
SPMWeightAgainstAverage = (DisconnectingPlayerStats.scorePerMinute == 1) ? 1 : SessionSPM / DisconnectingPlayerStats.scorePerMinute;
// calculate the weight of the new play time againmst lifetime playtime
//
@ -357,7 +392,18 @@ namespace StatsPlugin
if (!File.Exists(FileName))
{
String Create = "CREATE TABLE [STATS] ( [npID] TEXT, [KILLS] INTEGER DEFAULT 0, [DEATHS] INTEGER DEFAULT 0, [KDR] REAL DEFAULT 0, [SKILL] REAL DEFAULT 0, [MEAN] REAL DEFAULT 0, [DEV] REAL DEFAULT 0, [SPM] REAL DEFAULT 0, [PLAYTIME] INTEGER DEFAULT 0);";
String createKillsTable = @"CREATE TABLE `KILLS` (
`KillerID` INTEGER NOT NULL,
`VictimID` INTEGER NOT NULL,
`DeathOrigin` TEXT NOT NULL,
`MeansOfDeath` INTEGER NOT NULL,
`Weapon` INTEGER NOT NULL,
`HitLocation` INTEGER NOT NULL,
`Damage` INTEGER,
`KillOrigin` TEXT NOT NULL
); ";
ExecuteNonQuery(Create);
ExecuteNonQuery(createKillsTable);
}
}
@ -436,7 +482,7 @@ namespace StatsPlugin
{
foreach (DataRow ResponseRow in Result.Rows)
{
pStats.Add( new KeyValuePair<String, PlayerStats>(ResponseRow["npID"].ToString(),
pStats.Add(new KeyValuePair<String, PlayerStats>(ResponseRow["npID"].ToString(),
new PlayerStats(
Convert.ToInt32(ResponseRow["KILLS"]),
Convert.ToInt32(ResponseRow["DEATHS"]),

View File

@ -23,7 +23,7 @@
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release-Nightly|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
@ -41,6 +41,21 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<PlatformTarget>x86</PlatformTarget>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release-Nightly|x86' ">
<PlatformTarget>x86</PlatformTarget>
<OutputPath>bin\x86\Release\</OutputPath>
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-Stable|x86'">
<PlatformTarget>x86</PlatformTarget>
<OutputPath>bin\x86\Release-Stable\</OutputPath>
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
@ -54,8 +69,10 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="IW4Info.cs" />
<Compile Include="Plugin.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Vector3.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\SharedLibrary\SharedLibrary.csproj">

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace StatsPlugin
{
public class Vector3
{
public float X { get; private set; }
public float Y { get; private set; }
public float Z { get; private set; }
public Vector3(float x, float y, float z)
{
X = x;
Y = y;
Z = z;
}
public override string ToString()
{
return $"({X}, {Y}, {Z})";
}
public static Vector3 Parse(string s)
{
bool valid = Regex.Match(s, @"\(-?[0-9]+.?[0-9]*,\ -?[0-9]+.?[0-9]*,\ -?[0-9]+.?[0-9]*\)").Success;
if (!valid)
throw new FormatException("Vector3 is not in correct format");
string removeParenthesis = s.Substring(1, s.Length - 2);
string[] eachPoint = removeParenthesis.Split(',');
return new Vector3(float.Parse(eachPoint[0]), float.Parse(eachPoint[1]), float.Parse(eachPoint[2]));
}
public static double Distance(Vector3 a, Vector3 b)
{
return Math.Round(Math.Sqrt(Math.Pow(b.X - a.X, 2) + Math.Pow(b.Y - a.Y, 2) + Math.Pow(b.Z - a.Z, 2)), 2);
}
}
}