added stats!

actually unban by database id
check for latest update
adjusted rcon queue for slower output
hide more console output
This commit is contained in:
RaidMax 2015-03-09 20:28:37 -05:00
parent 2486bc9993
commit fea331cabf
8 changed files with 183 additions and 41 deletions

View File

@ -442,4 +442,18 @@ namespace IW4MAdmin
E.Origin.Tell("Sucessfully sent message"); 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()));
}
}
} }

View File

@ -10,22 +10,39 @@ namespace IW4MAdmin
{ {
class Database class Database
{ {
public Database(String FN) public enum Type
{
Clients,
Stats
}
public Database(String FN, Type T)
{ {
FileName = FN; FileName = FN;
DBCon = String.Format("Data Source={0}", FN); DBCon = String.Format("Data Source={0}", FN);
Con = new SQLiteConnection(DBCon); Con = new SQLiteConnection(DBCon);
Init(); DBType = T;
Init(T);
} }
private void Init() private void Init(Type T)
{ {
if(!File.Exists(FileName)) if(!File.Exists(FileName))
{ {
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);"; 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); ExecuteNonQuery(query);
query = "CREATE TABLE [BANS] ( [Reason] TEXT NULL, [npID] TEXT NULL, [bannedByID] Text NULL)"; query = "CREATE TABLE [BANS] ( [Reason] TEXT NULL, [npID] TEXT NULL, [bannedByID] Text NULL);";
ExecuteNonQuery(query); 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; 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) public void removeBan(String GUID)
{ {
String Query = String.Format("DELETE FROM BANS WHERE npID = '{0}'", GUID); String Query = String.Format("DELETE FROM BANS WHERE npID = '{0}'", GUID);
@ -114,30 +146,54 @@ namespace IW4MAdmin
{ {
Dictionary<String, object> newPlayer = new Dictionary<String, object>(); Dictionary<String, object> newPlayer = new Dictionary<String, object>();
if (DBType == Type.Clients)
{
newPlayer.Add("Name", Utilities.removeNastyChars(P.getName())); newPlayer.Add("Name", Utilities.removeNastyChars(P.getName()));
newPlayer.Add("npID", P.getID()); newPlayer.Add("npID", P.getID());
newPlayer.Add("Level", (int)P.getLevel()); newPlayer.Add("Level", (int)P.getLevel());
// newPlayer.Add("Number", P.getClientNum().ToString());
newPlayer.Add("LastOffense", ""); newPlayer.Add("LastOffense", "");
newPlayer.Add("Connections", 1); 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) public void updatePlayer(Player P)
{ {
Dictionary<String, object> updatedPlayer = new Dictionary<String, object>(); Dictionary<String, object> updatedPlayer = new Dictionary<String, object>();
if (DBType == Type.Clients)
{
updatedPlayer.Add("Name", P.getName()); updatedPlayer.Add("Name", P.getName());
updatedPlayer.Add("npID", P.getID()); updatedPlayer.Add("npID", P.getID());
updatedPlayer.Add("Level", (int)P.getLevel()); updatedPlayer.Add("Level", (int)P.getLevel());
// updatedPlayer.Add("Number", P.getClientNum().ToString());
updatedPlayer.Add("LastOffense", P.getLastO()); updatedPlayer.Add("LastOffense", P.getLastO());
updatedPlayer.Add("Connections", P.getConnections()); 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) public void addBan(Ban B)
{ {
Dictionary<String, object> newBan = new Dictionary<String, object>(); Dictionary<String, object> newBan = new Dictionary<String, object>();
@ -240,5 +296,6 @@ namespace IW4MAdmin
private String FileName; private String FileName;
private String DBCon; private String DBCon;
private SQLiteConnection Con; private SQLiteConnection Con;
private Type DBType;
} }
} }

View File

@ -69,16 +69,22 @@ namespace IW4MAdmin
if (eventType == "Q") if (eventType == "Q")
return new Event(GType.Disconnect, null, SV.clientFromLine(line, 3, false), null, null); 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[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 -! -_]"); Regex rgx = new Regex("[^a-zA-Z0-9 -! -_]");
string message = rgx.Replace(line[4], ""); 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); 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); return new Event(GType.MapEnd, null, null, null, null);
if (line[0].Length > 400) // blaze it if (line[0].Length > 400) // blaze it

View File

@ -10,17 +10,17 @@ namespace IW4MAdmin
static String IP; static String IP;
static int Port; static int Port;
static String RCON; static String RCON;
static double Version = 0.2; static public double Version = 0.2;
static public double latestVersion;
static void Main(string[] args) static void Main(string[] args)
{ {
double.TryParse(checkUpdate(), out latestVersion);
Console.WriteLine("====================================================="); Console.WriteLine("=====================================================");
Console.WriteLine(" IW4M ADMIN"); Console.WriteLine(" IW4M ADMIN");
Console.WriteLine(" by RaidMax "); Console.WriteLine(" by RaidMax ");
String latestVer = checkUpdate(); if (latestVersion != 0)
if (latestVer != null) Console.WriteLine(" Version " + Version + " (latest " + latestVersion + ")");
Console.WriteLine(" Version " + Version + " (latest " + latestVer + ")");
else else
Console.WriteLine(" Version " + Version + " (unable to retrieve latest)"); Console.WriteLine(" Version " + Version + " (unable to retrieve latest)");
Console.WriteLine("====================================================="); Console.WriteLine("=====================================================");
@ -80,7 +80,7 @@ namespace IW4MAdmin
static String checkUpdate() 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(); return Ver.Read();
} }
} }

View File

@ -4,6 +4,28 @@ using System.Text;
namespace IW4MAdmin 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 class Player
{ {
public enum Permission public enum Permission
@ -50,9 +72,9 @@ namespace IW4MAdmin
return npID; return npID;
} }
public String getDBID() public int getDBID()
{ {
return Convert.ToString(dbID); return dbID;
} }
public int getClientNum() public int getClientNum()
@ -130,5 +152,6 @@ namespace IW4MAdmin
public Event lastEvent; public Event lastEvent;
public String LastOffense; public String LastOffense;
public int Warnings; public int Warnings;
public Stats stats;
} }
} }

View File

@ -24,6 +24,7 @@ namespace IW4MAdmin
Instance = I; Instance = I;
toSend = new Queue<String>(); toSend = new Queue<String>();
} }
//When we don't care about a response //When we don't care about a response
public bool sendRCON(String message) public bool sendRCON(String message)
{ {
@ -116,8 +117,10 @@ namespace IW4MAdmin
{ {
sendRCON(toSend.Peek()); sendRCON(toSend.Peek());
toSend.Dequeue(); toSend.Dequeue();
Utilities.Wait(0.85);
} }
Utilities.Wait(0.3); else
Utilities.Wait(0.1);
} }
} }

View File

@ -22,7 +22,8 @@ namespace IW4MAdmin
logFile = new file("admin_" + port + ".log", true); logFile = new file("admin_" + port + ".log", true);
Log = new Log(logFile, Log.Level.Production); Log = new Log(logFile, Log.Level.Production);
players = new List<Player>(new Player[18]); players = new List<Player>(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(); Bans = DB.getBans();
owner = DB.getOwner(); owner = DB.getOwner();
maps = new List<Map>(); maps = new List<Map>();
@ -94,6 +95,12 @@ namespace IW4MAdmin
P = A; 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()] = null;
players[P.getClientNum()] = P; players[P.getClientNum()] = P;
@ -101,13 +108,13 @@ namespace IW4MAdmin
if (P.getLevel() == Player.Permission.Banned) 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(); String Message = "^1Player Kicked: ^7Previously Banned for ^5" + isBanned(P).getReason();
P.Kick(Message); P.Kick(Message);
} }
else else
Log.Write("Client " + P.getName() + " connecting...", Log.Level.Production); Log.Write("Client " + P.getName() + " connecting...", Log.Level.Debug);
return true; return true;
} }
@ -121,7 +128,7 @@ namespace IW4MAdmin
//Remove player by CLIENT NUMBER //Remove player by CLIENT NUMBER
public bool removePlayer(int cNum) 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; players[cNum] = null;
clientnum--; clientnum--;
return true; return true;
@ -204,6 +211,9 @@ namespace IW4MAdmin
int cNum = -1; int cNum = -1;
int.TryParse(Args[0], out cNum); int.TryParse(Args[0], out cNum);
if (Args[0] == String.Empty)
return C;
if (Args[0][0] == '@') if (Args[0][0] == '@')
{ {
int dbID = -1; int dbID = -1;
@ -282,6 +292,8 @@ namespace IW4MAdmin
lastMessage = DateTime.Now - start; lastMessage = DateTime.Now - start;
if(lastMessage.TotalSeconds > messageTime && messages.Count > 0) 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]); Broadcast(messages[nextMessage]);
if (nextMessage == (messages.Count - 1)) if (nextMessage == (messages.Count - 1))
nextMessage = 0; nextMessage = 0;
@ -496,12 +508,30 @@ namespace IW4MAdmin
if (E.Type == Event.GType.Disconnect) if (E.Type == Event.GType.Disconnect)
{ {
if (getNumPlayers() > 0) if (getNumPlayers() > 0)
{
DB.updatePlayer(E.Origin);
stats.updatePlayer(E.Origin);
removePlayer(E.Origin.getClientNum()); removePlayer(E.Origin.getClientNum());
}
return true; 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.Type == Event.GType.Say)
{ {
if (E.Data.Length < 2)
return false;
Log.Write("Message from " + E.Origin.getName() + ": " + E.Data, Log.Level.Debug); Log.Write("Message from " + E.Origin.getName() + ": " + E.Data, Log.Level.Debug);
if (E.Data.Substring(0, 1) != "!") if (E.Data.Substring(0, 1) != "!")
@ -539,6 +569,13 @@ namespace IW4MAdmin
if (E.Type == Event.GType.MapEnd) if (E.Type == Event.GType.MapEnd)
{ {
Log.Write("Game ending...", Log.Level.Production); 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; return true;
} }
@ -578,11 +615,11 @@ namespace IW4MAdmin
{ {
foreach (Ban B in Bans) foreach (Ban B in Bans)
{ {
if (B.getID() == GUID) if (B.getID() == Target.getID())
{ {
DB.removeBan(GUID); DB.removeBan(GUID);
Bans.Remove(B); Bans.Remove(B);
Player P = DB.getPlayer(GUID, 0); Player P = DB.getPlayer(Target.getID(), 0);
P.setLevel(Player.Permission.User); P.setLevel(Player.Permission.User);
DB.updatePlayer(P); DB.updatePlayer(P);
return true; 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 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 <player> <reason>.", "w", Player.Permission.Moderator, 2, true)); commands.Add(new Warn("warn", "warn player for infringing rules syntax: !warn <player> <reason>.", "w", Player.Permission.Moderator, 2, true));
commands.Add(new WarnClear("warnclear", "remove all warning for a player syntax: !warnclear <player>.", "wc", Player.Permission.Administrator, 1, true)); commands.Add(new WarnClear("warnclear", "remove all warning for a player syntax: !warnclear <player>.", "wc", Player.Permission.Administrator, 1, true));
commands.Add(new Unban("unban", "unban player by guid. syntax: !unban <guid>.", "ub", Player.Permission.Administrator, 1, false)); commands.Add(new Unban("unban", "unban player by guid. syntax: !unban <guid>.", "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 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 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 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 <player>", "f", Player.Permission.Administrator, 1, false)); commands.Add(new Find("find", "find player in database. syntax: !find <player>", "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 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 <player> <message>", "pm", Player.Permission.User, 2, true)); commands.Add(new PrivateMessage("privatemessage", "send message to other player. syntax: !pm <player> <message>", "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 = "stats", desc = "view your server stats.", requiredPer = 0 });
commands.Add(new commands { command = "speed", desc = "change player speed. syntax: !speed <number>", requiredPer = 3 }); commands.Add(new commands { command = "speed", desc = "change player speed. syntax: !speed <number>", requiredPer = 3 });
@ -735,6 +773,7 @@ namespace IW4MAdmin
public List<Map> maps; public List<Map> maps;
public List<String> rules; public List<String> rules;
public Queue<Event> events; public Queue<Event> events;
public Database stats;
//Info //Info
private String IP; private String IP;

View File

@ -1,5 +1,5 @@
60 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! ^5IW4M Admin ^7sees ^5YOU!
Cheaters are ^1unwelcome ^7 on this server Cheaters are ^1unwelcome ^7 on this server
Did you know 8/10 people agree with unverified statistics? Did you know 8/10 people agree with unverified statistics?