diff --git a/Admin/Application.csproj b/Admin/Application.csproj index 6f64bf84a..a33717bfa 100644 --- a/Admin/Application.csproj +++ b/Admin/Application.csproj @@ -48,6 +48,7 @@ 4 true false + ..\..\..\RuleSet1.ruleset x86 @@ -204,7 +205,7 @@ PreserveNewest - Always + PreserveNewest PreserveNewest @@ -212,9 +213,9 @@ PreserveNewest - + PreserveNewest - + diff --git a/Admin/PenaltyList.cs b/Admin/PenaltyList.cs index e40ad159a..2b652881e 100644 --- a/Admin/PenaltyList.cs +++ b/Admin/PenaltyList.cs @@ -15,7 +15,7 @@ namespace IW4MAdmin public void AddPenalty(Penalty P) { - ApplicationManager.GetInstance().GetClientDatabase().AddBan(P); + ApplicationManager.GetInstance().GetClientDatabase().AddPenalty(P); } public void RemovePenalty(Penalty P) diff --git a/Admin/Server.cs b/Admin/Server.cs index d576a746e..92f3324ec 100644 --- a/Admin/Server.cs +++ b/Admin/Server.cs @@ -17,18 +17,18 @@ namespace IW4MAdmin override public async Task 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; 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 - Players[P.ClientID].Ping = P.Ping; + Players[P.ClientID].Ping = P.Ping; return true; } Logger.WriteDebug($"Client slot #{P.ClientID} now reserved"); - + try { Player NewPlayer = Manager.GetClientDatabase().GetPlayer(P.NetworkID, P.ClientID); @@ -57,19 +57,19 @@ namespace IW4MAdmin Manager.GetAliasesDatabase().AddPlayerAliases(new Aliases(NewPlayer.DatabaseID, NewPlayer.Name, NewPlayer.IP)); NewPlayer.Alias = Manager.GetAliasesDatabase().GetPlayerAliases(NewPlayer.DatabaseID); } - + 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 in too late else NewPlayer.lastEvent = P.lastEvent; - + // lets check aliases - if ((NewPlayer.Alias.Names.Find(m => m.Equals(P.Name))) == null || NewPlayer.Name == null || NewPlayer.Name == String.Empty) + if ((NewPlayer.Alias.Names.Find(m => m.Equals(P.Name))) == null || NewPlayer.Name == null || NewPlayer.Name == String.Empty) { NewPlayer.UpdateName(P.Name.Trim()); NewPlayer.Alias.Names.Add(NewPlayer.Name); } - + // and ips if (NewPlayer.Alias.IPS.Find(i => i.Equals(P.IP)) == null || P.IP == null || P.IP == String.Empty) NewPlayer.Alias.IPS.Add(P.IP); @@ -111,8 +111,14 @@ namespace IW4MAdmin return true; } + + var activeTB = IsTempBanned(aP); + if (activeTB != null) + { + await this.ExecuteCommandAsync($"clientkick {NewPlayer.ClientID} \"You are temporarily banned. ({(activeTB.Expires - DateTime.Now).TimeSpanText()} left)\""); + } } - + Players[NewPlayer.ClientID] = NewPlayer; Logger.WriteInfo($"Client {NewPlayer.Name}::{NewPlayer.NetworkID} connecting..."); // they're clean @@ -171,10 +177,15 @@ namespace IW4MAdmin } //Check ban list for every banned player and return ban if match is found - override public Penalty IsBanned(Player C) - { - return Manager.GetClientPenalties().FindPenalties(C).Where(b => b.BType == Penalty.Type.Ban).FirstOrDefault(); - } + override public Penalty IsBanned(Player C) + { + return Manager.GetClientPenalties().FindPenalties(C).Where(b => b.BType == Penalty.Type.Ban).FirstOrDefault(); + } + + public Penalty IsTempBanned(Player C) + { + return Manager.GetClientPenalties().FindPenalties(C).FirstOrDefault(b => b.BType == Penalty.Type.TempBan && b.Expires > DateTime.Now); + } //Process requested command correlating to an event // todo: this needs to be removed out of here @@ -197,7 +208,7 @@ namespace IW4MAdmin } E.Data = E.Data.RemoveWords(1); - String[] Args = E.Data.Trim().Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries); + String[] Args = E.Data.Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (E.Origin.Level < C.Permission) { @@ -211,7 +222,7 @@ namespace IW4MAdmin throw new SharedLibrary.Exceptions.CommandException($"{E.Origin} did not supply enough arguments for \"{C.Name}\""); } - if (C.RequiresTarget || Args.Length > 0) + if (C.RequiresTarget || Args.Length > 0) { int cNum = -1; int.TryParse(Args[0], out cNum); @@ -222,7 +233,7 @@ namespace IW4MAdmin if (Args[0][0] == '@') // user specifying target by database ID { int dbID = -1; - int.TryParse(Args[0].Substring(1, Args[0].Length-1), out dbID); + int.TryParse(Args[0].Substring(1, Args[0].Length - 1), out dbID); Player found = Manager.GetClientDatabase().GetPlayer(dbID); if (found != null) @@ -233,7 +244,7 @@ namespace IW4MAdmin } } - else if(Args[0].Length < 3 && cNum > -1 && cNum < 18) // user specifying target by client num + else if (Args[0].Length < 3 && cNum > -1 && cNum < 18) // user specifying target by client num { if (Players[cNum] != null) E.Target = Players[cNum]; @@ -259,7 +270,7 @@ namespace IW4MAdmin if (Throttled) return; - await ProcessEvent(E); + await ProcessEvent(E); foreach (IPlugin P in SharedLibrary.Plugins.PluginImporter.ActivePlugins) { @@ -325,7 +336,7 @@ namespace IW4MAdmin LastPoll = DateTime.Now; } - catch(SharedLibrary.Exceptions.NetworkException e) + catch (SharedLibrary.Exceptions.NetworkException e) { ConnectionErrors++; if (ConnectionErrors == 1) @@ -354,9 +365,9 @@ namespace IW4MAdmin playerCountStart = DateTime.Now; } - if (LastMessage.TotalSeconds > MessageTime && BroadcastMessages.Count > 0 && ClientNum > 0) + if (LastMessage.TotalSeconds > MessageTime && BroadcastMessages.Count > 0 /*&& ClientNum > 0*/) { - Console.WriteLine(Utilities.ProcessMessageToken(Manager.GetMessageTokens(), BroadcastMessages[NextMessage])); + await Broadcast(Utilities.ProcessMessageToken(Manager.GetMessageTokens(), BroadcastMessages[NextMessage])); NextMessage = NextMessage == (BroadcastMessages.Count - 1) ? 0 : NextMessage + 1; start = DateTime.Now; } @@ -477,14 +488,14 @@ namespace IW4MAdmin logfile = await this.GetDvarAsync("g_log"); } #if DEBUG - basepath.Value = (GameName == Game.IW4) ? - @"\\tsclient\K\MW2" : + basepath.Value = (GameName == Game.IW4) ? + @"\\tsclient\K\MW2" : @"\\tsclient\G\Program Files (x86)\Steam\SteamApps\common\Call of Duty 4"; #endif string mainPath = (GameName == Game.IW4) ? "userraw" : "main"; - string logPath = (game.Value == "" || onelog?.Value == 1) ? - $"{ basepath.Value.Replace("\\", "/")}/{mainPath}/{logfile.Value}" : + string logPath = (game.Value == "" || onelog?.Value == 1) ? + $"{ basepath.Value.Replace("\\", "/")}/{mainPath}/{logfile.Value}" : $"{basepath.Value.Replace("\\", "/")}/{game.Value}/{logfile.Value}"; if (!File.Exists(logPath)) @@ -529,7 +540,7 @@ namespace IW4MAdmin if (E.Type == Event.GType.Say && E.Data.Length >= 2) { - if (E.Data.Substring(0, 1) == "!" || E.Data.Substring(0, 1) == "@" || E.Origin.Level == Player.Permission.Console) + if (E.Data.Substring(0, 1) == "!" || E.Data.Substring(0, 1) == "@" || E.Origin.Level == Player.Permission.Console) { Command C = null; @@ -611,7 +622,7 @@ namespace IW4MAdmin await Target.Kick("Too many warnings!", Origin); else { - Penalty newPenalty = new Penalty(Penalty.Type.Warning, Reason.StripColors(), Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP); + Penalty newPenalty = new Penalty(Penalty.Type.Warning, Reason.StripColors(), Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP, DateTime.Now); Manager.GetClientPenalties().AddPenalty(newPenalty); Target.Warnings++; String Message = String.Format("^1WARNING ^7[^3{0}^7]: ^3{1}^7, {2}", Target.Warnings, Target.Name, Target.lastOffense); @@ -624,23 +635,20 @@ namespace IW4MAdmin if (Target.ClientID > -1) { String Message = "^1Player Kicked: ^5" + Reason; - Penalty newPenalty = new Penalty(Penalty.Type.Kick, Reason.StripColors().Trim(), Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP); + Penalty newPenalty = new Penalty(Penalty.Type.Kick, Reason.StripColors().Trim(), Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP, DateTime.Now); Manager.GetClientPenalties().AddPenalty(newPenalty); 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, TimeSpan length, Player Target, Player Origin) { - if (Target.ClientID > -1) + await this.ExecuteCommandAsync($"tempbanclient {Target.ClientID } \"^1Player Temporarily Banned: ^5{ Reason }\""); + Penalty newPenalty = new Penalty(Penalty.Type.TempBan, Reason.StripColors(), Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP, DateTime.Now + length); + await Task.Run(() => { - await this.ExecuteCommandAsync($"tempbanclient {Target.ClientID } \"^1Player Temporarily Banned: ^5{ Reason } (1 hour)\""); - Penalty newPenalty = new Penalty(Penalty.Type.TempBan, Reason.StripColors(), Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP); - await Task.Run(() => - { - Manager.GetClientPenalties().AddPenalty(newPenalty); - }); - } + Manager.GetClientPenalties().AddPenalty(newPenalty); + }); } override public async Task Ban(String Message, Player Target, Player Origin) @@ -670,7 +678,7 @@ namespace IW4MAdmin if (Origin != null) { Target.SetLevel(Player.Permission.Banned); - Penalty newBan = new Penalty(Penalty.Type.Ban, Target.lastOffense, Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP); + Penalty newBan = new Penalty(Penalty.Type.Ban, Target.lastOffense, Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP, DateTime.MaxValue); await Task.Run(() => { @@ -701,17 +709,21 @@ namespace IW4MAdmin // database stuff can be time consuming await Task.Run(() => { - var FoundPenalaties = Manager.GetClientPenalties().FindPenalties(Target); - var PenaltyToRemove = FoundPenalaties.Find(b => b.BType == Penalty.Type.Ban); + var FoundPenalties = Manager.GetClientPenalties().FindPenalties(Target); - if (PenaltyToRemove == null) - return; - - Manager.GetClientPenalties().RemovePenalty(PenaltyToRemove); + FoundPenalties.Where(p => p.BType > Penalty.Type.Kick) + .All(p => + { + Manager.GetClientPenalties().RemovePenalty(p); + return true; + }); Player P = Manager.GetClientDatabase().GetPlayer(Target.NetworkID, -1); - P.SetLevel(Player.Permission.User); - Manager.GetClientDatabase().UpdatePlayer(P); + if (P.Level < Player.Permission.Trusted) + { + P.SetLevel(Player.Permission.User); + Manager.GetClientDatabase().UpdatePlayer(P); + } }); } diff --git a/Admin/WebService.cs b/Admin/WebService.cs index ada778714..2e31c1c94 100644 --- a/Admin/WebService.cs +++ b/Admin/WebService.cs @@ -209,6 +209,8 @@ namespace IW4MAdmin chatHistory = S.ChatHistory, players = new List() }; + bool authed = ApplicationManager.GetInstance().GetClientDatabase().GetAdmins().FindAll(x => x.IP == querySet["IP"] && x.Level > Player.Permission.Trusted).Count > 0 + || querySet["IP"] == "127.0.0.1"; foreach (Player P in S.GetPlayersAsList()) { @@ -216,7 +218,7 @@ namespace IW4MAdmin { playerID = P.DatabaseID, playerName = P.Name, - playerLevel = P.Level.ToString() + playerLevel = authed ? P.Level.ToString() : Player.Permission.User.ToString() }; eachServer.players.Add(pInfo); } @@ -383,7 +385,6 @@ namespace IW4MAdmin try { - //selectedPenalties = Manager.GetInstance().Servers.First().Bans.OrderByDescending(x => x.When).ToList().GetRange(Convert.ToInt32(querySet["from"]), 15); selectedPenalties = ((ApplicationManager.GetInstance().GetClientPenalties()) as PenaltyList).AsChronoList(Convert.ToInt32(querySet["from"]), 15).OrderByDescending(b => b.When).ToList(); } diff --git a/Admin/lib/SharedLibrary.dll b/Admin/lib/SharedLibrary.dll index 3421cb94d..b819a852d 100644 Binary files a/Admin/lib/SharedLibrary.dll and b/Admin/lib/SharedLibrary.dll differ diff --git a/Admin/version.txt b/Admin/version.txt index b3056056e..9a0030d4d 100644 --- a/Admin/version.txt +++ b/Admin/version.txt @@ -10,6 +10,10 @@ CHANGELOG: -moved aliases to the manager -added admins page to view privileged users -fixed refactoring mistake with messages +-removes flag penality when unflagging a player +-fixed 'just now ago' on webfront +-webfront playerlist level colors are hidden to non admin users +-tempban length can now be specified (m, h, d, y) VERSION 1.3 diff --git a/Admin/webfront/admins.html b/Admin/webfront/admins.html index 80f8886eb..7d964f154 100644 --- a/Admin/webfront/admins.html +++ b/Admin/webfront/admins.html @@ -1,71 +1,71 @@ -
- - + +
+
+
Owner
+
+
-
-
Name
-
Aliases
-
IP
-
Level
-
Connections
-
V2
-
Last Seen
+
+
+
Senior Administrator
+
+
-
+ +
+
+
Administrator
+
+
-
+ +
+
+
Moderator
+
+
+
+ +
+
+
Trusted
+
+
+
+
\ No newline at end of file diff --git a/Admin/webfront/header.html b/Admin/webfront/header.html index 11599a9aa..989efcc04 100644 --- a/Admin/webfront/header.html +++ b/Admin/webfront/header.html @@ -183,10 +183,7 @@ function formatPlayers(players) function checkJustNow(timestr) { - if (timestr.includes("just now")) - return timestr; - else - return timestr + " ago"; + return timestr } function getDate(datestr) diff --git a/Admin/webfront/main.css b/Admin/webfront/main.css index 1a28a075c..111990e20 100644 --- a/Admin/webfront/main.css +++ b/Admin/webfront/main.css @@ -126,8 +126,6 @@ div#threadContainer .threadContent a:hover { color: #fff !important; } div.threadContent ol, div.threadContent ol { margin: 1em; } div.categoryThread .threadActions { color: rgba(255, 69, 69, 0.85); font-size: 18pt; width: 19px; } - - div#postReplyContainer { position: fixed; bottom: 0; left: 0; width: 100%; height: 20em; background-color: #181818; } div#postReplyClose { position: absolute; right: 0.25em; font-size: 24pt; } div#postReplyClose:hover { color: #007ACC; cursor: pointer; } @@ -192,9 +190,12 @@ div.threadInfo .actionHover { float: right; color: rgba(255, 69, 69, 0.85); marg .datThing { background-color: #007ACC; font-size: 16pt; border: none; color: #fff; font-size: 15pt; padding: 0.5em 10px; } span.light { opacity: 0.5; } span.userTitle span:hover {color: #007ACC !important; } - - input#bannercolor { margin: 0.35em; width: 265px; border: none; height: 45px; } - - div#footer { position: fixed; bottom: 0.5em; right: 0.5em; opacity: 0.5; } + +.privilege-title { font-size: 24pt; } +.privilege-title + hr { margin-bottom: 10px; } +.privilege hr { margin-top: 10px !important; } +.admin-name a { font-size: 14pt; color: #007ACC !important; } +.admin-name a:hover { color: #fff !important; } +.clients { margin: 0.5em; } diff --git a/Admin/webfront/penalties.html b/Admin/webfront/penalties.html index 59914c75c..ffcedb978 100644 --- a/Admin/webfront/penalties.html +++ b/Admin/webfront/penalties.html @@ -33,7 +33,7 @@ function getPenalties(from)
"+ getColorForLevel(penalty['penaltyType'], penalty['penaltyType']) + "
\
"+ penalty['penaltyReason'] + "
\
"+ getColorForLevel(penalty['adminLevel'], penalty['adminName']) + "
\ -
"+ penalty['penaltyTime'] + " ago
\ +
"+ penalty['penaltyTime'] + "
\
" ) }); diff --git a/Plugins/Welcome/Plugin.cs b/Plugins/Welcome/Plugin.cs index 5fac30885..8ae1f3d65 100644 --- a/Plugins/Welcome/Plugin.cs +++ b/Plugins/Welcome/Plugin.cs @@ -98,6 +98,10 @@ namespace Welcome_Plugin public async Task OnTickAsync(Server S) { + return; + + // TODO: check if this works + int MaxPing = (await S.GetDvarAsync("sv_maxping")).Value; if (MaxPing == 0) @@ -144,12 +148,12 @@ namespace Welcome_Plugin } - PlayerPings.Add(E.Origin.DatabaseID, 1.0f); + //PlayerPings.Add(E.Origin.DatabaseID, 1.0f); } if (E.Type == Event.GType.Disconnect) { - PlayerPings.Remove(E.Origin.DatabaseID); + //PlayerPings.Remove(E.Origin.DatabaseID); } } } diff --git a/SharedLibrary/Commands/NativeCommands.cs b/SharedLibrary/Commands/NativeCommands.cs index 935eb7f2e..d16559ac7 100644 --- a/SharedLibrary/Commands/NativeCommands.cs +++ b/SharedLibrary/Commands/NativeCommands.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Text; using System.Linq; using SharedLibrary.Network; +using SharedLibrary.Helpers; using System.Threading.Tasks; namespace SharedLibrary.Commands @@ -96,10 +97,15 @@ namespace SharedLibrary.Commands { E.Target.lastOffense = Utilities.RemoveWords(E.Data, 1); String Message = E.Target.lastOffense; + var length = Message.ParseTimespan(); + + if (length.TotalHours != 1) + Message = Utilities.RemoveWords(Message, 1); + if (E.Origin.Level > E.Target.Level) { - await E.Target.TempBan(Message, E.Origin); - await E.Origin.Tell($"Successfully temp banned {E.Target.Name}"); + await E.Target.TempBan(Message, length, E.Origin); + await E.Origin.Tell($"Successfully temp banned ^5{E.Target.Name} ^7for ^5{length.TimeSpanText()}"); } else await E.Origin.Tell("You cannot temp ban " + E.Target.Name); @@ -391,7 +397,7 @@ namespace SharedLibrary.Commands 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, Utilities.ConvertLevelToColor(P.Level), P.IP, P.GetLastConnection()); + String mesg = String.Format("[^3{0}^7] [^3@{1}^7] - [{2}^7] - {3} | last seen {4}", P.Name, P.DatabaseID, Utilities.ConvertLevelToColor(P.Level), P.IP, P.GetLastConnection()); await E.Origin.Tell(mesg); } } @@ -510,6 +516,7 @@ namespace SharedLibrary.Commands if (E.Target.Level == Player.Permission.Flagged) { E.Target.SetLevel(Player.Permission.User); + E.Owner.Manager.GetClientPenalties().RemovePenalty(new Penalty(Penalty.Type.Flag, "", E.Target.NetworkID, "", DateTime.Now, "", DateTime.Now)); await E.Origin.Tell("You have ^5unflagged ^7" + E.Target.Name); } @@ -517,7 +524,7 @@ namespace SharedLibrary.Commands { E.Data = Utilities.RemoveWords(E.Data, 1); 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)); + E.Owner.Manager.GetClientPenalties().AddPenalty(new Penalty(Penalty.Type.Flag, E.Data, E.Target.NetworkID, E.Origin.NetworkID, DateTime.Now, E.Target.IP, DateTime.Now)); await E.Owner.ExecuteEvent(new Event(Event.GType.Flag, E.Data, E.Origin, E.Target, E.Owner)); await E.Origin.Tell("You have ^5flagged ^7" + E.Target.Name); } @@ -617,7 +624,7 @@ namespace SharedLibrary.Commands } var B = E.Owner.Manager.GetClientPenalties().FindPenalties(E.Target); - var BannedPenalty = B.Find(b => b.BType == Penalty.Type.Ban); + var BannedPenalty = B.Find(b => b.BType > Penalty.Type.Kick && b.Expires > DateTime.Now); if (BannedPenalty == null) { @@ -627,13 +634,7 @@ namespace SharedLibrary.Commands Player Banner = E.Owner.Manager.GetClientDatabase().GetPlayer(BannedPenalty.PenaltyOriginID, -1); - if (Banner == null) - { - await E.Origin.Tell("Ban was found for the player, but origin of the ban is unavailable."); - return; - } - - await E.Origin.Tell(String.Format("^1{0} ^7was banned by ^5{1} ^7for: {2}", E.Target.Name, Banner.Name, BannedPenalty.Reason)); + await E.Origin.Tell(String.Format("^1{0} ^7was banned by ^5{1} ^7for: {2} {3}", E.Target.Name, Banner?.Name ?? "IW4MAdmin", BannedPenalty.Reason, BannedPenalty.BType == Penalty.Type.TempBan ? $"({(BannedPenalty.Expires - DateTime.Now).TimeSpanText()} remaining)" : "")); } } diff --git a/SharedLibrary/Database.cs b/SharedLibrary/Database.cs index 40385f49b..6ae9b9f03 100644 --- a/SharedLibrary/Database.cs +++ b/SharedLibrary/Database.cs @@ -227,7 +227,7 @@ namespace SharedLibrary { String Create = "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, [IP] TEXT NULL, [LastConnection] TEXT NULL, [UID] TEXT NULL, [Masked] INT DEFAULT 0, [Reserved] INT DEFAULT 0);"; ExecuteNonQuery(Create); - Create = "CREATE TABLE [BANS] ( [TYPE] TEXT NULL, [Reason] TEXT NULL, [npID] TEXT NULL, [bannedByID] TEXT NULL, [IP] TEXT NULL, [TIME] TEXT NULL);"; + Create = "CREATE TABLE [BANS] ( [TYPE] TEXT NULL, [Reason] TEXT NULL, [npID] TEXT NULL, [bannedByID] TEXT NULL, [IP] TEXT NULL, [TIME] TEXT NULL, [EXPIRES] TEXT);"; ExecuteNonQuery(Create); } } @@ -453,7 +453,7 @@ namespace SharedLibrary if (Row["TYPE"].ToString().Length != 0) BanType = (Penalty.Type)Enum.Parse(typeof(Penalty.Type), Row["TYPE"].ToString()); - ClientPenalties.Add(new Penalty(BanType, Row["Reason"].ToString().Trim(), Row["npID"].ToString(), Row["bannedByID"].ToString(), DateTime.Parse(Row["TIME"].ToString()), Row["IP"].ToString())); + ClientPenalties.Add(new Penalty(BanType, Row["Reason"].ToString().Trim(), Row["npID"].ToString(), Row["bannedByID"].ToString(), DateTime.Parse(Row["TIME"].ToString()), Row["IP"].ToString(), DateTime.Parse(Row["EXPIRES"].ToString()))); } @@ -470,12 +470,8 @@ namespace SharedLibrary if (Row["TIME"].ToString().Length < 2) //compatibility with my old database Row["TIME"] = DateTime.Now.ToString(); - Penalty.Type BanType = Penalty.Type.Ban; - if (Row["TYPE"].ToString().Length != 0) - BanType = (Penalty.Type)Enum.Parse(typeof(Penalty.Type), Row["TYPE"].ToString()); - - ClientPenalties.Add(new Penalty(BanType, Row["Reason"].ToString().Trim(), Row["npID"].ToString(), Row["bannedByID"].ToString(), DateTime.Parse(Row["TIME"].ToString()), Row["IP"].ToString())); - + var BanType = (Penalty.Type)Enum.Parse(typeof(Penalty.Type), Row["TYPE"].ToString()); + ClientPenalties.Add(new Penalty(BanType, Row["Reason"].ToString().Trim(), Row["npID"].ToString(), Row["bannedByID"].ToString(), DateTime.Parse(Row["TIME"].ToString()), Row["IP"].ToString(), DateTime.Parse(Row["EXPIRES"].ToString()))); } return ClientPenalties; @@ -542,7 +538,7 @@ namespace SharedLibrary //Add specified ban to database - public void AddBan(Penalty B) + public void AddPenalty(Penalty B) { Dictionary newBan = new Dictionary { @@ -551,7 +547,8 @@ namespace SharedLibrary { "bannedByID", B.PenaltyOriginID }, { "IP", B.IP }, { "TIME", Utilities.DateTimeSQLite(DateTime.Now) }, - { "TYPE", B.BType } + { "TYPE", B.BType }, + { "EXPIRES", B.Expires } }; Insert("BANS", newBan); } diff --git a/SharedLibrary/Penalty.cs b/SharedLibrary/Penalty.cs index dceccf321..b78d43b62 100644 --- a/SharedLibrary/Penalty.cs +++ b/SharedLibrary/Penalty.cs @@ -5,12 +5,13 @@ namespace SharedLibrary { public class Penalty { - 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, DateTime exp) { Reason = Reas.CleanChars().StripColors(); OffenderID = TargID; PenaltyOriginID = From; When = time; + Expires = exp; IP = ip; this.BType = BType; } @@ -34,6 +35,7 @@ namespace SharedLibrary public String OffenderID { get; private set; } public String PenaltyOriginID { get; private set; } public DateTime When { get; private set; } + public DateTime Expires { get; private set; } public String IP { get; private set; } public Type BType { get; private set; } } diff --git a/SharedLibrary/Player.cs b/SharedLibrary/Player.cs index 9a1e55fcc..2e0aea8e3 100644 --- a/SharedLibrary/Player.cs +++ b/SharedLibrary/Player.cs @@ -154,9 +154,9 @@ namespace SharedLibrary await lastEvent.Owner.Kick(Message, this, Sender); } - public async Task TempBan(String Message, Player Sender) + public async Task TempBan(String Message, TimeSpan Length, Player Sender) { - await lastEvent.Owner.TempBan(Message, this, Sender); + await lastEvent.Owner.TempBan(Message, Length, this, Sender); } public async Task Warn(String Message, Player Sender) diff --git a/SharedLibrary/Server.cs b/SharedLibrary/Server.cs index b7abea14b..68fd9ab72 100644 --- a/SharedLibrary/Server.cs +++ b/SharedLibrary/Server.cs @@ -210,7 +210,7 @@ namespace SharedLibrary /// /// Reason for banning the player /// The player to ban - abstract public Task TempBan(String Reason, Player Target, Player Origin); + abstract public Task TempBan(String Reason, TimeSpan length, Player Target, Player Origin); /// /// Perm ban a player from the server diff --git a/SharedLibrary/SharedLibrary.csproj b/SharedLibrary/SharedLibrary.csproj index 672cbd65c..1d1a1f8a9 100644 --- a/SharedLibrary/SharedLibrary.csproj +++ b/SharedLibrary/SharedLibrary.csproj @@ -25,6 +25,7 @@ prompt 4 false + ..\..\..\RuleSet1.ruleset AnyCPU diff --git a/SharedLibrary/Utilities.cs b/SharedLibrary/Utilities.cs index cb197c9ae..7048a55d7 100644 --- a/SharedLibrary/Utilities.cs +++ b/SharedLibrary/Utilities.cs @@ -229,23 +229,23 @@ namespace SharedLibrary if (Elapsed.TotalMinutes < 120) { if (Elapsed.TotalMinutes < 1.5) - return "1 minute"; - return Math.Round(Elapsed.TotalMinutes, 0) + " minutes"; + return "1 minute ago"; + return Math.Round(Elapsed.TotalMinutes, 0) + " minutes ago"; } if (Elapsed.TotalHours <= 24) { if (Elapsed.TotalHours < 1.5) - return "1 hour"; - return Math.Round(Elapsed.TotalHours, 0) + " hours"; + return "1 hour ago"; + return Math.Round(Elapsed.TotalHours, 0) + " hours ago"; } if (Elapsed.TotalDays <= 365) { if (Elapsed.TotalDays < 1.5) - return "1 day"; - return Math.Round(Elapsed.TotalDays, 0) + " days"; + return "1 day ago"; + return Math.Round(Elapsed.TotalDays, 0) + " days ago"; } else - return "a very long time"; + return "a very long time ago"; } public static Game GetGame(string gameName) @@ -263,5 +263,48 @@ namespace SharedLibrary return Game.UKN; } + + public static TimeSpan ParseTimespan(this string input) + { + var expressionMatch = Regex.Match(input, @"[0-9]+.\b"); + + if (!expressionMatch.Success) // fallback to default tempban length of 1 hour + return new TimeSpan(1, 0, 0); + + char lengthDenote = expressionMatch.Value[expressionMatch.Value.Length - 1]; + int length = Int32.Parse(expressionMatch.Value.Substring(0, expressionMatch.Value.Length - 1)); + + switch (lengthDenote) + { + case 'm': + return new TimeSpan(0, length, 0); + case 'h': + return new TimeSpan(length, 0, 0); + case 'd': + return new TimeSpan(length, 0, 0, 0); + case 'w': + return new TimeSpan(length * 7, 0, 0, 0); + case 'y': + return new TimeSpan(length * 365, 0, 0, 0); + default: + return new TimeSpan(1, 0, 0); + } + } + + public static string TimeSpanText(this TimeSpan span) + { + if (span.TotalMinutes < 6) + return $"{span.Minutes} minutes"; + else if (span.TotalHours < 24) + return $"{span.Hours} hours"; + else if (span.TotalDays < 7) + return $"{span.Days} days"; + else if (span.TotalDays > 7 && span.TotalDays < 365) + return $"{Math.Ceiling(span.Days / 7.0)} weeks"; + else if (span.TotalDays >= 365) + return $"{Math.Ceiling(span.Days / 365.0)} years"; + + return "1 hour"; + } } }