Add temp banning, remove /ban clear, fix temp ban check

This commit is contained in:
MarioE 2013-11-10 23:03:12 -05:00
parent 6a4e7584a0
commit ebc36a5ada
4 changed files with 258 additions and 282 deletions

View file

@ -598,26 +598,27 @@ namespace TShockAPI
{ {
char c = str[i]; char c = str[i];
if (instr) if (c == '\\' && ++i < str.Length)
{ {
if (c == '\\') if (str[i] != '"' && str[i] != ' ' && str[i] != '\\')
{ sb.Append('\\');
if (i + 1 >= str.Length) sb.Append(str[i]);
break;
c = GetEscape(str[++i]);
} }
else if (c == '"') else if (c == '"')
{
instr = !instr;
if (!instr)
{ {
ret.Add(sb.ToString()); ret.Add(sb.ToString());
sb.Clear(); sb.Clear();
instr = false;
continue;
} }
sb.Append(c); else if (sb.Length > 0)
}
else
{ {
if (IsWhiteSpace(c)) ret.Add(sb.ToString());
sb.Clear();
}
}
else if (IsWhiteSpace(c))
{ {
if (sb.Length > 0) if (sb.Length > 0)
{ {
@ -625,21 +626,9 @@ namespace TShockAPI
sb.Clear(); sb.Clear();
} }
} }
else if (c == '"')
{
if (sb.Length > 0)
{
ret.Add(sb.ToString());
sb.Clear();
}
instr = true;
}
else else
{
sb.Append(c); sb.Append(c);
} }
}
}
if (sb.Length > 0) if (sb.Length > 0)
ret.Add(sb.ToString()); ret.Add(sb.ToString());
@ -1091,259 +1080,199 @@ namespace TShockAPI
args.Player.SendInfoMessage("In addition, a reason may be provided for all new bans after the arguments."); args.Player.SendInfoMessage("In addition, a reason may be provided for all new bans after the arguments.");
return; return;
} }
if (args.Parameters[0].ToLower() == "list")
{
#region List bans
if (TShock.Bans.GetBans().Count == 0)
{
args.Player.SendErrorMessage("There are currently no players banned.");
return;
}
string banString = ""; string subcmd = args.Parameters[0].ToLower();
foreach (Ban b in TShock.Bans.GetBans()) switch (subcmd)
{ {
case "add":
if (b.Name.Trim() == "")
{
continue;
}
if (banString.Length == 0)
{
banString = b.Name;
}
else
{
int length = banString.Length;
while (length > 60)
{
length = length - 60;
}
if (length + b.Name.Length >= 60)
{
banString += "|, " + b.Name;
}
else
{
banString += ", " + b.Name;
}
}
}
String[] banStrings = banString.Split('|');
if (banStrings.Length == 0)
{
args.Player.SendErrorMessage("There are currently no players with valid names banned.");
return;
}
if (banStrings[0].Trim() == "")
{
args.Player.SendErrorMessage("There are currently no bans with valid names found.");
return;
}
args.Player.SendInfoMessage("List of banned players:");
foreach (string s in banStrings)
{
args.Player.SendInfoMessage(s);
}
return;
#endregion List bans
}
if (args.Parameters[0].ToLower() == "listip")
{
#region List ip bans
if (TShock.Bans.GetBans().Count == 0)
{
args.Player.SendWarningMessage("There are currently no players banned.");
return;
}
string banString = "";
foreach (Ban b in TShock.Bans.GetBans())
{
if (b.IP.Trim() == "")
{
continue;
}
if (banString.Length == 0)
{
banString = b.IP;
}
else
{
int length = banString.Length;
while (length > 60)
{
length = length - 60;
}
if (length + b.Name.Length >= 60)
{
banString += "|, " + b.IP;
}
else
{
banString += ", " + b.IP;
}
}
}
String[] banStrings = banString.Split('|');
if (banStrings.Length == 0)
{
args.Player.SendErrorMessage("There are currently no players with valid IPs banned.");
return;
}
if (banStrings[0].Trim() == "")
{
args.Player.SendErrorMessage("There are currently no bans with valid IPs found.");
return;
}
args.Player.SendInfoMessage("List of IP banned players:");
foreach (string s in banStrings)
{
args.Player.SendInfoMessage(s);
}
return;
#endregion List ip bans
}
if (args.Parameters.Count >= 2)
{
if (args.Parameters[0].ToLower() == "add")
{ {
#region Add ban #region Add ban
string plStr = args.Parameters[1]; if (args.Parameters.Count < 2)
var players = TShock.Utils.FindPlayer(plStr); {
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /ban add <player> [reason]");
return;
}
List<TSPlayer> players = TShock.Utils.FindPlayer(args.Parameters[1]);
if (players.Count == 0) if (players.Count == 0)
{
args.Player.SendErrorMessage("Invalid player!"); args.Player.SendErrorMessage("Invalid player!");
}
else if (players.Count > 1) else if (players.Count > 1)
{
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
}
else else
{ {
string reason = args.Parameters.Count > 2 string reason = args.Parameters.Count > 2
? String.Join(" ", args.Parameters.GetRange(2, args.Parameters.Count - 2)) ? String.Join(" ", args.Parameters.GetRange(2, args.Parameters.Count - 2))
: "Misbehavior."; : "Misbehavior.";
if (!TShock.Utils.Ban(players[0], reason, !args.Player.RealPlayer, args.Player.UserAccountName)) if (!TShock.Utils.Ban(players[0], reason, !args.Player.RealPlayer, args.Player.UserAccountName))
{ args.Player.SendErrorMessage("You can't ban {0}!", players[0].Name);
args.Player.SendErrorMessage("You can't ban another admin!");
} }
#endregion
} }
return; return;
#endregion Add ban case "addip":
}
else if (args.Parameters[0].ToLower() == "addip")
{ {
#region Add ip ban #region Add IP ban
if (args.Parameters.Count < 2)
{
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /ban addip <ip> [reason]");
return;
}
string ip = args.Parameters[1]; string ip = args.Parameters[1];
string reason = args.Parameters.Count > 2 string reason = args.Parameters.Count > 2
? String.Join(" ", args.Parameters.GetRange(2, args.Parameters.Count - 2)) ? String.Join(" ", args.Parameters.GetRange(2, args.Parameters.Count - 2))
: "Manually added IP address ban."; : "Manually added IP address ban.";
TShock.Bans.AddBan(ip, "", "", reason, false, args.Player.UserAccountName); TShock.Bans.AddBan(ip, "", "", reason, false, args.Player.UserAccountName);
args.Player.SendSuccessMessage(ip + " banned."); args.Player.SendSuccessMessage("Banned IP {0}.", ip);
return; #endregion
#endregion Add ip ban
}
else if (args.Parameters[0].ToLower() == "delip")
{
#region Delete ip ban
var ip = args.Parameters[1];
var ban = TShock.Bans.GetBanByIp(ip);
if (ban != null)
{
if (TShock.Bans.RemoveBan(ban.IP))
args.Player.SendSuccessMessage(string.Format("Unbanned {0} ({1})!", ban.Name, ban.IP));
else
args.Player.SendErrorMessage(string.Format("Failed to unban {0} ({1})!", ban.Name, ban.IP));
}
else
{
args.Player.SendErrorMessage(string.Format("No bans for ip {0} exist", ip));
} }
return; return;
#endregion Delete ip ban case "addtemp":
{
#region Add temp ban
if (args.Parameters.Count < 3)
{
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /ban addtemp <player> <time> [reason]");
return;
} }
else if (args.Parameters[0].ToLower() == "del")
List<TSPlayer> players = TShock.Utils.FindPlayer(args.Parameters[1]);
if (players.Count == 0)
args.Player.SendErrorMessage("Invalid player!");
else if (players.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
else
{
int time;
if (!TShock.Utils.TryParseTime(args.Parameters[2], out time))
{
args.Player.SendErrorMessage("Invalid time string! Proper format: 0d0h0m0s, with at least one time specifier.");
return;
}
string reason = args.Parameters.Count > 3
? String.Join(" ", args.Parameters.GetRange(3, args.Parameters.Count - 3))
: "Misbehavior.";
if (args.Player.RealPlayer && players[0].Group.HasPermission(Permissions.immunetoban))
{
args.Player.SendErrorMessage("You can't ban {0}!", players[0].Name);
return;
}
if (TShock.Bans.AddBan(players[0].IP, players[0].Name, players[0].UUID, reason,
false, args.Player.Name, DateTime.UtcNow.AddSeconds(time).ToString("s")))
{
players[0].Disconnect(String.Format("Banned: {0}", reason));
Log.ConsoleInfo("Banned {0} for : '{1}'", players[0].Name, reason);
string verb = args.Player.RealPlayer ? "force " : "";
if (args.Player.RealPlayer)
TSPlayer.All.SendSuccessMessage("{0} {1}banned {2} for '{3}'", args.Player.Name, verb, players[0].Name, reason);
else
TSPlayer.All.SendSuccessMessage("{0} was {1}banned for '{2}'", players[0].Name, verb, reason);
}
else
args.Player.SendErrorMessage("Failed to ban {0}, check logs.", players[0].Name);
}
#endregion
}
return;
case "del":
{ {
#region Delete ban #region Delete ban
string plStr = args.Parameters[1]; string plStr = args.Parameters[1];
var ban = TShock.Bans.GetBanByName(plStr, false); Ban ban = TShock.Bans.GetBanByName(plStr, false);
if (ban != null) if (ban != null)
{ {
if (TShock.Bans.RemoveBan(ban.Name, true)) if (TShock.Bans.RemoveBan(ban.Name, true))
args.Player.SendSuccessMessage(string.Format("Unbanned {0} ({1})!", ban.Name, ban.IP)); args.Player.SendSuccessMessage("Unbanned {0} ({1}).", ban.Name, ban.IP);
else else
args.Player.SendErrorMessage(string.Format("Failed to unban {0} ({1})!", ban.Name, ban.IP)); args.Player.SendErrorMessage("Failed to unban {0} ({1}), check logs.", ban.Name, ban.IP);
} }
else else
{ args.Player.SendErrorMessage("No bans for {0} exist.", plStr);
args.Player.SendErrorMessage(string.Format("No bans for player {0} exist", plStr)); #endregion
} }
return; return;
#endregion Delete ban case "delip":
}
#region Clear bans
if (args.Parameters[0].ToLower() == "clear")
{ {
if (args.Parameters.Count < 1 && ClearBansCode == -1) #region Delete IP ban
if (args.Parameters.Count != 2)
{ {
ClearBansCode = new Random().Next(0, short.MaxValue); args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /ban delip <ip>");
args.Player.SendInfoMessage("ClearBans Code: " + ClearBansCode);
return;
}
if (args.Parameters.Count < 1)
{
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /ban clear <code>");
return; return;
} }
int num; string ip = args.Parameters[1];
if (!int.TryParse(args.Parameters[1], out num)) Ban ban = TShock.Bans.GetBanByIp(ip);
if (ban != null)
{
if (TShock.Bans.RemoveBan(ban.IP, false))
args.Player.SendSuccessMessage("Unbanned IP {0} ({1}).", ban.IP, ban.Name);
else
args.Player.SendErrorMessage("Failed to unban IP {0} ({1}), check logs.", ban.IP, ban.Name);
}
else
args.Player.SendErrorMessage("IP {0} is not banned.", ip);
#endregion
}
return;
case "list":
{
#region List bans
int pageNumber;
if (!PaginationTools.TryParsePageNumber(args.Parameters, 1, args.Player, out pageNumber))
{ {
args.Player.SendErrorMessage("Invalid syntax! Expected a number, didn't get one.");
return; return;
} }
if (num == ClearBansCode) List<Ban> bans = TShock.Bans.GetBans();
var nameBans = from ban in bans
where !String.IsNullOrEmpty(ban.Name)
select ban.Name;
PaginationTools.SendPage(args.Player, pageNumber, PaginationTools.BuildLinesFromTerms(nameBans),
new PaginationTools.Settings
{ {
ClearBansCode = -1; HeaderFormat = "Bans ({0}/{1}):",
if (TShock.Bans.ClearBans()) FooterFormat = "Type /ban list {0} for more.",
{ NothingToDisplayString = "There are currently no bans."
Log.ConsoleInfo("Bans cleared."); });
args.Player.SendSuccessMessage("Bans cleared."); #endregion
}
else
{
args.Player.SendErrorMessage("Failed to clear bans.");
}
}
else
{
args.Player.SendErrorMessage("Incorrect clear code.");
}
} }
return; return;
#endregion Clear bans case "listip":
} {
args.Player.SendErrorMessage("Invalid syntax or old command provided."); #region List IP bans
args.Player.SendErrorMessage("Type /ban help for more information."); int pageNumber;
if (!PaginationTools.TryParsePageNumber(args.Parameters, 1, args.Player, out pageNumber))
{
return;
} }
private static int ClearBansCode = -1; List<Ban> bans = TShock.Bans.GetBans();
var ipBans = from ban in bans
where String.IsNullOrEmpty(ban.Name)
select ban.IP;
PaginationTools.SendPage(args.Player, pageNumber, PaginationTools.BuildLinesFromTerms(ipBans),
new PaginationTools.Settings
{
HeaderFormat = "IP Bans ({0}/{1}):",
FooterFormat = "Type /ban listip {0} for more.",
NothingToDisplayString = "There are currently no IP bans."
});
#endregion
}
return;
default:
args.Player.SendErrorMessage("Invalid subcommand! Type /ban help for more information.");
return;
}
}
private static void Whitelist(CommandArgs args) private static void Whitelist(CommandArgs args)
{ {

View file

@ -55,6 +55,11 @@ namespace TShockAPI.DB
} }
} }
/// <summary>
/// Gets a ban by IP.
/// </summary>
/// <param name="ip">The IP.</param>
/// <returns>The ban.</returns>
public Ban GetBanByIp(string ip) public Ban GetBanByIp(string ip)
{ {
try try
@ -72,6 +77,9 @@ namespace TShockAPI.DB
return null; return null;
} }
/// <summary>
/// Gets a list of bans.
/// </summary>
public List<Ban> GetBans() public List<Ban> GetBans()
{ {
List<Ban> banlist = new List<Ban>(); List<Ban> banlist = new List<Ban>();
@ -94,6 +102,12 @@ namespace TShockAPI.DB
return null; return null;
} }
/// <summary>
/// Gets a ban by name.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="casesensitive">Whether to check with case sensitivity.</param>
/// <returns>The ban.</returns>
public Ban GetBanByName(string name, bool casesensitive = true) public Ban GetBanByName(string name, bool casesensitive = true)
{ {
try try
@ -114,6 +128,11 @@ namespace TShockAPI.DB
return null; return null;
} }
/// <summary>
/// Gets a ban by UUID.
/// </summary>
/// <param name="uuid">The UUID.</param>
/// <returns>The ban.</returns>
public Ban GetBanByUUID(string uuid) public Ban GetBanByUUID(string uuid)
{ {
try try

View file

@ -887,23 +887,6 @@ namespace TShockAPI
return; return;
} }
var ipban = Bans.GetBanByIp(player.IP);
Ban ban = null;
if (ipban != null && Config.EnableIPBans)
ban = ipban;
if (ban != null)
{
if (!Utils.HasBanExpired(ban))
{
DateTime exp;
string duration = DateTime.TryParse(ban.Expiration, out exp) ? String.Format("until {0}", exp.ToString("G")) : "forever";
Utils.ForceKick(player, string.Format("You are banned {0}: {1}", duration, ban.Reason), true, false);
args.Handled = true;
return;
}
}
if (!FileTools.OnWhitelist(player.IP)) if (!FileTools.OnWhitelist(player.IP))
{ {
Utils.ForceKick(player, Config.WhitelistKickReason, true, false); Utils.ForceKick(player, Config.WhitelistKickReason, true, false);
@ -939,7 +922,9 @@ namespace TShockAPI
if (Config.KickEmptyUUID && String.IsNullOrWhiteSpace(player.UUID)) if (Config.KickEmptyUUID && String.IsNullOrWhiteSpace(player.UUID))
{ {
Utils.ForceKick(player, "Your client did not send a UUID, this server is not configured to accept such a client"); Utils.ForceKick(player, "Your client did not send a UUID, this server is not configured to accept such a client.", true);
args.Handled = true;
return;
} }
Ban ban = null; Ban ban = null;
@ -974,7 +959,6 @@ namespace TShockAPI
private void OnLeave(LeaveEventArgs args) private void OnLeave(LeaveEventArgs args)
{ {
var tsplr = Players[args.Who]; var tsplr = Players[args.Who];
Players[args.Who] = null; Players[args.Who] = null;

View file

@ -698,7 +698,7 @@ namespace TShockAPI
bool expirationExists = DateTime.TryParse(ban.Expiration, out exp); bool expirationExists = DateTime.TryParse(ban.Expiration, out exp);
if (!string.IsNullOrWhiteSpace(ban.Expiration) && (expirationExists) && if (!string.IsNullOrWhiteSpace(ban.Expiration) && (expirationExists) &&
(DateTime.Now >= exp)) (DateTime.UtcNow >= exp))
{ {
if (byName) if (byName)
{ {
@ -880,6 +880,50 @@ namespace TShockAPI
return true; return true;
} }
/// <summary>
/// Attempts to parse a string as a timespan (_d_m_h_s).
/// </summary>
/// <param name="time">The time string.</param>
/// <param name="seconds">The seconds.</param>
/// <returns>Whether the string was parsed successfully.</returns>
public bool TryParseTime(string str, out int seconds)
{
seconds = 0;
var sb = new StringBuilder(3);
for (int i = 0; i < str.Length; i++)
{
if (char.IsDigit(str[i]) || (str[i] == '-' || str[i] == '+'))
sb.Append(str[i]);
else
{
int num;
if (!int.TryParse(sb.ToString(), out num))
return false;
sb.Clear();
switch (str[i])
{
case 's':
seconds += num;
break;
case 'm':
seconds += num * 60;
break;
case 'h':
seconds += num * 60 * 60;
break;
case 'd':
seconds += num * 60 * 60 * 24;
break;
default:
return false;
}
}
}
return true;
}
/// <summary> /// <summary>
/// Searches for a projectile by identity and owner /// Searches for a projectile by identity and owner
/// </summary> /// </summary>