Hey,
i just was bored, and i made that plugin, written in 40 minutes. I know it is useless...
Features
* Statistic saving
Saves match statistic, and statistic for ALL matches.
* Better log
Says all player's events.
Multi-kill system
Simple multikill system.
* Most/Bad player count
Finds best player, player with most score, player with most assists and deaths. Prints every 30 seconds. ( Configurable ).
Also you can see thoose players by thoose cmds:
!mostkills - prints most player
!mostscore - prints player with most score
!mostdeaths - most deaths player
!mostassists - most assists
*Files
In plugins folder you will see folder called "statAddon"
That folder contains config.ini ( configuration ), stats.log(stats for LAST match), stats.ini (stats for ALL matches ), game.log ( client events etc.. ).
*Killing sprees
Just simple system which counts player kills and print them. ( 10, 15, 20 .. etc )
To be added
Stat saving into site (mysql)
smth more..
Information
I know it is useless, i just made that because i was bored.
Do not delete folder called "statAddon" in plugin folder.
Bugs, problems
some bugs possible, because addon is bugged.
Credits
@JayDi - creator
@zxz0O0 - help with code ( client count )
DOWNLOAD
statAddon.rar (Size: 7.62 KB / Downloads: 490)
S O U R C E
i just was bored, and i made that plugin, written in 40 minutes. I know it is useless...
Features
* Statistic saving
Saves match statistic, and statistic for ALL matches.
* Better log
Says all player's events.
Multi-kill system
Simple multikill system.
* Most/Bad player count
Finds best player, player with most score, player with most assists and deaths. Prints every 30 seconds. ( Configurable ).
Also you can see thoose players by thoose cmds:
!mostkills - prints most player
!mostscore - prints player with most score
!mostdeaths - most deaths player
!mostassists - most assists
*Files
In plugins folder you will see folder called "statAddon"
That folder contains config.ini ( configuration ), stats.log(stats for LAST match), stats.ini (stats for ALL matches ), game.log ( client events etc.. ).
*Killing sprees
Just simple system which counts player kills and print them. ( 10, 15, 20 .. etc )
To be added
Stat saving into site (mysql)
smth more..
Information
I know it is useless, i just made that because i was bored.
Do not delete folder called "statAddon" in plugin folder.
Bugs, problems
some bugs possible, because addon is bugged.
Credits
@JayDi - creator
@zxz0O0 - help with code ( client count )
DOWNLOAD

S O U R C E
Spoiler (Click to View)
Code:
using System; // main
using System.IO; // file sys
using System.Threading; // threads
using System.Collections;
using Addon; // main
using System.Collections.Generic; // i forgot
using System.Text; // StringBuilder
using System.Runtime.InteropServices; // dllimport
namespace statAddon
{
public class statsAddon : CPlugin
{
/* ===== Variables ===== */
IniFile ini; // custom ini file for settings
IniFile saves; // custom ini for global stats
Hashtable mk = new Hashtable(); // multikill count for each client
int msgDelay; // message time in seconds between messages
StreamWriter log; // log file
StreamWriter logforstats; // log for stats
/* ===== Stat counting values ===== */
int maprestarts = 0;
int mapchanges = 0;
int killedplayers = 0;
int totalDmg = 0;
int connectedPlayers = 0;
int spawnedPlayers = 0;
int disconnectedPlayers = 0;
int changedWeps = 0;
int saidWords = 0;
/* ===== Addon specific functions ===== */
public override void OnServerLoad()
{
try
{
// set the current culture to the invariant culture
Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
// create ini file for settings
ini = new IniFile(@Directory.GetCurrentDirectory() + "/plugins/statAddon/config.ini");
// create ini file for stat saving
saves = new IniFile(@Directory.GetCurrentDirectory() + "/plugins/statAddon/stats.ini");
// global stat saves
if (saves.IniReadValue("stats", "kills") == "") { saves.IniWriteValue("stats", "kills", "0"); }
if (saves.IniReadValue("stats", "tDamage") == "") { saves.IniWriteValue("stats", "tDamage", "0"); }
if (saves.IniReadValue("stats", "mapRestarts") == "") { saves.IniWriteValue("stats", "mapRestarts", "0"); }
if (saves.IniReadValue("stats", "mapChanges") == "") { saves.IniWriteValue("stats", "mapChanges", "0"); }
if (saves.IniReadValue("stats", "connected") == "") { saves.IniWriteValue("stats", "connected", "0"); }
if (saves.IniReadValue("stats", "spawned") == "") { saves.IniWriteValue("stats", "spawned", "0"); }
if (saves.IniReadValue("stats", "disconnected") == "") { saves.IniWriteValue("stats", "disconnected", "0"); }
if (saves.IniReadValue("stats", "changedWeps") == "") { saves.IniWriteValue("stats", "changedWeps", "0"); }
if (saves.IniReadValue("stats", "chatUsed") == "") { saves.IniWriteValue("stats", "chatUsed", "0"); }
// set if empty
if (ini.IniReadValue("stat", "mostKillMsg") == "")
{
ini.IniWriteValue("stat", "mostKillMsg", "^2 got ^3most ^1kills: ^3");
}
if (ini.IniReadValue("stat", "mostDeathMsg") == "")
{
ini.IniWriteValue("stat", "mostDeathMsg", "^2 got ^3most ^1deaths: ^3");
}
if (ini.IniReadValue("stat", "mostScoreMsg") == "")
{
ini.IniWriteValue("stat", "mostScoreMsg", "^2 got ^3most ^1score: ^3");
}
if (ini.IniReadValue("stat", "mostAssistMsg") == "")
{
ini.IniWriteValue("stat", "mostAssistMsg", "^2 got ^3most ^1assist: ^3");
}
// enable sprees?
if (ini.IniReadValue("stat", "enableSprees") == "")
{
ini.IniWriteValue("stat", "enableSprees", "true");
}
// mk = multikill
if (ini.IniReadValue("stat", "mkpart1") == "")
{
ini.IniWriteValue("stat", "mkpart1", " ^2have got multi kill with^7");
}
if (ini.IniReadValue("stat", "mkpart2") == "")
{
ini.IniWriteValue("stat", "mkpart2", " ^2kills!");
}
// configurations
if (ini.IniReadValue("stat", "msgDelay") == "")
{
ini.IniWriteValue("stat", "msgDelay", "30");
}
string mDelay = ini.IniReadValue("stat", "msgDelay");
//var r_modeHeightin = int.Parse(r_modeHeight, System.Globalization.CultureInfo.InvariantCulture);
msgDelay = Convert.ToInt32(mDelay);
// check folders
if (@Directory.Exists(@Directory.GetCurrentDirectory() + "/plugins/statAddon/"))
{
// create log for game.log ( like games_mp.log but better )
try { createLog(); } // trying to create log
catch { System.Windows.Forms.MessageBox.Show("Failed to create log file"); } // tell us
// create log for global counts
try { createStatsLog(); } // trying to create log
catch { System.Windows.Forms.MessageBox.Show("Failed to create log file"); } // tell us
ServerPrint("Stats plugin by JayDi Loaded!");
ServerPrint("ItsMods.com");
// success!
writeLog("Stat plugin successfuly loaded");
// let spam begin
ThreadPool.QueueUserWorkItem(new WaitCallback(spamMsg));
}
else
{
ServerPrint("Stats plugin failed to load. Please check folder name, it must be ''statAddon''");
}
}
catch (Exception x)
{
System.Windows.Forms.MessageBox.Show("Failed to load stats plugin!\n" + x.Message, "Error!");
}
}
public override void OnMapChange()
{
ServerPrint("[dev: statplugin - writting logs into file and saving...]");
mapchanges++;
writeStatsInLog();
}
public override void OnFastRestart()
{
maprestarts++;
}
public override void OnPlayerDisconnect(ServerClient Client)
{
disconnectedPlayers++;
}
public override void OnPlayerChangeWeapon(ServerClient Client, int WeaponID)
{
changedWeps++;
}
public override void OnPlayerConnect(ServerClient Client)
{
connectedPlayers++;
writeLog("Player " + Client.Name + " connected");
}
public override void OnPlayerSpawned(ServerClient Client)
{
if (mk[Client.XUID] == null)
{
mk.Add(Client.XUID, 0);
}
spawnedPlayers++;
writeLog("Player " + Client.Name + " spawned!");
}
public override int OnPlayerDamaged(ServerClient Attacker, ServerClient Victim, string Weapon, int Damage)
{
if (Damage >= Victim.Other.Health && Attacker.Team != Victim.Team && Victim.XUID != Attacker.XUID)
{
try
{
// count killed players
killedplayers++;
// total iDamage
totalDmg += Damage;
// threaded mk count
domk(Attacker);
// row
string w = ini.IniReadValue("stats", "enableSprees");
if (w == "true")
{
specialAbility(Attacker);
}
// write
writeLog("Player " + Victim.Name + " were killed by " + Attacker.Name);
}
catch (Exception z)
{
// just testing
iPrintLn("error " + z.Message, Attacker);
}
}
return Damage;
}
public override ChatType OnSay(string Message, ServerClient Client)
{
if (Message == "!mostkills")
{
mostPlayer(true, Client);
}
if (Message == "!mostdeaths")
{
badPlayer(true, Client);
}
if (Message == "!mostassists")
{
assistPlayer(true, Client);
}
if (Message == "!mostscore")
{
scorePlayer(true, Client);
}
saidWords++;
writeLog(Client.Name + " said: " + Message);
return base.OnSay(Message, Client);
}
/* ==== Specific functions ==== */
/// <summary>
/// Sprees like UT
/// </summary>
/// <param name="Client"></param>
void specialAbility(ServerClient Client)
{
try
{
if (Client.Stats.Kills == 10)
{
iPrintLnBold(Client.Name + " - ^110 kills in the row!", null);
}
if (Client.Stats.Kills == 15)
{
iPrintLnBold(Client.Name + " - ^215 kills in the row!", null);
}
if (Client.Stats.Kills == 20)
{
iPrintLnBold(Client.Name + " - ^320 kills in the row!", null);
}
if (Client.Stats.Kills == 25)
{
iPrintLnBold(Client.Name + " - ^325 kills in the row!", null);
}
if (Client.Stats.Kills == 30)
{
iPrintLnBold(Client.Name + " - ^430 kills in the row!", null);
}
}
catch
{
ServerPrint("error while printing client kills ( spree )");
}
}
/// <summary>
/// Log for stats
/// </summary>
private void createStatsLog()
{
if (!File.Exists(@Directory.GetCurrentDirectory() + "/plugins/statAddon/stats.log"))
{
logforstats = new StreamWriter(Directory.GetCurrentDirectory() + "/plugins/statAddon/stats.log");
}
else
{
logforstats = File.AppendText(Directory.GetCurrentDirectory() + "/plugins/statAddon/stats.log");
}
}
/// <summary>
/// Write all statistic in log
/// </summary>
public void writeStatsInLog()
{
try
{
logforstats.WriteLine("========= NEW MATCH ( " + DateTime.Now + " ) =========");
// last match values
logforstats.WriteLine("Killed players: " + killedplayers);
logforstats.WriteLine("Connected players: " + connectedPlayers);
logforstats.WriteLine("Spawned players: " + spawnedPlayers);
logforstats.WriteLine("Total chat using: " + saidWords);
logforstats.WriteLine("Map restarts: " + maprestarts);
logforstats.WriteLine("Map changes: " + mapchanges);
logforstats.WriteLine("Disconnected players: " + disconnectedPlayers);
logforstats.WriteLine("Weapons changed: " + changedWeps);
logforstats.WriteLine("Total damage: " + totalDmg);
if (GetClients().Count > 0)
{
logforstats.WriteLine("Most kills: " + getMostKills().Name);
logforstats.WriteLine("Most deaths: " + getMostDeaths().Name);
logforstats.WriteLine("Most score: " + getMostScore().Name);
logforstats.WriteLine("Most assists: " + getMostAssists().Name);
}
else
{
ServerPrint("[dev: writting log in file(stats)]: 0 or 1 player at server. Aborting!]");
}
logforstats.WriteLine("===========================================================");
// Flush them.
logforstats.Flush();
//logforstats.Close();
ThreadPool.QueueUserWorkItem(new WaitCallback(threadedWrite));
}
catch (Exception x)
{
System.Windows.Forms.MessageBox.Show(x.Message);
}
}
private void threadedWrite(object x)
{
try
{
// values for ALL matches
// kills
var kills2 = saves.IniReadValue("stats", "kills");
int killsSave = int.Parse(kills2, System.Globalization.CultureInfo.InvariantCulture);
int totalKills = killsSave + killedplayers;
saves.IniWriteValue("stats", "kills", "" + totalKills);
Thread.Sleep(200);
// dmg
var dmg2 = saves.IniReadValue("stats", "tDamage");
int dmgSave = int.Parse(dmg2, System.Globalization.CultureInfo.InvariantCulture);
int totalDmg2 = dmgSave + totalDmg;
saves.IniWriteValue("stats", "tDamage", "" + totalDmg2);
Thread.Sleep(200);
// map restarts
var mr2 = saves.IniReadValue("stats", "mapRestarts");
int mrSave = int.Parse(mr2, System.Globalization.CultureInfo.InvariantCulture);
int totalMr = mrSave + maprestarts;
saves.IniWriteValue("stats", "mapRestarts", "" + totalMr);
Thread.Sleep(200);
// map changes
var mc2 = saves.IniReadValue("stats", "mapChanges");
int mcSave = int.Parse(mc2, System.Globalization.CultureInfo.InvariantCulture);
int totalMc = mcSave + mapchanges;
saves.IniWriteValue("stats", "mapChanges", "" + totalMc);
Thread.Sleep(200);
// connected
var c2 = saves.IniReadValue("stats", "connected");
int cSave = int.Parse(c2, System.Globalization.CultureInfo.InvariantCulture);
int totalc = cSave + connectedPlayers;
saves.IniWriteValue("stats", "connected", "" + totalc);
Thread.Sleep(200);
// spawned
var s2 = saves.IniReadValue("stats", "spawned");
int sSave = int.Parse(s2, System.Globalization.CultureInfo.InvariantCulture);
int totalSp = sSave + spawnedPlayers;
saves.IniWriteValue("stats", "spawned", "" + totalSp);
Thread.Sleep(200);
// disconnected
var dc2 = saves.IniReadValue("stats", "disconnected");
int dcSave = int.Parse(dc2, System.Globalization.CultureInfo.InvariantCulture);
int totaldc = dcSave + disconnectedPlayers;
saves.IniWriteValue("stats", "disconnected", "" + totaldc);
Thread.Sleep(200);
// changed weps
var cw2 = saves.IniReadValue("stats", "changedweps");
int cwSave = int.Parse(cw2, System.Globalization.CultureInfo.InvariantCulture);
int totalcw = cwSave + changedWeps;
saves.IniWriteValue("stats", "changedweps", "" + totalcw);
Thread.Sleep(200);
// chat used
var cu2 = saves.IniReadValue("stats", "saidwords");
int cuSave = int.Parse(c2, System.Globalization.CultureInfo.InvariantCulture);
int totalcu = cuSave + saidWords;
saves.IniWriteValue("stats", "saidwords", "" + totalcu);
Thread.Sleep(200);
ServerPrint("[dev: statplugin - log successfuly saved]");
}
catch
{
ServerPrint("Error in ''threadedWrite'' func");
}
}
/// <summary>
/// Create log
/// </summary>
private void createLog()
{
if (!File.Exists(@Directory.GetCurrentDirectory() + "/plugins/statAddon/game.log"))
{
log = new StreamWriter(Directory.GetCurrentDirectory() + "/plugins/statAddon/game.log");
}
else
{
log = File.AppendText(Directory.GetCurrentDirectory() + "/plugins/statAddon/game.log");
}
}
/// <summary>
/// Write in log
/// </summary>
/// <param name="logtext">Text which will be written in logfile.</param>
public void writeLog(string logtext)
{
try
{
log.WriteLine("[" + DateTime.Now + "] " + logtext);
log.Flush();
}
catch
{
ServerPrint("[dev: statplugin - log writting failed]");
}
}
/// <summary>
/// Spamming messages
/// </summary>
public void spamMsg(Object x)
{
List<ServerClient> clients = new List<ServerClient>();
while (true) // looped
{
Thread.Sleep(msgDelay * 1000);
clients = GetClients();
if (clients != null && clients.Count > 0)
{
try
{
mostPlayer(false, null, true);
Thread.Sleep(msgDelay * 1000);
}
catch(Exception z)
{
System.Windows.Forms.MessageBox.Show("error\n"+ z.Message);
}
}
clients = GetClients();
if (clients != null && clients.Count > 0)
{
try{
badPlayer(false, null, true);
Thread.Sleep(msgDelay * 1000);
}
catch (Exception z)
{
System.Windows.Forms.MessageBox.Show("error\n" + z.Message);
}
}
clients = GetClients();
if (clients != null && clients.Count > 0)
{
try{
scorePlayer(false, null, true);
Thread.Sleep(msgDelay * 1000);
}
catch (Exception z)
{
System.Windows.Forms.MessageBox.Show("error\n" + z.Message);
}
}
clients = GetClients();
if (clients != null && clients.Count > 0)
{
try{
assistPlayer(false, null, true);
Thread.Sleep(msgDelay * 1000);
}
catch (Exception z)
{
System.Windows.Forms.MessageBox.Show("error\n" + z.Message);
}
}
iPrintLn("^2Stats plugin by ^3JayDi", null);
}
}
/// <summary>
/// Multikill
/// </summary>
/// <param name="Client"></param>
void domk(ServerClient Client)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(multikill), Client);
}
void multikill(Object arg)
{
try
{
ServerClient Attacker = (ServerClient)arg;
mk[Attacker.XUID] = ((int)mk[Attacker.XUID] + 1);
if ((int)mk[Attacker.XUID] > 1)
{
iPrintLn(Attacker.Name + " " + ini.IniReadValue("stat", "mkpart1") + " " + (int)mk[Attacker.XUID] + " " + ini.IniReadValue("stat", "mkpart2"), null);
}
Thread.Sleep(90);
writeLog(Attacker.Name + " got multikill with " + mk[Attacker.XUID] + " kills!");
mk[Attacker.XUID] = 0;
ServerPrint("[dev: statplugin - Successfuly called ''multikill'' func]");
}
catch
{
ServerPrint("[dev: statplugin - Error in ''multikill'' func]");
}
}
/// <summary>
/// Most player stat - score
/// </summary>
public void scorePlayer(bool bold = false, ServerClient client = null, bool tellclient = false)
{
ServerClient guy = getMostScore();
string msg = ini.IniReadValue("stat", "mostScoreMsg");
if (bold == false)
{
iPrintLn(guy.Name + "" + msg + "" + guy.Stats.Score + "", client);
}
else
{
iPrintLnBold(guy.Name + "" + msg + "" + guy.Stats.Score + "", client);
}
if (tellclient == true)
{
tellToAll(guy.Name + "" + msg + "" + guy.Stats.Score);
}
writeLog(guy.Name + " got most score!");
}
public ServerClient getMostScore()
{
int temp = 0;
ServerClient guy = null;
for (int i = 0; i < GetClients().Count; i++)
{
if (GetClients()[i].Stats.Score >= temp)
{
temp = GetClients()[i].Stats.Score;
guy = GetClients()[i];
}
}
return guy;
}
/// <summary>
/// Tell to all clients ( num )
/// </summary>
/// <param name="msg"></param>
void tellToAll(string msg)
{
List<ServerClient> clients = new List<ServerClient>();
clients = GetClients();
if (clients != null && clients.Count > 0) // check
{
foreach (ServerClient c in GetClients())
{
TellClient(c.ClientNum, msg, true);
}
}
}
/// <summary>
/// Most player stat - assists
/// </summary>
public void assistPlayer(bool bold = false, ServerClient client = null, bool tellClient = false)
{
ServerClient guy = getMostAssists();
string msg = ini.IniReadValue("stat", "mostAssistMsg");
if (bold == false)
{
iPrintLn(guy.Name + "" + msg + "" + guy.Stats.Assists + "", null);
}
else
{
iPrintLnBold(guy.Name + "" + msg + "" + guy.Stats.Assists + "", null);
}
if (tellClient == true)
{
tellToAll(guy.Name + "" + msg + "" + guy.Stats.Assists);
}
writeLog(guy.Name + " got most assists!");
}
public ServerClient getMostAssists()
{
int temp = 0;
ServerClient guy = null;
for (int i = 0; i < GetClients().Count; i++)
{
if (GetClients()[i].Stats.Assists >= temp)
{
temp = GetClients()[i].Stats.Assists;
guy = GetClients()[i];
}
}
return guy;
}
/// <summary>
/// Most player stat - deaths
/// </summary>
public void badPlayer(bool bold = false, ServerClient client = null, bool tellclient = false)
{
ServerClient guy = getMostDeaths();
string msg = ini.IniReadValue("stat", "mostDeathMsg");
if (bold == false)
{
iPrintLn(guy.Name + "" + msg + "" + guy.Stats.Deaths + "", null);
}
else
{
iPrintLnBold(guy.Name + "" + msg + "" + guy.Stats.Deaths + "", null);
}
if (tellclient == true)
{
tellToAll( guy.Name + "" + msg + "" + guy.Stats.Deaths + "");
}
writeLog(guy.Name + " got most deaths!");
}
public ServerClient getMostDeaths()
{
int temp = 0;
ServerClient guy = null;
for (int i = 0; i < GetClients().Count; i++)
{
if (GetClients()[i].Stats.Deaths >= temp)
{
temp = GetClients()[i].Stats.Deaths;
guy = GetClients()[i];
}
}
return guy;
}
/// <summary>
/// Most player stat - kills
/// </summary>
public void mostPlayer(bool bold = false, ServerClient client = null, bool tellClient = false)
{
ServerClient guy = getMostKills();
string msg = ini.IniReadValue("stat", "mostKillMsg");
if (bold == false)
{
iPrintLn(guy.Name + "" + msg + "" + guy.Stats.Kills + "", null);
}
else
{
iPrintLnBold(guy.Name + "" + msg + "" + guy.Stats.Kills + "", null);
}
if (tellClient == true)
{
tellToAll( guy.Name + "" + msg + "" + guy.Stats.Kills + "");
}
writeLog(guy.Name + " got most kills!");
}
public ServerClient getMostKills()
{
int temp = 0;
ServerClient guy = null;
for (int i = 0; i < GetClients().Count; i++)
{
if (GetClients()[i].Stats.Kills >= temp)
{
temp = GetClients()[i].Stats.Kills;
guy = GetClients()[i];
}
}
return guy;
}
}
/// <summary>
/// by jaydi
/// </summary>
public class IniFile
{
public string path;
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section,
string key, string val, string filePath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section,
string key, string def, StringBuilder retVal,
int size, string filePath);
public IniFile(string INIPath)
{
path = INIPath;
}
public void IniWriteValue(string Section, string Key, string Value)
{
WritePrivateProfileString(Section, Key, Value, this.path);
}
public string IniReadValue(string Section, string Key)
{
StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString(Section, Key, "", temp,
255, this.path);
return temp.ToString();
}
}
}