Some i18nifiying

This commit is contained in:
Janet Blackquill 2022-10-21 16:12:04 -04:00
parent 39576e3180
commit f63b26ac76
31 changed files with 538 additions and 455 deletions

View file

@ -48,9 +48,9 @@ namespace TShockAPI
DoBackup(null); DoBackup(null);
DeleteOld(null); DeleteOld(null);
}); });
t.Name = "Backup Thread"; t.Name = GetString("Backup Thread");
t.Start(); t.Start();
// ThreadPool.QueueUserWorkItem(DoBackup); // ThreadPool.QueueUserWorkItem(DoBackup);
// ThreadPool.QueueUserWorkItem(DeleteOld); // ThreadPool.QueueUserWorkItem(DeleteOld);
} }
@ -70,23 +70,23 @@ namespace TShockAPI
if (TShock.Config.Settings.ShowBackupAutosaveMessages) if (TShock.Config.Settings.ShowBackupAutosaveMessages)
{ {
TSPlayer.All.SendInfoMessage("Server map saving..."); TSPlayer.All.SendInfoMessage(GetString("Server map saving..."));
} }
Console.WriteLine("Backing up world..."); Console.WriteLine(GetString("Backing up world..."));
SaveManager.Instance.SaveWorld(); SaveManager.Instance.SaveWorld();
Console.WriteLine("World backed up."); Console.WriteLine(GetString("World backed up."));
Console.ForegroundColor = ConsoleColor.Gray; Console.ForegroundColor = ConsoleColor.Gray;
TShock.Log.Info(string.Format("World backed up ({0}).", Main.worldPathName)); TShock.Log.Info(GetString("World backed up ({0}).", Main.worldPathName));
Main.ActiveWorldFileData._path = worldname; Main.ActiveWorldFileData._path = worldname;
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.ForegroundColor = ConsoleColor.Red; Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Backup failed!"); Console.WriteLine(GetString("Backup failed!"));
Console.ForegroundColor = ConsoleColor.Gray; Console.ForegroundColor = ConsoleColor.Gray;
TShock.Log.Error("Backup failed!"); TShock.Log.Error(GetString("Backup failed!"));
TShock.Log.Error(ex.ToString()); TShock.Log.Error(ex.ToString());
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -78,8 +78,8 @@ namespace TShockAPI.DB
} }
catch (DllNotFoundException) catch (DllNotFoundException)
{ {
System.Console.WriteLine("Possible problem with your database - is Sqlite3.dll present?"); System.Console.WriteLine(GetString("Possible problem with your database - is Sqlite3.dll present?"));
throw new Exception("Could not find a database library (probably Sqlite3.dll)"); throw new Exception(GetString("Could not find a database library (probably Sqlite3.dll)"));
} }
EnsureBansCollection(); EnsureBansCollection();
@ -205,12 +205,12 @@ namespace TShockAPI.DB
{ {
if (ban.ExpirationDateTime == DateTime.MaxValue) if (ban.ExpirationDateTime == DateTime.MaxValue)
{ {
player.Disconnect($"#{ban.TicketNumber} - You are banned: {ban.Reason}"); player.Disconnect(GetParticularString("{0} is ban number, {1} is ban reason", $"#{ban.TicketNumber} - You are banned: {ban.Reason}"));
return true; return true;
} }
TimeSpan ts = ban.ExpirationDateTime - DateTime.UtcNow; TimeSpan ts = ban.ExpirationDateTime - DateTime.UtcNow;
player.Disconnect($"#{ban.TicketNumber} - You are banned: {ban.Reason} ({ban.GetPrettyExpirationString()} remaining)"); player.Disconnect(GetParticularString("{0} is ban number, {1} is ban reason, {2} is a timestamp", $"#{ban.TicketNumber} - You are banned: {ban.Reason} ({ban.GetPrettyExpirationString()} remaining)"));
return true; return true;
} }
@ -255,7 +255,7 @@ namespace TShockAPI.DB
//E.g., if a previous ban has expired, a new ban is valid. //E.g., if a previous ban has expired, a new ban is valid.
//However, if a previous ban on the provided identifier is still in effect, a new ban is not valid //However, if a previous ban on the provided identifier is still in effect, a new ban is not valid
args.Valid = !Bans.Any(b => b.Value.Identifier == args.Identifier && b.Value.ExpirationDateTime > DateTime.UtcNow); args.Valid = !Bans.Any(b => b.Value.Identifier == args.Identifier && b.Value.ExpirationDateTime > DateTime.UtcNow);
args.Message = args.Valid ? null : "a current ban for this identifier already exists."; args.Message = args.Valid ? null : GetString("The ban is invalid because a current ban for this identifier already exists.");
} }
} }
@ -292,7 +292,7 @@ namespace TShockAPI.DB
if (!args.Valid) if (!args.Valid)
{ {
string message = $"Ban was not valid: {(args.Message ?? "no further information provided.")}"; string message = args.Message ?? GetString("The ban was not valid for an unknown reason.");
return new AddBanResult { Message = message }; return new AddBanResult { Message = message };
} }
@ -311,7 +311,7 @@ namespace TShockAPI.DB
if (ticketId == 0) if (ticketId == 0)
{ {
return new AddBanResult { Message = "Database insert failed." }; return new AddBanResult { Message = GetString("Inserting the ban into the database failed.") };
} }
Ban b = new Ban(ticketId, args.Identifier, args.Reason, args.BanningUser, args.BanDateTime, args.ExpirationDateTime); Ban b = new Ban(ticketId, args.Identifier, args.Reason, args.BanningUser, args.BanDateTime, args.ExpirationDateTime);
@ -633,19 +633,19 @@ namespace TShockAPI.DB
/// <summary> /// <summary>
/// IP identifier /// IP identifier
/// </summary> /// </summary>
public static Identifier IP = Register("ip:", $"An identifier for an IP Address in octet format. Eg., '{"127.0.0.1".Color(Utils.RedHighlight)}'."); public static Identifier IP = Register("ip:", GetString($"An identifier for an IP Address in octet format. e.g., '{"127.0.0.1".Color(Utils.RedHighlight)}'."));
/// <summary> /// <summary>
/// UUID identifier /// UUID identifier
/// </summary> /// </summary>
public static Identifier UUID = Register("uuid:", "An identifier for a UUID."); public static Identifier UUID = Register("uuid:", GetString("An identifier for a UUID."));
/// <summary> /// <summary>
/// Player name identifier /// Player name identifier
/// </summary> /// </summary>
public static Identifier Name = Register("name:", "An identifier for a character name."); public static Identifier Name = Register("name:", GetString("An identifier for a character name."));
/// <summary> /// <summary>
/// User account identifier /// User account identifier
/// </summary> /// </summary>
public static Identifier Account = Register("acc:", "An identifier for a TShock User Account name."); public static Identifier Account = Register("acc:", GetString("An identifier for a TShock User Account name."));
private Identifier(string prefix, string description) private Identifier(string prefix, string description)
{ {

View file

@ -171,7 +171,7 @@ namespace TShockAPI.DB
if (player.HasPermission(Permissions.bypassssc) && !fromCommand) if (player.HasPermission(Permissions.bypassssc) && !fromCommand)
{ {
TShock.Log.ConsoleInfo("Skipping SSC save (due to tshock.ignore.ssc) for " + player.Account.Name); TShock.Log.ConsoleInfo(GetParticularString("{0} is a player name", $"Skipping SSC save (due to tshock.ignore.ssc) for {player.Account.Name}"));
return false; return false;
} }
@ -241,7 +241,7 @@ namespace TShockAPI.DB
if (player.HasPermission(Permissions.bypassssc)) if (player.HasPermission(Permissions.bypassssc))
{ {
TShock.Log.ConsoleInfo("Skipping SSC save (due to tshock.ignore.ssc) for " + player.Account.Name); TShock.Log.ConsoleInfo(GetParticularString("{0} is a player name", "Skipping SSC save (due to tshock.ignore.ssc) for {player.Account.Name}"));
return true; return true;
} }

View file

@ -208,14 +208,14 @@ namespace TShockAPI.DB
{ {
if (!GroupExists(TShock.Config.Settings.DefaultGuestGroupName)) if (!GroupExists(TShock.Config.Settings.DefaultGuestGroupName))
{ {
TShock.Log.ConsoleError("The guest group could not be found. This may indicate a typo in the configuration file, or that the group was renamed or deleted."); TShock.Log.ConsoleError(GetString("The guest group could not be found. This may indicate a typo in the configuration file, or that the group was renamed or deleted."));
throw new Exception("The guest group could not be found."); throw new Exception(GetString("The guest group could not be found."));
} }
if (!GroupExists(TShock.Config.Settings.DefaultRegistrationGroupName)) if (!GroupExists(TShock.Config.Settings.DefaultRegistrationGroupName))
{ {
TShock.Log.ConsoleError("The default usergroup could not be found. This may indicate a typo in the configuration file, or that the group was renamed or deleted."); TShock.Log.ConsoleError(GetString("The default usergroup could not be found. This may indicate a typo in the configuration file, or that the group was renamed or deleted."));
throw new Exception("The default usergroup could not be found."); throw new Exception(GetString("The default usergroup could not be found."));
} }
} }
@ -232,9 +232,9 @@ namespace TShockAPI.DB
if (group == null) if (group == null)
{ {
if (kick) if (kick)
player.Disconnect("Your account's group could not be loaded. Please contact server administrators about this."); player.Disconnect(GetString("Your account's group could not be loaded. Please contact server administrators about this."));
else else
player.SendErrorMessage("Your account's group could not be loaded. Please contact server administrators about this."); player.SendErrorMessage(GetString("Your account's group could not be loaded. Please contact server administrators about this."));
return false; return false;
} }
@ -306,7 +306,7 @@ namespace TShockAPI.DB
var parent = groups.FirstOrDefault(gp => gp.Name == parentname); var parent = groups.FirstOrDefault(gp => gp.Name == parentname);
if (parent == null || name == parentname) if (parent == null || name == parentname)
{ {
var error = "Invalid parent {0} for group {1}".SFormat(parentname, group.Name); var error = GetString($"Invalid parent group {parentname} for group {group.Name}");
TShock.Log.ConsoleError(error); TShock.Log.ConsoleError(error);
throw new GroupManagerException(error); throw new GroupManagerException(error);
} }
@ -321,7 +321,7 @@ namespace TShockAPI.DB
groups.Add(group); groups.Add(group);
} }
else else
throw new GroupManagerException("Failed to add group '" + name + ".'"); throw new GroupManagerException(GetString($"Failed to add group {name}."));
} }
/// <summary> /// <summary>
@ -344,7 +344,7 @@ namespace TShockAPI.DB
{ {
parent = GetGroupByName(parentname); parent = GetGroupByName(parentname);
if (parent == null || parent == group) if (parent == null || parent == group)
throw new GroupManagerException("Invalid parent \"{0}\" for group \"{1}\".".SFormat(parentname, name)); throw new GroupManagerException(GetString($"Invalid parent group {parentname} for group {name}."));
// Check if the new parent would cause loops. // Check if the new parent would cause loops.
List<Group> groupChain = new List<Group> { group, parent }; List<Group> groupChain = new List<Group> { group, parent };
@ -353,7 +353,7 @@ namespace TShockAPI.DB
{ {
if (groupChain.Contains(checkingGroup)) if (groupChain.Contains(checkingGroup))
throw new GroupManagerException( throw new GroupManagerException(
string.Format("Invalid parent \"{0}\" for group \"{1}\" would cause loops in the parent chain.", parentname, name)); GetString($"Parenting group {group} to {parentname} would cause loops in the parent chain."));
groupChain.Add(checkingGroup); groupChain.Add(checkingGroup);
checkingGroup = checkingGroup.Parent; checkingGroup = checkingGroup.Parent;
@ -366,7 +366,7 @@ namespace TShockAPI.DB
newGroup.Suffix = suffix; newGroup.Suffix = suffix;
string query = "UPDATE GroupList SET Parent=@0, Commands=@1, ChatColor=@2, Suffix=@3, Prefix=@4 WHERE GroupName=@5"; string query = "UPDATE GroupList SET Parent=@0, Commands=@1, ChatColor=@2, Suffix=@3, Prefix=@4 WHERE GroupName=@5";
if (database.Query(query, parentname, newGroup.Permissions, newGroup.ChatColor, suffix, prefix, name) != 1) if (database.Query(query, parentname, newGroup.Permissions, newGroup.ChatColor, suffix, prefix, name) != 1)
throw new GroupManagerException(string.Format("Failed to update group \"{0}\".", name)); throw new GroupManagerException(GetString($"Failed to update group \"{name}\"."));
group.ChatColor = chatcolor; group.ChatColor = chatcolor;
group.Permissions = permissions; group.Permissions = permissions;
@ -417,7 +417,7 @@ namespace TShockAPI.DB
groups.Remove(oldGroup); groups.Remove(oldGroup);
groups.Add(newGroup); groups.Add(newGroup);
// We need to check if the old group has been referenced as a parent and update those references accordingly // We need to check if the old group has been referenced as a parent and update those references accordingly
using (var command = db.CreateCommand()) using (var command = db.CreateCommand())
{ {
command.CommandText = "UPDATE GroupList SET Parent = @0 WHERE Parent = @1"; command.CommandText = "UPDATE GroupList SET Parent = @0 WHERE Parent = @1";
@ -460,24 +460,24 @@ namespace TShockAPI.DB
} }
transaction.Commit(); transaction.Commit();
return $"Group \"{name}\" has been renamed to \"{newName}\"."; return GetString($"Group {name} has been renamed to {newName}.");
} }
catch (Exception ex) catch (Exception ex)
{ {
TShock.Log.Error($"An exception has occurred during database transaction: {ex.Message}"); TShock.Log.Error(GetString($"An exception has occurred during database transaction: {ex.Message}"));
try try
{ {
transaction.Rollback(); transaction.Rollback();
} }
catch (Exception rollbackEx) catch (Exception rollbackEx)
{ {
TShock.Log.Error($"An exception has occurred during database rollback: {rollbackEx.Message}"); TShock.Log.Error(GetString($"An exception has occurred during database rollback: {rollbackEx.Message}"));
} }
} }
} }
} }
throw new GroupManagerException($"Failed to rename group \"{name}\"."); throw new GroupManagerException(GetString($"Failed to rename group {name}."));
} }
/// <summary> /// <summary>
@ -492,25 +492,25 @@ namespace TShockAPI.DB
{ {
if (exceptions) if (exceptions)
throw new GroupNotExistException(name); throw new GroupNotExistException(name);
return "Error: Group doesn't exist."; return GetString($"Group {name} doesn't exist.");
} }
if (name == Group.DefaultGroup.Name) if (name == Group.DefaultGroup.Name)
{ {
if (exceptions) if (exceptions)
throw new GroupManagerException("Unable to remove default guest group."); throw new GroupManagerException(GetString("You can't remove the default guest group."));
return "Error: Unable to remove the default guest group."; return GetString("You can't remove the default guest group.");
} }
if (database.Query("DELETE FROM GroupList WHERE GroupName=@0", name) == 1) if (database.Query("DELETE FROM GroupList WHERE GroupName=@0", name) == 1)
{ {
groups.Remove(TShock.Groups.GetGroupByName(name)); groups.Remove(TShock.Groups.GetGroupByName(name));
return "Group " + name + " has been deleted successfully."; return GetString($"Group {name} has been deleted successfully.");
} }
if (exceptions) if (exceptions)
throw new GroupManagerException("Failed to delete group '" + name + ".'"); throw new GroupManagerException(GetString($"Failed to delete group {name}."));
return "Failed to delete group '" + name + ".'"; return GetString($"Failed to delete group {name}.");
} }
/// <summary> /// <summary>
@ -522,7 +522,7 @@ namespace TShockAPI.DB
public String AddPermissions(String name, List<String> permissions) public String AddPermissions(String name, List<String> permissions)
{ {
if (!GroupExists(name)) if (!GroupExists(name))
return "Error: Group doesn't exist."; return GetString($"Group {name} doesn't exist.");
var group = TShock.Groups.GetGroupByName(name); var group = TShock.Groups.GetGroupByName(name);
var oldperms = group.Permissions; // Store old permissions in case of error var oldperms = group.Permissions; // Store old permissions in case of error
@ -545,7 +545,7 @@ namespace TShockAPI.DB
public String DeletePermissions(String name, List<String> permissions) public String DeletePermissions(String name, List<String> permissions)
{ {
if (!GroupExists(name)) if (!GroupExists(name))
return "Error: Group doesn't exist."; return GetString($"Group {name} doesn't exist.");
var group = TShock.Groups.GetGroupByName(name); var group = TShock.Groups.GetGroupByName(name);
var oldperms = group.Permissions; // Store old permissions in case of error var oldperms = group.Permissions; // Store old permissions in case of error
@ -575,7 +575,7 @@ namespace TShockAPI.DB
string groupName = reader.Get<string>("GroupName"); string groupName = reader.Get<string>("GroupName");
if (groupName == "superadmin") if (groupName == "superadmin")
{ {
TShock.Log.ConsoleInfo("WARNING: Group \"superadmin\" is defined in the database even though it's a reserved group name."); TShock.Log.ConsoleWarn(GetString("Group \"superadmin\" is defined in the database even though it's a reserved group name."));
continue; continue;
} }
@ -592,7 +592,7 @@ namespace TShockAPI.DB
catch (ArgumentException) catch (ArgumentException)
{ {
// Just in case somebody messed with the unique primary key. // Just in case somebody messed with the unique primary key.
TShock.Log.ConsoleError("ERROR: Group name \"{0}\" occurs more than once. Keeping current group settings."); TShock.Log.ConsoleError(GetString($"The group {groupName} appeared more than once. Keeping current group settings."));
return; return;
} }
} }
@ -628,14 +628,13 @@ namespace TShockAPI.DB
if (group.Parent == null) if (group.Parent == null)
{ {
TShock.Log.ConsoleError( TShock.Log.ConsoleError(
"ERROR: Group \"{0}\" is referencing non existent parent group \"{1}\", parent reference was removed.", GetString($"Group {group.Name} is referencing a non existent parent group {parentGroupName}, parent reference was removed."));
group.Name, parentGroupName);
} }
else else
{ {
if (group.Parent == group) if (group.Parent == group)
TShock.Log.ConsoleInfo( TShock.Log.ConsoleWarn(
"WARNING: Group \"{0}\" is referencing itself as parent group, parent reference was removed.", group.Name); GetString($"Group {group.Name} is referencing itself as parent group; parent reference was removed."));
List<Group> groupChain = new List<Group> { group }; List<Group> groupChain = new List<Group> { group };
Group checkingGroup = group; Group checkingGroup = group;
@ -644,8 +643,7 @@ namespace TShockAPI.DB
if (groupChain.Contains(checkingGroup.Parent)) if (groupChain.Contains(checkingGroup.Parent))
{ {
TShock.Log.ConsoleError( TShock.Log.ConsoleError(
"ERROR: Group \"{0}\" is referencing parent group \"{1}\" which is already part of the parent chain. Parent reference removed.", GetString($"Group \"{checkingGroup.Name}\" is referencing parent group {checkingGroup.Parent.Name} which is already part of the parent chain. Parent reference removed."));
checkingGroup.Name, checkingGroup.Parent.Name);
checkingGroup.Parent = null; checkingGroup.Parent = null;
break; break;
@ -664,7 +662,7 @@ namespace TShockAPI.DB
} }
catch (Exception ex) catch (Exception ex)
{ {
TShock.Log.ConsoleError("Error on reloading groups: " + ex); TShock.Log.ConsoleError(GetString($"Error on reloading groups: {ex}"));
} }
} }
} }
@ -707,7 +705,7 @@ namespace TShockAPI.DB
/// </summary> /// </summary>
/// <param name="name">The group name.</param> /// <param name="name">The group name.</param>
public GroupExistsException(string name) public GroupExistsException(string name)
: base("Group '" + name + "' already exists") : base(GetString($"Group {name} already exists"))
{ {
} }
} }
@ -724,7 +722,7 @@ namespace TShockAPI.DB
/// </summary> /// </summary>
/// <param name="name">The group name.</param> /// <param name="name">The group name.</param>
public GroupNotExistException(string name) public GroupNotExistException(string name)
: base("Group '" + name + "' does not exist") : base(GetString($"Group {name} does not exist"))
{ {
} }
} }

View file

@ -316,8 +316,7 @@ namespace TShockAPI.DB
{ {
if (x.DefaultCurrentTimestamp && x.Type != MySqlDbType.DateTime) if (x.DefaultCurrentTimestamp && x.Type != MySqlDbType.DateTime)
{ {
throw new SqlColumnException("Can't set to true SqlColumn.DefaultCurrentTimestamp " + throw new SqlColumnException(GetString("Can't set to true SqlColumn.DefaultCurrentTimestamp when the MySqlDbType is not DateTime"));
"when the MySqlDbType is not DateTime");
} }
}); });
} }
@ -343,7 +342,7 @@ namespace TShockAPI.DB
public string UpdateValue(string table, List<SqlValue> values, List<SqlValue> wheres) public string UpdateValue(string table, List<SqlValue> values, List<SqlValue> wheres)
{ {
if (0 == values.Count) if (0 == values.Count)
throw new ArgumentException("No values supplied"); throw new ArgumentException(GetString("No values supplied"));
return "UPDATE {0} SET {1} {2}".SFormat(EscapeTableName(table), string.Join(", ", values.Select(v => v.Name + " = " + v.Value)), BuildWhere(wheres)); return "UPDATE {0} SET {1} {2}".SFormat(EscapeTableName(table), string.Join(", ", values.Select(v => v.Name + " = " + v.Value)), BuildWhere(wheres));
} }

View file

@ -220,7 +220,7 @@ namespace TShockAPI.DB
} }
if (traversed.Contains(cur)) if (traversed.Contains(cur))
{ {
throw new InvalidOperationException("Infinite group parenting ({0})".SFormat(cur.Name)); throw new InvalidOperationException(GetString($"Infinite group parenting ({cur.Name})"));
} }
traversed.Add(cur); traversed.Add(cur);
cur = cur.Parent; cur = cur.Parent;
@ -255,4 +255,4 @@ namespace TShockAPI.DB
return ID + (AllowedGroups.Count > 0 ? " (" + String.Join(",", AllowedGroups) + ")" : ""); return ID + (AllowedGroups.Count > 0 ? " (" + String.Join(",", AllowedGroups) + ")" : "");
} }
} }
} }

View file

@ -99,13 +99,13 @@ namespace TShockAPI.DB
if (Int32.TryParse(splitids[i], out userid)) // if unparsable, it's not an int, so silently skip if (Int32.TryParse(splitids[i], out userid)) // if unparsable, it's not an int, so silently skip
r.AllowedIDs.Add(userid); r.AllowedIDs.Add(userid);
else else
TShock.Log.Warn("One of your UserIDs is not a usable integer: " + splitids[i]); TShock.Log.Warn(GetString($"One of your UserIDs is not a usable integer: {splitids[i]}"));
} }
} }
catch (Exception e) catch (Exception e)
{ {
TShock.Log.Error("Your database contains invalid UserIDs (they should be ints)."); TShock.Log.Error(GetString("Your database contains invalid UserIDs (they should be integers)."));
TShock.Log.Error("A lot of things will fail because of this. You must manually delete and re-create the allowed field."); TShock.Log.Error(GetString("A lot of things will fail because of this. You must manually delete and re-create the allowed field."));
TShock.Log.Error(e.ToString()); TShock.Log.Error(e.ToString());
TShock.Log.Error(e.StackTrace); TShock.Log.Error(e.StackTrace);
} }
@ -283,7 +283,7 @@ namespace TShockAPI.DB
if (region.InArea(x, y)) if (region.InArea(x, y))
{ {
if (top == null || region.Z > top.Z) if (top == null || region.Z > top.Z)
top = region; top = region;
} }
} }
return top == null || top.HasPermissionToBuildInRegion(ply); return top == null || top.HasPermissionToBuildInRegion(ply);
@ -313,7 +313,7 @@ namespace TShockAPI.DB
} }
/// <summary> /// <summary>
/// Checks if any regions exist at the given (x, y) coordinate /// Checks if any regions exist at the given (x, y) coordinate
/// and returns an IEnumerable containing their IDs /// and returns an IEnumerable containing their IDs
/// </summary> /// </summary>
/// <param name="x">X coordinate</param> /// <param name="x">X coordinate</param>
@ -390,7 +390,7 @@ namespace TShockAPI.DB
default: default:
return false; return false;
} }
foreach (var region in Regions.Where(r => r.Name == regionName)) foreach (var region in Regions.Where(r => r.Name == regionName))
region.Area = new Rectangle(X, Y, width, height); region.Area = new Rectangle(X, Y, width, height);
int q = database.Query("UPDATE Regions SET X1 = @0, Y1 = @1, width = @2, height = @3 WHERE RegionName = @4 AND WorldID=@5", X, Y, width, int q = database.Query("UPDATE Regions SET X1 = @0, Y1 = @1, width = @2, height = @3 WHERE RegionName = @4 AND WorldID=@5", X, Y, width,
@ -404,7 +404,7 @@ namespace TShockAPI.DB
} }
return false; return false;
} }
/// <summary> /// <summary>
/// Renames a region /// Renames a region
/// </summary> /// </summary>
@ -438,7 +438,7 @@ namespace TShockAPI.DB
return result; return result;
} }
/// <summary> /// <summary>
/// Removes an allowed user from a region /// Removes an allowed user from a region
/// </summary> /// </summary>
@ -769,7 +769,7 @@ namespace TShockAPI.DB
*/ */
return x >= Area.X && x <= Area.X + Area.Width && y >= Area.Y && y <= Area.Y + Area.Height; return x >= Area.X && x <= Area.X + Area.Width && y >= Area.Y && y <= Area.Y + Area.Height;
} }
/// <summary> /// <summary>
/// Checks if a given player has permission to build in the region /// Checks if a given player has permission to build in the region
/// </summary> /// </summary>
@ -785,7 +785,7 @@ namespace TShockAPI.DB
{ {
if (!ply.HasBeenNaggedAboutLoggingIn) if (!ply.HasBeenNaggedAboutLoggingIn)
{ {
ply.SendMessage("You must be logged in to take advantage of protected regions.", Color.Red); ply.SendMessage(GetString("You must be logged in to take advantage of protected regions."), Color.Red);
ply.HasBeenNaggedAboutLoggingIn = true; ply.HasBeenNaggedAboutLoggingIn = true;
} }
return false; return false;

View file

@ -50,8 +50,8 @@ namespace TShockAPI.DB
} }
catch (DllNotFoundException) catch (DllNotFoundException)
{ {
Console.WriteLine("Possible problem with your database - is Sqlite3.dll present?"); TShock.Log.ConsoleWarn(GetString("Possible problem with your database - is Sqlite3.dll present?"));
throw new Exception("Could not find a database library (probably Sqlite3.dll)"); throw new Exception(GetString("Could not find a database library (probably Sqlite3.dll)"));
} }
} }
@ -84,7 +84,7 @@ namespace TShockAPI.DB
where WorldId = @0 where WorldId = @0
group by itemId"; group by itemId";
try { try {
using (var reader = database.QueryReader(sql, Main.worldID)) using (var reader = database.QueryReader(sql, Main.worldID))
{ {
while (reader.Read()) while (reader.Read())

View file

@ -220,7 +220,7 @@ namespace TShockAPI.DB
} }
if (traversed.Contains(cur)) if (traversed.Contains(cur))
{ {
throw new InvalidOperationException("Infinite group parenting ({0})".SFormat(cur.Name)); throw new InvalidOperationException(GetString($"Infinite group parenting ({cur.Name})"));
} }
traversed.Add(cur); traversed.Add(cur);
cur = cur.Parent; cur = cur.Parent;
@ -255,4 +255,4 @@ namespace TShockAPI.DB
return ID + (AllowedGroups.Count > 0 ? " (" + String.Join(",", AllowedGroups) + ")" : ""); return ID + (AllowedGroups.Count > 0 ? " (" + String.Join(",", AllowedGroups) + ")" : "");
} }
} }
} }

View file

@ -78,7 +78,7 @@ namespace TShockAPI.DB
// Detect duplicate user using a regexp as Sqlite doesn't have well structured exceptions // Detect duplicate user using a regexp as Sqlite doesn't have well structured exceptions
if (Regex.IsMatch(ex.Message, "Username.*not unique|UNIQUE constraint failed: Users\\.Username")) if (Regex.IsMatch(ex.Message, "Username.*not unique|UNIQUE constraint failed: Users\\.Username"))
throw new UserAccountExistsException(account.Name); throw new UserAccountExistsException(account.Name);
throw new UserAccountManagerException("AddUser SQL returned an error (" + ex.Message + ")", ex); throw new UserAccountManagerException(GetString($"AddUser SQL returned an error ({ex.Message})"), ex);
} }
if (1 > ret) if (1 > ret)
@ -109,7 +109,7 @@ namespace TShockAPI.DB
} }
catch (Exception ex) catch (Exception ex)
{ {
throw new UserAccountManagerException("RemoveUser SQL returned an error", ex); throw new UserAccountManagerException(GetString("RemoveUser SQL returned an error"), ex);
} }
} }
@ -131,7 +131,7 @@ namespace TShockAPI.DB
} }
catch (Exception ex) catch (Exception ex)
{ {
throw new UserAccountManagerException("SetUserPassword SQL returned an error", ex); throw new UserAccountManagerException(GetString("SetUserPassword SQL returned an error"), ex);
} }
} }
@ -151,7 +151,7 @@ namespace TShockAPI.DB
} }
catch (Exception ex) catch (Exception ex)
{ {
throw new UserAccountManagerException("SetUserUUID SQL returned an error", ex); throw new UserAccountManagerException(GetString("SetUserUUID SQL returned an error"), ex);
} }
} }
@ -168,7 +168,7 @@ namespace TShockAPI.DB
if (_database.Query("UPDATE Users SET UserGroup = @0 WHERE Username = @1;", group, account.Name) == 0) if (_database.Query("UPDATE Users SET UserGroup = @0 WHERE Username = @1;", group, account.Name) == 0)
throw new UserAccountNotExistException(account.Name); throw new UserAccountNotExistException(account.Name);
try try
{ {
// Update player group reference for any logged in player // Update player group reference for any logged in player
@ -179,7 +179,7 @@ namespace TShockAPI.DB
} }
catch (Exception ex) catch (Exception ex)
{ {
throw new UserAccountManagerException("SetUserGroup SQL returned an error", ex); throw new UserAccountManagerException(GetString("SetUserGroup SQL returned an error"), ex);
} }
} }
@ -194,7 +194,7 @@ namespace TShockAPI.DB
} }
catch (Exception ex) catch (Exception ex)
{ {
throw new UserAccountManagerException("UpdateLogin SQL returned an error", ex); throw new UserAccountManagerException(GetString("UpdateLogin SQL returned an error"), ex);
} }
} }
@ -215,7 +215,7 @@ namespace TShockAPI.DB
} }
catch (Exception ex) catch (Exception ex)
{ {
TShock.Log.ConsoleError("FetchHashedPasswordAndGroup SQL returned an error: " + ex); TShock.Log.ConsoleError(GetString($"FetchHashedPasswordAndGroup SQL returned an error: {ex}"));
} }
return -1; return -1;
} }
@ -288,10 +288,10 @@ namespace TShockAPI.DB
} }
catch (Exception ex) catch (Exception ex)
{ {
throw new UserAccountManagerException("GetUser SQL returned an error (" + ex.Message + ")", ex); throw new UserAccountManagerException(GetString($"GetUser SQL returned an error {ex.Message}"), ex);
} }
if (multiple) if (multiple)
throw new UserAccountManagerException(String.Format("Multiple user accounts found for {0} '{1}'", type, arg)); throw new UserAccountManagerException(GetString($"Multiple user accounts found for {type} '{arg}'"));
throw new UserAccountNotExistException(account.Name); throw new UserAccountNotExistException(account.Name);
} }
@ -447,7 +447,7 @@ namespace TShockAPI.DB
} }
catch (SaltParseException) catch (SaltParseException)
{ {
TShock.Log.ConsoleError("Error: Unable to verify the password hash for user {0} ({1})", Name, ID); TShock.Log.ConsoleError(GetString($"Unable to verify the password hash for user {Name} ({ID})"));
return false; return false;
} }
return false; return false;
@ -465,7 +465,7 @@ namespace TShockAPI.DB
} }
catch (FormatException) catch (FormatException)
{ {
TShock.Log.ConsoleError("Warning: Not upgrading work factor because bcrypt hash in an invalid format."); TShock.Log.ConsoleWarn(GetString("Not upgrading work factor because bcrypt hash in an invalid format."));
return; return;
} }
@ -488,7 +488,8 @@ namespace TShockAPI.DB
{ {
if (password.Trim().Length < Math.Max(4, TShock.Config.Settings.MinimumPasswordLength)) if (password.Trim().Length < Math.Max(4, TShock.Config.Settings.MinimumPasswordLength))
{ {
throw new ArgumentOutOfRangeException("password", "Password must be > " + TShock.Config.Settings.MinimumPasswordLength + " characters."); int minLength = TShock.Config.Settings.MinimumPasswordLength;
throw new ArgumentOutOfRangeException("password", GetString($"Password must be at least {minLength} characters."));
} }
try try
{ {
@ -496,7 +497,7 @@ namespace TShockAPI.DB
} }
catch (ArgumentOutOfRangeException) catch (ArgumentOutOfRangeException)
{ {
TShock.Log.ConsoleError("Invalid BCrypt work factor in config file! Creating new hash using default work factor."); TShock.Log.ConsoleError(GetString("Invalid BCrypt work factor in config file! Creating new hash using default work factor."));
Password = BCrypt.Net.BCrypt.HashPassword(password.Trim()); Password = BCrypt.Net.BCrypt.HashPassword(password.Trim());
} }
} }
@ -508,7 +509,8 @@ namespace TShockAPI.DB
{ {
if (password.Trim().Length < Math.Max(4, TShock.Config.Settings.MinimumPasswordLength)) if (password.Trim().Length < Math.Max(4, TShock.Config.Settings.MinimumPasswordLength))
{ {
throw new ArgumentOutOfRangeException("password", "Password must be > " + TShock.Config.Settings.MinimumPasswordLength + " characters."); int minLength = TShock.Config.Settings.MinimumPasswordLength;
throw new ArgumentOutOfRangeException("password", GetString($"Password must be at least {minLength} characters."));
} }
Password = BCrypt.Net.BCrypt.HashPassword(password.Trim(), workFactor); Password = BCrypt.Net.BCrypt.HashPassword(password.Trim(), workFactor);
} }
@ -607,7 +609,7 @@ namespace TShockAPI.DB
/// <param name="name">The name of the user account that already exists.</param> /// <param name="name">The name of the user account that already exists.</param>
/// <returns>A UserAccountExistsException object with the user's name passed in the message.</returns> /// <returns>A UserAccountExistsException object with the user's name passed in the message.</returns>
public UserAccountExistsException(string name) public UserAccountExistsException(string name)
: base("User account '" + name + "' already exists") : base(GetString($"User account {name} already exists"))
{ {
} }
} }
@ -620,7 +622,7 @@ namespace TShockAPI.DB
/// <param name="name">The user account name to be pasesd in the message.</param> /// <param name="name">The user account name to be pasesd in the message.</param>
/// <returns>A new UserAccountNotExistException object with a message containing the user account name that does not exist.</returns> /// <returns>A new UserAccountNotExistException object with a message containing the user account name that does not exist.</returns>
public UserAccountNotExistException(string name) public UserAccountNotExistException(string name)
: base("User account '" + name + "' does not exist") : base(GetString($"User account {name} does not exist"))
{ {
} }
} }
@ -633,7 +635,7 @@ namespace TShockAPI.DB
/// <param name="group">The group name.</param> /// <param name="group">The group name.</param>
/// <returns>A new GroupNotExistsException with the group that does not exist's name in the message.</returns> /// <returns>A new GroupNotExistsException with the group that does not exist's name in the message.</returns>
public GroupNotExistsException(string group) public GroupNotExistsException(string group)
: base("Group '" + group + "' does not exist") : base(GetString($"Group {group} does not exist"))
{ {
} }
} }

View file

@ -76,7 +76,7 @@ namespace TShockAPI.DB
} }
catch (Exception ex) catch (Exception ex)
{ {
throw new Exception("Fatal TShock initialization exception: failed to connect to MySQL database. See inner exception for details.", ex); throw new Exception(GetString("Fatal TShock initialization exception: failed to connect to MySQL database. See inner exception for details."), ex);
} }
} }
@ -251,7 +251,7 @@ namespace TShockAPI.DB
if (typeof(T) != (t = reader.GetFieldType(column))) if (typeof(T) != (t = reader.GetFieldType(column)))
{ {
string columnName = reader.GetName(column); string columnName = reader.GetName(column);
throw new InvalidCastException($"Received type '{typeof(T).Name}', however column '{columnName}' expects type '{t.Name}'"); throw new InvalidCastException(GetString($"Received type '{typeof(T).Name}', however column '{columnName}' expects type '{t.Name}'"));
} }
if (reader.IsDBNull(column)) if (reader.IsDBNull(column))

View file

@ -18,7 +18,7 @@ namespace TShockAPI.Handlers
/// Thus, they would not be able to modify its content. This means that a hacker attempted to send this packet directly, or through raw bytes to tamper with the DisplayDoll. This is why I do not bother with making sure the player gets their item back. /// Thus, they would not be able to modify its content. This means that a hacker attempted to send this packet directly, or through raw bytes to tamper with the DisplayDoll. This is why I do not bother with making sure the player gets their item back.
if (!args.Player.HasBuildPermission(args.DisplayDollEntity.Position.X, args.DisplayDollEntity.Position.Y, false)) if (!args.Player.HasBuildPermission(args.DisplayDollEntity.Position.X, args.DisplayDollEntity.Position.Y, false))
{ {
args.Player.SendErrorMessage("You do not have permission to modify a Mannequin in a protected area!"); args.Player.SendErrorMessage(GetString("You do not have permission to modify a Mannequin in a protected area!"));
args.Handled = true; args.Handled = true;
return; return;
} }

View file

@ -16,7 +16,7 @@ namespace TShockAPI.Handlers
{ {
if (!args.Player.HasPermission(Permissions.sendemoji)) if (!args.Player.HasPermission(Permissions.sendemoji))
{ {
args.Player.SendErrorMessage("You do not have permission to send emotes!"); args.Player.SendErrorMessage(GetString("You do not have permission to send emotes!"));
args.Handled = true; args.Handled = true;
return; return;
} }

View file

@ -16,7 +16,7 @@ namespace TShockAPI.Handlers.IllegalPerSe
{ {
if (args.PlayerIndex != args.Player.Index) if (args.PlayerIndex != args.Player.Index)
{ {
TShock.Log.ConsoleError($"IllegalPerSe: Emoji packet rejected for ID spoofing. Expected {args.Player.Index}, received {args.PlayerIndex} from {args.Player.Name}."); TShock.Log.ConsoleError(GetString($"IllegalPerSe: Emoji packet rejected for ID spoofing. Expected {args.Player.Index}, received {args.PlayerIndex} from {args.Player.Name}."));
args.Handled = true; args.Handled = true;
return; return;
} }

View file

@ -89,7 +89,7 @@ namespace TShockAPI.Handlers
{ {
if (args.PlayerIndex != args.Player.Index) if (args.PlayerIndex != args.Player.Index)
{ {
TShock.Log.ConsoleDebug($"LandGolfBallInCupHandler: Packet rejected for ID spoofing. Expected {args.Player.Index}, received {args.PlayerIndex} from {args.Player.Name}."); TShock.Log.ConsoleDebug(GetString($"LandGolfBallInCupHandler: Packet rejected for ID spoofing. Expected {args.Player.Index}, received {args.PlayerIndex} from {args.Player.Name}."));
args.Handled = true; args.Handled = true;
return; return;
} }
@ -97,21 +97,21 @@ namespace TShockAPI.Handlers
if (args.TileX > Main.maxTilesX || args.TileX < 0 if (args.TileX > Main.maxTilesX || args.TileX < 0
|| args.TileY > Main.maxTilesY || args.TileY < 0) || args.TileY > Main.maxTilesY || args.TileY < 0)
{ {
TShock.Log.ConsoleDebug($"LandGolfBallInCupHandler: X and Y position is out of world bounds! - From {args.Player.Name}"); TShock.Log.ConsoleDebug(GetString($"LandGolfBallInCupHandler: X and Y position is out of world bounds! - From {args.Player.Name}"));
args.Handled = true; args.Handled = true;
return; return;
} }
if (!Main.tile[args.TileX, args.TileY].active() && Main.tile[args.TileX, args.TileY].type != TileID.GolfHole) if (!Main.tile[args.TileX, args.TileY].active() && Main.tile[args.TileX, args.TileY].type != TileID.GolfHole)
{ {
TShock.Log.ConsoleDebug($"LandGolfBallInCupHandler: Tile at packet position X:{args.TileX} Y:{args.TileY} is not a golf hole! - From {args.Player.Name}"); TShock.Log.ConsoleDebug(GetString($"LandGolfBallInCupHandler: Tile at packet position X:{args.TileX} Y:{args.TileY} is not a golf hole! - From {args.Player.Name}"));
args.Handled = true; args.Handled = true;
return; return;
} }
if (!GolfBallProjectileIDs.Contains(args.ProjectileType)) if (!GolfBallProjectileIDs.Contains(args.ProjectileType))
{ {
TShock.Log.ConsoleDebug($"LandGolfBallInCupHandler: Invalid golf ball projectile ID {args.ProjectileType}! - From {args.Player.Name}"); TShock.Log.ConsoleDebug(GetString($"LandGolfBallInCupHandler: Invalid golf ball projectile ID {args.ProjectileType}! - From {args.Player.Name}"));
args.Handled = true; args.Handled = true;
return; return;
} }
@ -120,14 +120,14 @@ namespace TShockAPI.Handlers
var usedGolfClub = args.Player.RecentlyCreatedProjectiles.Any(e => e.Type == ProjectileID.GolfClubHelper); var usedGolfClub = args.Player.RecentlyCreatedProjectiles.Any(e => e.Type == ProjectileID.GolfClubHelper);
if (!usedGolfClub && !usedGolfBall) if (!usedGolfClub && !usedGolfBall)
{ {
TShock.Log.ConsoleDebug($"GolfPacketHandler: Player did not have create a golf club projectile the last 5 seconds! - From {args.Player.Name}"); TShock.Log.ConsoleDebug(GetString($"GolfPacketHandler: Player did not have create a golf club projectile the last 5 seconds! - From {args.Player.Name}"));
args.Handled = true; args.Handled = true;
return; return;
} }
if (!GolfClubItemIDs.Contains(args.Player.SelectedItem.type)) if (!GolfClubItemIDs.Contains(args.Player.SelectedItem.type))
{ {
TShock.Log.ConsoleDebug($"LandGolfBallInCupHandler: Item selected is not a golf club! - From {args.Player.Name}"); TShock.Log.ConsoleDebug(GetString($"LandGolfBallInCupHandler: Item selected is not a golf club! - From {args.Player.Name}"));
args.Handled = true; args.Handled = true;
return; return;
} }

View file

@ -50,7 +50,7 @@ namespace TShockAPI.Handlers.NetModules
{ {
if (!PowerToPermissionMap.ContainsKey(powerType)) if (!PowerToPermissionMap.ContainsKey(powerType))
{ {
TShock.Log.ConsoleDebug("CreativePowerHandler received permission check request for unknown creative power"); TShock.Log.ConsoleDebug(GetString("CreativePowerHandler received permission check request for unknown creative power"));
return false; return false;
} }
@ -65,7 +65,7 @@ namespace TShockAPI.Handlers.NetModules
if (!player.HasPermission(permission)) if (!player.HasPermission(permission))
{ {
player.SendErrorMessage("You do not have permission to {0}.", PermissionToDescriptionMap[permission]); player.SendErrorMessage(PermissionToDescriptionMap[permission]);
return false; return false;
} }
@ -100,18 +100,18 @@ namespace TShockAPI.Handlers.NetModules
/// </summary> /// </summary>
public static Dictionary<string, string> PermissionToDescriptionMap = new Dictionary<string, string> public static Dictionary<string, string> PermissionToDescriptionMap = new Dictionary<string, string>
{ {
{ Permissions.journey_timefreeze, "freeze the time of the server" }, { Permissions.journey_timefreeze, GetString("You do not have permission to freeze the time of the server.") },
{ Permissions.journey_timeset, "modify the time of the server" }, { Permissions.journey_timeset, GetString("You do not have permission to modify the time of the server.") },
{ Permissions.journey_godmode, "toggle godmode" }, { Permissions.journey_godmode, GetString("You do not have permission to toggle godmode.") },
{ Permissions.journey_windstrength, "modify the wind strength of the server" }, { Permissions.journey_windstrength, GetString("You do not have permission to modify the wind strength of the server.") },
{ Permissions.journey_rainstrength, "modify the rain strength of the server" }, { Permissions.journey_rainstrength, GetString("You do not have permission to modify the rain strength of the server.") },
{ Permissions.journey_timespeed, "modify the time speed of the server" }, { Permissions.journey_timespeed, GetString("You do not have permission to modify the time speed of the server.") },
{ Permissions.journey_rainfreeze, "freeze the rain strength of the server" }, { Permissions.journey_rainfreeze, GetString("You do not have permission to freeze the rain strength of the server.") },
{ Permissions.journey_windfreeze, "freeze the wind strength of the server" }, { Permissions.journey_windfreeze, GetString("You do not have permission to freeze the wind strength of the server.") },
{ Permissions.journey_placementrange, "modify the tile placement range of your character" }, { Permissions.journey_placementrange, GetString("You do not have permission to modify the tile placement range of your character.") },
{ Permissions.journey_setdifficulty, "modify the world difficulty of the server" }, { Permissions.journey_setdifficulty, GetString("You do not have permission to modify the world difficulty of the server.") },
{ Permissions.journey_biomespreadfreeze, "freeze the biome spread of the server" }, { Permissions.journey_biomespreadfreeze, GetString("You do not have permission to freeze the biome spread of the server.") },
{ Permissions.journey_setspawnrate, "modify the NPC spawn rate of the server" }, { Permissions.journey_setspawnrate, GetString("You do not have permission to modify the NPC spawn rate of the server.") },
}; };
} }
} }

View file

@ -52,8 +52,7 @@ namespace TShockAPI.Handlers.NetModules
if (!Main.GameModeInfo.IsJourneyMode) if (!Main.GameModeInfo.IsJourneyMode)
{ {
TShock.Log.ConsoleDebug( TShock.Log.ConsoleDebug(
"NetModuleHandler received attempt to unlock sacrifice while not in journey mode from", GetString($"NetModuleHandler received attempt to unlock sacrifice while not in journey mode from {player.Name}")
player.Name
); );
rejectPacket = true; rejectPacket = true;
@ -63,9 +62,7 @@ namespace TShockAPI.Handlers.NetModules
if (UnknownField != 0) if (UnknownField != 0)
{ {
TShock.Log.ConsoleDebug( TShock.Log.ConsoleDebug(
"CreativeUnlocksHandler received non-vanilla unlock request. Random field value: {0} but should be 0 from {1}", GetString($"CreativeUnlocksHandler received non-vanilla unlock request. Random field value: {UnknownField} but should be 0 from {player.Name}")
UnknownField,
player.Name
); );
rejectPacket = true; rejectPacket = true;
@ -74,7 +71,7 @@ namespace TShockAPI.Handlers.NetModules
if (!player.HasPermission(Permissions.journey_contributeresearch)) if (!player.HasPermission(Permissions.journey_contributeresearch))
{ {
player.SendErrorMessage("You do not have permission to contribute research."); player.SendErrorMessage(GetString("You do not have permission to contribute research."));
rejectPacket = true; rejectPacket = true;
return; return;
} }

View file

@ -51,7 +51,7 @@ namespace TShockAPI.Handlers.NetModules
if (!player.HasPermission(Permissions.pylon)) if (!player.HasPermission(Permissions.pylon))
{ {
rejectPacket = true; rejectPacket = true;
player.SendErrorMessage("You do not have permission to teleport using pylons."); player.SendErrorMessage(GetString("You do not have permission to teleport using pylons."));
return; return;
} }
} }

View file

@ -11,7 +11,7 @@ using static TShockAPI.GetDataHandlers;
namespace TShockAPI.Handlers namespace TShockAPI.Handlers
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class RequestTileEntityInteractionHandler : IPacketHandler<RequestTileEntityInteractionEventArgs> public class RequestTileEntityInteractionHandler : IPacketHandler<RequestTileEntityInteractionEventArgs>
{ {
@ -19,20 +19,20 @@ namespace TShockAPI.Handlers
{ {
if (args.TileEntity is TEHatRack && !args.Player.HasBuildPermissionForTileObject(args.TileEntity.Position.X, args.TileEntity.Position.Y, TEHatRack.entityTileWidth, TEHatRack.entityTileHeight, false)) if (args.TileEntity is TEHatRack && !args.Player.HasBuildPermissionForTileObject(args.TileEntity.Position.X, args.TileEntity.Position.Y, TEHatRack.entityTileWidth, TEHatRack.entityTileHeight, false))
{ {
args.Player.SendErrorMessage("You do not have permission to modify a Hat Rack in a protected area!"); args.Player.SendErrorMessage(GetString("You do not have permission to modify a Hat Rack in a protected area!"));
args.Handled = true; args.Handled = true;
return; return;
} }
else if (args.TileEntity is TEDisplayDoll && !args.Player.HasBuildPermissionForTileObject(args.TileEntity.Position.X, args.TileEntity.Position.Y, TEDisplayDoll.entityTileWidth, TEDisplayDoll.entityTileHeight, false)) else if (args.TileEntity is TEDisplayDoll && !args.Player.HasBuildPermissionForTileObject(args.TileEntity.Position.X, args.TileEntity.Position.Y, TEDisplayDoll.entityTileWidth, TEDisplayDoll.entityTileHeight, false))
{ {
args.Player.SendErrorMessage("You do not have permission to modify a Mannequin in a protected area!"); args.Player.SendErrorMessage(GetString("You do not have permission to modify a Mannequin in a protected area!"));
args.Handled = true; args.Handled = true;
return; return;
} }
else if (!args.Player.HasBuildPermission(args.TileEntity.Position.X, args.TileEntity.Position.Y, false)) else if (!args.Player.HasBuildPermission(args.TileEntity.Position.X, args.TileEntity.Position.Y, false))
{ {
args.Player.SendErrorMessage("You do not have permission to modify a TileEntity in a protected area!"); args.Player.SendErrorMessage(GetString("You do not have permission to modify a TileEntity in a protected area!"));
TShock.Log.ConsoleDebug($"RequestTileEntityInteractionHandler: Rejected packet due to lack of building permissions! - From {args.Player.Name} | Position X:{args.TileEntity.Position.X} Y:{args.TileEntity.Position.Y}, TileEntity type: {args.TileEntity.type}, Tile type: {Main.tile[args.TileEntity.Position.X, args.TileEntity.Position.Y].type}"); TShock.Log.ConsoleDebug(GetString($"RequestTileEntityInteractionHandler: Rejected packet due to lack of building permissions! - From {args.Player.Name} | Position X:{args.TileEntity.Position.X} Y:{args.TileEntity.Position.Y}, TileEntity type: {args.TileEntity.type}, Tile type: {Main.tile[args.TileEntity.Position.X, args.TileEntity.Position.Y].type}"));
args.Handled = true; args.Handled = true;
return; return;
} }

View file

@ -126,7 +126,7 @@ namespace TShockAPI.Handlers
if (args.Handled == true) if (args.Handled == true)
{ {
TSPlayer.All.SendTileRect(args.TileX, args.TileY, args.Width, args.Length); TSPlayer.All.SendTileRect(args.TileX, args.TileY, args.Width, args.Length);
TShock.Log.ConsoleDebug("Bouncer / SendTileRect reimplemented from carbonara from {0}", args.Player.Name); TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect reimplemented from carbonara from {args.Player.Name}"));
} }
} }
@ -289,13 +289,13 @@ namespace TShockAPI.Handlers
// More in depth checks should take place in handlers for the Place Object (79), Update Tile Entity (86), and Place Tile Entity (87) packets // More in depth checks should take place in handlers for the Place Object (79), Update Tile Entity (86), and Place Tile Entity (87) packets
if (!args.Player.HasBuildPermissionForTileObject(realX, realY, width, height)) if (!args.Player.HasBuildPermissionForTileObject(realX, realY, width, height))
{ {
TShock.Log.ConsoleDebug("Bouncer / SendTileRect rejected from no permission for tile object from {0}", args.Player.Name); TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect rejected from no permission for tile object from {args.Player.Name}"));
return; return;
} }
if (TShock.TileBans.TileIsBanned((short)tileType)) if (TShock.TileBans.TileIsBanned((short)tileType))
{ {
TShock.Log.ConsoleDebug("Bouncer / SendTileRect rejected for banned tile"); TShock.Log.ConsoleDebug(GetString("Bouncer / SendTileRect rejected for banned tile"));
return; return;
} }
@ -410,7 +410,7 @@ namespace TShockAPI.Handlers
TileID.Sets.Conversion.MossBrick[tile.type] && TileID.Sets.Conversion.MossBrick[newTile.Type] TileID.Sets.Conversion.MossBrick[tile.type] && TileID.Sets.Conversion.MossBrick[newTile.Type]
) )
{ {
TShock.Log.ConsoleDebug("Bouncer / SendTileRect processing a tile conversion update - [{0}] -> [{1}]", tile.type, newTile.Type); TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect processing a tile conversion update - [{tile.type}] -> [{newTile.Type}]"));
UpdateServerTileState(tile, newTile, TileDataType.Tile); UpdateServerTileState(tile, newTile, TileDataType.Tile);
} }
@ -425,7 +425,7 @@ namespace TShockAPI.Handlers
WallID.Sets.Conversion.NewWall4[tile.wall] && WallID.Sets.Conversion.NewWall4[newTile.Wall] WallID.Sets.Conversion.NewWall4[tile.wall] && WallID.Sets.Conversion.NewWall4[newTile.Wall]
) )
{ {
TShock.Log.ConsoleDebug("Bouncer / SendTileRect processing a wall conversion update - [{0}] -> [{1}]", tile.wall, newTile.Wall); TShock.Log.ConsoleDebug($"Bouncer / SendTileRect processing a wall conversion update - [{tile.wall}] -> [{newTile.Wall}]");
UpdateServerTileState(tile, newTile, TileDataType.Wall); UpdateServerTileState(tile, newTile, TileDataType.Wall);
} }
} }
@ -554,27 +554,27 @@ namespace TShockAPI.Handlers
{ {
if (args.Player.HasPermission(Permissions.allowclientsideworldedit)) if (args.Player.HasPermission(Permissions.allowclientsideworldedit))
{ {
TShock.Log.ConsoleDebug("Bouncer / SendTileRect accepted clientside world edit from {0}", args.Player.Name); TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect accepted clientside world edit from {args.Player.Name}"));
args.Handled = false; args.Handled = false;
return true; return true;
} }
if (args.Width > 4 || args.Length > 4) // as of 1.4.3.6 this is the biggest size the client will send in any case if (args.Width > 4 || args.Length > 4) // as of 1.4.3.6 this is the biggest size the client will send in any case
{ {
TShock.Log.ConsoleDebug("Bouncer / SendTileRect rejected from non-vanilla tilemod from {0}", args.Player.Name); TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect rejected from non-vanilla tilemod from {args.Player.Name}"));
return true; return true;
} }
if (args.Player.IsBouncerThrottled()) if (args.Player.IsBouncerThrottled())
{ {
TShock.Log.ConsoleDebug("Bouncer / SendTileRect rejected from throttle from {0}", args.Player.Name); TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect rejected from throttle from {args.Player.Name}"));
args.Player.SendTileRect(args.TileX, args.TileY, args.Length, args.Width); args.Player.SendTileRect(args.TileX, args.TileY, args.Length, args.Width);
return true; return true;
} }
if (args.Player.IsBeingDisabled()) if (args.Player.IsBeingDisabled())
{ {
TShock.Log.ConsoleDebug("Bouncer / SendTileRect rejected from being disabled from {0}", args.Player.Name); TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect rejected from being disabled from {args.Player.Name}"));
args.Player.SendTileRect(args.TileX, args.TileY, args.Length, args.Width); args.Player.SendTileRect(args.TileX, args.TileY, args.Length, args.Width);
return true; return true;
} }
@ -606,7 +606,7 @@ namespace TShockAPI.Handlers
} }
} }
TShock.Log.ConsoleDebug("Bouncer / SendTileRectHandler - rejected tile object because object dimensions fall outside the tile rect (excessive size)"); TShock.Log.ConsoleDebug(GetString("Bouncer / SendTileRectHandler - rejected tile object because object dimensions fall outside the tile rect (excessive size)"));
return false; return false;
} }

View file

@ -20,7 +20,7 @@ namespace TShockAPI.Handlers
if (args.TileX > Main.maxTilesX || args.TileX < 0 if (args.TileX > Main.maxTilesX || args.TileX < 0
|| args.TileY > Main.maxTilesY || args.TileY < 0) || args.TileY > Main.maxTilesY || args.TileY < 0)
{ {
TShock.Log.ConsoleDebug($"SyncTilePickingHandler: X and Y position is out of world bounds! - From {args.Player.Name}"); TShock.Log.ConsoleDebug(GetString($"SyncTilePickingHandler: X and Y position is out of world bounds! - From {args.Player.Name}"));
args.Handled = true; args.Handled = true;
return; return;
} }

View file

@ -50,6 +50,19 @@ namespace TShockAPI
/// <param name="args">The format arguments.</param> /// <param name="args">The format arguments.</param>
void ConsoleInfo(string format, params object[] args); void ConsoleInfo(string format, params object[] args);
/// <summary>
/// Writes a warning message to the log and to the console.
/// </summary>
/// <param name="message">The message to be written.</param>
void ConsoleWarn(string message);
/// <summary>
/// Writes a warning message to the log and to the console.
/// </summary>
/// <param name="format">The format of the message to be written.</param>
/// <param name="args">The format arguments.</param>
void ConsoleWarn(string format, params object[] args);
/// <summary> /// <summary>
/// Writes an error message to the log and to the console. /// Writes an error message to the log and to the console.
/// </summary> /// </summary>

View file

@ -53,7 +53,7 @@ namespace TShockAPI.Modules
public void InitialiseModule(Type moduleType, object[] parameters) public void InitialiseModule(Type moduleType, object[] parameters)
{ {
if (!typeof(Module).IsAssignableFrom(moduleType)) if (!typeof(Module).IsAssignableFrom(moduleType))
throw new NotSupportedException($"Cannot load module {moduleType.FullName} as it does not derive from {typeof(Module).FullName}"); throw new NotSupportedException(GetString($"Cannot load module {moduleType.FullName} as it does not derive from {typeof(Module).FullName}"));
var args = new List<object>(); var args = new List<object>();
ConstructorInfo constructor = null; ConstructorInfo constructor = null;

View file

@ -26,7 +26,7 @@ namespace TShockAPI.Net
{ {
public virtual PacketTypes ID public virtual PacketTypes ID
{ {
get { throw new NotImplementedException("Msg ID not implemented"); } get { throw new NotImplementedException(GetString("Msg ID not implemented")); }
} }
public void PackFull(Stream stream) public void PackFull(Stream stream)
@ -51,4 +51,4 @@ namespace TShockAPI.Net
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
} }

View file

@ -242,9 +242,9 @@ namespace Rests
} }
catch (Exception ex) catch (Exception ex)
{ {
TShock.Log.Error("Fatal Startup Exception"); TShock.Log.Error(GetString("Fatal Startup Exception"));
TShock.Log.Error(ex.ToString()); TShock.Log.Error(ex.ToString());
TShock.Log.ConsoleError("Invalid REST configuration: \nYou may already have a REST service bound to port {0}. \nPlease adjust your configuration and restart the server. \nPress any key to exit.", Port); TShock.Log.ConsoleError(GetString("Invalid REST configuration: \nYou may already have a REST service bound to port {0}. \nPlease adjust your configuration and restart the server. \nPress any key to exit.", Port));
Console.ReadLine(); Console.ReadLine();
Environment.Exit(1); Environment.Exit(1);
} }
@ -423,14 +423,14 @@ namespace Rests
{ {
return new RestObject("500") return new RestObject("500")
{ {
{"error", "Internal server error."}, {"error", GetString("Internal server error.") },
{"errormsg", exception.Message}, {"errormsg", exception.Message},
{"stacktrace", exception.StackTrace}, {"stacktrace", exception.StackTrace},
}; };
} }
return new RestObject("404") return new RestObject("404")
{ {
{"error", "Specified API endpoint doesn't exist. Refer to the documentation for a list of valid endpoints."} {"error", GetString("Specified API endpoint doesn't exist. Refer to the documentation for a list of valid endpoints.") }
}; };
} }
@ -448,7 +448,8 @@ namespace Rests
object result = cmd.Execute(verbs, parms, request, context); object result = cmd.Execute(verbs, parms, request, context);
if (cmd.DoLog && TShock.Config.Settings.LogRest) if (cmd.DoLog && TShock.Config.Settings.LogRest)
{ {
TShock.Log.ConsoleInfo("Anonymous requested REST endpoint: " + BuildRequestUri(cmd, verbs, parms, false)); var endpoint = BuildRequestUri(cmd, verbs, parms, false);
TShock.Log.ConsoleInfo(GetString($"Anonymous requested REST endpoint: {endpoint}"));
} }
return result; return result;
@ -479,7 +480,7 @@ namespace Rests
requestBuilder.Append(param.Value); requestBuilder.Append(param.Value);
separator = '&'; separator = '&';
} }
return requestBuilder.ToString(); return requestBuilder.ToString();
} }

View file

@ -92,15 +92,15 @@ namespace Rests
public override object Execute(RestVerbs verbs, IParameterCollection parameters, IRequest request, IHttpContext context) public override object Execute(RestVerbs verbs, IParameterCollection parameters, IRequest request, IHttpContext context)
{ {
return new RestObject("401") { Error = "Not authorized. The specified API endpoint requires a token." }; return new RestObject("401") { Error = GetString("Not authorized. The specified API endpoint requires a token.") };
} }
public object Execute(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData, IRequest request, IHttpContext context) public object Execute(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData, IRequest request, IHttpContext context)
{ {
if (tokenData.Equals(SecureRest.TokenData.None)) if (tokenData.Equals(SecureRest.TokenData.None))
return new RestObject("401") { Error = "Not authorized. The specified API endpoint requires a token." }; return new RestObject("401") { Error = GetString("Not authorized. The specified API endpoint requires a token.") };
return callback(new RestRequestArgs(verbs, parameters, request, tokenData, context)); return callback(new RestRequestArgs(verbs, parameters, request, tokenData, context));
} }
} }
} }

View file

@ -155,7 +155,7 @@ namespace TShockAPI
/// <summary> /// <summary>
/// Creates a new instance of <see cref="Token"/> /// Creates a new instance of <see cref="Token"/>
/// </summary> /// </summary>
public Token() : base("token", true, "The REST authentication token.", typeof(String)) { } public Token() : base("token", true, GetString("The REST authentication token."), typeof(String)) { }
} }
/// <summary> /// <summary>
@ -665,10 +665,10 @@ namespace TShockAPI
player.Kick(reason, true); player.Kick(reason, true);
} }
return RestResponse($"Ban added. Ticket number: {banResult.Ban.TicketNumber}"); return RestResponse(GetString($"Ban added. Ticket number: {banResult.Ban.TicketNumber}"));
} }
return RestError($"Failed to add ban. {banResult.Message}", status: "500"); return RestError(GetString($"Failed to add ban. {banResult.Message}"), status: "500");
} }
[Description("Delete an existing ban entry.")] [Description("Delete an existing ban entry.")]
@ -692,10 +692,10 @@ namespace TShockAPI
if (TShock.Bans.RemoveBan(ticketNumber, fullDelete)) if (TShock.Bans.RemoveBan(ticketNumber, fullDelete))
{ {
return RestResponse("Ban removed."); return RestResponse(GetString("Ban removed."));
} }
return RestError("Failed to remove ban.", status: "500"); return RestError(GetString("Failed to remove ban."), status: "500");
} }
[Description("View the details of a specific ban.")] [Description("View the details of a specific ban.")]
@ -718,7 +718,7 @@ namespace TShockAPI
if (ban == null) if (ban == null)
{ {
return RestResponse("No matching bans found."); return RestResponse(GetString("No matching bans found."));
} }
return new RestObject return new RestObject
@ -777,7 +777,7 @@ namespace TShockAPI
return RestInvalidParam("state"); return RestInvalidParam("state");
TShock.Config.Settings.AutoSave = autoSave; TShock.Config.Settings.AutoSave = autoSave;
var resp = RestResponse("AutoSave has been set to " + autoSave); var resp = RestResponse($"AutoSave has been set to {autoSave}");
resp.Add("upgrade", "/v3/world/autosave"); resp.Add("upgrade", "/v3/world/autosave");
return resp; return resp;
} }
@ -791,11 +791,25 @@ namespace TShockAPI
bool autoSave; bool autoSave;
if (!bool.TryParse(args.Parameters["state"], out autoSave)) if (!bool.TryParse(args.Parameters["state"], out autoSave))
{ {
return RestResponse($"Autosave is currently {(TShock.Config.Settings.AutoSave ? "enabled" : "disabled")}"); if (TShock.Config.Settings.AutoSave)
{
return RestResponse(GetString($"Autosave is currently enabled"));
}
else
{
return RestResponse(GetString($"Autosave is currently disabled"));
}
} }
TShock.Config.Settings.AutoSave = autoSave; TShock.Config.Settings.AutoSave = autoSave;
return RestResponse($"AutoSave has been {(TShock.Config.Settings.AutoSave ? "enabled" : "disabled")}"); if (TShock.Config.Settings.AutoSave)
{
return RestResponse(GetString($"AutoSave has been enabled"));
}
else
{
return RestResponse(GetString($"AutoSave has been disabled"));
}
} }
[Description("Save the world.")] [Description("Save the world.")]
@ -830,7 +844,7 @@ namespace TShockAPI
} }
} }
return RestResponse(killcount + " NPCs have been killed"); return RestResponse(GetPluralString($"{killcount} NPC has been killed.", "{killcount} NPCs have been killed.", killcount));
} }
[Description("Get information regarding the world.")] [Description("Get information regarding the world.")]
@ -857,7 +871,7 @@ namespace TShockAPI
{ {
WorldGen.spawnMeteor = false; WorldGen.spawnMeteor = false;
WorldGen.dropMeteor(); WorldGen.dropMeteor();
return RestResponse("Meteor has been spawned"); return RestResponse(GetString("Meteor has been spawned"));
} }
[Description("Toggle the status of blood moon.")] [Description("Toggle the status of blood moon.")]
@ -872,7 +886,7 @@ namespace TShockAPI
return RestInvalidParam("bloodmoon"); return RestInvalidParam("bloodmoon");
Main.bloodMoon = bloodmoon; Main.bloodMoon = bloodmoon;
var resp = RestResponse("Blood Moon has been set to " + bloodmoon); var resp = RestResponse(GetString($"Blood Moon has been set to {bloodmoon}"));
resp.Add("upgrade", "/v3/world/bloodmoon"); resp.Add("upgrade", "/v3/world/bloodmoon");
return resp; return resp;
} }
@ -887,11 +901,18 @@ namespace TShockAPI
bool bloodmoon; bool bloodmoon;
if (!bool.TryParse(args.Verbs["state"], out bloodmoon)) if (!bool.TryParse(args.Verbs["state"], out bloodmoon))
{ {
return RestResponse($"Bloodmoon state: {(Main.bloodMoon ? "Enabled" : "Disabled")}"); return RestResponse(GetString($"Bloodmoon state: {(Main.bloodMoon ? "Enabled" : "Disabled")}"));
} }
Main.bloodMoon = bloodmoon; Main.bloodMoon = bloodmoon;
return RestResponse($"Blood Moon has been {(Main.bloodMoon ? "enabled" : "disabled")}"); if (Main.bloodMoon)
{
return RestResponse($"Blood Moon has been enabled");
}
else
{
return RestResponse($"Blood Moon has been disabled");
}
} }
#endregion #endregion
@ -1025,8 +1046,8 @@ namespace TShockAPI
return ret; return ret;
TSPlayer player = (TSPlayer)ret; TSPlayer player = (TSPlayer)ret;
player.Kick(null == args.Parameters["reason"] ? "Kicked via web" : args.Parameters["reason"], false, true, null, true); player.Kick(null == args.Parameters["reason"] ? GetString("Kicked via web") : args.Parameters["reason"], false, true, null, true);
return RestResponse("Player " + player.Name + " was kicked"); return RestResponse($"Player {player.Name} was kicked");
} }
[Description("Kill a player.")] [Description("Kill a player.")]
@ -1044,8 +1065,8 @@ namespace TShockAPI
TSPlayer player = (TSPlayer)ret; TSPlayer player = (TSPlayer)ret;
player.DamagePlayer(999999); player.DamagePlayer(999999);
var from = string.IsNullOrWhiteSpace(args.Parameters["from"]) ? "Server Admin" : args.Parameters["from"]; var from = string.IsNullOrWhiteSpace(args.Parameters["from"]) ? "Server Admin" : args.Parameters["from"];
player.SendInfoMessage(string.Format("{0} just killed you!", from)); player.SendInfoMessage(GetString($"{from} just killed you!"));
return RestResponse("Player " + player.Name + " was killed"); return RestResponse(GetString($"Player {player.Name} was killed"));
} }
#endregion #endregion
@ -1109,7 +1130,7 @@ namespace TShockAPI
return RestError(e.Message); return RestError(e.Message);
} }
return RestResponse("Group '" + group.Name + "' deleted successfully"); return RestResponse(GetString($"Group {group.Name} deleted successfully"));
} }
[Description("Create a new group.")] [Description("Create a new group.")]
@ -1134,7 +1155,7 @@ namespace TShockAPI
return RestError(e.Message); return RestError(e.Message);
} }
return RestResponse("Group '" + name + "' created successfully"); return RestResponse(GetString($"Group {name} created successfully"));
} }
[Route("/v2/groups/update")] [Route("/v2/groups/update")]
@ -1163,13 +1184,14 @@ namespace TShockAPI
return RestError(e.Message); return RestError(e.Message);
} }
return RestResponse("Group '" + group.Name + "' updated successfully"); return RestResponse(GetString($"Group {group.Name} updated successfully"));
} }
#endregion #endregion
#region Utility Methods #region Utility Methods
// TODO: figure out how to localise the route descriptions
public static void DumpDescriptions() public static void DumpDescriptions()
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
@ -1243,7 +1265,7 @@ namespace TShockAPI
private RestObject RestMissingParam(string var) private RestObject RestMissingParam(string var)
{ {
return RestError("Missing or empty " + var + " parameter"); return RestError(GetString($"Missing or empty {var} parameter"));
} }
private RestObject RestMissingParam(params string[] vars) private RestObject RestMissingParam(params string[] vars)
@ -1253,7 +1275,7 @@ namespace TShockAPI
private RestObject RestInvalidParam(string var) private RestObject RestInvalidParam(string var)
{ {
return RestError("Missing or invalid " + var + " parameter"); return RestError(GetString($"Missing or invalid {var} parameter"));
} }
private bool GetBool(string val, bool def) private bool GetBool(string val, bool def)
@ -1274,9 +1296,9 @@ namespace TShockAPI
case 1: case 1:
return found[0]; return found[0];
case 0: case 0:
return RestError("Player " + name + " was not found"); return RestError(GetString($"Player {name} was not found"));
default: default:
return RestError("Player " + name + " matches " + found.Count + " players"); return RestError(GetPluralString($"Player {name} matches {found.Count} player", $"Player {name} matches {found.Count} players", found.Count));
} }
} }
@ -1301,7 +1323,7 @@ namespace TShockAPI
account = TShock.UserAccounts.GetUserAccountByID(Convert.ToInt32(name)); account = TShock.UserAccounts.GetUserAccountByID(Convert.ToInt32(name));
break; break;
default: default:
return RestError("Invalid Type: '" + type + "'"); return RestError(GetString($"Invalid Type: '{type}'"));
} }
} }
catch (Exception e) catch (Exception e)
@ -1310,7 +1332,7 @@ namespace TShockAPI
} }
if (null == account) if (null == account)
return RestError(String.Format("User {0} '{1}' doesn't exist", type, name)); return RestError(GetString($"User {type} '{name}' doesn't exist"));
return account; return account;
} }
@ -1323,7 +1345,7 @@ namespace TShockAPI
var group = TShock.Groups.GetGroupByName(name); var group = TShock.Groups.GetGroupByName(name);
if (null == group) if (null == group)
return RestError("Group '" + name + "' doesn't exist"); return RestError(GetString($"Group {name} doesn't exist"));
return group; return group;
} }
@ -1360,9 +1382,16 @@ namespace TShockAPI
TSPlayer player = (TSPlayer)ret; TSPlayer player = (TSPlayer)ret;
player.mute = mute; player.mute = mute;
var verb = mute ? "muted" : "unmuted"; if (mute)
player.SendInfoMessage("You have been remotely " + verb); {
return RestResponse("Player " + player.Name + " was " + verb); player.SendInfoMessage(GetString("You have been remotely muted"));
return RestResponse(GetString($"Player {player.Name} has been muted"));
}
else
{
player.SendInfoMessage(GetString("You have been remotely unmmuted"));
return RestResponse(GetString($"Player {player.Name} has been unmuted"));
}
} }
#endregion #endregion

View file

@ -87,10 +87,10 @@ namespace Rests
catch (Exception) catch (Exception)
{ {
return new RestObject("400") return new RestObject("400")
{ Error = "The specified token queued for destruction failed to be deleted." }; { Error = GetString("The specified token queued for destruction failed to be deleted.") };
} }
return new RestObject() return new RestObject()
{ Response = "Requested token was successfully destroyed." }; { Response = GetString("Requested token was successfully destroyed.") };
} }
private object DestroyAllTokens(RestRequestArgs args) private object DestroyAllTokens(RestRequestArgs args)
@ -117,7 +117,7 @@ namespace Rests
{ {
if (tokens >= TShock.Config.Settings.RESTMaximumRequestsPerInterval) if (tokens >= TShock.Config.Settings.RESTMaximumRequestsPerInterval)
{ {
TShock.Log.ConsoleError("A REST login from {0} was blocked as it currently has {1} rate-limit tokens and is at the RESTMaximumRequestsPerInterval threshold.", context.RemoteEndPoint.Address.ToString(), tokens); TShock.Log.ConsoleError(GetString("A REST login from {0} was blocked as it currently has {1} rate-limit tokens and is at the RESTMaximumRequestsPerInterval threshold.", context.RemoteEndPoint.Address.ToString(), tokens));
tokenBucket[context.RemoteEndPoint.Address.ToString()] += 1; // Tokens over limit, increment by one and reject request tokenBucket[context.RemoteEndPoint.Address.ToString()] += 1; // Tokens over limit, increment by one and reject request
return new RestObject("403") return new RestObject("403")
{ {
@ -135,13 +135,13 @@ namespace Rests
if (userAccount == null) if (userAccount == null)
{ {
AddTokenToBucket(context.RemoteEndPoint.Address.ToString()); AddTokenToBucket(context.RemoteEndPoint.Address.ToString());
return new RestObject("403") { Error = "Username or password may be incorrect or this account may not have sufficient privileges." }; return new RestObject("403") { Error = GetString("Username or password may be incorrect or this account may not have sufficient privileges.") };
} }
if (!userAccount.VerifyPassword(password)) if (!userAccount.VerifyPassword(password))
{ {
AddTokenToBucket(context.RemoteEndPoint.Address.ToString()); AddTokenToBucket(context.RemoteEndPoint.Address.ToString());
return new RestObject("403") { Error = "Username or password may be incorrect or this account may not have sufficient privileges." }; return new RestObject("403") { Error = GetString("Username or password may be incorrect or this account may not have sufficient privileges.") };
} }
Group userGroup = TShock.Groups.GetGroupByName(userAccount.Group); Group userGroup = TShock.Groups.GetGroupByName(userAccount.Group);
@ -149,7 +149,7 @@ namespace Rests
{ {
AddTokenToBucket(context.RemoteEndPoint.Address.ToString()); AddTokenToBucket(context.RemoteEndPoint.Address.ToString());
return new RestObject("403") return new RestObject("403")
{ Error = "Username or password may be incorrect or this account may not have sufficient privileges." }; { Error = GetString("Username or password may be incorrect or this account may not have sufficient privileges.") };
} }
string tokenHash; string tokenHash;
@ -164,7 +164,7 @@ namespace Rests
AddTokenToBucket(context.RemoteEndPoint.Address.ToString()); AddTokenToBucket(context.RemoteEndPoint.Address.ToString());
RestObject response = new RestObject() { Response = "Successful login" }; RestObject response = new RestObject() { Response = GetString("Successful login") };
response["token"] = tokenHash; response["token"] = tokenHash;
return response; return response;
} }
@ -177,13 +177,13 @@ namespace Rests
var token = parms["token"]; var token = parms["token"];
if (token == null) if (token == null)
return new RestObject("401") return new RestObject("401")
{ Error = "Not authorized. The specified API endpoint requires a token." }; { Error = GetString("Not authorized. The specified API endpoint requires a token.") };
SecureRestCommand secureCmd = (SecureRestCommand)cmd; SecureRestCommand secureCmd = (SecureRestCommand)cmd;
TokenData tokenData; TokenData tokenData;
if (!Tokens.TryGetValue(token, out tokenData) && !AppTokens.TryGetValue(token, out tokenData)) if (!Tokens.TryGetValue(token, out tokenData) && !AppTokens.TryGetValue(token, out tokenData))
return new RestObject("403") return new RestObject("403")
{ Error = "Not authorized. The specified API endpoint requires a token, but the provided token was not valid." }; { Error = GetString("Not authorized. The specified API endpoint requires a token, but the provided token was not valid.") };
Group userGroup = TShock.Groups.GetGroupByName(tokenData.UserGroupName); Group userGroup = TShock.Groups.GetGroupByName(tokenData.UserGroupName);
if (userGroup == null) if (userGroup == null)
@ -191,13 +191,13 @@ namespace Rests
Tokens.Remove(token); Tokens.Remove(token);
return new RestObject("403") return new RestObject("403")
{ Error = "Not authorized. The provided token became invalid due to group changes, please create a new token." }; { Error = GetString("Not authorized. The provided token became invalid due to group changes, please create a new token.") };
} }
if (secureCmd.Permissions.Length > 0 && secureCmd.Permissions.All(perm => !userGroup.HasPermission(perm))) if (secureCmd.Permissions.Length > 0 && secureCmd.Permissions.All(perm => !userGroup.HasPermission(perm)))
{ {
return new RestObject("403") return new RestObject("403")
{ Error = string.Format("Not authorized. User \"{0}\" has no access to use the specified API endpoint.", tokenData.Username) }; { Error = GetString("Not authorized. User \"{0}\" has no access to use the specified API endpoint.", tokenData.Username) };
} }
//Main.rand being null can cause issues in command execution. //Main.rand being null can cause issues in command execution.
@ -209,7 +209,7 @@ namespace Rests
object result = secureCmd.Execute(verbs, parms, tokenData, request, context); object result = secureCmd.Execute(verbs, parms, tokenData, request, context);
if (cmd.DoLog && TShock.Config.Settings.LogRest) if (cmd.DoLog && TShock.Config.Settings.LogRest)
TShock.Utils.SendLogs(string.Format( TShock.Utils.SendLogs(GetString(
"\"{0}\" requested REST endpoint: {1}", tokenData.Username, this.BuildRequestUri(cmd, verbs, parms, false)), "\"{0}\" requested REST endpoint: {1}", tokenData.Username, this.BuildRequestUri(cmd, verbs, parms, false)),
Color.PaleVioletRed); Color.PaleVioletRed);

View file

@ -145,6 +145,28 @@ namespace TShockAPI
ConsoleError(string.Format(format, args)); ConsoleError(string.Format(format, args));
} }
/// <summary>
/// Writes an error to the log file.
/// </summary>
/// <param name="message">The message to be written.</param>
public void ConsoleWarn(string message)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(message);
Console.ForegroundColor = ConsoleColor.Gray;
Write(message, TraceLevel.Warning);
}
/// <summary>
/// Writes an error to the log file.
/// </summary>
/// <param name="format">The format of the message to be written.</param>
/// <param name="args">The format arguments.</param>
public void ConsoleWarn(string format, params object[] args)
{
ConsoleWarn(string.Format(format, args));
}
/// <summary> /// <summary>
/// Writes a warning to the log file. /// Writes a warning to the log file.
/// </summary> /// </summary>

View file

@ -102,6 +102,28 @@ namespace TShockAPI
Write(message, TraceLevel.Error); Write(message, TraceLevel.Error);
} }
/// <summary>
/// Writes an error to the log file.
/// </summary>
/// <param name="message">The message to be written.</param>
public void ConsoleWarn(string message)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(message);
Console.ForegroundColor = ConsoleColor.Gray;
Write(message, TraceLevel.Warning);
}
/// <summary>
/// Writes an error to the log file.
/// </summary>
/// <param name="format">The format of the message to be written.</param>
/// <param name="args">The format arguments.</param>
public void ConsoleWarn(string format, params object[] args)
{
ConsoleWarn(string.Format(format, args));
}
/// <summary> /// <summary>
/// Writes an error to the log file. /// Writes an error to the log file.
/// </summary> /// </summary>