From fea331cabf219a8029fbff0365271d7301621010 Mon Sep 17 00:00:00 2001 From: RaidMax Date: Mon, 9 Mar 2015 20:28:37 -0500 Subject: [PATCH] added stats! actually unban by database id check for latest update adjusted rcon queue for slower output hide more console output --- Admin/Command.cs | 14 ++++++ Admin/Database.cs | 99 ++++++++++++++++++++++++++++++--------- Admin/Event.cs | 12 +++-- Admin/Main.cs | 12 ++--- Admin/Player.cs | 27 ++++++++++- Admin/RCON.cs | 5 +- Admin/Server.cs | 53 ++++++++++++++++++--- Admin/config/messages.cfg | 2 +- 8 files changed, 183 insertions(+), 41 deletions(-) diff --git a/Admin/Command.cs b/Admin/Command.cs index dc7860afa..15674f2db 100644 --- a/Admin/Command.cs +++ b/Admin/Command.cs @@ -442,4 +442,18 @@ namespace IW4MAdmin E.Origin.Tell("Sucessfully sent message"); } } + + class _Stats : Command + { + public _Stats(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } + + public override void Execute(Event E) + { + if (E.Target == null) + E.Origin.Tell(String.Format("^5{0} ^7KILLS | ^5{1} ^7DEATHS | ^5{2} ^7KDR | ^5{3} ^7SKILL", E.Origin.stats.Kills, E.Origin.stats.Deaths, E.Origin.stats.KDR, E.Origin.stats.Skill)); + else + E.Origin.Tell(String.Format("[^3{4}^7] ^5{0} ^7KILLS | ^5{1} ^7DEATHS | ^5{2} ^7KDR | ^5{3} ^7SKILL", E.Target.stats.Kills, E.Target.stats.Deaths, E.Target.stats.KDR, E.Target.stats.Skill, E.Target.getName())); + } + } + } diff --git a/Admin/Database.cs b/Admin/Database.cs index fa34fd99b..0d78b3e22 100644 --- a/Admin/Database.cs +++ b/Admin/Database.cs @@ -10,22 +10,39 @@ namespace IW4MAdmin { class Database { - public Database(String FN) + public enum Type + { + Clients, + Stats + } + + public Database(String FN, Type T) { FileName = FN; DBCon = String.Format("Data Source={0}", FN); Con = new SQLiteConnection(DBCon); - Init(); + DBType = T; + Init(T); } - private void Init() + private void Init(Type T) { if(!File.Exists(FileName)) { - String query = "CREATE TABLE [CLIENTS] ( [Name] TEXT NULL, [npID] TEXT NULL, [Number] INTEGER PRIMARY KEY AUTOINCREMENT, [Level] INT DEFAULT 0 NULL, [LastOffense] TEXT NULL, [Connections] INT DEFAULT 1 NULL);"; - ExecuteNonQuery(query); - query = "CREATE TABLE [BANS] ( [Reason] TEXT NULL, [npID] TEXT NULL, [bannedByID] Text NULL)"; - ExecuteNonQuery(query); + switch (T) + { + case Type.Clients: + String query = "CREATE TABLE [CLIENTS] ( [Name] TEXT NULL, [npID] TEXT NULL, [Number] INTEGER PRIMARY KEY AUTOINCREMENT, [Level] INT DEFAULT 0 NULL, [LastOffense] TEXT NULL, [Connections] INT DEFAULT 1 NULL);"; + ExecuteNonQuery(query); + query = "CREATE TABLE [BANS] ( [Reason] TEXT NULL, [npID] TEXT NULL, [bannedByID] Text NULL);"; + ExecuteNonQuery(query); + break; + case Type.Stats: + String query_stats = "CREATE TABLE [STATS] ( [Number] INTEGER, [KILLS] INTEGER DEFAULT 0, [DEATHS] INTEGER DEFAULT 0, [KDR] REAL DEFAULT 0, [SKILL] REAL DEFAULT 0 );"; + ExecuteNonQuery(query_stats); + break; + } + } } @@ -104,6 +121,21 @@ namespace IW4MAdmin return Bans; } + public Stats getStats(int DBID) + { + String Query = String.Format("SELECT * FROM STATS WHERE Number = '{0}'", DBID); + DataTable Result = GetDataTable(Query); + + if (Result != null && Result.Rows.Count > 0) + { + DataRow ResponseRow = Result.Rows[0]; + return new Stats(Convert.ToInt32(ResponseRow["KILLS"]), Convert.ToInt32(ResponseRow["DEATHS"]), Convert.ToDouble(ResponseRow["KDR"]), Convert.ToDouble(ResponseRow["SKILL"])); + } + + else + return null; + } + public void removeBan(String GUID) { String Query = String.Format("DELETE FROM BANS WHERE npID = '{0}'", GUID); @@ -114,28 +146,52 @@ namespace IW4MAdmin { Dictionary newPlayer = new Dictionary(); - newPlayer.Add("Name", Utilities.removeNastyChars(P.getName())); - newPlayer.Add("npID", P.getID()); - newPlayer.Add("Level", (int)P.getLevel()); - // newPlayer.Add("Number", P.getClientNum().ToString()); - newPlayer.Add("LastOffense", ""); - newPlayer.Add("Connections", 1); + if (DBType == Type.Clients) + { + newPlayer.Add("Name", Utilities.removeNastyChars(P.getName())); + newPlayer.Add("npID", P.getID()); + newPlayer.Add("Level", (int)P.getLevel()); + newPlayer.Add("LastOffense", ""); + newPlayer.Add("Connections", 1); - Insert("CLIENTS", newPlayer); + Insert("CLIENTS", newPlayer); + } + + if (DBType == Type.Stats) + { + newPlayer.Add("Number", P.getDBID()); + newPlayer.Add("KILLS", 0); + newPlayer.Add("DEATHS", 0); + newPlayer.Add("KDR", 0); + newPlayer.Add("SKILL", 0); + Insert("STATS", newPlayer); + } } public void updatePlayer(Player P) { Dictionary updatedPlayer = new Dictionary(); - updatedPlayer.Add("Name", P.getName()); - updatedPlayer.Add("npID", P.getID()); - updatedPlayer.Add("Level", (int)P.getLevel()); - // updatedPlayer.Add("Number", P.getClientNum().ToString()); - updatedPlayer.Add("LastOffense", P.getLastO()); - updatedPlayer.Add("Connections", P.getConnections()); + if (DBType == Type.Clients) + { + updatedPlayer.Add("Name", P.getName()); + updatedPlayer.Add("npID", P.getID()); + updatedPlayer.Add("Level", (int)P.getLevel()); + updatedPlayer.Add("LastOffense", P.getLastO()); + updatedPlayer.Add("Connections", P.getConnections()); - Update("CLIENTS", updatedPlayer, String.Format("npID = '{0}'", P.getID())); + Update("CLIENTS", updatedPlayer, String.Format("npID = '{0}'", P.getID())); + } + + if (DBType == Type.Stats) + { + updatedPlayer.Add("KILLS", P.stats.Kills); + updatedPlayer.Add("DEATHS", P.stats.Deaths); + updatedPlayer.Add("KDR", P.stats.KDR); + updatedPlayer.Add("SKILL", P.stats.Skill); + + Update("STATS", updatedPlayer, String.Format("Number = '{0}'", P.getDBID())); + } } public void addBan(Ban B) @@ -240,5 +296,6 @@ namespace IW4MAdmin private String FileName; private String DBCon; private SQLiteConnection Con; + private Type DBType; } } diff --git a/Admin/Event.cs b/Admin/Event.cs index f9e0c061b..35fdef7ab 100644 --- a/Admin/Event.cs +++ b/Admin/Event.cs @@ -69,16 +69,22 @@ namespace IW4MAdmin if (eventType == "Q") return new Event(GType.Disconnect, null, SV.clientFromLine(line, 3, false), null, null); + if (eventType == "K") + return new Event(GType.Kill, line[9], SV.clientFromLine(line[8]), SV.clientFromLine(line[4]), null); + if (line[0].Substring(line[0].Length - 3).Trim() == "say") { + if (line.Length < 4) + { + Console.WriteLine("SAY FUCKED UP"); + return null; + } Regex rgx = new Regex("[^a-zA-Z0-9 -! -_]"); string message = rgx.Replace(line[4], ""); - if (message.Length < 2) - message = " "; return new Event(GType.Say, Utilities.removeNastyChars(message), SV.clientFromLine(line, 3, false), null, null); } - if (eventType == "d") + if (eventType == "d" || eventType == ":") return new Event(GType.MapEnd, null, null, null, null); if (line[0].Length > 400) // blaze it diff --git a/Admin/Main.cs b/Admin/Main.cs index 6da523153..649116605 100644 --- a/Admin/Main.cs +++ b/Admin/Main.cs @@ -10,17 +10,17 @@ namespace IW4MAdmin static String IP; static int Port; static String RCON; - static double Version = 0.2; - + static public double Version = 0.2; + static public double latestVersion; static void Main(string[] args) { + double.TryParse(checkUpdate(), out latestVersion); Console.WriteLine("====================================================="); Console.WriteLine(" IW4M ADMIN"); Console.WriteLine(" by RaidMax "); - String latestVer = checkUpdate(); - if (latestVer != null) - Console.WriteLine(" Version " + Version + " (latest " + latestVer + ")"); + if (latestVersion != 0) + Console.WriteLine(" Version " + Version + " (latest " + latestVersion + ")"); else Console.WriteLine(" Version " + Version + " (unable to retrieve latest)"); Console.WriteLine("====================================================="); @@ -80,7 +80,7 @@ namespace IW4MAdmin static String checkUpdate() { - Connection Ver = new Connection("http://raidmax.org/IW4M/Admin/version.txt"); + Connection Ver = new Connection("http://raidmax.org/IW4M/Admin/version.php"); return Ver.Read(); } } diff --git a/Admin/Player.cs b/Admin/Player.cs index 4434d8102..5b90389de 100644 --- a/Admin/Player.cs +++ b/Admin/Player.cs @@ -4,6 +4,28 @@ using System.Text; namespace IW4MAdmin { + class Stats + { + public Stats(int K, int D, double kdr, double skill) + { + Kills = K; + Deaths = D; + KDR = kdr; + Skill = Math.Round(skill,2); + } + + public void Update() + { + KDR = Math.Round((double)((double)Kills / (double)Deaths), 2); + Skill = Math.Round((double)Kills * (((double)Kills / (double)Deaths) / 10), 2); + } + + public int Kills; + public int Deaths; + public double KDR; + public double Skill; + } + class Player { public enum Permission @@ -50,9 +72,9 @@ namespace IW4MAdmin return npID; } - public String getDBID() + public int getDBID() { - return Convert.ToString(dbID); + return dbID; } public int getClientNum() @@ -130,5 +152,6 @@ namespace IW4MAdmin public Event lastEvent; public String LastOffense; public int Warnings; + public Stats stats; } } diff --git a/Admin/RCON.cs b/Admin/RCON.cs index 69188c3e7..d62eaf178 100644 --- a/Admin/RCON.cs +++ b/Admin/RCON.cs @@ -24,6 +24,7 @@ namespace IW4MAdmin Instance = I; toSend = new Queue(); } + //When we don't care about a response public bool sendRCON(String message) { @@ -116,8 +117,10 @@ namespace IW4MAdmin { sendRCON(toSend.Peek()); toSend.Dequeue(); + Utilities.Wait(0.85); } - Utilities.Wait(0.3); + else + Utilities.Wait(0.1); } } diff --git a/Admin/Server.cs b/Admin/Server.cs index 3b491381c..d2a8f6871 100644 --- a/Admin/Server.cs +++ b/Admin/Server.cs @@ -22,7 +22,8 @@ namespace IW4MAdmin logFile = new file("admin_" + port + ".log", true); Log = new Log(logFile, Log.Level.Production); players = new List(new Player[18]); - DB = new Database("clients.dll"); + DB = new Database("clients.rm", Database.Type.Clients); + stats = new Database("stats_" + port + ".rm", Database.Type.Stats); Bans = DB.getBans(); owner = DB.getOwner(); maps = new List(); @@ -94,6 +95,12 @@ namespace IW4MAdmin P = A; } + P.stats = stats.getStats(P.getDBID()); + if (P.stats == null) + { + stats.addPlayer(P); + P.stats = new Stats(0, 0, 0, 0); + } players[P.getClientNum()] = null; players[P.getClientNum()] = P; @@ -101,13 +108,13 @@ namespace IW4MAdmin if (P.getLevel() == Player.Permission.Banned) { - Log.Write("Banned client " + P.getName() + " trying to connect...", Log.Level.Production); + Log.Write("Banned client " + P.getName() + " trying to connect...", Log.Level.Debug); String Message = "^1Player Kicked: ^7Previously Banned for ^5" + isBanned(P).getReason(); P.Kick(Message); } else - Log.Write("Client " + P.getName() + " connecting...", Log.Level.Production); + Log.Write("Client " + P.getName() + " connecting...", Log.Level.Debug); return true; } @@ -121,7 +128,7 @@ namespace IW4MAdmin //Remove player by CLIENT NUMBER public bool removePlayer(int cNum) { - Log.Write("Client at " + cNum + " disconnecting...", Log.Level.Production); + Log.Write("Client at " + cNum + " disconnecting...", Log.Level.Debug); players[cNum] = null; clientnum--; return true; @@ -204,6 +211,9 @@ namespace IW4MAdmin int cNum = -1; int.TryParse(Args[0], out cNum); + if (Args[0] == String.Empty) + return C; + if (Args[0][0] == '@') { int dbID = -1; @@ -282,6 +292,8 @@ namespace IW4MAdmin lastMessage = DateTime.Now - start; if(lastMessage.TotalSeconds > messageTime && messages.Count > 0) { + if (Program.Version != Program.latestVersion && Program.latestVersion != 0) + Broadcast("^5IW4M Admin ^7is outdated. Please ^5update ^7to version " + Program.latestVersion); Broadcast(messages[nextMessage]); if (nextMessage == (messages.Count - 1)) nextMessage = 0; @@ -496,12 +508,30 @@ namespace IW4MAdmin if (E.Type == Event.GType.Disconnect) { if (getNumPlayers() > 0) + { + DB.updatePlayer(E.Origin); + stats.updatePlayer(E.Origin); removePlayer(E.Origin.getClientNum()); + } return true; } + if (E.Type == Event.GType.Kill) + { + if (E.Origin != null && E.Target != null) + { + E.Origin.stats.Kills++; + E.Origin.stats.Update(); + E.Target.stats.Deaths++; + E.Target.stats.Update(); + } + } + if (E.Type == Event.GType.Say) { + if (E.Data.Length < 2) + return false; + Log.Write("Message from " + E.Origin.getName() + ": " + E.Data, Log.Level.Debug); if (E.Data.Substring(0, 1) != "!") @@ -539,6 +569,13 @@ namespace IW4MAdmin if (E.Type == Event.GType.MapEnd) { Log.Write("Game ending...", Log.Level.Production); + foreach (Player P in players) + { + if (P == null) + continue; + stats.updatePlayer(P); + Log.Write("Updated stats for client " + P.getDBID(), Log.Level.Debug); + } return true; } @@ -578,11 +615,11 @@ namespace IW4MAdmin { foreach (Ban B in Bans) { - if (B.getID() == GUID) + if (B.getID() == Target.getID()) { DB.removeBan(GUID); Bans.Remove(B); - Player P = DB.getPlayer(GUID, 0); + Player P = DB.getPlayer(Target.getID(), 0); P.setLevel(Player.Permission.User); DB.updatePlayer(P); return true; @@ -711,13 +748,14 @@ namespace IW4MAdmin commands.Add(new Uptime("uptime", "get current application running time. syntax: !uptime.", "up", Player.Permission.Moderator, 0, false)); commands.Add(new Warn("warn", "warn player for infringing rules syntax: !warn .", "w", Player.Permission.Moderator, 2, true)); commands.Add(new WarnClear("warnclear", "remove all warning for a player syntax: !warnclear .", "wc", Player.Permission.Administrator, 1, true)); - commands.Add(new Unban("unban", "unban player by guid. syntax: !unban .", "ub", Player.Permission.Administrator, 1, false)); + commands.Add(new Unban("unban", "unban player by guid. syntax: !unban .", "ub", Player.Permission.Administrator, 1, true)); commands.Add(new Admins("admins", "list currently connected admins. syntax: !admins.", "a", Player.Permission.User, 0, false)); commands.Add(new Wisdom("wisdom", "get a random wisdom quote. syntax: !wisdom", "w", Player.Permission.Administrator, 0, false)); commands.Add(new MapCMD("map", "change to specified map. syntax: !map", "m", Player.Permission.Administrator, 1, false)); commands.Add(new Find("find", "find player in database. syntax: !find ", "f", Player.Permission.Administrator, 1, false)); commands.Add(new Rules("rules", "list server rules. syntax: !rules", "r", Player.Permission.User, 0, false)); commands.Add(new PrivateMessage("privatemessage", "send message to other player. syntax: !pm ", "pm", Player.Permission.User, 2, true)); + commands.Add(new _Stats("stats", "view your stats or another player's. syntax: !stats", "xlrstats", Player.Permission.User, 0, true)); /* commands.Add(new commands { command = "stats", desc = "view your server stats.", requiredPer = 0 }); commands.Add(new commands { command = "speed", desc = "change player speed. syntax: !speed ", requiredPer = 3 }); @@ -735,6 +773,7 @@ namespace IW4MAdmin public List maps; public List rules; public Queue events; + public Database stats; //Info private String IP; diff --git a/Admin/config/messages.cfg b/Admin/config/messages.cfg index 80e503617..c7a6c5b60 100644 --- a/Admin/config/messages.cfg +++ b/Admin/config/messages.cfg @@ -1,5 +1,5 @@ 60 -This server uses ^5IW4M Admin v0.1 ^7get it at ^5raidmax.org +This server uses ^5IW4M Admin v0.2 ^7get it at ^5raidmax.org ^5IW4M Admin ^7sees ^5YOU! Cheaters are ^1unwelcome ^7 on this server Did you know 8/10 people agree with unverified statistics? \ No newline at end of file