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
This commit is contained in:
parent
a56f386644
commit
cdeb7e8eaf
@ -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 "$(ProjectDir)webfront\*" "$(SolutionDir)BUILD\Webfront"
|
||||||
xcopy /Y /I /E "$(SolutionDir)Admin\Config\*" "$(SolutionDir)BUILD\Config"
|
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-Nightly powershell.exe -file "$(SolutionDir)DEPLOY\publish_nightly.ps1" 1.6
|
||||||
if $(ConfigurationName) == Release-Stable powershell.exe -file "$(SolutionDir)DEPLOY\publish_stable.ps1" 1.5
|
if $(ConfigurationName) == Release-Stable powershell.exe -file "$(SolutionDir)DEPLOY\publish_stable.ps1" 1.6
|
||||||
|
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -37,19 +37,19 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
class Request : IHttpRequestDelegate
|
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();
|
var logger = ApplicationManager.GetInstance().GetLogger();
|
||||||
logger.WriteInfo($"HTTP request {request.Path}");
|
logger.WriteDebug($"HTTP request {request.Path}");
|
||||||
logger.WriteInfo($"QueryString: {request.QueryString}");
|
logger.WriteDebug($"QueryString: {request.QueryString}");
|
||||||
logger.WriteInfo($"IP: {IP}");
|
logger.WriteDebug($"IP: {request.IPAddress}");
|
||||||
|
|
||||||
NameValueCollection querySet = new NameValueCollection();
|
NameValueCollection querySet = new NameValueCollection();
|
||||||
|
|
||||||
if (request.QueryString != null)
|
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
|
try
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,7 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
Version = 1.5;
|
Version = 1.6;
|
||||||
handler = new ConsoleEventDelegate(OnProcessExit);
|
handler = new ConsoleEventDelegate(OnProcessExit);
|
||||||
SetConsoleCtrlHandler(handler, true);
|
SetConsoleCtrlHandler(handler, true);
|
||||||
|
|
||||||
|
@ -257,11 +257,33 @@ namespace IW4MAdmin
|
|||||||
E.Target = Players[cNum];
|
E.Target = Players[cNum];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Player> matchingPlayers;
|
||||||
|
|
||||||
if (E.Target == null) // Find active player including quotes (multiple words)
|
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
|
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)
|
if (E.Target == null && C.RequiresTarget)
|
||||||
{
|
{
|
||||||
@ -600,7 +622,7 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
else // Not a command
|
else // Not a command
|
||||||
{
|
{
|
||||||
E.Data = E.Data.StripColors().CleanChars();
|
E.Data = E.Data.StripColors();
|
||||||
// this should not be done for all messages.
|
// this should not be done for all messages.
|
||||||
//if (E.Data.Length > 50)
|
//if (E.Data.Length > 50)
|
||||||
// E.Data = E.Data.Substring(0, 50) + "...";
|
// E.Data = E.Data.Substring(0, 50) + "...";
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -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:
|
CHANGELOG:
|
||||||
-added back player history graphs (past 12 hours every 15 minutes)
|
-added back player history graphs (past 12 hours every 15 minutes)
|
||||||
-fixed issue with configurationmanager files and threading
|
-fixed issue with configurationmanager files and threading
|
||||||
@ -8,7 +17,7 @@ CHANGELOG:
|
|||||||
-started working on more advanced statistics
|
-started working on more advanced statistics
|
||||||
-all chat is stored
|
-all chat is stored
|
||||||
-word cloud displays most commonly used words on the server
|
-word cloud displays most commonly used words on the server
|
||||||
-fixed misc issuess
|
-fixed misc issues
|
||||||
|
|
||||||
VERSION 1.4
|
VERSION 1.4
|
||||||
CHANGELOG:
|
CHANGELOG:
|
||||||
@ -27,7 +36,6 @@ CHANGELOG:
|
|||||||
-webfront playerlist level colors are hidden to non admin users
|
-webfront playerlist level colors are hidden to non admin users
|
||||||
-tempban length can now be specified (<int>m, <int>h, <int>d, <int>y)
|
-tempban length can now be specified (<int>m, <int>h, <int>d, <int>y)
|
||||||
|
|
||||||
|
|
||||||
VERSION 1.3
|
VERSION 1.3
|
||||||
CHANGELOG:
|
CHANGELOG:
|
||||||
-complete rewrite of lots of parts
|
-complete rewrite of lots of parts
|
||||||
|
@ -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 .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 .serverMap { text-align: center; width: calc( 100% / 3); background-color: #007ACC; }
|
||||||
div#content .serverPlayerList {float: right; margin: 0.5em; }
|
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 { 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 .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; }
|
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 #consoleWrap { width: 60%; margin: 0 auto; }
|
||||||
div#content #console { padding: 1em; height: 35vh; background-color: #181818; }
|
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 input[type="text"]:focus, select:focus { border-width: 0; outline: none; }
|
||||||
div#consoleWrap .playerSearchWrap { margin: 0 !important; width: 100%; }
|
div#consoleWrap .playerSearchWrap { margin: 0 !important; width: 100%; }
|
||||||
div#consoleWrap .searchButton { width: calc(20% - 10px); }
|
div#consoleWrap .searchButton { width: calc(20% - 10px); }
|
||||||
|
@ -16,7 +16,7 @@ namespace StatsPlugin
|
|||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
Name = "player",
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <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
|
||||||
@ -420,7 +453,7 @@ namespace StatsPlugin
|
|||||||
// calculate the players Score Per Minute for the current session
|
// calculate the players Score Per Minute for the current session
|
||||||
double SessionSPM = curServer.Kills[P.ClientID] * 100 / Math.Max(1, newPlayTime);
|
double SessionSPM = curServer.Kills[P.ClientID] * 100 / Math.Max(1, newPlayTime);
|
||||||
// calculate how much the KDR should way
|
// 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 KDRWeight = Math.Round(Math.Pow(DisconnectingPlayerStats.KDR, 1.637 / Math.E), 3);
|
||||||
double SPMWeightAgainstAverage;
|
double SPMWeightAgainstAverage;
|
||||||
|
|
||||||
@ -428,7 +461,6 @@ namespace StatsPlugin
|
|||||||
SPMWeightAgainstAverage = (DisconnectingPlayerStats.scorePerMinute == 1) ? 1 : SessionSPM / DisconnectingPlayerStats.scorePerMinute;
|
SPMWeightAgainstAverage = (DisconnectingPlayerStats.scorePerMinute == 1) ? 1 : SessionSPM / DisconnectingPlayerStats.scorePerMinute;
|
||||||
|
|
||||||
// calculate the weight of the new play time againmst lifetime playtime
|
// calculate the weight of the new play time againmst lifetime playtime
|
||||||
//
|
|
||||||
double SPMAgainstPlayWeight = newPlayTime / Math.Min(600, DisconnectingPlayerStats.TotalPlayTime + newPlayTime);
|
double SPMAgainstPlayWeight = newPlayTime / Math.Min(600, DisconnectingPlayerStats.TotalPlayTime + newPlayTime);
|
||||||
// calculate the new weight against average times the weight against play time
|
// calculate the new weight against average times the weight against play time
|
||||||
double newSkillFactor = SPMWeightAgainstAverage * SPMAgainstPlayWeight * SessionSPM;
|
double newSkillFactor = SPMWeightAgainstAverage * SPMAgainstPlayWeight * SessionSPM;
|
||||||
@ -436,7 +468,7 @@ namespace StatsPlugin
|
|||||||
// if the weight is greater than 1, add, else subtract
|
// if the weight is greater than 1, add, else subtract
|
||||||
DisconnectingPlayerStats.scorePerMinute += (SPMWeightAgainstAverage >= 1) ? newSkillFactor : -newSkillFactor;
|
DisconnectingPlayerStats.scorePerMinute += (SPMWeightAgainstAverage >= 1) ? newSkillFactor : -newSkillFactor;
|
||||||
|
|
||||||
DisconnectingPlayerStats.Skill = DisconnectingPlayerStats.scorePerMinute * KDRWeight / 10;
|
DisconnectingPlayerStats.Skill = DisconnectingPlayerStats.scorePerMinute * KDRWeight * 10;
|
||||||
DisconnectingPlayerStats.TotalPlayTime += newPlayTime;
|
DisconnectingPlayerStats.TotalPlayTime += newPlayTime;
|
||||||
|
|
||||||
curServer.playerStats.UpdateStats(P, DisconnectingPlayerStats);
|
curServer.playerStats.UpdateStats(P, DisconnectingPlayerStats);
|
||||||
|
@ -42,10 +42,11 @@ namespace IW4MAdmin.Plugins
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region PLUGIN_INFO
|
#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))
|
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).EscapeMarkdown()}|{command.Permission}|");
|
||||||
Console.WriteLine($"|{command.Name}|{command.Alias}|{command.Description}|{command.RequiresTarget}|{command.Syntax.Substring(8)}|{command.Permission}|");
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
@ -62,7 +63,7 @@ namespace IW4MAdmin.Plugins
|
|||||||
{
|
{
|
||||||
var rand = new Random();
|
var rand = new Random();
|
||||||
int index = rand.Next(0, 17);
|
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
|
Ping = 1
|
||||||
};
|
};
|
||||||
|
101
README.md
101
README.md
@ -37,49 +37,49 @@ _If you wish to customize your experience of IW4MAdmin, the following configurat
|
|||||||
|
|
||||||
___
|
___
|
||||||
### Commands
|
### Commands
|
||||||
|Name |Alias|Description |Requires Target|Arguments |Required Level|
|
|Name |Alias|Description |Requires Target|Syntax |Required Level|
|
||||||
|--------------|-----|--------------------------------------------------------|---------------|---------------|--------------|
|
|--------------| -----| --------------------------------------------------------| -----------------| -------------| ----------------|
|
||||||
|disabletrusted|dt|disable trusted player group for the server|False|0|Owner|
|
|disabletrusted|dt|disable trusted player group for the server|False|!dt |Owner|
|
||||||
|enabletrusted|et|enable trusted player group for the server|False|0|Owner|
|
|enabletrusted|et|enable trusted player group for the server|False|!et |Owner|
|
||||||
|quit|q|quit IW4MAdmin|False|0|Owner|
|
|prune|p|demote any admins that have not connected recently (defaults to 30 days)|False|!p \<optional inactive days\>|Owner|
|
||||||
|rcon|rcon|send rcon command to server|False|1|Owner|
|
|quit|q|quit IW4MAdmin|False|!q |Owner|
|
||||||
|setlevel|sl|set player to specified administration level|True|2|Owner|
|
|rcon|rcon|send rcon command to server|False|!rcon \<command\>|Owner|
|
||||||
|ban|b|permanently ban a player from the server|True|2|SeniorAdmin|
|
|reload|rl|reload configuration files|False|!rl |Owner|
|
||||||
|find|f|find player in database|False|1|SeniorAdmin|
|
|setlevel|sl|set player to specified administration level|True|!sl \<player\> \<level\>|Owner|
|
||||||
|fredisable|frd|disable fast restarting at the end of a map|False|0|SeniorAdmin|
|
|ban|b|permanently ban a player from the server|True|!b \<player\> \<reason\>|SeniorAdmin|
|
||||||
|frenable|fre|enable fast restarting at the end of a map|False|0|SeniorAdmin|
|
|fredisable|frd|disable fast restarting at the end of a map|False|!frd |SeniorAdmin|
|
||||||
|unban|ub|unban player by database id|True|1|SeniorAdmin|
|
|frenable|fre|enable fast restarting at the end of a map|False|!fre |SeniorAdmin|
|
||||||
|map|m|change to specified map|False|1|Administrator|
|
|unban|ub|unban player by database id|True|!ub \<databaseID\>|SeniorAdmin|
|
||||||
|maprotate|mr|cycle to the next map in rotation|False|0|Administrator|
|
|find|f|find player in database|False|!f \<player\>|Administrator|
|
||||||
|mask|hide|hide your online presence from online admin list|False|0|Administrator|
|
|findall|fa|find a player by their aliase(s)|False|!fa \<player\>|Administrator|
|
||||||
|plugins|p|view all loaded plugins|False|0|Administrator|
|
|map|m|change to specified map|False|!m \<map\>|Administrator|
|
||||||
|alias|known|get past aliases and ips of a player|True|1|Moderator|
|
|maprotate|mr|cycle to the next map in rotation|False|!mr |Administrator|
|
||||||
|baninfo|bi|get information about a ban for a player|True|1|Moderator|
|
|plugins|p|view all loaded plugins|False|!p |Administrator|
|
||||||
|fastrestart|fr|fast restart current map|False|0|Moderator|
|
|alias|known|get past aliases and ips of a player|True|!known \<player\>|Moderator|
|
||||||
|findall|fa|find a player by their aliase(s)|False|1|Moderator|
|
|baninfo|bi|get information about a ban for a player|True|!bi \<player\>|Moderator|
|
||||||
|flag|fp|flag a suspicious player and announce to admins on join|True|2|Moderator|
|
|fastrestart|fr|fast restart current map|False|!fr |Moderator|
|
||||||
|list|l|list active clients|False|0|Moderator|
|
|flag|fp|flag a suspicious player and announce to admins on join|True|!fp \<player\> \<reason\>|Moderator|
|
||||||
|reports|reps|get most recent reports|False|0|Moderator|
|
|list|l|list active clients|False|!l |Moderator|
|
||||||
|say|s|broadcast message to all players|False|1|Moderator|
|
|reports|reps|get or clear recent reports|False|!reps \<optional clear\>|Moderator|
|
||||||
|tempban|tb|temporarily ban a player for for specified time (defaults to 1 hour)|True|2|Moderator|
|
|say|s|broadcast message to all players|False|!s \<message\>|Moderator|
|
||||||
|uptime|up|get current application running time|False|0|Moderator|
|
|tempban|tb|temporarily ban a player for specified time (defaults to 1 hour)|True|!tb \<player\> \<duration (m\|h\|d\|w\|y)\> \<reason\>|Moderator|
|
||||||
|usage|us|get current application memory usage|False|0|Moderator|
|
|uptime|up|get current application running time|False|!up |Moderator|
|
||||||
|kick|k|kick a player by name|True|2|Trusted|
|
|usage|us|get current application memory usage|False|!us |Moderator|
|
||||||
|warn|w|warn player for infringing rules|True|2|Trusted|
|
|kick|k|kick a player by name|True|!k \<player\> \<reason\>|Trusted|
|
||||||
|warnclear|wc|remove all warning for a player|True|1|Trusted|
|
|warn|w|warn player for infringing rules|True|!w \<player\> \<reason\>|Trusted|
|
||||||
|admins|a|list currently connected admins|False|0|User|
|
|warnclear|wc|remove all warning for a player|True|!wc \<player\>|Trusted|
|
||||||
|getexternalip|ip|view your external IP address|False|0|User|
|
|admins|a|list currently connected admins|False|!a |User|
|
||||||
|help|h|list all available commands|False|0|User|
|
|getexternalip|ip|view your external IP address|False|!ip |User|
|
||||||
|owner|o|claim ownership of the server|False|0|User|
|
|help|h|list all available commands|False|!h \<optional command\>|User|
|
||||||
|privatemessage|pm|send message to other player|True|2|User|
|
|privatemessage|pm|send message to other player|True|!pm \<player\> \<message\>|User|
|
||||||
|report|rep|report a player for suspicious behaivor|True|2|User|
|
|report|rep|report a player for suspicious behavior|True|!rep \<player\> \<reason\>|User|
|
||||||
|resetstats|rs|reset your stats to factory-new|False|0|User|
|
|resetstats|rs|reset your stats to factory-new|False|!rs |User|
|
||||||
|rules|r|list server rules|False|0|User|
|
|rules|r|list server rules|False|!r |User|
|
||||||
|stats|xlrstats|view your stats|False|0|User|
|
|stats|xlrstats|view your stats|False|!xlrstats \<optional player\>|User|
|
||||||
|topstats|ts|view the top 5 players on this server|False|0|User|
|
|topstats|ts|view the top 5 players on this server|False|!ts |User|
|
||||||
|vote|v|vote for the next map|False|1|User|
|
|vote|v|vote for the next map|False|!v \<map\>|User|
|
||||||
|votecancel|vc|cancel your vote for the next map|False|0|User|
|
|votecancel|vc|cancel your vote for the next map|False|!vc |User|
|
||||||
|whoami|who|give information about yourself|False|0|User|
|
|whoami|who|give information about yourself.|False|!who |User|
|
||||||
|
|
||||||
#### Player Identification
|
#### Player Identification
|
||||||
All players are identified 4 seperate ways
|
All players are identified 4 seperate ways
|
||||||
@ -159,13 +159,14 @@ ___
|
|||||||
**Commands added by this plugin**
|
**Commands added by this plugin**
|
||||||
|
|
||||||
|
|
||||||
|Name |Alias|Description |Requires Target|Arguments |Required Level|
|
|Name |Alias|Description |Requires Target|Syntax |Required Level|
|
||||||
|--------------|-----|--------------------------------------------------------|---------------|---------------|--------------|
|
|--------------| -----| --------------------------------------------------------| -----------------| -------------| ----------------|
|
||||||
|disabletrusted|dt|disable trusted player group for the server|False|0|Owner|
|
|disabletrusted|dt|disable trusted player group for the server|False|!dt |Owner|
|
||||||
|enabletrusted|et|enable trusted player group for the server|False|0|Owner|
|
|enabletrusted|et|enable trusted player group for the server|False|!et |Owner|
|
||||||
|resetstats|rs|reset your stats to factory-new|False|0|User|
|
|prune|p|demote any admins that have not connected recently (defaults to 30 days)|False|!p \<optional inactive days\>|Owner|
|
||||||
|stats|xlrstats|view your stats|False|0|User|
|
|resetstats|rs|reset your stats to factory-new|False|!rs |User|
|
||||||
|topstats|ts|view the top 5 players on this server|False|0|User|
|
|stats|xlrstats|view your stats|False|!xlrstats \<optional player\>|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
|
- To qualify for top stats, a player must meet the following criteria
|
||||||
* `Skill` > 10
|
* `Skill` > 10
|
||||||
|
@ -151,7 +151,7 @@ namespace SharedLibrary.Commands
|
|||||||
},
|
},
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
Name = "duration (m|d|w|y|)",
|
Name = "duration (m|h|d|w|y)",
|
||||||
Required = true,
|
Required = true,
|
||||||
},
|
},
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
@ -193,8 +193,8 @@ namespace SharedLibrary.Commands
|
|||||||
},
|
},
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
Name = "reason",
|
Name = "reason",
|
||||||
Required = true
|
Required = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
{ }
|
{ }
|
||||||
@ -247,7 +247,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.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);
|
await E.Origin.Tell(You);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -663,8 +663,9 @@ namespace SharedLibrary.Commands
|
|||||||
|
|
||||||
public class CReload : Command
|
public class CReload : Command
|
||||||
{
|
{
|
||||||
public CReload() :
|
public CReload() :
|
||||||
base("reload", "reload configuration files", "rl", Player.Permission.Owner, false) { }
|
base("reload", "reload configuration files", "rl", Player.Permission.Owner, false)
|
||||||
|
{ }
|
||||||
|
|
||||||
public override async Task ExecuteAsync(Event E)
|
public override async Task ExecuteAsync(Event E)
|
||||||
{
|
{
|
||||||
@ -755,14 +756,14 @@ namespace SharedLibrary.Commands
|
|||||||
|
|
||||||
if (E.Target.Level > E.Origin.Level)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
E.Data = E.Data.RemoveWords(1);
|
E.Data = E.Data.RemoveWords(1);
|
||||||
E.Owner.Reports.Add(new Report(E.Target, E.Origin, E.Data));
|
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.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));
|
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()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
Name = "player",
|
Name = "player",
|
||||||
Required = true
|
Required = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
{ }
|
{ }
|
||||||
|
@ -564,7 +564,7 @@ namespace SharedLibrary
|
|||||||
{
|
{
|
||||||
Dictionary<String, object> newPlayer = new Dictionary<String, object>
|
Dictionary<String, object> newPlayer = new Dictionary<String, object>
|
||||||
{
|
{
|
||||||
{ "Name", Utilities.StripIllegalCharacters(P.Name) },
|
{ "Name", P.Name },
|
||||||
{ "npID", P.NetworkID },
|
{ "npID", P.NetworkID },
|
||||||
{ "Level", (int)P.Level },
|
{ "Level", (int)P.Level },
|
||||||
{ "LastOffense", "" },
|
{ "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
|
//Add specified ban to database
|
||||||
public void AddPenalty(Penalty B)
|
public void AddPenalty(Penalty B)
|
||||||
{
|
{
|
||||||
Dictionary<String, object> newBan = new Dictionary<String, object>
|
Dictionary<String, object> newBan = new Dictionary<String, object>
|
||||||
{
|
{
|
||||||
{ "Reason", Utilities.StripIllegalCharacters(B.Reason) },
|
{ "Reason", B.Reason },
|
||||||
{ "npID", B.OffenderID },
|
{ "npID", B.OffenderID },
|
||||||
{ "bannedByID", B.PenaltyOriginID },
|
{ "bannedByID", B.PenaltyOriginID },
|
||||||
{ "IP", B.IP },
|
{ "IP", B.IP },
|
||||||
@ -712,7 +717,7 @@ namespace SharedLibrary
|
|||||||
Dictionary<String, object> newPlayer = new Dictionary<String, object>
|
Dictionary<String, object> newPlayer = new Dictionary<String, object>
|
||||||
{
|
{
|
||||||
{ "Number", Alias.Number },
|
{ "Number", Alias.Number },
|
||||||
{ "NAMES", Utilities.StripIllegalCharacters(String.Join(";", Alias.Names)) },
|
{ "NAMES", String.Join(";", Alias.Names) },
|
||||||
{ "IPS", String.Join(";", Alias.IPS) }
|
{ "IPS", String.Join(";", Alias.IPS) }
|
||||||
};
|
};
|
||||||
Insert("ALIASES", newPlayer);
|
Insert("ALIASES", newPlayer);
|
||||||
|
@ -29,10 +29,10 @@ namespace SharedLibrary
|
|||||||
{
|
{
|
||||||
Type = Ty;
|
Type = Ty;
|
||||||
Version = V;
|
Version = V;
|
||||||
Message = M;
|
Message = System.Web.HttpUtility.HtmlEncode(M);
|
||||||
Title = T;
|
Title = T;
|
||||||
Origin = O;
|
Origin = System.Web.HttpUtility.HtmlEncode(O);
|
||||||
Target = Ta;
|
Target = System.Web.HttpUtility.HtmlEncode(Ta);
|
||||||
|
|
||||||
ID = Math.Abs(DateTime.Now.GetHashCode());
|
ID = Math.Abs(DateTime.Now.GetHashCode());
|
||||||
}
|
}
|
||||||
@ -124,7 +124,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.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"))
|
if (removeTime.Contains("ScriptKill"))
|
||||||
|
@ -7,7 +7,7 @@ namespace SharedLibrary
|
|||||||
{
|
{
|
||||||
public Penalty(Type BType, String Reas, String TargID, String From, DateTime time, String ip, DateTime exp)
|
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;
|
OffenderID = TargID;
|
||||||
PenaltyOriginID = From;
|
PenaltyOriginID = From;
|
||||||
When = time;
|
When = time;
|
||||||
|
@ -91,12 +91,19 @@ namespace SharedLibrary
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pName">Player name to search for</param>
|
/// <param name="pName">Player name to search for</param>
|
||||||
/// <returns>Matching player if found</returns>
|
/// <returns>Matching player if found</returns>
|
||||||
public Player GetClientByName(String pName)
|
public List<Player> GetClientByName(String pName)
|
||||||
{
|
{
|
||||||
string[] QuoteSplit = pName.Split('"');
|
string[] QuoteSplit = pName.Split('"');
|
||||||
|
bool literal = false;
|
||||||
if (QuoteSplit.Length > 1)
|
if (QuoteSplit.Length > 1)
|
||||||
|
{
|
||||||
pName = QuoteSplit[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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -75,6 +75,7 @@
|
|||||||
<HintPath>..\packages\System.Data.SQLite.Core.1.0.105.1\lib\net45\System.Data.SQLite.dll</HintPath>
|
<HintPath>..\packages\System.Data.SQLite.Core.1.0.105.1\lib\net45\System.Data.SQLite.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="System.Web" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
@ -80,27 +80,6 @@ namespace SharedLibrary
|
|||||||
return Player.Permission.Banned;
|
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remove all IW Engine color codes
|
/// Remove all IW Engine color codes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -314,5 +293,10 @@ namespace SharedLibrary
|
|||||||
|
|
||||||
return "1 hour";
|
return "1 hour";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string EscapeMarkdown(this string markdownString)
|
||||||
|
{
|
||||||
|
return markdownString.Replace("<", "\\<").Replace(">", "\\>").Replace("|", "\\|");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user