reworked some stats, redid the macro -> Tokens

added reset stats commands
broadcast for some commands
This commit is contained in:
RaidMax 2017-05-31 00:31:56 -05:00
parent 354cec0951
commit 063449d9c4
17 changed files with 322 additions and 240 deletions

View File

@ -22,6 +22,7 @@ namespace IW4MAdmin
Database AliasesDatabase; Database AliasesDatabase;
SharedLibrary.Interfaces.IPenaltyList ClientPenalties; SharedLibrary.Interfaces.IPenaltyList ClientPenalties;
List<Command> Commands; List<Command> Commands;
List<MessageToken> MessageTokens;
Kayak.IScheduler webServiceTask; Kayak.IScheduler webServiceTask;
Thread WebThread; Thread WebThread;
public SharedLibrary.Interfaces.ILogger Logger { get; private set; } public SharedLibrary.Interfaces.ILogger Logger { get; private set; }
@ -38,6 +39,7 @@ namespace IW4MAdmin
Servers = new List<Server>(); Servers = new List<Server>();
Commands = new List<Command>(); Commands = new List<Command>();
TaskStatuses = new List<AsyncStatus>(); TaskStatuses = new List<AsyncStatus>();
MessageTokens = new List<MessageToken>();
ClientDatabase = new ClientsDB("Database/clients.rm"); ClientDatabase = new ClientsDB("Database/clients.rm");
AliasesDatabase = new AliasesDB("Database/aliases.rm"); AliasesDatabase = new AliasesDB("Database/aliases.rm");
@ -106,6 +108,7 @@ namespace IW4MAdmin
{ {
Name = "Web Thread" Name = "Web Thread"
}; };
WebThread.Start(); WebThread.Start();
Running = true; Running = true;
@ -162,5 +165,10 @@ namespace IW4MAdmin
{ {
return Logger; return Logger;
} }
public IList<MessageToken> GetMessageTokens()
{
return MessageTokens;
}
} }
} }

View File

@ -20,7 +20,7 @@ namespace IW4MAdmin
public void RemovePenalty(Penalty P) public void RemovePenalty(Penalty P)
{ {
Manager.GetInstance().GetClientDatabase().RemoveBan(P.npID); Manager.GetInstance().GetClientDatabase().RemoveBan(P.OffenderID);
} }
public List<Penalty> FindPenalties(Player P) public List<Penalty> FindPenalties(Player P)

View File

@ -40,7 +40,7 @@ namespace IW4MAdmin
if (Origin == null) if (Origin == null)
return allAliases; return allAliases;
Aliases currentIdentityAliases = Manager.GetAliasesDatabase().GetPlayerAliases(Origin.databaseID); Aliases currentIdentityAliases = Manager.GetAliasesDatabase().GetPlayerAliases(Origin.DatabaseID);
if (currentIdentityAliases == null) if (currentIdentityAliases == null)
return allAliases; return allAliases;
@ -51,50 +51,50 @@ namespace IW4MAdmin
override public async Task<bool> AddPlayer(Player P) override public async Task<bool> AddPlayer(Player P)
{ {
if (P.clientID < 0 || P.clientID > (Players.Count-1) || P.Ping < 1 || P.Ping == 999) // invalid index if (P.ClientID < 0 || P.ClientID > (Players.Count-1) || P.Ping < 1 || P.Ping == 999) // invalid index
return false; return false;
if (Players[P.clientID] != null && Players[P.clientID].npID == P.npID) // if someone has left and a new person has taken their spot between polls if (Players[P.ClientID] != null && Players[P.ClientID].NetworkID == P.NetworkID) // if someone has left and a new person has taken their spot between polls
{ {
// update their ping // update their ping
Players[P.clientID].Ping = P.Ping; Players[P.ClientID].Ping = P.Ping;
return true; return true;
} }
Logger.WriteDebug($"Client slot #{P.clientID} now reserved"); Logger.WriteDebug($"Client slot #{P.ClientID} now reserved");
try try
{ {
Player NewPlayer = Manager.GetClientDatabase().GetPlayer(P.npID, P.clientID); Player NewPlayer = Manager.GetClientDatabase().GetPlayer(P.NetworkID, P.ClientID);
if (NewPlayer == null) // first time connecting if (NewPlayer == null) // first time connecting
{ {
Logger.WriteDebug($"Client slot #{P.clientID} first time connecting"); Logger.WriteDebug($"Client slot #{P.ClientID} first time connecting");
Manager.GetClientDatabase().AddPlayer(P); Manager.GetClientDatabase().AddPlayer(P);
NewPlayer = Manager.GetClientDatabase().GetPlayer(P.npID, P.clientID); NewPlayer = Manager.GetClientDatabase().GetPlayer(P.NetworkID, P.ClientID);
Manager.GetAliasesDatabase().AddPlayerAliases(new Aliases(NewPlayer.databaseID, NewPlayer.Name, NewPlayer.IP)); Manager.GetAliasesDatabase().AddPlayerAliases(new Aliases(NewPlayer.DatabaseID, NewPlayer.Name, NewPlayer.IP));
} }
List<Player> Admins = Manager.GetClientDatabase().GetAdmins(); List<Player> Admins = Manager.GetClientDatabase().GetAdmins();
if (Admins.Find(x => x.Name == P.Name) != null) if (Admins.Find(x => x.Name == P.Name) != null)
{ {
if ((Admins.Find(x => x.Name == P.Name).npID != P.npID) && NewPlayer.Level < Player.Permission.Moderator) if ((Admins.Find(x => x.Name == P.Name).NetworkID != P.NetworkID) && NewPlayer.Level < Player.Permission.Moderator)
await this.ExecuteCommandAsync("clientkick " + P.clientID + " \"Please do not impersonate an admin^7\""); await this.ExecuteCommandAsync("clientkick " + P.ClientID + " \"Please do not impersonate an admin^7\"");
} }
// below this needs to be optimized ~ 425ms runtime // below this needs to be optimized ~ 425ms runtime
NewPlayer.updateName(P.Name.Trim()); NewPlayer.updateName(P.Name.Trim());
NewPlayer.Alias = Manager.GetAliasesDatabase().GetPlayerAliases(NewPlayer.databaseID); NewPlayer.Alias = Manager.GetAliasesDatabase().GetPlayerAliases(NewPlayer.DatabaseID);
if (NewPlayer.Alias == null) if (NewPlayer.Alias == null)
{ {
Manager.GetAliasesDatabase().AddPlayerAliases(new Aliases(NewPlayer.databaseID, NewPlayer.Name, NewPlayer.IP)); Manager.GetAliasesDatabase().AddPlayerAliases(new Aliases(NewPlayer.DatabaseID, NewPlayer.Name, NewPlayer.IP));
NewPlayer.Alias = Manager.GetAliasesDatabase().GetPlayerAliases(NewPlayer.databaseID); NewPlayer.Alias = Manager.GetAliasesDatabase().GetPlayerAliases(NewPlayer.DatabaseID);
} }
if (P.lastEvent == null || P.lastEvent.Owner == null) if (P.lastEvent == null || P.lastEvent.Owner == null)
NewPlayer.lastEvent = new Event(Event.GType.Say, null, NewPlayer, null, this); // this is messy but its throwing an error when they've started it too late NewPlayer.lastEvent = new Event(Event.GType.Say, null, NewPlayer, null, this); // this is messy but its throwing an error when they've started in too late
else else
NewPlayer.lastEvent = P.lastEvent; NewPlayer.lastEvent = P.lastEvent;
@ -120,7 +120,7 @@ namespace IW4MAdmin
if (NewPlayer.Level == Player.Permission.Banned) // their guid is already banned so no need to check aliases if (NewPlayer.Level == Player.Permission.Banned) // their guid is already banned so no need to check aliases
{ {
Logger.WriteInfo($"Banned client {P.Name}::{P.npID} trying to connect..."); Logger.WriteInfo($"Banned client {P.Name}::{P.NetworkID} trying to connect...");
await NewPlayer.Kick(NewPlayer.lastOffense != null ? "^7Previously banned for ^5 " + NewPlayer.lastOffense : "^7Previous Ban", NewPlayer); await NewPlayer.Kick(NewPlayer.lastOffense != null ? "^7Previously banned for ^5 " + NewPlayer.lastOffense : "^7Previous Ban", NewPlayer);
return true; return true;
@ -140,19 +140,19 @@ namespace IW4MAdmin
if (B != null && B.BType == Penalty.Type.Ban) if (B != null && B.BType == Penalty.Type.Ban)
{ {
Logger.WriteDebug($"Banned client {aP.Name}::{aP.npID} is connecting with new alias {NewPlayer.Name}"); Logger.WriteDebug($"Banned client {aP.Name}::{aP.NetworkID} is connecting with new alias {NewPlayer.Name}");
NewPlayer.lastOffense = String.Format("Evading ( {0} )", aP.Name); NewPlayer.lastOffense = String.Format("Evading ( {0} )", aP.Name);
await NewPlayer.Ban(B.Reason != null ? "^7Previously banned for ^5 " + B.Reason : "^7Previous Ban", NewPlayer); await NewPlayer.Ban(B.Reason != null ? "^7Previously banned for ^5 " + B.Reason : "^7Previous Ban", NewPlayer);
Players[NewPlayer.clientID] = null; Players[NewPlayer.ClientID] = null;
return true; return true;
} }
} }
Players[NewPlayer.clientID] = null; Players[NewPlayer.ClientID] = null;
Players[NewPlayer.clientID] = NewPlayer; Players[NewPlayer.ClientID] = NewPlayer;
Logger.WriteInfo($"Client {NewPlayer.Name}::{NewPlayer.npID} connecting..."); // they're clean Logger.WriteInfo($"Client {NewPlayer.Name}::{NewPlayer.NetworkID} connecting..."); // they're clean
// todo: get this out of here // todo: get this out of here
while (chatHistory.Count > Math.Ceiling((double)ClientNum / 2)) while (chatHistory.Count > Math.Ceiling((double)ClientNum / 2))
@ -168,7 +168,7 @@ namespace IW4MAdmin
catch (Exception E) catch (Exception E)
{ {
Manager.GetLogger().WriteError($"Unable to add player {P.Name}::{P.npID}"); Manager.GetLogger().WriteError($"Unable to add player {P.Name}::{P.NetworkID}");
Manager.GetLogger().WriteDebug(E.StackTrace); Manager.GetLogger().WriteDebug(E.StackTrace);
return false; return false;
} }
@ -183,7 +183,7 @@ namespace IW4MAdmin
Leaving.Connections++; Leaving.Connections++;
Manager.GetClientDatabase().UpdatePlayer(Leaving); Manager.GetClientDatabase().UpdatePlayer(Leaving);
Logger.WriteInfo($"Client {Leaving.Name}::{Leaving.npID} disconnecting..."); Logger.WriteInfo($"Client {Leaving.Name}::{Leaving.NetworkID} disconnecting...");
await ExecuteEvent(new Event(Event.GType.Disconnect, "", Leaving, null, this)); await ExecuteEvent(new Event(Event.GType.Disconnect, "", Leaving, null, this));
Players[cNum] = null; Players[cNum] = null;
@ -241,6 +241,7 @@ namespace IW4MAdmin
override public async Task<Command> ValidateCommand(Event E) override public async Task<Command> ValidateCommand(Event E)
{ {
string CommandString = E.Data.Substring(1, E.Data.Length - 1).Split(' ')[0]; string CommandString = E.Data.Substring(1, E.Data.Length - 1).Split(' ')[0];
E.Message = E.Data;
Command C = null; Command C = null;
foreach (Command cmd in Manager.GetCommands()) foreach (Command cmd in Manager.GetCommands())
@ -270,14 +271,11 @@ namespace IW4MAdmin
throw new SharedLibrary.Exceptions.CommandException($"{E.Origin} did not supply enough arguments for \"{C.Name}\""); throw new SharedLibrary.Exceptions.CommandException($"{E.Origin} did not supply enough arguments for \"{C.Name}\"");
} }
if (C.needsTarget) if (C.needsTarget || Args.Length > 0)
{ {
int cNum = -1; int cNum = -1;
int.TryParse(Args[0], out cNum); int.TryParse(Args[0], out cNum);
// this is so ugly wtf is it doing here?
if (C.Name == "stats" && Args.Length == 1)
E.Target = E.Origin;
if (Args[0] == String.Empty) if (Args[0] == String.Empty)
return C; return C;
@ -346,7 +344,7 @@ namespace IW4MAdmin
for (int i = 0; i < Players.Count; i++) for (int i = 0; i < Players.Count; i++)
{ {
if (CurrentPlayers.Find(p => p.clientID == i) == null && Players[i] != null) if (CurrentPlayers.Find(p => p.ClientID == i) == null && Players[i] != null)
await RemovePlayer(i); await RemovePlayer(i);
} }
@ -397,8 +395,7 @@ namespace IW4MAdmin
if (lastMessage.TotalSeconds > messageTime && messages.Count > 0 && Players.Count > 0) if (lastMessage.TotalSeconds > messageTime && messages.Count > 0 && Players.Count > 0)
{ {
initMacros(); // somethings dynamically change so we have to re-init the dictionary await Broadcast(Utilities.ProcessMessageToken(Manager.GetMessageTokens(), messages[nextMessage]));
await Broadcast(Utilities.LoadMacro(Macros, messages[nextMessage]));
if (nextMessage == (messages.Count - 1)) if (nextMessage == (messages.Count - 1))
nextMessage = 0; nextMessage = 0;
else else
@ -653,7 +650,7 @@ namespace IW4MAdmin
await Target.Kick("Too many warnings!", Origin); await Target.Kick("Too many warnings!", Origin);
else else
{ {
Penalty newPenalty = new Penalty(Penalty.Type.Warning, Reason.StripColors(), Target.npID, Origin.npID, DateTime.Now, Target.IP); Penalty newPenalty = new Penalty(Penalty.Type.Warning, Reason.StripColors(), Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP);
Manager.GetClientPenalties().AddPenalty(newPenalty); Manager.GetClientPenalties().AddPenalty(newPenalty);
Target.Warnings++; Target.Warnings++;
String Message = String.Format("^1WARNING ^7[^3{0}^7]: ^3{1}^7, {2}", Target.Warnings, Target.Name, Target.lastOffense); String Message = String.Format("^1WARNING ^7[^3{0}^7]: ^3{1}^7, {2}", Target.Warnings, Target.Name, Target.lastOffense);
@ -663,21 +660,21 @@ namespace IW4MAdmin
public override async Task Kick(String Reason, Player Target, Player Origin) public override async Task Kick(String Reason, Player Target, Player Origin)
{ {
if (Target.clientID > -1) if (Target.ClientID > -1)
{ {
String Message = "^1Player Kicked: ^5" + Reason; String Message = "^1Player Kicked: ^5" + Reason;
Penalty newPenalty = new Penalty(Penalty.Type.Kick, Reason.StripColors().Trim(), Target.npID, Origin.npID, DateTime.Now, Target.IP); Penalty newPenalty = new Penalty(Penalty.Type.Kick, Reason.StripColors().Trim(), Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP);
Manager.GetClientPenalties().AddPenalty(newPenalty); Manager.GetClientPenalties().AddPenalty(newPenalty);
await this.ExecuteCommandAsync("clientkick " + Target.clientID + " \"" + Message + "^7\""); await this.ExecuteCommandAsync("clientkick " + Target.ClientID + " \"" + Message + "^7\"");
} }
} }
public override async Task TempBan(String Reason, Player Target, Player Origin) public override async Task TempBan(String Reason, Player Target, Player Origin)
{ {
if (Target.clientID > -1) if (Target.ClientID > -1)
{ {
await this.ExecuteCommandAsync($"tempbanclient {Target.clientID } \"^1Player Temporarily Banned: ^5{ Reason } (1 hour)\""); await this.ExecuteCommandAsync($"tempbanclient {Target.ClientID } \"^1Player Temporarily Banned: ^5{ Reason } (1 hour)\"");
Penalty newPenalty = new Penalty(Penalty.Type.TempBan, Reason.StripColors(), Target.npID, Origin.npID, DateTime.Now, Target.IP); Penalty newPenalty = new Penalty(Penalty.Type.TempBan, Reason.StripColors(), Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP);
await Task.Run(() => await Task.Run(() =>
{ {
Manager.GetClientPenalties().AddPenalty(newPenalty); Manager.GetClientPenalties().AddPenalty(newPenalty);
@ -696,7 +693,7 @@ namespace IW4MAdmin
{ {
Logger.WriteError("Ban target is null"); Logger.WriteError("Ban target is null");
Logger.WriteDebug($"Message: {Message}"); Logger.WriteDebug($"Message: {Message}");
Logger.WriteDebug($"Origin: {Origin.Name}::{Origin.npID}"); Logger.WriteDebug($"Origin: {Origin.Name}::{Origin.NetworkID}");
return; return;
} }
@ -705,16 +702,16 @@ namespace IW4MAdmin
{ {
if (server.getPlayers().Count > 0) if (server.getPlayers().Count > 0)
{ {
var activeClient = server.getPlayers().Find(x => x.npID == Target.npID); var activeClient = server.getPlayers().Find(x => x.NetworkID == Target.NetworkID);
if (activeClient != null) if (activeClient != null)
await server.ExecuteCommandAsync("tempbanclient " + activeClient.clientID + " \"" + Message + "^7" + GetWebsiteString() + "^7\""); await server.ExecuteCommandAsync("tempbanclient " + activeClient.ClientID + " \"" + Message + "^7" + GetWebsiteString() + "^7\"");
} }
} }
if (Origin != null) if (Origin != null)
{ {
Target.setLevel(Player.Permission.Banned); Target.setLevel(Player.Permission.Banned);
Penalty newBan = new Penalty(Penalty.Type.Ban, Target.lastOffense, Target.npID, Origin.npID, DateTime.Now, Target.IP); Penalty newBan = new Penalty(Penalty.Type.Ban, Target.lastOffense, Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP);
await Task.Run(() => await Task.Run(() =>
{ {
@ -727,14 +724,14 @@ namespace IW4MAdmin
List<Report> toRemove = new List<Report>(); List<Report> toRemove = new List<Report>();
foreach (Report R in Reports) foreach (Report R in Reports)
{ {
if (R.Target.npID == Target.npID) if (R.Target.NetworkID == Target.NetworkID)
toRemove.Add(R); toRemove.Add(R);
} }
foreach (Report R in toRemove) foreach (Report R in toRemove)
{ {
Reports.Remove(R); Reports.Remove(R);
Logger.WriteInfo("Removing report for banned GUID - " + R.Origin.npID); Logger.WriteInfo("Removing report for banned GUID - " + R.Origin.NetworkID);
} }
} }
} }
@ -753,7 +750,7 @@ namespace IW4MAdmin
Manager.GetClientPenalties().RemovePenalty(PenaltyToRemove); Manager.GetClientPenalties().RemovePenalty(PenaltyToRemove);
Player P = Manager.GetClientDatabase().GetPlayer(Target.npID, -1); Player P = Manager.GetClientDatabase().GetPlayer(Target.NetworkID, -1);
P.setLevel(Player.Permission.User); P.setLevel(Player.Permission.User);
Manager.GetClientDatabase().UpdatePlayer(P); Manager.GetClientDatabase().UpdatePlayer(P);
}); });
@ -789,10 +786,8 @@ namespace IW4MAdmin
override public void initMacros() override public void initMacros()
{ {
Macros = new Dictionary<String, Object>(); Manager.GetMessageTokens().Add(new MessageToken("TOTALPLAYERS", Manager.GetClientDatabase().TotalPlayers().ToString));
Macros.Add("TOTALPLAYERS", Manager.GetClientDatabase().TotalPlayers()); Manager.GetMessageTokens().Add(new MessageToken("VERSION", Program.Version.ToString));
Macros.Add("TOTALKILLS", totalKills);
Macros.Add("VERSION", IW4MAdmin.Program.Version);
} }
override public void initCommands() override public void initCommands()

View File

@ -196,7 +196,7 @@ namespace IW4MAdmin
foreach (Player P in S.getPlayers()) foreach (Player P in S.getPlayers())
{ {
PlayerInfo pInfo = new PlayerInfo(); PlayerInfo pInfo = new PlayerInfo();
pInfo.playerID = P.databaseID; pInfo.playerID = P.DatabaseID;
pInfo.playerName = P.Name; pInfo.playerName = P.Name;
pInfo.playerLevel = P.Level.ToString(); pInfo.playerLevel = P.Level.ToString();
eachServer.players.Add(pInfo); eachServer.players.Add(pInfo);
@ -366,8 +366,8 @@ namespace IW4MAdmin
foreach (var p in selectedPenalties) foreach (var p in selectedPenalties)
{ {
Player admin = Manager.GetInstance().GetClientDatabase().GetPlayer(p.bannedByID, 0); Player admin = Manager.GetInstance().GetClientDatabase().GetPlayer(p.PenaltyOriginID, 0);
Player penalized = Manager.GetInstance().GetClientDatabase().GetPlayer(p.npID, 0); Player penalized = Manager.GetInstance().GetClientDatabase().GetPlayer(p.OffenderID, 0);
if (admin == null && penalized == null) if (admin == null && penalized == null)
continue; continue;
if (admin == null) if (admin == null)
@ -379,8 +379,8 @@ namespace IW4MAdmin
pInfo.penaltyTime = SharedLibrary.Utilities.timePassed(p.When); pInfo.penaltyTime = SharedLibrary.Utilities.timePassed(p.When);
pInfo.penaltyType = p.BType.ToString(); pInfo.penaltyType = p.BType.ToString();
pInfo.playerName = penalized.Name; pInfo.playerName = penalized.Name;
pInfo.playerID = penalized.databaseID; pInfo.playerID = penalized.DatabaseID;
if (admin.npID == penalized.npID) if (admin.NetworkID == penalized.NetworkID)
{ {
pInfo.adminName = "IW4MAdmin"; pInfo.adminName = "IW4MAdmin";
pInfo.adminLevel = Player.Permission.Console.ToString(); pInfo.adminLevel = Player.Permission.Console.ToString();
@ -621,11 +621,11 @@ namespace IW4MAdmin
var playerAliases = Manager.GetInstance().Servers.First().GetAliases(pp); var playerAliases = Manager.GetInstance().Servers.First().GetAliases(pp);
PlayerInfo eachPlayer = new PlayerInfo(); PlayerInfo eachPlayer = new PlayerInfo();
eachPlayer.playerID = pp.databaseID; eachPlayer.playerID = pp.DatabaseID;
eachPlayer.playerIP = pp.IP; eachPlayer.playerIP = pp.IP;
eachPlayer.playerLevel = pp.Level.ToString(); eachPlayer.playerLevel = pp.Level.ToString();
eachPlayer.playerName = pp.Name; eachPlayer.playerName = pp.Name;
eachPlayer.playernpID = pp.npID; eachPlayer.playernpID = pp.NetworkID;
eachPlayer.forumID = -1; eachPlayer.forumID = -1;
eachPlayer.authed = authed; eachPlayer.authed = authed;
eachPlayer.showV2Features = false; eachPlayer.showV2Features = false;

Binary file not shown.

View File

@ -7,9 +7,9 @@ using System.Threading.Tasks;
namespace SharedLibrary.Commands namespace SharedLibrary.Commands
{ {
class Quit : Command class CQuit : Command
{ {
public Quit(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CQuit(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
@ -36,9 +36,9 @@ namespace SharedLibrary.Commands
} }
} }
class Warn : Command class Cwarn : Command
{ {
public Warn(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public Cwarn(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
@ -50,9 +50,9 @@ namespace SharedLibrary.Commands
} }
} }
class WarnClear : Command class CWarnClear : Command
{ {
public WarnClear(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CWarnClear(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
@ -63,9 +63,9 @@ namespace SharedLibrary.Commands
} }
} }
class Kick : Command class CKick : Command
{ {
public Kick(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CKick(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
@ -77,9 +77,9 @@ namespace SharedLibrary.Commands
} }
} }
class Say : Command class CSay : Command
{ {
public Say(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CSay(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
@ -87,16 +87,19 @@ namespace SharedLibrary.Commands
} }
} }
class TempBan : Command class CTempBan : Command
{ {
public TempBan(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CTempBan(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
E.Target.lastOffense = SharedLibrary.Utilities.RemoveWords(E.Data, 1); E.Target.lastOffense = SharedLibrary.Utilities.RemoveWords(E.Data, 1);
String Message = E.Target.lastOffense; String Message = E.Target.lastOffense;
if (E.Origin.Level > E.Target.Level) if (E.Origin.Level > E.Target.Level)
{
await E.Target.TempBan(Message, E.Origin); await E.Target.TempBan(Message, E.Origin);
await E.Origin.Tell($"Successfully temp banned {E.Target.Name}");
}
else else
await E.Origin.Tell("You cannot temp ban " + E.Target.Name); await E.Origin.Tell("You cannot temp ban " + E.Target.Name);
} }
@ -118,7 +121,7 @@ namespace SharedLibrary.Commands
if (E.Origin.Level > E.Target.Level) if (E.Origin.Level > E.Target.Level)
{ {
await E.Target.Ban(Message, E.Origin); await E.Target.Ban(Message, E.Origin);
await E.Origin.Tell(String.Format("Sucessfully banned ^5{0} ^7({1})", E.Target.Name, E.Target.npID)); await E.Origin.Tell(String.Format("Sucessfully banned ^5{0} ^7({1})", E.Target.Name, E.Target.NetworkID));
} }
else else
await E.Origin.Tell("You cannot ban " + E.Target.Name); await E.Origin.Tell("You cannot ban " + E.Target.Name);
@ -132,7 +135,7 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
await E.Owner.Unban(E.Target); await E.Owner.Unban(E.Target);
await E.Origin.Tell($"Successfully unbanned {E.Target.Name}::{E.Target.npID}"); await E.Origin.Tell($"Successfully unbanned {E.Target.Name}::{E.Target.NetworkID}");
} }
} }
@ -142,7 +145,7 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
String You = String.Format("{0} [^3#{1}^7] {2} [^3@{3}^7] [{4}^7] IP: {5}", E.Origin.Name, E.Origin.clientID, E.Origin.npID, E.Origin.databaseID, SharedLibrary.Utilities.levelToColor(E.Origin.Level), E.Origin.IP); String You = String.Format("{0} [^3#{1}^7] {2} [^3@{3}^7] [{4}^7] IP: {5}", E.Origin.Name, E.Origin.ClientID, E.Origin.NetworkID, E.Origin.DatabaseID, SharedLibrary.Utilities.levelToColor(E.Origin.Level), E.Origin.IP);
await E.Origin.Tell(You); await E.Origin.Tell(You);
} }
} }
@ -163,9 +166,9 @@ namespace SharedLibrary.Commands
continue; continue;
if (P.Masked) if (P.Masked)
playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.levelToColor(Player.Permission.User), P.clientID, P.Name, SharedLibrary.Utilities.getSpaces(Player.Permission.SeniorAdmin.ToString().Length - Player.Permission.User.ToString().Length)); playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.levelToColor(Player.Permission.User), P.ClientID, P.Name, SharedLibrary.Utilities.getSpaces(Player.Permission.SeniorAdmin.ToString().Length - Player.Permission.User.ToString().Length));
else else
playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.levelToColor(P.Level), P.clientID, P.Name, SharedLibrary.Utilities.getSpaces(Player.Permission.SeniorAdmin.ToString().Length - P.Level.ToString().Length)); playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.levelToColor(P.Level), P.ClientID, P.Name, SharedLibrary.Utilities.getSpaces(Player.Permission.SeniorAdmin.ToString().Length - P.Level.ToString().Length));
if (count == 2 || E.Owner.getPlayers().Count == 1) if (count == 2 || E.Owner.getPlayers().Count == 1)
{ {
@ -217,7 +220,10 @@ namespace SharedLibrary.Commands
helpResponse.Append(" [^3" + C.Name + "^7] "); helpResponse.Append(" [^3" + C.Name + "^7] ");
if (count >= 4) if (count >= 4)
{ {
await E.Origin.Tell(helpResponse.ToString()); if (E.Message[0] == '@')
await E.Owner.Broadcast(helpResponse.ToString());
else
await E.Origin.Tell(helpResponse.ToString());
helpResponse = new StringBuilder(); helpResponse = new StringBuilder();
count = 0; count = 0;
} }
@ -288,7 +294,7 @@ namespace SharedLibrary.Commands
{ {
foreach (var player in server.getPlayers()) foreach (var player in server.getPlayers())
{ {
if (player != null && player.npID == E.Target.npID) if (player != null && player.NetworkID == E.Target.NetworkID)
{ {
player.setLevel(newPerm); player.setLevel(newPerm);
await E.Target.Tell("Congratulations! You have been promoted to ^3" + newPerm); await E.Target.Tell("Congratulations! You have been promoted to ^3" + newPerm);
@ -341,7 +347,12 @@ namespace SharedLibrary.Commands
{ {
var P = E.Owner.Players[i]; var P = E.Owner.Players[i];
if (P != null && P.Level > Player.Permission.Flagged && !P.Masked) if (P != null && P.Level > Player.Permission.Flagged && !P.Masked)
await E.Origin.Tell(String.Format("[^3{0}^7] {1}", Utilities.levelToColor(P.Level), P.Name)); {
if (E.Message[0] == '@')
await E.Owner.Broadcast(String.Format("[^3{0}^7] {1}", Utilities.levelToColor(P.Level), P.Name));
else
await E.Origin.Tell(String.Format("[^3{0}^7] {1}", Utilities.levelToColor(P.Level), P.Name));
}
} }
} }
} }
@ -386,7 +397,7 @@ namespace SharedLibrary.Commands
foreach (Player P in db_players) foreach (Player P in db_players)
{ {
String mesg = String.Format("[^3{0}^7] [^3@{1}^7] - [{2}^7] - {3} | last seen {4} ago", P.Name, P.databaseID, SharedLibrary.Utilities.levelToColor(P.Level), P.IP, P.getLastConnection()); String mesg = String.Format("[^3{0}^7] [^3@{1}^7] - [{2}^7] - {3} | last seen {4} ago", P.Name, P.DatabaseID, SharedLibrary.Utilities.levelToColor(P.Level), P.IP, P.getLastConnection());
await E.Origin.Tell(mesg); await E.Origin.Tell(mesg);
} }
} }
@ -431,7 +442,7 @@ namespace SharedLibrary.Commands
if (Current != null) if (Current != null)
{ {
String mesg = String.Format("^1{0} ^7now goes by ^5{1}^7 [^3{2}^7]", lookingFor, Current.Name, Current.databaseID); String mesg = String.Format("^1{0} ^7now goes by ^5{1}^7 [^3{2}^7]", lookingFor, Current.Name, Current.DatabaseID);
await E.Origin.Tell(mesg); await E.Origin.Tell(mesg);
} }
} }
@ -445,11 +456,22 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
if (E.Owner.rules.Count < 1) if (E.Owner.rules.Count < 1)
await E.Origin.Tell("The server onwer has not set any rules."); {
if (E.Message.IsBroadcastCommand())
await E.Owner.Broadcast("The server owner has not set any rules.");
else
await E.Origin.Tell("The server owner has not set any rules.");
}
else else
{ {
foreach (String r in E.Owner.rules) foreach (String r in E.Owner.rules)
await E.Origin.Tell("- " + r); {
if (E.Message.IsBroadcastCommand())
await E.Owner.Broadcast("- " + r);
else
await E.Origin.Tell("- " + r);
}
} }
} }
} }
@ -479,9 +501,9 @@ namespace SharedLibrary.Commands
} }
} }
class Flag : Command class CFlag : Command
{ {
public Flag(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CFlag(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
@ -499,7 +521,9 @@ namespace SharedLibrary.Commands
else else
{ {
E.Data = Utilities.RemoveWords(E.Data, 1);
E.Target.setLevel(Player.Permission.Flagged); E.Target.setLevel(Player.Permission.Flagged);
E.Owner.Manager.GetClientPenalties().AddPenalty(new Penalty(Penalty.Type.Flag, E.Data, E.Target.NetworkID, E.Origin.NetworkID, DateTime.Now, E.Target.IP));
await E.Origin.Tell("You have ^5flagged ^7" + E.Target.Name); await E.Origin.Tell("You have ^5flagged ^7" + E.Target.Name);
} }
@ -513,7 +537,7 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
if (E.Owner.Reports.Find(x => (x.Origin == E.Origin && x.Target.npID == E.Target.npID)) != null) if (E.Owner.Reports.Find(x => (x.Origin == E.Origin && x.Target.NetworkID == E.Target.NetworkID)) != null)
{ {
await E.Origin.Tell("You have already reported this player"); await E.Origin.Tell("You have already reported this player");
return; return;
@ -606,7 +630,7 @@ namespace SharedLibrary.Commands
return; return;
} }
Player Banner = E.Owner.Manager.GetClientDatabase().GetPlayer(BannedPenalty.bannedByID, -1); Player Banner = E.Owner.Manager.GetClientDatabase().GetPlayer(BannedPenalty.PenaltyOriginID, -1);
if (Banner == null) if (Banner == null)
{ {
@ -624,7 +648,7 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
E.Target.Alias = E.Owner.Manager.GetAliasesDatabase().GetPlayerAliases(E.Target.databaseID); E.Target.Alias = E.Owner.Manager.GetAliasesDatabase().GetPlayerAliases(E.Target.DatabaseID);
if (E.Target.Alias == null) if (E.Target.Alias == null)
{ {
@ -675,7 +699,7 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
await E.Origin.currentServer.ExecuteCommandAsync(E.Data.Trim()); await E.Owner.ExecuteCommandAsync(E.Data.Trim());
await E.Origin.Tell("Successfuly sent RCON command!"); await E.Origin.Tell("Successfuly sent RCON command!");
} }
} }

View File

@ -440,7 +440,7 @@ namespace SharedLibrary
public List<Penalty> GetClientPenalties(Player P) public List<Penalty> GetClientPenalties(Player P)
{ {
List<Penalty> ClientPenalties = new List<Penalty>(); List<Penalty> ClientPenalties = new List<Penalty>();
String Query = $"SELECT * FROM `BANS` WHERE `npID` = '{P.npID}' OR `IP` = '{P.IP}'"; String Query = $"SELECT * FROM `BANS` WHERE `npID` = '{P.NetworkID}' OR `IP` = '{P.IP}'";
DataTable Result = GetDataTable(Query); DataTable Result = GetDataTable(Query);
foreach (DataRow Row in Result.Rows) foreach (DataRow Row in Result.Rows)
@ -509,7 +509,7 @@ namespace SharedLibrary
Dictionary<String, object> newPlayer = new Dictionary<String, object> Dictionary<String, object> newPlayer = new Dictionary<String, object>
{ {
{ "Name", Utilities.removeNastyChars(P.Name) }, { "Name", Utilities.removeNastyChars(P.Name) },
{ "npID", P.npID }, { "npID", P.NetworkID },
{ "Level", (int)P.Level }, { "Level", (int)P.Level },
{ "LastOffense", "" }, { "LastOffense", "" },
{ "Connections", 1 }, { "Connections", 1 },
@ -527,7 +527,7 @@ namespace SharedLibrary
Dictionary<String, Object> updatedPlayer = new Dictionary<String, Object> Dictionary<String, Object> updatedPlayer = new Dictionary<String, Object>
{ {
{ "Name", P.Name }, { "Name", P.Name },
{ "npID", P.npID }, { "npID", P.NetworkID },
{ "Level", (int)P.Level }, { "Level", (int)P.Level },
{ "LastOffense", P.lastOffense }, { "LastOffense", P.lastOffense },
{ "Connections", P.Connections }, { "Connections", P.Connections },
@ -536,7 +536,7 @@ namespace SharedLibrary
{ "UID", P.UID }, { "UID", P.UID },
{ "Masked", Convert.ToInt32(P.Masked) } { "Masked", Convert.ToInt32(P.Masked) }
}; };
Update("CLIENTS", updatedPlayer, new KeyValuePair<string, object>("npID", P.npID)); Update("CLIENTS", updatedPlayer, new KeyValuePair<string, object>("npID", P.NetworkID));
} }
@ -546,8 +546,8 @@ namespace SharedLibrary
Dictionary<String, object> newBan = new Dictionary<String, object> Dictionary<String, object> newBan = new Dictionary<String, object>
{ {
{ "Reason", Utilities.removeNastyChars(B.Reason) }, { "Reason", Utilities.removeNastyChars(B.Reason) },
{ "npID", B.npID }, { "npID", B.OffenderID },
{ "bannedByID", B.bannedByID }, { "bannedByID", B.PenaltyOriginID },
{ "IP", B.IP }, { "IP", B.IP },
{ "TIME", Utilities.DateTimeSQLite(DateTime.Now) }, { "TIME", Utilities.DateTimeSQLite(DateTime.Now) },
{ "TYPE", B.BType } { "TYPE", B.BType }

View File

@ -125,7 +125,7 @@ namespace SharedLibrary
{ {
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], "");
return new Event(GType.Say, Utilities.removeNastyChars(message), SV.clientFromEventLine(line, 2), null, SV); return new Event(GType.Say, Utilities.removeNastyChars(message), SV.clientFromEventLine(line, 2), null, SV) { Message = Utilities.removeNastyChars(message) };
} }
if (eventType == ":") if (eventType == ":")
@ -149,6 +149,7 @@ namespace SharedLibrary
public GType Type; public GType Type;
public string Data; // Data is usually the message sent by player public string Data; // Data is usually the message sent by player
public string Message;
public Player Origin; public Player Origin;
public Player Target; public Player Target;
public Server Owner; public Server Owner;

View File

@ -17,5 +17,6 @@ namespace SharedLibrary.Interfaces
IPenaltyList GetClientPenalties(); IPenaltyList GetClientPenalties();
ClientsDB GetClientDatabase(); ClientsDB GetClientDatabase();
AliasesDB GetAliasesDatabase(); AliasesDB GetAliasesDatabase();
IList<MessageToken> GetMessageTokens();
} }
} }

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SharedLibrary
{
public class MessageToken
{
public string Name { get; private set; }
Func<string> Value;
public MessageToken(string Name, Func<string> Value)
{
this.Name = Name;
this.Value = Value;
}
public override string ToString()
{
return Value().ToString();
}
}
}

View File

@ -10,8 +10,8 @@ namespace SharedLibrary
public Penalty(Type BType, String Reas, String TargID, String From, DateTime time, String ip) public Penalty(Type BType, String Reas, String TargID, String From, DateTime time, String ip)
{ {
Reason = Reas.Replace("!",""); Reason = Reas.Replace("!","");
npID = TargID; OffenderID = TargID;
bannedByID = From; PenaltyOriginID = From;
When = time; When = time;
IP = ip; IP = ip;
this.BType = BType; this.BType = BType;
@ -24,15 +24,17 @@ namespace SharedLibrary
public enum Type public enum Type
{ {
Report,
Warning, Warning,
Flag,
Kick, Kick,
TempBan, TempBan,
Ban Ban
} }
public String Reason { get; private set; } public String Reason { get; private set; }
public String npID { get; private set; } public String OffenderID { get; private set; }
public String bannedByID { get; private set; } public String PenaltyOriginID { get; private set; }
public DateTime When { get; private set; } public DateTime When { get; private set; }
public String IP { get; private set; } public String IP { get; private set; }
public Type BType { get; private set; } public Type BType { get; private set; }

View File

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -38,7 +37,7 @@ namespace SharedLibrary
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
return ((Player)obj).npID == this.npID; return ((Player)obj).NetworkID == NetworkID;
} }
public override int GetHashCode() public override int GetHashCode()
@ -49,8 +48,8 @@ namespace SharedLibrary
public Player(string n, string id, int num, int l) public Player(string n, string id, int num, int l)
{ {
Name = n; Name = n;
npID = id; NetworkID = id;
clientID = num; ClientID = num;
Level = (Player.Permission)l; Level = (Player.Permission)l;
lastOffense = String.Empty; lastOffense = String.Empty;
Connections = 0; Connections = 0;
@ -64,8 +63,8 @@ namespace SharedLibrary
public Player(string n, string id, int num, String I) public Player(string n, string id, int num, String I)
{ {
Name = n; Name = n;
npID = id; NetworkID = id;
clientID = num; ClientID = num;
IP = I; IP = I;
LastConnection = DateTime.Now; LastConnection = DateTime.Now;
} }
@ -73,20 +72,20 @@ namespace SharedLibrary
public Player(String n, String id, Player.Permission P, String I, String UID) public Player(String n, String id, Player.Permission P, String I, String UID)
{ {
Name = n; Name = n;
npID = id; NetworkID = id;
Level = P; Level = P;
IP = I; IP = I;
clientID = -1; ClientID = -1;
this.UID = UID; this.UID = UID;
} }
public Player(string n, string id, int num, Player.Permission l, int cind, String lo, int con, String IP2) public Player(string n, string id, int num, Player.Permission l, int cind, String lo, int con, String IP2)
{ {
Name = n; Name = n;
npID = id; NetworkID = id;
clientID = num; ClientID = num;
Level = l; Level = l;
databaseID = cind; DatabaseID = cind;
if (lo == null) if (lo == null)
lastOffense = String.Empty; lastOffense = String.Empty;
else else
@ -101,10 +100,10 @@ namespace SharedLibrary
public Player(string n, string id, int num, Player.Permission l, int cind, String lo, int con, String IP2, DateTime LC, string UID, bool masked) public Player(string n, string id, int num, Player.Permission l, int cind, String lo, int con, String IP2, DateTime LC, string UID, bool masked)
{ {
Name = n; Name = n;
npID = id; NetworkID = id;
clientID = num; ClientID = num;
Level = l; Level = l;
databaseID = cind; DatabaseID = cind;
if (lo == null) if (lo == null)
lastOffense = String.Empty; lastOffense = String.Empty;
else else
@ -118,12 +117,9 @@ namespace SharedLibrary
Masked = masked; Masked = masked;
} }
public bool registerUID(String UID) public override string ToString()
{ {
if (UID.Length > 5) return $"{Name}::{NetworkID}";
this.UID = UID;
return this.UID == UID;
} }
public String getLastConnection() public String getLastConnection()
@ -142,7 +138,7 @@ namespace SharedLibrary
IP = I; IP = I;
} }
public void setLevel(Player.Permission Perm) public void setLevel(Permission Perm)
{ {
Level = Perm; Level = Perm;
} }
@ -173,16 +169,14 @@ namespace SharedLibrary
} }
public String Name { get; private set; } public String Name { get; private set; }
public string npID { get; private set; } public string NetworkID { get; private set; }
public int clientID { get; private set; } public int ClientID { get; private set; }
public Player.Permission Level { get; private set; } public Permission Level { get; private set; }
public int databaseID { get; private set; } public int DatabaseID { get; private set; }
public int Connections { get; set; } public int Connections { get; set; }
public String IP { get; private set; } public String IP { get; private set; }
public String UID { get; private set; } public String UID { get; private set; }
public DateTime LastConnection { get; private set; } public DateTime LastConnection { get; private set; }
public Server currentServer { get; private set; }
public int Ping; public int Ping;
public Event lastEvent; public Event lastEvent;

View File

@ -25,9 +25,7 @@ namespace SharedLibrary
Players = new List<Player>(new Player[18]); Players = new List<Player>(new Player[18]);
events = new Queue<Event>(); events = new Queue<Event>();
Macros = new Dictionary<String, Object>();
Reports = new List<Report>(); Reports = new List<Report>();
statusPlayers = new Dictionary<string, Player>();
playerHistory = new Queue<PlayerHistory>(); playerHistory = new Queue<PlayerHistory>();
chatHistory = new List<Chat>(); chatHistory = new List<Chat>();
lastWebChat = DateTime.Now; lastWebChat = DateTime.Now;
@ -44,10 +42,10 @@ namespace SharedLibrary
if (owner == null) if (owner == null)
commands.Add(new Owner("owner", "claim ownership of the server", "owner", Player.Permission.User, 0, false)); commands.Add(new Owner("owner", "claim ownership of the server", "owner", Player.Permission.User, 0, false));
commands.Add(new Quit("quit", "quit IW4MAdmin", "q", Player.Permission.Owner, 0, false)); commands.Add(new CQuit("quit", "quit IW4MAdmin", "q", Player.Permission.Owner, 0, false));
commands.Add(new Kick("kick", "kick a player by name. syntax: !kick <player> <reason>.", "k", Player.Permission.Trusted, 2, true)); commands.Add(new CKick("kick", "kick a player by name. syntax: !kick <player> <reason>.", "k", Player.Permission.Trusted, 2, true));
commands.Add(new Say("say", "broadcast message to all players. syntax: !say <message>.", "s", Player.Permission.Moderator, 1, false)); commands.Add(new CSay("say", "broadcast message to all players. syntax: !say <message>.", "s", Player.Permission.Moderator, 1, false));
commands.Add(new TempBan("tempban", "temporarily ban a player for 1 hour. syntax: !tempban <player> <reason>.", "tb", Player.Permission.Moderator, 2, true)); commands.Add(new CTempBan("tempban", "temporarily ban a player for 1 hour. syntax: !tempban <player> <reason>.", "tb", Player.Permission.Moderator, 2, true));
commands.Add(new CBan("ban", "permanently ban a player from the server. syntax: !ban <player> <reason>", "b", Player.Permission.SeniorAdmin, 2, true)); commands.Add(new CBan("ban", "permanently ban a player from the server. syntax: !ban <player> <reason>", "b", Player.Permission.SeniorAdmin, 2, true));
commands.Add(new CWhoAmI("whoami", "give information about yourself. syntax: !whoami.", "who", Player.Permission.User, 0, false)); commands.Add(new CWhoAmI("whoami", "give information about yourself. syntax: !whoami.", "who", Player.Permission.User, 0, false));
commands.Add(new CList("list", "list active clients syntax: !list.", "l", Player.Permission.Moderator, 0, false)); commands.Add(new CList("list", "list active clients syntax: !list.", "l", Player.Permission.Moderator, 0, false));
@ -57,15 +55,15 @@ namespace SharedLibrary
commands.Add(new CSetLevel("setlevel", "set player to specified administration level. syntax: !setlevel <player> <level>.", "sl", Player.Permission.Owner, 2, true)); commands.Add(new CSetLevel("setlevel", "set player to specified administration level. syntax: !setlevel <player> <level>.", "sl", Player.Permission.Owner, 2, true));
commands.Add(new CUsage("usage", "get current application memory usage. syntax: !usage.", "us", Player.Permission.Moderator, 0, false)); commands.Add(new CUsage("usage", "get current application memory usage. syntax: !usage.", "us", Player.Permission.Moderator, 0, false));
commands.Add(new CUptime("uptime", "get current application running time. syntax: !uptime.", "up", Player.Permission.Moderator, 0, false)); commands.Add(new CUptime("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.Trusted, 2, true)); commands.Add(new Cwarn("warn", "warn player for infringing rules syntax: !warn <player> <reason>.", "w", Player.Permission.Trusted, 2, true));
commands.Add(new WarnClear("warnclear", "remove all warning for a player syntax: !warnclear <player>.", "wc", Player.Permission.Trusted, 1, true)); commands.Add(new CWarnClear("warnclear", "remove all warning for a player syntax: !warnclear <player>.", "wc", Player.Permission.Trusted, 1, true));
commands.Add(new CUnban("unban", "unban player by database id. syntax: !unban @<id>.", "ub", Player.Permission.SeniorAdmin, 1, true)); commands.Add(new CUnban("unban", "unban player by database id. syntax: !unban @<id>.", "ub", Player.Permission.SeniorAdmin, 1, true));
commands.Add(new CListAdmins("admins", "list currently connected admins. syntax: !admins.", "a", Player.Permission.User, 0, false)); commands.Add(new CListAdmins("admins", "list currently connected admins. syntax: !admins.", "a", Player.Permission.User, 0, false));
commands.Add(new CLoadMap("map", "change to specified map. syntax: !map", "m", Player.Permission.Administrator, 1, false)); commands.Add(new CLoadMap("map", "change to specified map. syntax: !map", "m", Player.Permission.Administrator, 1, false));
commands.Add(new CFindPlayer("find", "find player in database. syntax: !find <player>", "f", Player.Permission.SeniorAdmin, 1, false)); commands.Add(new CFindPlayer("find", "find player in database. syntax: !find <player>", "f", Player.Permission.SeniorAdmin, 1, false));
commands.Add(new CListRules("rules", "list server rules. syntax: !rules", "r", Player.Permission.User, 0, false)); commands.Add(new CListRules("rules", "list server rules. syntax: !rules", "r", Player.Permission.User, 0, false));
commands.Add(new CPrivateMessage("privatemessage", "send message to other player. syntax: !pm <player> <message>", "pm", Player.Permission.User, 2, true)); commands.Add(new CPrivateMessage("privatemessage", "send message to other player. syntax: !pm <player> <message>", "pm", Player.Permission.User, 2, true));
commands.Add(new Flag("flag", "flag a suspicious player and announce to admins on join . syntax !flag <player>:", "flag", Player.Permission.Moderator, 1, true)); commands.Add(new CFlag("flag", "flag a suspicious player and announce to admins on join . syntax !flag <player> <reason>:", "flag", Player.Permission.Moderator, 2, true));
commands.Add(new CReport("report", "report a player for suspicious behaivor. syntax !report <player> <reason>", "rep", Player.Permission.User, 2, true)); commands.Add(new CReport("report", "report a player for suspicious behaivor. syntax !report <player> <reason>", "rep", Player.Permission.User, 2, true));
commands.Add(new CListReports("reports", "get most recent reports. syntax !reports", "reports", Player.Permission.Moderator, 0, false)); commands.Add(new CListReports("reports", "get most recent reports. syntax !reports", "reports", Player.Permission.Moderator, 0, false));
commands.Add(new CMask("mask", "hide your online presence from online admin list. syntax: !mask", "mask", Player.Permission.Administrator, 0, false)); commands.Add(new CMask("mask", "hide your online presence from online admin list. syntax: !mask", "mask", Player.Permission.Administrator, 0, false));
@ -234,10 +232,11 @@ namespace SharedLibrary
public async Task Tell(String Message, Player Target) public async Task Tell(String Message, Player Target)
{ {
#if DEBUG #if DEBUG
return; if (!Target.lastEvent.Remote)
return;
#endif #endif
if (Target.clientID > -1 && Message.Length > 0 && Target.Level != Player.Permission.Console && !Target.lastEvent.Remote) if (Target.ClientID > -1 && Message.Length > 0 && Target.Level != Player.Permission.Console && !Target.lastEvent.Remote)
await this.ExecuteCommandAsync($"tellraw {Target.clientID} {Message}^7"); await this.ExecuteCommandAsync($"tellraw {Target.ClientID} {Message}^7");
if (Target.Level == Player.Permission.Console) if (Target.Level == Player.Permission.Console)
{ {
@ -456,24 +455,15 @@ namespace SharedLibrary
protected DateTime lastPoll; protected DateTime lastPoll;
protected int nextMessage; protected int nextMessage;
protected Dictionary<String, Object> Macros;
protected DateTime lastWebChat; protected DateTime lastWebChat;
public string Password { get; private set; } public string Password { get; private set; }
public int Handle { get; private set; } public int Handle { get; private set; }
protected int PID; protected int PID;
protected IFile logFile; protected IFile logFile;
// Will probably move this later
public Dictionary<String, Player> statusPlayers;
public bool isRunning;
// Log stuff // Log stuff
protected String Mod; protected String Mod;
// Databases
//public ClientsDB clientDB;
//public AliasesDB aliasDB;
//Remote //Remote
public Queue<String> commandResult = new Queue<string>(); public Queue<String> commandResult = new Queue<string>();
} }

View File

@ -76,6 +76,7 @@
<Compile Include="Interfaces\IManager.cs" /> <Compile Include="Interfaces\IManager.cs" />
<Compile Include="Interfaces\IPenaltyList.cs" /> <Compile Include="Interfaces\IPenaltyList.cs" />
<Compile Include="Interfaces\ISerializable.cs" /> <Compile Include="Interfaces\ISerializable.cs" />
<Compile Include="MessageToken.cs" />
<Compile Include="Penalty.cs" /> <Compile Include="Penalty.cs" />
<Compile Include="Command.cs" /> <Compile Include="Command.cs" />
<Compile Include="Database.cs" /> <Compile Include="Database.cs" />

View File

@ -2,6 +2,7 @@
using System.Threading; using System.Threading;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
namespace SharedLibrary namespace SharedLibrary
@ -120,27 +121,28 @@ namespace SharedLibrary
} }
} }
public static String LoadMacro(Dictionary<String, Object> Dict, String str) public static String ProcessMessageToken(IList<MessageToken> tokens, String str)
{ {
MatchCollection Found = Regex.Matches(str, @"\{\{[A-Z]+\}\}", RegexOptions.IgnoreCase); MatchCollection RegexMatches = Regex.Matches(str, @"\{\{[A-Z]+\}\}", RegexOptions.IgnoreCase);
foreach (Match M in Found) foreach (Match M in RegexMatches)
{ {
String Match = M.Value; String Match = M.Value;
String Identifier = M.Value.Substring(2, M.Length - 4); String Identifier = M.Value.Substring(2, M.Length - 4);
Dict.TryGetValue(Identifier, out object foundVal);
String Replacement;
if (foundVal != null) var found = tokens.FirstOrDefault(t => t.Name.ToLower() == Identifier.ToLower());
Replacement = foundVal.ToString();
else
Replacement = "";
str = str.Replace(Match, Replacement); if (found != null)
str = str.Replace(Match, found.ToString());
} }
return str; return str;
} }
public static bool IsBroadcastCommand(this string str)
{
return str[0] == '@';
}
/// <summary> /// <summary>
/// Get the full gametype name /// Get the full gametype name
/// </summary> /// </summary>

View File

@ -20,27 +20,34 @@ namespace StatsPlugin
if (E.Target != null) if (E.Target != null)
{ {
pStats = Stats.statLists.Find(x => x.Port == E.Owner.getPort()).playerStats.getStats(E.Target); pStats = Stats.statLists.Find(x => x.Port == E.Owner.getPort()).playerStats.GetStats(E.Target);
statLine = String.Format("^5{0} ^7KILLS | ^5{1} ^7DEATHS | ^5{2} ^7KDR | ^5{3} ^7SKILL", pStats.Kills, pStats.Deaths, pStats.KDR, pStats.Skill); statLine = String.Format("^5{0} ^7KILLS | ^5{1} ^7DEATHS | ^5{2} ^7KDR | ^5{3} ^7SKILL", pStats.Kills, pStats.Deaths, pStats.KDR, pStats.Skill);
} }
else else
{ {
pStats = Stats.statLists.Find(x => x.Port == E.Owner.getPort()).playerStats.getStats(E.Origin); pStats = Stats.statLists.Find(x => x.Port == E.Owner.getPort()).playerStats.GetStats(E.Origin);
statLine = String.Format("^5{0} ^7KILLS | ^5{1} ^7DEATHS | ^5{2} ^7KDR | ^5{3} ^7SKILL", pStats.Kills, pStats.Deaths, pStats.KDR, pStats.Skill); statLine = String.Format("^5{0} ^7KILLS | ^5{1} ^7DEATHS | ^5{2} ^7KDR | ^5{3} ^7SKILL", pStats.Kills, pStats.Deaths, pStats.KDR, pStats.Skill);
} }
await E.Origin.Tell(statLine); if (E.Message.IsBroadcastCommand())
{
string name = E.Target == null ? E.Origin.Name : E.Target.Name;
await E.Owner.Broadcast($"Stats for ^5{name}^7");
await E.Owner.Broadcast(statLine);
}
else
await E.Origin.Tell(statLine);
} }
} }
public class CViewTopStats : Command public class CViewTopStats : Command
{ {
public CViewTopStats() : base("topstats", "view the top 5 players on this server. syntax !topstats", "!ts", Player.Permission.User, 0, false) { } public CViewTopStats() : base("topstats", "view the top 5 players on this server. syntax !topstats", "ts", Player.Permission.User, 0, false) { }
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
List<KeyValuePair<String, PlayerStats>> pStats = Stats.statLists.Find(x => x.Port == E.Owner.getPort()).playerStats.topStats(); List<KeyValuePair<String, PlayerStats>> pStats = Stats.statLists.Find(x => x.Port == E.Owner.getPort()).playerStats.GetTopStats();
StringBuilder msgBlder = new StringBuilder(); StringBuilder msgBlder = new StringBuilder();
await E.Origin.Tell("^5--Top Players--"); await E.Origin.Tell("^5--Top Players--");
@ -54,6 +61,23 @@ namespace StatsPlugin
} }
} }
public class CResetStats : Command
{
public CResetStats() : base("resetstats", "reset your stats to factory-new, !syntax !resetstats", "rs", Player.Permission.User, 0, false) { }
public override async Task ExecuteAsync(Event E)
{
var stats = Stats.statLists.Find(x => x.Port == E.Owner.getPort()).playerStats.GetStats(E.Origin);
stats.Deaths = 0;
stats.Kills = 0;
stats.scorePerMinute = 0.0;
stats.Skill = 0;
stats.KDR = 0.0;
await Task.Run(() => { Stats.statLists.Find(x => x.Port == E.Owner.getPort()).playerStats.UpdateStats(E.Origin, stats); });
await E.Origin.Tell("Your stats have been reset");
}
}
/// <summary> /// <summary>
/// Each server runs from the same plugin ( for easier reloading and reduced memory usage ). /// Each server runs from the same plugin ( for easier reloading and reduced memory usage ).
/// So, to have multiple stat tracking, we must store a stat struct for each server /// So, to have multiple stat tracking, we must store a stat struct for each server
@ -89,7 +113,7 @@ namespace StatsPlugin
public float Version public float Version
{ {
get { return 1f; } get { return 1.1f; }
} }
public string Author public string Author
@ -117,6 +141,8 @@ namespace StatsPlugin
if (E.Type == Event.GType.Start) if (E.Type == Event.GType.Start)
{ {
statLists.Add(new StatTracking(S.getPort())); statLists.Add(new StatTracking(S.getPort()));
S.Manager.GetMessageTokens().Add(new MessageToken("TOTALPLAYTIME", statLists.Find(c => c.Port == S.getPort()).playerStats.GetTotalPlaytime().ToString("#,##0").ToString));
S.Manager.GetMessageTokens().Add(new MessageToken("TOTALKILLS", statLists.Find(c => c.Port == S.getPort()).playerStats.GetTotalKills().ToString("#,##0").ToString));
} }
if (E.Type == Event.GType.Stop) if (E.Type == Event.GType.Stop)
@ -126,10 +152,10 @@ namespace StatsPlugin
if (E.Type == Event.GType.Connect) if (E.Type == Event.GType.Connect)
{ {
resetCounters(E.Origin.clientID, S.getPort()); ResetCounters(E.Origin.ClientID, S.getPort());
PlayerStats checkForTrusted = statLists.Find(x => x.Port == S.getPort()).playerStats.getStats(E.Origin); PlayerStats checkForTrusted = statLists.Find(x => x.Port == S.getPort()).playerStats.GetStats(E.Origin);
if (checkForTrusted.playTime >= 4320 && E.Origin.Level < Player.Permission.Trusted) if (checkForTrusted.TotalPlayTime >= 4320 && E.Origin.Level < Player.Permission.Trusted)
{ {
E.Origin.setLevel(Player.Permission.Trusted); E.Origin.setLevel(Player.Permission.Trusted);
E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Origin); E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Origin);
@ -146,19 +172,19 @@ namespace StatsPlugin
if (P == null) if (P == null)
continue; continue;
calculateAndSaveSkill(P, statLists.Find(x =>x.Port == S.getPort())); CalculateAndSaveSkill(P, statLists.Find(x =>x.Port == S.getPort()));
resetCounters(P.clientID, S.getPort()); ResetCounters(P.ClientID, S.getPort());
E.Owner.Logger.WriteInfo("Updated skill for client #" + P.databaseID); E.Owner.Logger.WriteInfo("Updated skill for client #" + P.DatabaseID);
//E.Owner.Log.Write(String.Format("\r\nJoin: {0}\r\nInactive Minutes: {1}\r\nnewPlayTime: {2}\r\nnewSPM: {3}\r\nkdrWeight: {4}\r\nMultiplier: {5}\r\nscoreWeight: {6}\r\nnewSkillFactor: {7}\r\nprojectedNewSkill: {8}\r\nKills: {9}\r\nDeaths: {10}", connectionTime[P.clientID].ToShortTimeString(), inactiveMinutes[P.clientID], newPlayTime, newSPM, kdrWeight, Multiplier, scoreWeight, newSkillFactor, disconnectStats.Skill, disconnectStats.Kills, disconnectStats.Deaths)); //E.Owner.Log.Write(String.Format("\r\nJoin: {0}\r\nInactive Minutes: {1}\r\nnewPlayTime: {2}\r\nnewSPM: {3}\r\nkdrWeight: {4}\r\nMultiplier: {5}\r\nscoreWeight: {6}\r\nnewSkillFactor: {7}\r\nprojectedNewSkill: {8}\r\nKills: {9}\r\nDeaths: {10}", connectionTime[P.clientID].ToShortTimeString(), inactiveMinutes[P.clientID], newPlayTime, newSPM, kdrWeight, Multiplier, scoreWeight, newSkillFactor, disconnectStats.Skill, disconnectStats.Kills, disconnectStats.Deaths));
} }
} }
if (E.Type == Event.GType.Disconnect) 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()); ResetCounters(E.Origin.ClientID, S.getPort());
E.Owner.Logger.WriteInfo("Updated skill for disconnecting client #" + E.Origin.databaseID); E.Owner.Logger.WriteInfo("Updated skill for disconnecting client #" + E.Origin.DatabaseID);
} }
if (E.Type == Event.GType.Kill) if (E.Type == Event.GType.Kill)
@ -168,14 +194,14 @@ namespace StatsPlugin
Player Killer = E.Origin; Player Killer = E.Origin;
StatTracking curServer = statLists.Find(x => x.Port == S.getPort()); StatTracking curServer = statLists.Find(x => x.Port == S.getPort());
PlayerStats killerStats = curServer.playerStats.getStats(Killer); PlayerStats killerStats = curServer.playerStats.GetStats(Killer);
curServer.lastKill[E.Origin.clientID] = DateTime.Now; curServer.lastKill[E.Origin.ClientID] = DateTime.Now;
curServer.Kills[E.Origin.clientID]++; curServer.Kills[E.Origin.ClientID]++;
if ((curServer.lastKill[E.Origin.clientID] - DateTime.Now).TotalSeconds > 60) if ((curServer.lastKill[E.Origin.ClientID] - DateTime.Now).TotalSeconds > 60)
curServer.inactiveMinutes[E.Origin.clientID]++; curServer.inactiveMinutes[E.Origin.ClientID]++;
killerStats.Kills++; killerStats.Kills++;
@ -184,12 +210,12 @@ namespace StatsPlugin
else else
killerStats.KDR = Math.Round((double)killerStats.Kills / (double)killerStats.Deaths, 2); killerStats.KDR = Math.Round((double)killerStats.Kills / (double)killerStats.Deaths, 2);
curServer.playerStats.updateStats(Killer, killerStats); curServer.playerStats.UpdateStats(Killer, killerStats);
curServer.killStreaks[Killer.clientID] += 1; curServer.killStreaks[Killer.ClientID] += 1;
curServer.deathStreaks[Killer.clientID] = 0; curServer.deathStreaks[Killer.ClientID] = 0;
await Killer.Tell(messageOnStreak(curServer.killStreaks[Killer.clientID], curServer.deathStreaks[Killer.clientID])); await Killer.Tell(MessageOnStreak(curServer.killStreaks[Killer.ClientID], curServer.deathStreaks[Killer.ClientID]));
} }
if (E.Type == Event.GType.Death) if (E.Type == Event.GType.Death)
@ -199,61 +225,63 @@ namespace StatsPlugin
Player Victim = E.Origin; Player Victim = E.Origin;
StatTracking curServer = statLists.Find(x => x.Port == S.getPort()); StatTracking curServer = statLists.Find(x => x.Port == S.getPort());
PlayerStats victimStats = curServer.playerStats.getStats(Victim); PlayerStats victimStats = curServer.playerStats.GetStats(Victim);
victimStats.Deaths++; victimStats.Deaths++;
victimStats.KDR = Math.Round((double)victimStats.Kills / (double)victimStats.Deaths, 2); victimStats.KDR = Math.Round((double)victimStats.Kills / (double)victimStats.Deaths, 2);
curServer.playerStats.updateStats(Victim, victimStats); curServer.playerStats.UpdateStats(Victim, victimStats);
curServer.deathStreaks[Victim.clientID] += 1; curServer.deathStreaks[Victim.ClientID] += 1;
curServer.killStreaks[Victim.clientID] = 0; curServer.killStreaks[Victim.ClientID] = 0;
await Victim.Tell(messageOnStreak(curServer.killStreaks[Victim.clientID], curServer.deathStreaks[Victim.clientID])); await Victim.Tell(MessageOnStreak(curServer.killStreaks[Victim.ClientID], curServer.deathStreaks[Victim.ClientID]));
} }
} }
private void calculateAndSaveSkill(Player P, StatTracking curServer) private void CalculateAndSaveSkill(Player P, StatTracking curServer)
{ {
if (P == null) if (P == null)
return; return;
PlayerStats disconnectStats = curServer.playerStats.getStats(P); PlayerStats DisconnectingPlayerStats = curServer.playerStats.GetStats(P);
if (curServer.Kills[P.clientID] == 0) if (curServer.Kills[P.ClientID] == 0)
return; return;
else if (curServer.lastKill[P.clientID] > curServer.connectionTime[P.clientID]) else if (curServer.lastKill[P.ClientID] > curServer.connectionTime[P.ClientID])
curServer.inactiveMinutes[P.clientID] += (int)(DateTime.Now - curServer.lastKill[P.clientID]).TotalMinutes; curServer.inactiveMinutes[P.ClientID] += (int)(DateTime.Now - curServer.lastKill[P.ClientID]).TotalMinutes;
int newPlayTime = (int)(DateTime.Now - curServer.connectionTime[P.clientID]).TotalMinutes - curServer.inactiveMinutes[P.clientID]; int newPlayTime = (int)(DateTime.Now - curServer.connectionTime[P.ClientID]).TotalMinutes - curServer.inactiveMinutes[P.ClientID];
if (newPlayTime < 2) if (newPlayTime < 2)
return; return;
double newSPM = curServer.Kills[P.clientID] * 50 / Math.Max(1, newPlayTime); // calculate the players Score Per Minute for the current session
double kdrWeight = Math.Round(Math.Pow(disconnectStats.KDR, 2 / Math.E), 3); double SessionSPM = curServer.Kills[P.ClientID] * 100 / Math.Max(1, newPlayTime);
double Multiplier; // calculate how much the KDR should way
// 0.81829 is a Eddie-Generated number that weights the KDR nicely
double KDRWeight = Math.Round(Math.Pow(DisconnectingPlayerStats.KDR, 1.637 / Math.E), 3);
double SPMWeightAgainstAverage;
if (disconnectStats.scorePerMinute == 1) // if no SPM, weight is 1 else the weight is the current sessions spm / lifetime average score per minute
Multiplier = 1; SPMWeightAgainstAverage = (DisconnectingPlayerStats.scorePerMinute == 1) ? 1 : SessionSPM / DisconnectingPlayerStats.scorePerMinute;
else
Multiplier = newSPM / disconnectStats.scorePerMinute;
double scoreWeight = (newSPM * (newPlayTime / disconnectStats.playTime)); // calculate the weight of the new play time againmst lifetime playtime
double newSkillFactor = Multiplier * scoreWeight; //
double SPMAgainstPlayWeight = newPlayTime / Math.Min(600, DisconnectingPlayerStats.TotalPlayTime);
// calculate the new weight against average times the weight against play time
double newSkillFactor = SPMWeightAgainstAverage * SPMAgainstPlayWeight;
if (Multiplier >= 1) // if the weight is greater than 1, add, else subtract
disconnectStats.scorePerMinute += newSkillFactor; DisconnectingPlayerStats.scorePerMinute += (SPMWeightAgainstAverage >= 1) ? newSkillFactor : -newSkillFactor;
else
disconnectStats.scorePerMinute -= (scoreWeight - newSkillFactor);
disconnectStats.Skill = disconnectStats.scorePerMinute * kdrWeight / 10; DisconnectingPlayerStats.Skill = DisconnectingPlayerStats.scorePerMinute * KDRWeight / 10;
disconnectStats.playTime += newPlayTime; DisconnectingPlayerStats.TotalPlayTime += newPlayTime;
curServer.playerStats.updateStats(P, disconnectStats); curServer.playerStats.UpdateStats(P, DisconnectingPlayerStats);
} }
private void resetCounters(int cID, int serverPort) private void ResetCounters(int cID, int serverPort)
{ {
StatTracking selectedPlayers = statLists.Find(x => x.Port == serverPort); StatTracking selectedPlayers = statLists.Find(x => x.Port == serverPort);
@ -264,7 +292,7 @@ namespace StatsPlugin
selectedPlayers.killStreaks[cID] = 0; selectedPlayers.killStreaks[cID] = 0;
} }
private String messageOnStreak(int killStreak, int deathStreak) private String MessageOnStreak(int killStreak, int deathStreak)
{ {
String Message = ""; String Message = "";
switch (killStreak) switch (killStreak)
@ -304,24 +332,24 @@ namespace StatsPlugin
} }
} }
public void addPlayer(Player P) public void AddPlayer(Player P)
{ {
Dictionary<String, object> newPlayer = new Dictionary<String, object>(); Dictionary<String, object> newPlayer = new Dictionary<String, object>
{
newPlayer.Add("npID", P.npID); { "npID", P.NetworkID },
newPlayer.Add("KILLS", 0); { "KILLS", 0 },
newPlayer.Add("DEATHS", 0); { "DEATHS", 0 },
newPlayer.Add("KDR", 0.0); { "KDR", 0.0 },
newPlayer.Add("SKILL", 1.0); { "SKILL", 1.0 },
newPlayer.Add("SPM", 1.0); { "SPM", 1.0 },
newPlayer.Add("PLAYTIME", 1.0); { "PLAYTIME", 1.0 }
};
Insert("STATS", newPlayer); Insert("STATS", newPlayer);
} }
public PlayerStats getStats(Player P) public PlayerStats GetStats(Player P)
{ {
DataTable Result = GetDataTable("STATS", new KeyValuePair<string, object>("npID", P.npID)); DataTable Result = GetDataTable("STATS", new KeyValuePair<string, object>("npID", P.NetworkID));
if (Result != null && Result.Rows.Count > 0) if (Result != null && Result.Rows.Count > 0)
{ {
@ -338,26 +366,38 @@ namespace StatsPlugin
else else
{ {
addPlayer(P); AddPlayer(P);
return getStats(P); return GetStats(P);
} }
} }
public void updateStats(Player P, PlayerStats S) public int GetTotalKills()
{ {
Dictionary<String, object> updatedPlayer = new Dictionary<String, object>(); var Result = GetDataTable("SELECT SUM(KILLS) FROM STATS");
return Result.Rows[0][0].GetType() == typeof(DBNull) ? 0 : Convert.ToInt32(Result.Rows[0][0]);
updatedPlayer.Add("KILLS", S.Kills);
updatedPlayer.Add("DEATHS", S.Deaths);
updatedPlayer.Add("KDR", Math.Round(S.KDR, 2));
updatedPlayer.Add("SKILL", Math.Round(S.Skill, 1));
updatedPlayer.Add("SPM", Math.Round(S.scorePerMinute, 1));
updatedPlayer.Add("PLAYTIME", S.playTime);
Update("STATS", updatedPlayer, new KeyValuePair<string, object>("npID", P.npID));
} }
public List<KeyValuePair<String, PlayerStats>> topStats() public int GetTotalPlaytime()
{
var Result = GetDataTable("SELECT SUM(PLAYTIME) FROM STATS");
return Result.Rows[0][0].GetType() == typeof(DBNull) ? 0 : Convert.ToInt32(Result.Rows[0][0]) / 60;
}
public void UpdateStats(Player P, PlayerStats S)
{
Dictionary<String, object> updatedPlayer = new Dictionary<String, object>
{
{ "KILLS", S.Kills },
{ "DEATHS", S.Deaths },
{ "KDR", Math.Round(S.KDR, 2) },
{ "SKILL", Math.Round(S.Skill, 1) },
{ "SPM", Math.Round(S.scorePerMinute, 1) },
{ "PLAYTIME", S.TotalPlayTime }
};
Update("STATS", updatedPlayer, new KeyValuePair<string, object>("npID", P.NetworkID));
}
public List<KeyValuePair<String, PlayerStats>> GetTopStats()
{ {
String Query = String.Format("SELECT * FROM STATS WHERE SKILL > 0 AND KDR < '{0}' AND KILLS > '{1}' AND PLAYTIME > '{2}' ORDER BY SKILL DESC LIMIT '{3}'", 10, 150, 60, 5); String Query = String.Format("SELECT * FROM STATS WHERE SKILL > 0 AND KDR < '{0}' AND KILLS > '{1}' AND PLAYTIME > '{2}' ORDER BY SKILL DESC LIMIT '{3}'", 10, 150, 60, 5);
DataTable Result = GetDataTable(Query); DataTable Result = GetDataTable(Query);
@ -392,7 +432,7 @@ namespace StatsPlugin
KDR = DR; KDR = DR;
Skill = S; Skill = S;
scorePerMinute = sc; scorePerMinute = sc;
playTime = P; TotalPlayTime = P;
} }
public int Kills; public int Kills;
@ -400,6 +440,6 @@ namespace StatsPlugin
public double KDR; public double KDR;
public double Skill; public double Skill;
public double scorePerMinute; public double scorePerMinute;
public int playTime; public int TotalPlayTime;
} }
} }

View File

@ -31,7 +31,7 @@ namespace Votemap_Plugin
// we only want to allow a vote during a vote session // we only want to allow a vote during a vote session
if (voting.voteInSession) if (voting.voteInSession)
{ {
if (voting.hasVoted(E.Origin.npID)) if (voting.hasVoted(E.Origin.NetworkID))
await E.Origin.Tell("You have already voted. Use ^5!vc ^7to ^5cancel ^7your vote"); await E.Origin.Tell("You have already voted. Use ^5!vc ^7to ^5cancel ^7your vote");
else else
{ {
@ -42,7 +42,7 @@ namespace Votemap_Plugin
await E.Origin.Tell("^1" + E.Data + " is not a recognized map"); await E.Origin.Tell("^1" + E.Data + " is not a recognized map");
else else
{ {
voting.castVote(E.Origin.npID, votedMap); voting.castVote(E.Origin.NetworkID, votedMap);
await E.Origin.Tell("You voted for ^5" + votedMap.Alias); await E.Origin.Tell("You voted for ^5" + votedMap.Alias);
} }
} }
@ -63,9 +63,9 @@ namespace Votemap_Plugin
if (voting.voteInSession) if (voting.voteInSession)
{ {
if (voting.hasVoted(E.Origin.npID)) if (voting.hasVoted(E.Origin.NetworkID))
{ {
voting.cancelVote(E.Origin.npID); voting.cancelVote(E.Origin.NetworkID);
await E.Origin.Tell("Vote cancelled"); await E.Origin.Tell("Vote cancelled");
} }