From cdeb7e8eaff7e273f94fd8a36424115c8087cc40 Mon Sep 17 00:00:00 2001 From: RaidMax Date: Thu, 16 Nov 2017 17:09:19 -0600 Subject: [PATCH] Finally stopped the "error on character" printout (removed console.writeline in Kayak submodule) Fixed console execute button cascading on IE/Edge Fixed reports truncating reason if space in target name If multiple matches are found when finding a player, a list of matches is shown Reallowed special characters in names/chat stats command player isn't required Added prune command --- Admin/Application.csproj | 4 +- Admin/Kayak.cs | 12 +-- Admin/Main.cs | 2 +- Admin/Server.cs | 28 ++++++- Admin/lib/Kayak.dll | Bin 43008 -> 43008 bytes Admin/lib/SharedLibrary.dll | Bin 117248 -> 117248 bytes Admin/version.txt | 14 +++- Admin/webfront/main.css | 4 +- Plugins/SimpleStats/Plugin.cs | 40 ++++++++- Plugins/Tests/Plugin.cs | 7 +- README.md | 101 ++++++++++++----------- SharedLibrary/Commands/NativeCommands.cs | 21 ++--- SharedLibrary/Database.cs | 11 ++- SharedLibrary/Event.cs | 8 +- SharedLibrary/Penalty.cs | 2 +- SharedLibrary/Server.cs | 11 ++- SharedLibrary/SharedLibrary.csproj | 1 + SharedLibrary/Utilities.cs | 26 ++---- 18 files changed, 177 insertions(+), 115 deletions(-) diff --git a/Admin/Application.csproj b/Admin/Application.csproj index cbcfcd4d..2e92bb4b 100644 --- a/Admin/Application.csproj +++ b/Admin/Application.csproj @@ -367,8 +367,8 @@ copy /Y "$(ProjectDir)lib\Kayak.dll" "$(SolutionDir)BUILD\lib" xcopy /Y /I /E "$(ProjectDir)webfront\*" "$(SolutionDir)BUILD\Webfront" xcopy /Y /I /E "$(SolutionDir)Admin\Config\*" "$(SolutionDir)BUILD\Config" -if $(ConfigurationName) == Release-Nightly powershell.exe -file "$(SolutionDir)DEPLOY\publish_nightly.ps1" 1.5 -if $(ConfigurationName) == Release-Stable powershell.exe -file "$(SolutionDir)DEPLOY\publish_stable.ps1" 1.5 +if $(ConfigurationName) == Release-Nightly powershell.exe -file "$(SolutionDir)DEPLOY\publish_nightly.ps1" 1.6 +if $(ConfigurationName) == Release-Stable powershell.exe -file "$(SolutionDir)DEPLOY\publish_stable.ps1" 1.6 diff --git a/Admin/Kayak.cs b/Admin/Kayak.cs index e7450073..cf60b3c0 100644 --- a/Admin/Kayak.cs +++ b/Admin/Kayak.cs @@ -37,19 +37,19 @@ namespace IW4MAdmin class Request : IHttpRequestDelegate { - public void OnRequest(HttpRequestHead request, IDataProducer requestBody, IHttpResponseDelegate response, string IP) + public void OnRequest(HttpRequestHead request, IDataProducer requestBody, IHttpResponseDelegate response) { var logger = ApplicationManager.GetInstance().GetLogger(); - logger.WriteInfo($"HTTP request {request.Path}"); - logger.WriteInfo($"QueryString: {request.QueryString}"); - logger.WriteInfo($"IP: {IP}"); + logger.WriteDebug($"HTTP request {request.Path}"); + logger.WriteDebug($"QueryString: {request.QueryString}"); + logger.WriteDebug($"IP: {request.IPAddress}"); NameValueCollection querySet = new NameValueCollection(); if (request.QueryString != null) - querySet = System.Web.HttpUtility.ParseQueryString(SharedLibrary.Utilities.StripIllegalCharacters(request.QueryString)); + querySet = System.Web.HttpUtility.ParseQueryString(request.QueryString); - querySet.Set("IP", IP); + querySet.Set("IP", request.IPAddress); try { diff --git a/Admin/Main.cs b/Admin/Main.cs index 42437535..74840b39 100644 --- a/Admin/Main.cs +++ b/Admin/Main.cs @@ -15,7 +15,7 @@ namespace IW4MAdmin static void Main(string[] args) { - Version = 1.5; + Version = 1.6; handler = new ConsoleEventDelegate(OnProcessExit); SetConsoleCtrlHandler(handler, true); diff --git a/Admin/Server.cs b/Admin/Server.cs index fe3dfa9a..796882cc 100644 --- a/Admin/Server.cs +++ b/Admin/Server.cs @@ -257,11 +257,33 @@ namespace IW4MAdmin E.Target = Players[cNum]; } + List matchingPlayers; + if (E.Target == null) // Find active player including quotes (multiple words) - E.Target = GetClientByName(E.Data.Trim()); + { + matchingPlayers = GetClientByName(E.Data.Trim()); + if (matchingPlayers.Count > 1) + { + await E.Origin.Tell("Multiple players match that name"); + throw new SharedLibrary.Exceptions.CommandException($"{E.Origin} had multiple players found for {C.Name}"); + } + else if (matchingPlayers.Count == 1) + E.Target = matchingPlayers.First(); + } if (E.Target == null) // Find active player as single word - E.Target = GetClientByName(Args[0]); + { + matchingPlayers = GetClientByName(Args[0]); + if (matchingPlayers.Count > 1) + { + await E.Origin.Tell("Multiple players match that name"); + foreach (var p in matchingPlayers) + await E.Origin.Tell($"[^3{p.ClientID}^7] {p.Name}"); + throw new SharedLibrary.Exceptions.CommandException($"{E.Origin} had multiple players found for {C.Name}"); + } + else if (matchingPlayers.Count == 1) + E.Target = matchingPlayers.First(); + } if (E.Target == null && C.RequiresTarget) { @@ -600,7 +622,7 @@ namespace IW4MAdmin else // Not a command { - E.Data = E.Data.StripColors().CleanChars(); + E.Data = E.Data.StripColors(); // this should not be done for all messages. //if (E.Data.Length > 50) // E.Data = E.Data.Substring(0, 50) + "..."; diff --git a/Admin/lib/Kayak.dll b/Admin/lib/Kayak.dll index d9eb6a3cb8cedeaabc5bdd1371c54c063111e7b1..149365797044bff8c620fe97050ec1302e90a7be 100644 GIT binary patch delta 16932 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 WgyxVb1T`6 zPM_(l-^%|b_Z*xmmNmSPV||CiA+{tSIGq2Ez!@_xI~;z`+geU_mdgKmW}GIKAWD6$ z;X0u>!^*P&`Cn4Pk#a|AZZbBZt*1|?H^juxr<@bI<3RHHXA|s~=9iNJV$-J8vMM=- zcp&~`cm0Rn;<_sRH`34%}Owe>v2_&Soh(*0i-QFi>lUqjo;!o>rMzOiLh zazIu(vnnyETBwtyeI)^%ah)#ZRQ?l^C610$jv(DsdMBkXTe3&T$5<0znN8f&@Rvb} zlVjJ&JFslxgGC{zLTy2P_-t(C1@P6E=|G{wgpL(DS?DaGSAi<{hQ@R)@sr>C#7B_~ zT2@qs@D#y~6(iSBnU_&2|-E@y~z`H?eC4}BVPb)8k@1c$K z1)ebOp#xsF^Dv$Zwve7?AD~Z^#olWG-og|6M#Wq36v{WE%u0t*-j)3ly$;hy(0NAQ zar#2}(EA}c_xe8t4TqcYpu(+JR1UFH%4t&GDEdzer;?t@2q=5#V}HK#G`)ddd7Asi z#*I6zl3vLuf#6aI4$z05c2MQFy06n;0}&-nG4eWtz7*&K%KB-_HRcfEj0F8L%L5L- zm>USq<0xl^rz!U+*}0cO>IpAW2C4^hRx0l+)4Vq*+0enTsvi|36kAa)&;PYDR_#^% zfKsT`7U$7q^?AIV;SPUB=`OL)Qs)%^TjB0i)$VxhQliY0_I0OOSvlZ*neU(?d88?$GDoXvw!-f?(v&&orJ(#y zBTacXd%3z+?H0IB-Kf5pb)z~+42{6}mEmhR8@)$8;oGlHmGUJL&?Pk1|9ABga1^>q z=~D8YdX;h_XD-U$gD#-T;&g2R!p+t;D&-{wpj|*05%T}IjCwC^2il~dTv&Jw?NPg> z&DWN}+!9oqpS4n3CCRu-TD(eHyh@y{689UGsU=&rtI)B#v};K%II69aY`;}z!CiDT z;|I8WyFk(JqV~mQ$St)XT}L|G=018|eOu4bUsrF-E7T9rOwU|;M?!gB{aj;yuD?d- zSx6%^x)_{W)n%Z!tBs&{sjKxenhnQog?6TNlsi)n z9rAXjFuefUj!uGB&=;WH=m*d~Qa+!yq;fQy--v4U`%LCMEA)g=4RgF!Z|7zH`9fz4T`Bzgq-;Mcw-Z9O zG*;DoOlJyh5c*ywa|Q(2&9+>ohlIW-w4snW1KR8aohfvi&_hDs6G~+)Efb25lQ{g> zVxhmDDDlR`@;*Cp%%7wzP~yt%%1-5X$`i^9$}7s-%6}{WRMIdBZc_(nBeZeaByFa4 zt9FNWpSD+PqqoyL>D7sDlX}j+CwvDEJc9#UK`#`v2xyrs1D+cSC8D%=G+!~x3Y`EXQ zulw~g)ZzRePH2J-VN|pzN=sH!7p&EV$^Yb`aAA=S&?m z=bAYStc6$1xpL9e%V%9X>+-5AX4Nm6Q V^Kbj!qkh$UU-pClP&QVZ{|_#Ds~G?Q diff --git a/Admin/lib/SharedLibrary.dll b/Admin/lib/SharedLibrary.dll index ebce2c11cac008ff9e21f89a9ab39e660fade7a0..c5e9a3dbe006153319ed2f8f3fbf43364d2057fe 100644 GIT binary patch delta 46351 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 diff --git a/Admin/version.txt b/Admin/version.txt index 70869f2a..2dd3dcfb 100644 --- a/Admin/version.txt +++ b/Admin/version.txt @@ -1,4 +1,13 @@ -Version 1.5 +Version 1.6: +CHANGELOG: +-got rid of pesky "error on character" message +-optimizations to commands +-report reason doesn't truncate if there's a space in the target name +-If multiple matches are found when finding a player, a list of matches is shown +-"special" characters are allowed in names and messages +-prune command demotes inactive admins (defaults to 30 days if no days are specified) + +Version 1.5 CHANGELOG: -added back player history graphs (past 12 hours every 15 minutes) -fixed issue with configurationmanager files and threading @@ -8,7 +17,7 @@ CHANGELOG: -started working on more advanced statistics -all chat is stored -word cloud displays most commonly used words on the server --fixed misc issuess +-fixed misc issues VERSION 1.4 CHANGELOG: @@ -27,7 +36,6 @@ CHANGELOG: -webfront playerlist level colors are hidden to non admin users -tempban length can now be specified (m, h, d, y) - VERSION 1.3 CHANGELOG: -complete rewrite of lots of parts diff --git a/Admin/webfront/main.css b/Admin/webfront/main.css index 6f7f4403..9eb8edd4 100644 --- a/Admin/webfront/main.css +++ b/Admin/webfront/main.css @@ -25,7 +25,7 @@ div#content .serverTitle { width: calc( 100% / 3); background-color: #007ACC; } div#content .serverPlayers { text-align: right; width: calc( 100% / 3); background-color: #007ACC; } div#content .serverMap { text-align: center; width: calc( 100% / 3); background-color: #007ACC; } div#content .serverPlayerList {float: right; margin: 0.5em; } -div#content .serverChatList { float: left; margin: 0.5em } +div#content .serverChatList { float: left; margin: 0.5em; max-width: 60%; overflow:hidden } div#content .playerName { font-size: 1.1vw; color: rgba(78, 140, 77, 0.64); width: 10em; text-align: right; } div#content .playerName:hover { color: rgb(0, 122, 204) !important; } div#content .chatPlayerName { font-weight: bold; font-size: 1.1vw; color:#fff; padding-right: 0.5em; opacity: 0.5; } @@ -60,7 +60,7 @@ div#content .hiddenWrapper { color: #007ACC;} div#content #consoleWrap { width: 60%; margin: 0 auto; } div#content #console { padding: 1em; height: 35vh; background-color: #181818; } -div#content #consoleWrap .search { width: calc(80% - 10px); } +div#content #consoleWrap .search { width: calc(80% - 10px); float: left; } div#consoleWrap .playerSearchWrap input[type="text"]:focus, select:focus { border-width: 0; outline: none; } div#consoleWrap .playerSearchWrap { margin: 0 !important; width: 100%; } div#consoleWrap .searchButton { width: calc(20% - 10px); } diff --git a/Plugins/SimpleStats/Plugin.cs b/Plugins/SimpleStats/Plugin.cs index 5d03b9f6..534a4f15 100644 --- a/Plugins/SimpleStats/Plugin.cs +++ b/Plugins/SimpleStats/Plugin.cs @@ -16,7 +16,7 @@ namespace StatsPlugin new CommandArgument() { Name = "player", - Required = true + Required = false } }) { } @@ -100,6 +100,39 @@ namespace StatsPlugin } } + public class CPruneAdmins : Command + { + public CPruneAdmins() : base("prune", "demote any admins that have not connected recently (defaults to 30 days)", "p", Player.Permission.Owner, false, new CommandArgument[] + { + new CommandArgument() + { + Name = "inactive days", + Required = false + } + }) + { } + + public override async Task ExecuteAsync(Event E) + { + int inactiveDays = 30; + + try + { + inactiveDays = Int32.Parse(E.Data); + if (inactiveDays < 1) + throw new FormatException(); + } + + catch (FormatException) + { + await E.Origin.Tell("Invalid number of inactive days"); + } + + E.Owner.Manager.GetClientDatabase().PruneAdmins(inactiveDays); + + } + } + /// /// 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 @@ -420,7 +453,7 @@ namespace StatsPlugin // calculate the players Score Per Minute for the current session double SessionSPM = curServer.Kills[P.ClientID] * 100 / Math.Max(1, newPlayTime); // calculate how much the KDR should way - // 0.81829 is a Eddie-Generated number that weights the KDR nicely + // 1.637 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; @@ -428,7 +461,6 @@ namespace StatsPlugin SPMWeightAgainstAverage = (DisconnectingPlayerStats.scorePerMinute == 1) ? 1 : SessionSPM / DisconnectingPlayerStats.scorePerMinute; // calculate the weight of the new play time againmst lifetime playtime - // double SPMAgainstPlayWeight = newPlayTime / Math.Min(600, DisconnectingPlayerStats.TotalPlayTime + newPlayTime); // calculate the new weight against average times the weight against play time double newSkillFactor = SPMWeightAgainstAverage * SPMAgainstPlayWeight * SessionSPM; @@ -436,7 +468,7 @@ namespace StatsPlugin // if the weight is greater than 1, add, else subtract DisconnectingPlayerStats.scorePerMinute += (SPMWeightAgainstAverage >= 1) ? newSkillFactor : -newSkillFactor; - DisconnectingPlayerStats.Skill = DisconnectingPlayerStats.scorePerMinute * KDRWeight / 10; + DisconnectingPlayerStats.Skill = DisconnectingPlayerStats.scorePerMinute * KDRWeight * 10; DisconnectingPlayerStats.TotalPlayTime += newPlayTime; curServer.playerStats.UpdateStats(P, DisconnectingPlayerStats); diff --git a/Plugins/Tests/Plugin.cs b/Plugins/Tests/Plugin.cs index 1e04e73c..c743a2fa 100644 --- a/Plugins/Tests/Plugin.cs +++ b/Plugins/Tests/Plugin.cs @@ -42,10 +42,11 @@ namespace IW4MAdmin.Plugins #endregion #region PLUGIN_INFO + Console.WriteLine("|Name |Alias|Description |Requires Target|Syntax |Required Level|"); + Console.WriteLine("|--------------| -----| --------------------------------------------------------| -----------------| -------------| ----------------|"); foreach (var command in S.Manager.GetCommands().OrderByDescending(c => c.Permission).ThenBy(c => c.Name)) { - //|Name|Alias|Description|Requires Target|Syntax|Required Level| - Console.WriteLine($"|{command.Name}|{command.Alias}|{command.Description}|{command.RequiresTarget}|{command.Syntax.Substring(8)}|{command.Permission}|"); + Console.WriteLine($"|{command.Name}|{command.Alias}|{command.Description}|{command.RequiresTarget}|{command.Syntax.Substring(8).EscapeMarkdown()}|{command.Permission}|"); } #endregion } @@ -62,7 +63,7 @@ namespace IW4MAdmin.Plugins { var rand = new Random(); int index = rand.Next(0, 17); - var p = new Player($"Test_{index}", $"_test{index}", index, (int)Player.Permission.User) + var p = new Player($"?!'\"\"'<>Test_{index}", $"_test{index}", index, (int)Player.Permission.User) { Ping = 1 }; diff --git a/README.md b/README.md index 87927160..78cdbdb8 100644 --- a/README.md +++ b/README.md @@ -37,49 +37,49 @@ _If you wish to customize your experience of IW4MAdmin, the following configurat ___ ### Commands -|Name |Alias|Description |Requires Target|Arguments |Required Level| -|--------------|-----|--------------------------------------------------------|---------------|---------------|--------------| -|disabletrusted|dt|disable trusted player group for the server|False|0|Owner| -|enabletrusted|et|enable trusted player group for the server|False|0|Owner| -|quit|q|quit IW4MAdmin|False|0|Owner| -|rcon|rcon|send rcon command to server|False|1|Owner| -|setlevel|sl|set player to specified administration level|True|2|Owner| -|ban|b|permanently ban a player from the server|True|2|SeniorAdmin| -|find|f|find player in database|False|1|SeniorAdmin| -|fredisable|frd|disable fast restarting at the end of a map|False|0|SeniorAdmin| -|frenable|fre|enable fast restarting at the end of a map|False|0|SeniorAdmin| -|unban|ub|unban player by database id|True|1|SeniorAdmin| -|map|m|change to specified map|False|1|Administrator| -|maprotate|mr|cycle to the next map in rotation|False|0|Administrator| -|mask|hide|hide your online presence from online admin list|False|0|Administrator| -|plugins|p|view all loaded plugins|False|0|Administrator| -|alias|known|get past aliases and ips of a player|True|1|Moderator| -|baninfo|bi|get information about a ban for a player|True|1|Moderator| -|fastrestart|fr|fast restart current map|False|0|Moderator| -|findall|fa|find a player by their aliase(s)|False|1|Moderator| -|flag|fp|flag a suspicious player and announce to admins on join|True|2|Moderator| -|list|l|list active clients|False|0|Moderator| -|reports|reps|get most recent reports|False|0|Moderator| -|say|s|broadcast message to all players|False|1|Moderator| -|tempban|tb|temporarily ban a player for for specified time (defaults to 1 hour)|True|2|Moderator| -|uptime|up|get current application running time|False|0|Moderator| -|usage|us|get current application memory usage|False|0|Moderator| -|kick|k|kick a player by name|True|2|Trusted| -|warn|w|warn player for infringing rules|True|2|Trusted| -|warnclear|wc|remove all warning for a player|True|1|Trusted| -|admins|a|list currently connected admins|False|0|User| -|getexternalip|ip|view your external IP address|False|0|User| -|help|h|list all available commands|False|0|User| -|owner|o|claim ownership of the server|False|0|User| -|privatemessage|pm|send message to other player|True|2|User| -|report|rep|report a player for suspicious behaivor|True|2|User| -|resetstats|rs|reset your stats to factory-new|False|0|User| -|rules|r|list server rules|False|0|User| -|stats|xlrstats|view your stats|False|0|User| -|topstats|ts|view the top 5 players on this server|False|0|User| -|vote|v|vote for the next map|False|1|User| -|votecancel|vc|cancel your vote for the next map|False|0|User| -|whoami|who|give information about yourself|False|0|User| +|Name |Alias|Description |Requires Target|Syntax |Required Level| +|--------------| -----| --------------------------------------------------------| -----------------| -------------| ----------------| +|disabletrusted|dt|disable trusted player group for the server|False|!dt |Owner| +|enabletrusted|et|enable trusted player group for the server|False|!et |Owner| +|prune|p|demote any admins that have not connected recently (defaults to 30 days)|False|!p \|Owner| +|quit|q|quit IW4MAdmin|False|!q |Owner| +|rcon|rcon|send rcon command to server|False|!rcon \|Owner| +|reload|rl|reload configuration files|False|!rl |Owner| +|setlevel|sl|set player to specified administration level|True|!sl \ \|Owner| +|ban|b|permanently ban a player from the server|True|!b \ \|SeniorAdmin| +|fredisable|frd|disable fast restarting at the end of a map|False|!frd |SeniorAdmin| +|frenable|fre|enable fast restarting at the end of a map|False|!fre |SeniorAdmin| +|unban|ub|unban player by database id|True|!ub \|SeniorAdmin| +|find|f|find player in database|False|!f \|Administrator| +|findall|fa|find a player by their aliase(s)|False|!fa \|Administrator| +|map|m|change to specified map|False|!m \|Administrator| +|maprotate|mr|cycle to the next map in rotation|False|!mr |Administrator| +|plugins|p|view all loaded plugins|False|!p |Administrator| +|alias|known|get past aliases and ips of a player|True|!known \|Moderator| +|baninfo|bi|get information about a ban for a player|True|!bi \|Moderator| +|fastrestart|fr|fast restart current map|False|!fr |Moderator| +|flag|fp|flag a suspicious player and announce to admins on join|True|!fp \ \|Moderator| +|list|l|list active clients|False|!l |Moderator| +|reports|reps|get or clear recent reports|False|!reps \|Moderator| +|say|s|broadcast message to all players|False|!s \|Moderator| +|tempban|tb|temporarily ban a player for specified time (defaults to 1 hour)|True|!tb \ \ \|Moderator| +|uptime|up|get current application running time|False|!up |Moderator| +|usage|us|get current application memory usage|False|!us |Moderator| +|kick|k|kick a player by name|True|!k \ \|Trusted| +|warn|w|warn player for infringing rules|True|!w \ \|Trusted| +|warnclear|wc|remove all warning for a player|True|!wc \|Trusted| +|admins|a|list currently connected admins|False|!a |User| +|getexternalip|ip|view your external IP address|False|!ip |User| +|help|h|list all available commands|False|!h \|User| +|privatemessage|pm|send message to other player|True|!pm \ \|User| +|report|rep|report a player for suspicious behavior|True|!rep \ \|User| +|resetstats|rs|reset your stats to factory-new|False|!rs |User| +|rules|r|list server rules|False|!r |User| +|stats|xlrstats|view your stats|False|!xlrstats \|User| +|topstats|ts|view the top 5 players on this server|False|!ts |User| +|vote|v|vote for the next map|False|!v \|User| +|votecancel|vc|cancel your vote for the next map|False|!vc |User| +|whoami|who|give information about yourself.|False|!who |User| #### Player Identification All players are identified 4 seperate ways @@ -159,13 +159,14 @@ ___ **Commands added by this plugin** -|Name |Alias|Description |Requires Target|Arguments |Required Level| -|--------------|-----|--------------------------------------------------------|---------------|---------------|--------------| -|disabletrusted|dt|disable trusted player group for the server|False|0|Owner| -|enabletrusted|et|enable trusted player group for the server|False|0|Owner| -|resetstats|rs|reset your stats to factory-new|False|0|User| -|stats|xlrstats|view your stats|False|0|User| -|topstats|ts|view the top 5 players on this server|False|0|User| +|Name |Alias|Description |Requires Target|Syntax |Required Level| +|--------------| -----| --------------------------------------------------------| -----------------| -------------| ----------------| +|disabletrusted|dt|disable trusted player group for the server|False|!dt |Owner| +|enabletrusted|et|enable trusted player group for the server|False|!et |Owner| +|prune|p|demote any admins that have not connected recently (defaults to 30 days)|False|!p \|Owner| +|resetstats|rs|reset your stats to factory-new|False|!rs |User| +|stats|xlrstats|view your stats|False|!xlrstats \|User| +|topstats|ts|view the top 5 players on this server|False|!ts |User| - To qualify for top stats, a player must meet the following criteria * `Skill` > 10 diff --git a/SharedLibrary/Commands/NativeCommands.cs b/SharedLibrary/Commands/NativeCommands.cs index ea4a50e5..66fc515b 100644 --- a/SharedLibrary/Commands/NativeCommands.cs +++ b/SharedLibrary/Commands/NativeCommands.cs @@ -151,7 +151,7 @@ namespace SharedLibrary.Commands }, new CommandArgument() { - Name = "duration (m|d|w|y|)", + Name = "duration (m|h|d|w|y)", Required = true, }, new CommandArgument() @@ -193,8 +193,8 @@ namespace SharedLibrary.Commands }, new CommandArgument() { - Name = "reason", - Required = true + Name = "reason", + Required = true } }) { } @@ -247,7 +247,7 @@ namespace SharedLibrary.Commands 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.NetworkID, E.Origin.DatabaseID, SharedLibrary.Utilities.ConvertLevelToColor(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, Utilities.ConvertLevelToColor(E.Origin.Level), E.Origin.IP); await E.Origin.Tell(You); } } @@ -663,8 +663,9 @@ namespace SharedLibrary.Commands public class CReload : Command { - public CReload() : - base("reload", "reload configuration files", "rl", Player.Permission.Owner, false) { } + public CReload() : + base("reload", "reload configuration files", "rl", Player.Permission.Owner, false) + { } public override async Task ExecuteAsync(Event E) { @@ -755,14 +756,14 @@ namespace SharedLibrary.Commands if (E.Target.Level > E.Origin.Level) { - await E.Origin.Tell("You cannot report " + E.Target.Name); + await E.Origin.Tell($"You cannot report {E.Target.Name}"); return; } E.Data = E.Data.RemoveWords(1); E.Owner.Reports.Add(new Report(E.Target, E.Origin, E.Data)); - await E.Origin.Tell("Successfully reported " + E.Target.Name); + await E.Origin.Tell($"Successfully reported {E.Target.Name}"); await E.Owner.ExecuteEvent(new Event(Event.GType.Report, E.Data, E.Origin, E.Target, E.Owner)); await E.Owner.ToAdmins(String.Format("^5{0}^7->^1{1}^7: {2}", E.Origin.Name, E.Target.Name, E.Data)); } @@ -831,8 +832,8 @@ namespace SharedLibrary.Commands { new CommandArgument() { - Name = "player", - Required = true + Name = "player", + Required = true } }) { } diff --git a/SharedLibrary/Database.cs b/SharedLibrary/Database.cs index d3582d65..65265b63 100644 --- a/SharedLibrary/Database.cs +++ b/SharedLibrary/Database.cs @@ -564,7 +564,7 @@ namespace SharedLibrary { Dictionary newPlayer = new Dictionary { - { "Name", Utilities.StripIllegalCharacters(P.Name) }, + { "Name", P.Name }, { "npID", P.NetworkID }, { "Level", (int)P.Level }, { "LastOffense", "" }, @@ -596,12 +596,17 @@ namespace SharedLibrary } + public void PruneAdmins(int inactiveDays) + { + ExecuteNonQuery($"UPDATE CLIENTS SET Level={(int)Player.Permission.User} WHERE LastConnection < '{Utilities.DateTimeSQLite(DateTime.Now.AddDays(-inactiveDays))}'"); + } + //Add specified ban to database public void AddPenalty(Penalty B) { Dictionary newBan = new Dictionary { - { "Reason", Utilities.StripIllegalCharacters(B.Reason) }, + { "Reason", B.Reason }, { "npID", B.OffenderID }, { "bannedByID", B.PenaltyOriginID }, { "IP", B.IP }, @@ -712,7 +717,7 @@ namespace SharedLibrary Dictionary newPlayer = new Dictionary { { "Number", Alias.Number }, - { "NAMES", Utilities.StripIllegalCharacters(String.Join(";", Alias.Names)) }, + { "NAMES", String.Join(";", Alias.Names) }, { "IPS", String.Join(";", Alias.IPS) } }; Insert("ALIASES", newPlayer); diff --git a/SharedLibrary/Event.cs b/SharedLibrary/Event.cs index a071d1fe..b19dad0d 100644 --- a/SharedLibrary/Event.cs +++ b/SharedLibrary/Event.cs @@ -29,10 +29,10 @@ namespace SharedLibrary { Type = Ty; Version = V; - Message = M; + Message = System.Web.HttpUtility.HtmlEncode(M); Title = T; - Origin = O; - Target = Ta; + Origin = System.Web.HttpUtility.HtmlEncode(O); + Target = System.Web.HttpUtility.HtmlEncode(Ta); ID = Math.Abs(DateTime.Now.GetHashCode()); } @@ -124,7 +124,7 @@ namespace SharedLibrary { Regex rgx = new Regex("[^a-zA-Z0-9 -! -_]"); string message = rgx.Replace(line[4], ""); - return new Event(GType.Say, Utilities.StripIllegalCharacters(message).StripColors(), SV.ParseClientFromString(line, 2), null, SV) { Message = Utilities.StripIllegalCharacters(message).StripColors() }; + return new Event(GType.Say, message.StripColors(), SV.ParseClientFromString(line, 2), null, SV) { Message = message }; } if (removeTime.Contains("ScriptKill")) diff --git a/SharedLibrary/Penalty.cs b/SharedLibrary/Penalty.cs index 93e77e5d..e2b5627e 100644 --- a/SharedLibrary/Penalty.cs +++ b/SharedLibrary/Penalty.cs @@ -7,7 +7,7 @@ namespace SharedLibrary { public Penalty(Type BType, String Reas, String TargID, String From, DateTime time, String ip, DateTime exp) { - Reason = Reas.CleanChars().StripColors(); + Reason = Reas.StripColors(); OffenderID = TargID; PenaltyOriginID = From; When = time; diff --git a/SharedLibrary/Server.cs b/SharedLibrary/Server.cs index e74504e6..b83ddb44 100644 --- a/SharedLibrary/Server.cs +++ b/SharedLibrary/Server.cs @@ -91,12 +91,19 @@ namespace SharedLibrary /// /// Player name to search for /// Matching player if found - public Player GetClientByName(String pName) + public List GetClientByName(String pName) { string[] QuoteSplit = pName.Split('"'); + bool literal = false; if (QuoteSplit.Length > 1) + { pName = QuoteSplit[1]; - return Players.FirstOrDefault(p => p != null && p.Name.ToLower().Contains(pName.ToLower())); + literal = true; + } + if (literal) + return Players.Where(p => p != null && p.Name.ToLower().Equals(pName.ToLower())).ToList(); + + return Players.Where(p => p != null && p.Name.ToLower().Contains(pName.ToLower())).ToList(); } /// diff --git a/SharedLibrary/SharedLibrary.csproj b/SharedLibrary/SharedLibrary.csproj index 76563899..77a372a3 100644 --- a/SharedLibrary/SharedLibrary.csproj +++ b/SharedLibrary/SharedLibrary.csproj @@ -75,6 +75,7 @@ ..\packages\System.Data.SQLite.Core.1.0.105.1\lib\net45\System.Data.SQLite.dll True + diff --git a/SharedLibrary/Utilities.cs b/SharedLibrary/Utilities.cs index 95d0c1f2..7b801cf6 100644 --- a/SharedLibrary/Utilities.cs +++ b/SharedLibrary/Utilities.cs @@ -80,27 +80,6 @@ namespace SharedLibrary return Player.Permission.Banned; } - public static String StripIllegalCharacters(String str) - { - if (str != null) - return str.Replace("`", "").Replace("\\", "").Replace("\"", "").Replace(""", "").Replace("&", "&").Replace("\"", "''").Replace("'", "").Replace("?", ""); - - else - return String.Empty; - } - - public static String CleanChars(this string S) - { - if (S == null) - return ""; - - StringBuilder Cleaned = new StringBuilder(); - - foreach (char c in S) - if (c < 127 && c > 31 && c != 37 && c != 34 && c != 92) Cleaned.Append(c); - return Cleaned.ToString(); - } - /// /// Remove all IW Engine color codes /// @@ -314,5 +293,10 @@ namespace SharedLibrary return "1 hour"; } + + public static string EscapeMarkdown(this string markdownString) + { + return markdownString.Replace("<", "\\<").Replace(">", "\\>").Replace("|", "\\|"); + } } }