diff --git a/CHANGELOG.md b/CHANGELOG.md index 11c6aad5..14bce826 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,9 +14,13 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Added a warning notifying users of the minimum memory required to run TShock (@bartico6) * Added /group rename to allow changing group names (@ColinBohn, @ProfessorXZ) * Added /region rename and OnRegionRenamed hook (@koneko-nyan, @deadsurgeon42) +* Rebuilt /ban add. New syntax is /ban add [time] [reason] where target is the target online player, offline player, or IP; where time is the time format or 0 for permanent; and where [reason] is the reason. (@hakusaro) +* Removed /ban addip and /ban addtemp. Now covered under /ban add. (@hakusaro) * Added /su, which temporarily elevates players with the tshock.su permission to super admin. In addition added, a new group, owner, that is suggested for new users to setup TShock with as opposed to superadmin. Finally, /su is implemented such that a 10 minute timeout will occur preventing people from just camping with it on. (@hakusaro) * Added /sudo, which runs a command as the superadmin group. If a user fails to execute a command but can sudo, they'll be told that they can override the permission check with sudo. Much better than just telling them to run /su and then re-run the command. (@hakusaro) - +* Fixed /savessc not bothering to save ssc data for people who bypass ssc. (@hakusaro) +* Default permission sets for new databases are more modern. (@hakusaro) +* Added the ability to ban by account name instead of just banning a character name assuming its an account name. (@hakusaro) ## TShock 4.3.24 * Updated OpenTerraria API to 1.3.5.3 (@DeathCradle) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 7e180f3c..72cddc6a 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -35,6 +35,7 @@ using Terraria.GameContent.Events; using Microsoft.Xna.Framework; using OTAPI.Tile; using TShockAPI.Localization; +using System.Text.RegularExpressions; namespace TShockAPI { @@ -1285,200 +1286,197 @@ namespace TShockAPI switch (subcmd) { case "add": - #region Add ban + #region Add Ban { if (args.Parameters.Count < 2) { - args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}ban add [reason]", Specifier); + args.Player.SendErrorMessage("Invalid command. Format: {0}ban add [time] [reason]", Specifier); + args.Player.SendErrorMessage("Example: {0}ban add Shank 10d Hacking and cheating", Specifier); + args.Player.SendErrorMessage("Example: {0}ban add Ash", Specifier); + args.Player.SendErrorMessage("Use the time 0 (zero) for a permanent ban."); return; } + // Used only to notify if a ban was successful and who the ban was about + bool success = false; + string targetGeneralizedName = ""; + + // Effective ban target assignment List players = TShock.Utils.FindPlayer(args.Parameters[1]); - string reason = args.Parameters.Count > 2 ? String.Join(" ", args.Parameters.Skip(2)) : "Misbehavior."; - if (players.Count == 0) + User offlineUser = TShock.Users.GetUserByName(args.Parameters[1]); + + // Storage variable to determine if the command executor is the server console + // If it is, we assume they have full control and let them override permission checks + bool callerIsServerConsole = false; + + if (args.Player is TSServerPlayer) { - var user = TShock.Users.GetUserByName(args.Parameters[1]); - if (user != null) - { - bool force = !args.Player.RealPlayer; - - if (user.Name == args.Player.Name && !force) - { - args.Player.SendErrorMessage("You can't ban yourself!"); - return; - } - - if (TShock.Groups.GetGroupByName(user.Group).HasPermission(Permissions.immunetoban) && !force) - args.Player.SendErrorMessage("You can't ban {0}!", user.Name); - else - { - if (user.KnownIps == null) - { - args.Player.SendErrorMessage("Cannot ban {0} because they have no IPs to ban.", user.Name); - return; - } - var knownIps = JsonConvert.DeserializeObject>(user.KnownIps); - TShock.Bans.AddBan(knownIps.Last(), user.Name, user.UUID, reason, false, args.Player.User.Name); - if (String.IsNullOrWhiteSpace(args.Player.User.Name)) - { - if (args.Silent) - { - args.Player.SendInfoMessage("{0} was {1}banned for '{2}'.", user.Name, force ? "Force " : "", reason); - } - else - { - TSPlayer.All.SendInfoMessage("{0} was {1}banned for '{2}'.", user.Name, force ? "Force " : "", reason); - } - } - else - { - if (args.Silent) - { - args.Player.SendInfoMessage("{0}banned {1} for '{2}'.", force ? "Force " : "", user.Name, reason); - } - else - { - TSPlayer.All.SendInfoMessage("{0} {1}banned {2} for '{3}'.", args.Player.Name, force ? "Force " : "", user.Name, reason); - } - } - } - } - else - args.Player.SendErrorMessage("Invalid player or account!"); + callerIsServerConsole = true; } - else if (players.Count > 1) + + // The ban reason the ban is going to have + string banReason = "Unknown."; + + // The default ban length + // 0 is permanent ban, otherwise temp ban + int banLengthInSeconds = 0; + + // Figure out if param 2 is a time or 0 or garbage + if (args.Parameters.Count >= 3) + { + bool parsedOkay = false; + if (!(args.Parameters[2] == "0")) + { + parsedOkay = TShock.Utils.TryParseTime(args.Parameters[2], out banLengthInSeconds); + } else { + parsedOkay = true; + } + + if (!parsedOkay) + { + args.Player.SendErrorMessage("Invalid time format. Example: 10d+5h+3m-2s."); + args.Player.SendErrorMessage("Use 0 (zero) for a permanent ban."); + return; + } + } + + // If a reason exists, use the given reason. + if (args.Parameters.Count > 3) + { + banReason = String.Join(" ", args.Parameters.Skip(3)); + } + + // Bad case: Players contains more than 1 person so we can't ban them + if (players.Count > 1) + { TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name)); - else - { - if (!TShock.Utils.Ban(players[0], reason, !args.Player.RealPlayer, args.Player.User.Name)) - args.Player.SendErrorMessage("You can't ban {0}!", players[0].Name); - } - } - #endregion - return; - case "addip": - #region Add IP ban - { - if (args.Parameters.Count < 2) - { - args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}ban addip [reason]", Specifier); return; } - string ip = args.Parameters[1]; - string reason = args.Parameters.Count > 2 - ? String.Join(" ", args.Parameters.GetRange(2, args.Parameters.Count - 2)) - : "Manually added IP address ban."; - TShock.Bans.AddBan(ip, "", "", reason, false, args.Player.User.Name); - args.Player.SendSuccessMessage("Banned IP {0}.", ip); - } - #endregion - return; - case "addtemp": - #region Add temp ban - { - if (args.Parameters.Count < 3) + // Good case: Online ban for matching character. + if (players.Count == 1) { - args.Player.SendErrorMessage("Invalid syntax! Proper syntax: {0}ban addtemp