Line ending normalization to CRLF (Windows)
This commit is contained in:
parent
f82bff1b17
commit
9470e20423
16 changed files with 1859 additions and 1854 deletions
5
.gitattributes
vendored
Normal file
5
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
* text=auto
|
||||
*.cs text eol=crlf
|
||||
*.sln text eol=crlf
|
||||
*.csproj text eol=crlf
|
||||
*.vsmdi text eol=crlf
|
||||
|
|
@ -244,8 +244,8 @@ namespace TShockAPI
|
|||
add(Permissions.savessi, SaveSSI, "savessi");
|
||||
add(Permissions.savessi, OverrideSSI, "overridessi", "ossi");
|
||||
add(Permissions.xmas, ForceXmas, "forcexmas");
|
||||
add(Permissions.settempgroup, TempGroup, "tempgroup");
|
||||
add(null, Aliases, "aliases");
|
||||
add(Permissions.settempgroup, TempGroup, "tempgroup");
|
||||
add(null, Aliases, "aliases");
|
||||
add(Rests.RestPermissions.restmanage, ManageRest, "rest");
|
||||
//add(null, TestCallbackCommand, "test");
|
||||
|
||||
|
|
@ -1284,11 +1284,11 @@ namespace TShockAPI
|
|||
|
||||
private static void Broadcast(CommandArgs args)
|
||||
{
|
||||
string message = string.Join(" ", args.Parameters);
|
||||
string message = string.Join(" ", args.Parameters);
|
||||
|
||||
TShock.Utils.Broadcast(
|
||||
"(Server Broadcast) " + message,
|
||||
Convert.ToByte(TShock.Config.BroadcastRGB[0]), Convert.ToByte(TShock.Config.BroadcastRGB[1]),
|
||||
TShock.Utils.Broadcast(
|
||||
"(Server Broadcast) " + message,
|
||||
Convert.ToByte(TShock.Config.BroadcastRGB[0]), Convert.ToByte(TShock.Config.BroadcastRGB[1]),
|
||||
Convert.ToByte(TShock.Config.BroadcastRGB[2]));
|
||||
}
|
||||
|
||||
|
|
@ -1318,7 +1318,7 @@ namespace TShockAPI
|
|||
}
|
||||
else
|
||||
{
|
||||
string reason = ((args.Parameters.Count > 0) ? "Server shutting down: " + String.Join(" ", args.Parameters) : "Server shutting down!");
|
||||
string reason = ((args.Parameters.Count > 0) ? "Server shutting down: " + String.Join(" ", args.Parameters) : "Server shutting down!");
|
||||
TShock.Utils.RestartServer(true, reason);
|
||||
}
|
||||
}
|
||||
|
|
@ -1340,57 +1340,57 @@ namespace TShockAPI
|
|||
args.Player.SendInfoMessage("Starting plugin update process:");
|
||||
args.Player.SendInfoMessage("This may take a while, do not turn off the server!");
|
||||
new PluginUpdaterThread(args.Player);
|
||||
}
|
||||
|
||||
private static void ManageRest(CommandArgs args)
|
||||
{
|
||||
string subCommand = "help";
|
||||
if (args.Parameters.Count > 0)
|
||||
subCommand = args.Parameters[0];
|
||||
}
|
||||
|
||||
switch(subCommand.ToLower())
|
||||
{
|
||||
case "listusers":
|
||||
{
|
||||
int pageNumber;
|
||||
if (!PaginationTools.TryParsePageNumber(args.Parameters, 1, args.Player, out pageNumber))
|
||||
return;
|
||||
|
||||
Dictionary<string,int> restUsersTokens = new Dictionary<string,int>();
|
||||
foreach (Rests.SecureRest.TokenData tokenData in TShock.RestApi.Tokens.Values)
|
||||
{
|
||||
if (restUsersTokens.ContainsKey(tokenData.Username))
|
||||
restUsersTokens[tokenData.Username]++;
|
||||
else
|
||||
restUsersTokens.Add(tokenData.Username, 1);
|
||||
}
|
||||
|
||||
List<string> restUsers = new List<string>(
|
||||
restUsersTokens.Select(ut => string.Format("{0} ({1} tokens)", ut.Key, ut.Value)));
|
||||
|
||||
PaginationTools.SendPage(
|
||||
args.Player, pageNumber, PaginationTools.BuildLinesFromTerms(restUsers), new PaginationTools.Settings {
|
||||
NothingToDisplayString = "There are currently no active REST users.",
|
||||
HeaderFormat = "Active REST Users ({0}/{1}):",
|
||||
FooterFormat = "Type /rest listusers {0} for more."
|
||||
}
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
case "destroytokens":
|
||||
{
|
||||
TShock.RestApi.Tokens.Clear();
|
||||
args.Player.SendSuccessMessage("All REST tokens have been destroyed.");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
args.Player.SendInfoMessage("Available REST Sub-Commands:");
|
||||
args.Player.SendMessage("listusers - Lists all REST users and their current active tokens.", Color.White);
|
||||
args.Player.SendMessage("destroytokens - Destroys all current REST tokens.", Color.White);
|
||||
break;
|
||||
}
|
||||
private static void ManageRest(CommandArgs args)
|
||||
{
|
||||
string subCommand = "help";
|
||||
if (args.Parameters.Count > 0)
|
||||
subCommand = args.Parameters[0];
|
||||
|
||||
switch(subCommand.ToLower())
|
||||
{
|
||||
case "listusers":
|
||||
{
|
||||
int pageNumber;
|
||||
if (!PaginationTools.TryParsePageNumber(args.Parameters, 1, args.Player, out pageNumber))
|
||||
return;
|
||||
|
||||
Dictionary<string,int> restUsersTokens = new Dictionary<string,int>();
|
||||
foreach (Rests.SecureRest.TokenData tokenData in TShock.RestApi.Tokens.Values)
|
||||
{
|
||||
if (restUsersTokens.ContainsKey(tokenData.Username))
|
||||
restUsersTokens[tokenData.Username]++;
|
||||
else
|
||||
restUsersTokens.Add(tokenData.Username, 1);
|
||||
}
|
||||
|
||||
List<string> restUsers = new List<string>(
|
||||
restUsersTokens.Select(ut => string.Format("{0} ({1} tokens)", ut.Key, ut.Value)));
|
||||
|
||||
PaginationTools.SendPage(
|
||||
args.Player, pageNumber, PaginationTools.BuildLinesFromTerms(restUsers), new PaginationTools.Settings {
|
||||
NothingToDisplayString = "There are currently no active REST users.",
|
||||
HeaderFormat = "Active REST Users ({0}/{1}):",
|
||||
FooterFormat = "Type /rest listusers {0} for more."
|
||||
}
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
case "destroytokens":
|
||||
{
|
||||
TShock.RestApi.Tokens.Clear();
|
||||
args.Player.SendSuccessMessage("All REST tokens have been destroyed.");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
args.Player.SendInfoMessage("Available REST Sub-Commands:");
|
||||
args.Player.SendMessage("listusers - Lists all REST users and their current active tokens.", Color.White);
|
||||
args.Player.SendMessage("destroytokens - Destroys all current REST tokens.", Color.White);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2044,8 +2044,8 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
#endregion
|
||||
return;
|
||||
|
||||
return;
|
||||
|
||||
case "parent":
|
||||
#region Parent
|
||||
{
|
||||
|
|
@ -2053,45 +2053,45 @@ namespace TShockAPI
|
|||
{
|
||||
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /group parent <group name> [new parent group name]");
|
||||
return;
|
||||
}
|
||||
|
||||
string groupName = args.Parameters[1];
|
||||
Group group = TShock.Groups.GetGroupByName(groupName);
|
||||
if (group == null)
|
||||
{
|
||||
args.Player.SendErrorMessage("No such group \"{0}\".", groupName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.Parameters.Count > 2)
|
||||
{
|
||||
string newParentGroupName = string.Join(" ", args.Parameters.Skip(2));
|
||||
if (!string.IsNullOrWhiteSpace(newParentGroupName) && !TShock.Groups.GroupExists(newParentGroupName))
|
||||
{
|
||||
args.Player.SendErrorMessage("No such group \"{0}\".", newParentGroupName);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
TShock.Groups.UpdateGroup(groupName, newParentGroupName, group.Permissions, group.ChatColor);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(newParentGroupName))
|
||||
args.Player.SendSuccessMessage("Parent of group \"{0}\" set to \"{1}\".", groupName, newParentGroupName);
|
||||
else
|
||||
args.Player.SendSuccessMessage("Removed parent of group \"{0}\".", groupName);
|
||||
}
|
||||
catch (GroupManagerException ex)
|
||||
{
|
||||
args.Player.SendErrorMessage(ex.Message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (group.Parent != null)
|
||||
args.Player.SendSuccessMessage("Parent of \"{0}\" is \"{1}\".", group.Name, group.Parent.Name);
|
||||
else
|
||||
args.Player.SendSuccessMessage("Group \"{0}\" has no parent.", group.Name);
|
||||
}
|
||||
|
||||
string groupName = args.Parameters[1];
|
||||
Group group = TShock.Groups.GetGroupByName(groupName);
|
||||
if (group == null)
|
||||
{
|
||||
args.Player.SendErrorMessage("No such group \"{0}\".", groupName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.Parameters.Count > 2)
|
||||
{
|
||||
string newParentGroupName = string.Join(" ", args.Parameters.Skip(2));
|
||||
if (!string.IsNullOrWhiteSpace(newParentGroupName) && !TShock.Groups.GroupExists(newParentGroupName))
|
||||
{
|
||||
args.Player.SendErrorMessage("No such group \"{0}\".", newParentGroupName);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
TShock.Groups.UpdateGroup(groupName, newParentGroupName, group.Permissions, group.ChatColor);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(newParentGroupName))
|
||||
args.Player.SendSuccessMessage("Parent of group \"{0}\" set to \"{1}\".", groupName, newParentGroupName);
|
||||
else
|
||||
args.Player.SendSuccessMessage("Removed parent of group \"{0}\".", groupName);
|
||||
}
|
||||
catch (GroupManagerException ex)
|
||||
{
|
||||
args.Player.SendErrorMessage(ex.Message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (group.Parent != null)
|
||||
args.Player.SendSuccessMessage("Parent of \"{0}\" is \"{1}\".", group.Name, group.Parent.Name);
|
||||
else
|
||||
args.Player.SendSuccessMessage("Group \"{0}\" has no parent.", group.Name);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
|
@ -2202,7 +2202,7 @@ namespace TShockAPI
|
|||
});
|
||||
}
|
||||
#endregion
|
||||
return;
|
||||
return;
|
||||
case "help":
|
||||
args.Player.SendInfoMessage("Syntax: /group <command> [arguments]");
|
||||
args.Player.SendInfoMessage("Commands: add, addperm, parent, del, delperm, list, listperm");
|
||||
|
|
@ -2413,7 +2413,7 @@ namespace TShockAPI
|
|||
|
||||
private static void Reload(CommandArgs args)
|
||||
{
|
||||
TShock.Utils.Reload(args.Player);
|
||||
TShock.Utils.Reload(args.Player);
|
||||
|
||||
args.Player.SendSuccessMessage(
|
||||
"Configuration, permissions, and regions reload complete. Some changes may require a server restart.");
|
||||
|
|
@ -3457,8 +3457,8 @@ namespace TShockAPI
|
|||
args.Player.SendSuccessMessage("Annoying " + ply.Name + " for " + annoy + " seconds.");
|
||||
(new Thread(ply.Whoopie)).Start(annoy);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void Aliases(CommandArgs args)
|
||||
{
|
||||
if (args.Parameters.Count < 1)
|
||||
|
|
@ -3466,31 +3466,31 @@ namespace TShockAPI
|
|||
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /aliases <command or alias>");
|
||||
return;
|
||||
}
|
||||
|
||||
string givenCommandName = string.Join(" ", args.Parameters);
|
||||
if (string.IsNullOrWhiteSpace(givenCommandName)) {
|
||||
args.Player.SendErrorMessage("Please enter a proper command name or alias.");
|
||||
return;
|
||||
}
|
||||
|
||||
string commandName;
|
||||
if (givenCommandName[0] == '/')
|
||||
commandName = givenCommandName.Substring(1);
|
||||
else
|
||||
commandName = givenCommandName;
|
||||
|
||||
bool didMatch = false;
|
||||
foreach (Command matchingCommand in ChatCommands.Where(cmd => cmd.Names.IndexOf(commandName) != -1)) {
|
||||
if (matchingCommand.Names.Count > 1)
|
||||
args.Player.SendInfoMessage(
|
||||
"Aliases of /{0}: /{1}", matchingCommand.Name, string.Join(", /", matchingCommand.Names.Skip(1)));
|
||||
else
|
||||
args.Player.SendInfoMessage("/{0} defines no aliases.", matchingCommand.Name);
|
||||
|
||||
didMatch = true;
|
||||
}
|
||||
|
||||
if (!didMatch)
|
||||
|
||||
string givenCommandName = string.Join(" ", args.Parameters);
|
||||
if (string.IsNullOrWhiteSpace(givenCommandName)) {
|
||||
args.Player.SendErrorMessage("Please enter a proper command name or alias.");
|
||||
return;
|
||||
}
|
||||
|
||||
string commandName;
|
||||
if (givenCommandName[0] == '/')
|
||||
commandName = givenCommandName.Substring(1);
|
||||
else
|
||||
commandName = givenCommandName;
|
||||
|
||||
bool didMatch = false;
|
||||
foreach (Command matchingCommand in ChatCommands.Where(cmd => cmd.Names.IndexOf(commandName) != -1)) {
|
||||
if (matchingCommand.Names.Count > 1)
|
||||
args.Player.SendInfoMessage(
|
||||
"Aliases of /{0}: /{1}", matchingCommand.Name, string.Join(", /", matchingCommand.Names.Skip(1)));
|
||||
else
|
||||
args.Player.SendInfoMessage("/{0} defines no aliases.", matchingCommand.Name);
|
||||
|
||||
didMatch = true;
|
||||
}
|
||||
|
||||
if (!didMatch)
|
||||
args.Player.SendErrorMessage("No command or command alias matching \"{0}\" found.", givenCommandName);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -251,9 +251,9 @@ namespace TShockAPI
|
|||
|
||||
[Description("The path of the directory where logs should be written into.")] public string LogPath = "tshock";
|
||||
|
||||
[Description("Prevents players from placing tiles with an invalid style.")] public bool PreventInvalidPlaceStyle = true;
|
||||
|
||||
[Description("#.#.#. = Red/Blue/Green - RGB Colors for broadcasts. Max value: 255.")] public float[] BroadcastRGB =
|
||||
[Description("Prevents players from placing tiles with an invalid style.")] public bool PreventInvalidPlaceStyle = true;
|
||||
|
||||
[Description("#.#.#. = Red/Blue/Green - RGB Colors for broadcasts. Max value: 255.")] public float[] BroadcastRGB =
|
||||
{127,255,212};
|
||||
|
||||
// TODO: Get rid of this when the old REST permission model is removed.
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
|
@ -166,7 +166,7 @@ namespace TShockAPI.DB
|
|||
/// <param name="permissions">permissions</param>
|
||||
/// <param name="chatcolor">chatcolor</param>
|
||||
public void UpdateGroup(string name, string parentname, string permissions, string chatcolor)
|
||||
{
|
||||
{
|
||||
Group group = GetGroupByName(name);
|
||||
if (group == null)
|
||||
throw new GroupNotExistException(name);
|
||||
|
|
@ -176,22 +176,22 @@ namespace TShockAPI.DB
|
|||
{
|
||||
parent = GetGroupByName(parentname);
|
||||
if (parent == null || parent == group)
|
||||
throw new GroupManagerException("Invalid parent \"{0}\" for group \"{1}\".".SFormat(parentname, name));
|
||||
|
||||
// Check if the new parent would cause loops.
|
||||
List<Group> groupChain = new List<Group> { group, parent };
|
||||
Group checkingGroup = parent.Parent;
|
||||
while (checkingGroup != null)
|
||||
{
|
||||
if (groupChain.Contains(checkingGroup))
|
||||
throw new GroupManagerException(
|
||||
string.Format("Invalid parent \"{0}\" for group \"{1}\" would cause loops in the parent chain.", parentname, name));
|
||||
|
||||
groupChain.Add(checkingGroup);
|
||||
checkingGroup = checkingGroup.Parent;
|
||||
}
|
||||
}
|
||||
|
||||
throw new GroupManagerException("Invalid parent \"{0}\" for group \"{1}\".".SFormat(parentname, name));
|
||||
|
||||
// Check if the new parent would cause loops.
|
||||
List<Group> groupChain = new List<Group> { group, parent };
|
||||
Group checkingGroup = parent.Parent;
|
||||
while (checkingGroup != null)
|
||||
{
|
||||
if (groupChain.Contains(checkingGroup))
|
||||
throw new GroupManagerException(
|
||||
string.Format("Invalid parent \"{0}\" for group \"{1}\" would cause loops in the parent chain.", parentname, name));
|
||||
|
||||
groupChain.Add(checkingGroup);
|
||||
checkingGroup = checkingGroup.Parent;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure any group validation is also persisted to the DB.
|
||||
var newGroup = new Group(name, parent, chatcolor, permissions);
|
||||
string query = "UPDATE GroupList SET Parent=@0, Commands=@1, ChatColor=@2 WHERE GroupName=@3";
|
||||
|
|
@ -265,107 +265,107 @@ namespace TShockAPI.DB
|
|||
}
|
||||
|
||||
public void LoadPermisions()
|
||||
{
|
||||
try
|
||||
{
|
||||
List<Group> newGroups = new List<Group>(groups.Count);
|
||||
Dictionary<string,string> newGroupParents = new Dictionary<string, string>(groups.Count);
|
||||
{
|
||||
try
|
||||
{
|
||||
List<Group> newGroups = new List<Group>(groups.Count);
|
||||
Dictionary<string,string> newGroupParents = new Dictionary<string, string>(groups.Count);
|
||||
using (var reader = database.QueryReader("SELECT * FROM GroupList"))
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
string groupName = reader.Get<string>("GroupName");
|
||||
if (groupName == "superadmin")
|
||||
{
|
||||
Log.ConsoleInfo("WARNING: Group \"superadmin\" is defined in the database even though it's a reserved group name.");
|
||||
continue;
|
||||
}
|
||||
{
|
||||
string groupName = reader.Get<string>("GroupName");
|
||||
if (groupName == "superadmin")
|
||||
{
|
||||
Log.ConsoleInfo("WARNING: Group \"superadmin\" is defined in the database even though it's a reserved group name.");
|
||||
continue;
|
||||
}
|
||||
|
||||
newGroups.Add(new Group(groupName, null, reader.Get<string>("ChatColor"), reader.Get<string>("Commands")) {
|
||||
Prefix = reader.Get<string>("Prefix"),
|
||||
Suffix = reader.Get<string>("Suffix"),
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
newGroupParents.Add(groupName, reader.Get<string>("Parent"));
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
// Just in case somebody messed with the unique primary key.
|
||||
Log.ConsoleError("ERROR: Group name \"{0}\" occurs more than once. Keeping current group settings.");
|
||||
return;
|
||||
Suffix = reader.Get<string>("Suffix"),
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
newGroupParents.Add(groupName, reader.Get<string>("Parent"));
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
// Just in case somebody messed with the unique primary key.
|
||||
Log.ConsoleError("ERROR: Group name \"{0}\" occurs more than once. Keeping current group settings.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Get rid of deleted groups.
|
||||
for (int i = 0; i < groups.Count; i++)
|
||||
if (newGroups.All(g => g.Name != groups[i].Name))
|
||||
groups.RemoveAt(i--);
|
||||
|
||||
// Apply changed group settings while keeping the current instances and add new groups.
|
||||
foreach (Group newGroup in newGroups)
|
||||
{
|
||||
Group currentGroup = groups.FirstOrDefault(g => g.Name == newGroup.Name);
|
||||
if (currentGroup != null)
|
||||
newGroup.AssignTo(currentGroup);
|
||||
else
|
||||
groups.Add(newGroup);
|
||||
}
|
||||
|
||||
// Resolve parent groups.
|
||||
Debug.Assert(newGroups.Count == newGroupParents.Count);
|
||||
for (int i = 0; i < groups.Count; i++)
|
||||
{
|
||||
Group group = groups[i];
|
||||
string parentGroupName;
|
||||
if (!newGroupParents.TryGetValue(group.Name, out parentGroupName) || string.IsNullOrEmpty(parentGroupName))
|
||||
continue;
|
||||
|
||||
group.Parent = groups.FirstOrDefault(g => g.Name == parentGroupName);
|
||||
if (group.Parent == null)
|
||||
{
|
||||
Log.ConsoleError(
|
||||
"ERROR: Group \"{0}\" is referencing non existent parent group \"{1}\", parent reference was removed.",
|
||||
group.Name, parentGroupName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (group.Parent == group)
|
||||
Log.ConsoleInfo(
|
||||
"WARNING: Group \"{0}\" is referencing itself as parent group, parent reference was removed.", group.Name);
|
||||
|
||||
List<Group> groupChain = new List<Group> { group };
|
||||
Group checkingGroup = group;
|
||||
while (checkingGroup.Parent != null)
|
||||
{
|
||||
if (groupChain.Contains(checkingGroup.Parent))
|
||||
{
|
||||
Log.ConsoleError(
|
||||
"ERROR: Group \"{0}\" is referencing parent group \"{1}\" which is already part of the parent chain. Parent reference removed.",
|
||||
checkingGroup.Name, checkingGroup.Parent.Name);
|
||||
|
||||
checkingGroup.Parent = null;
|
||||
break;
|
||||
}
|
||||
groupChain.Add(checkingGroup);
|
||||
checkingGroup = checkingGroup.Parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!groups.Any(g => g is SuperAdminGroup))
|
||||
groups.Add(new SuperAdminGroup());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ConsoleError("Error on reloading groups: " + ex);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Get rid of deleted groups.
|
||||
for (int i = 0; i < groups.Count; i++)
|
||||
if (newGroups.All(g => g.Name != groups[i].Name))
|
||||
groups.RemoveAt(i--);
|
||||
|
||||
// Apply changed group settings while keeping the current instances and add new groups.
|
||||
foreach (Group newGroup in newGroups)
|
||||
{
|
||||
Group currentGroup = groups.FirstOrDefault(g => g.Name == newGroup.Name);
|
||||
if (currentGroup != null)
|
||||
newGroup.AssignTo(currentGroup);
|
||||
else
|
||||
groups.Add(newGroup);
|
||||
}
|
||||
|
||||
// Resolve parent groups.
|
||||
Debug.Assert(newGroups.Count == newGroupParents.Count);
|
||||
for (int i = 0; i < groups.Count; i++)
|
||||
{
|
||||
Group group = groups[i];
|
||||
string parentGroupName;
|
||||
if (!newGroupParents.TryGetValue(group.Name, out parentGroupName) || string.IsNullOrEmpty(parentGroupName))
|
||||
continue;
|
||||
|
||||
group.Parent = groups.FirstOrDefault(g => g.Name == parentGroupName);
|
||||
if (group.Parent == null)
|
||||
{
|
||||
Log.ConsoleError(
|
||||
"ERROR: Group \"{0}\" is referencing non existent parent group \"{1}\", parent reference was removed.",
|
||||
group.Name, parentGroupName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (group.Parent == group)
|
||||
Log.ConsoleInfo(
|
||||
"WARNING: Group \"{0}\" is referencing itself as parent group, parent reference was removed.", group.Name);
|
||||
|
||||
List<Group> groupChain = new List<Group> { group };
|
||||
Group checkingGroup = group;
|
||||
while (checkingGroup.Parent != null)
|
||||
{
|
||||
if (groupChain.Contains(checkingGroup.Parent))
|
||||
{
|
||||
Log.ConsoleError(
|
||||
"ERROR: Group \"{0}\" is referencing parent group \"{1}\" which is already part of the parent chain. Parent reference removed.",
|
||||
checkingGroup.Name, checkingGroup.Parent.Name);
|
||||
|
||||
checkingGroup.Parent = null;
|
||||
break;
|
||||
}
|
||||
groupChain.Add(checkingGroup);
|
||||
checkingGroup = checkingGroup.Parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!groups.Any(g => g is SuperAdminGroup))
|
||||
groups.Add(new SuperAdminGroup());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ConsoleError("Error on reloading groups: " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -394,10 +394,10 @@ namespace TShockAPI.DB
|
|||
mergedIDs = reader.Get<string>("UserIds");
|
||||
}
|
||||
|
||||
string userIdToAdd = Convert.ToString(TShock.Users.GetUserID(userName));
|
||||
string[] ids = mergedIDs.Split(',');
|
||||
// Is the user already allowed to the region?
|
||||
if (ids.Contains(userIdToAdd))
|
||||
string userIdToAdd = Convert.ToString(TShock.Users.GetUserID(userName));
|
||||
string[] ids = mergedIDs.Split(',');
|
||||
// Is the user already allowed to the region?
|
||||
if (ids.Contains(userIdToAdd))
|
||||
return true;
|
||||
|
||||
if (string.IsNullOrEmpty(mergedIDs))
|
||||
|
|
@ -484,9 +484,9 @@ namespace TShockAPI.DB
|
|||
mergedGroups = reader.Get<string>("Groups");
|
||||
}
|
||||
|
||||
string[] groups = mergedGroups.Split(',');
|
||||
// Is the group already allowed to the region?
|
||||
if (groups.Contains(groupName))
|
||||
string[] groups = mergedGroups.Split(',');
|
||||
// Is the group already allowed to the region?
|
||||
if (groups.Contains(groupName))
|
||||
return true;
|
||||
|
||||
if (mergedGroups != "")
|
||||
|
|
|
|||
|
|
@ -270,26 +270,26 @@ namespace TShockAPI
|
|||
return;
|
||||
}
|
||||
permissions.Remove(permission);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns all fields of this instance to another.
|
||||
/// </summary>
|
||||
/// <param name="otherGroup">The other instance.</param>
|
||||
public void AssignTo(Group otherGroup)
|
||||
{
|
||||
otherGroup.Name = Name;
|
||||
otherGroup.Parent = Parent;
|
||||
otherGroup.Prefix = Prefix;
|
||||
otherGroup.Suffix = Suffix;
|
||||
otherGroup.R = R;
|
||||
otherGroup.G = G;
|
||||
otherGroup.B = B;
|
||||
otherGroup.Permissions = Permissions;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return this.Name;
|
||||
/// <param name="otherGroup">The other instance.</param>
|
||||
public void AssignTo(Group otherGroup)
|
||||
{
|
||||
otherGroup.Name = Name;
|
||||
otherGroup.Parent = Parent;
|
||||
otherGroup.Prefix = Prefix;
|
||||
otherGroup.Suffix = Suffix;
|
||||
otherGroup.R = R;
|
||||
otherGroup.G = G;
|
||||
otherGroup.B = B;
|
||||
otherGroup.Permissions = Permissions;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return this.Name;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -70,12 +70,12 @@ namespace TShockAPI
|
|||
public static void Data(String message)
|
||||
{
|
||||
Write(message, LogLevel.Data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes data to the log file.
|
||||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
public static void Data(String format, params String[] args)
|
||||
{
|
||||
|
|
@ -89,12 +89,12 @@ namespace TShockAPI
|
|||
public static void Error(String message)
|
||||
{
|
||||
Write(message, LogLevel.Error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an error to the log file.
|
||||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
public static void Error(String format, params String[] args)
|
||||
{
|
||||
|
|
@ -111,12 +111,12 @@ namespace TShockAPI
|
|||
Console.WriteLine(message);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
Write(message, LogLevel.Error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an error to the log file.
|
||||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
public static void ConsoleError(String format, params String[] args)
|
||||
{
|
||||
|
|
@ -130,12 +130,12 @@ namespace TShockAPI
|
|||
public static void Warn(String message)
|
||||
{
|
||||
Write(message, LogLevel.Warning);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a warning to the log file.
|
||||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
public static void Warn(String format, params String[] args)
|
||||
{
|
||||
|
|
@ -149,12 +149,12 @@ namespace TShockAPI
|
|||
public static void Info(String message)
|
||||
{
|
||||
Write(message, LogLevel.Info);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an informative string to the log file.
|
||||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
public static void Info(String format, params String[] args)
|
||||
{
|
||||
|
|
@ -171,12 +171,12 @@ namespace TShockAPI
|
|||
Console.WriteLine(message);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
Write(message, LogLevel.Info);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an informative string to the log file. Also outputs to the console.
|
||||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
public static void ConsoleInfo(String format, params String[] args)
|
||||
{
|
||||
|
|
@ -190,12 +190,12 @@ namespace TShockAPI
|
|||
public static void Debug(String message)
|
||||
{
|
||||
Write(message, LogLevel.Debug);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a debug string to the log file.
|
||||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
public static void Debug(String format, params String[] args)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -174,8 +174,8 @@ namespace TShockAPI
|
|||
|
||||
[Description("User can elevate other users' groups temporarily.")] public static readonly string settempgroup;
|
||||
|
||||
[Description("User can download updates to plugins that are currently running.")] public static readonly string updateplugins;
|
||||
|
||||
[Description("User can download updates to plugins that are currently running.")] public static readonly string updateplugins;
|
||||
|
||||
static Permissions()
|
||||
{
|
||||
foreach (var field in typeof (Permissions).GetFields())
|
||||
|
|
|
|||
|
|
@ -36,13 +36,13 @@ namespace Rests
|
|||
/// <param name="parameters">Parameters in the url</param>
|
||||
/// <param name="verbs">{x} in urltemplate</param>
|
||||
/// <returns>Response object or null to not handle request</returns>
|
||||
public delegate object RestCommandD(RestVerbs verbs, IParameterCollection parameters);
|
||||
|
||||
public delegate object RestCommandD(RestVerbs verbs, IParameterCollection parameters);
|
||||
|
||||
/// <summary>
|
||||
/// Secure Rest command delegate including token data.
|
||||
/// </summary>
|
||||
/// <param name="parameters">Parameters in the url</param>
|
||||
/// <param name="verbs">{x} in urltemplate</param>
|
||||
/// <param name="verbs">{x} in urltemplate</param>
|
||||
/// <param name="tokenData">The data of stored for the provided token.</param>
|
||||
/// <returns>Response object or null to not handle request</returns>
|
||||
public delegate object SecureRestCommandD(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData);
|
||||
|
|
@ -189,32 +189,32 @@ namespace Rests
|
|||
|
||||
protected virtual object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms)
|
||||
{
|
||||
object result = cmd.Execute(verbs, parms);
|
||||
if (cmd.DoLog)
|
||||
Log.ConsoleInfo("Anonymous requested REST endpoint: " + BuildRequestUri(cmd, verbs, parms, false));
|
||||
|
||||
object result = cmd.Execute(verbs, parms);
|
||||
if (cmd.DoLog)
|
||||
Log.ConsoleInfo("Anonymous requested REST endpoint: " + BuildRequestUri(cmd, verbs, parms, false));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected virtual string BuildRequestUri(
|
||||
RestCommand cmd, RestVerbs verbs, IParameterCollection parms, bool includeToken = true
|
||||
) {
|
||||
StringBuilder requestBuilder = new StringBuilder(cmd.UriTemplate);
|
||||
char separator = '?';
|
||||
foreach (IParameter paramImpl in parms)
|
||||
{
|
||||
Parameter param = (paramImpl as Parameter);
|
||||
if (param == null || (!includeToken && param.Name.Equals("token", StringComparison.InvariantCultureIgnoreCase)))
|
||||
continue;
|
||||
|
||||
requestBuilder.Append(separator);
|
||||
requestBuilder.Append(param.Name);
|
||||
requestBuilder.Append('=');
|
||||
requestBuilder.Append(param.Value);
|
||||
separator = '&';
|
||||
}
|
||||
|
||||
return requestBuilder.ToString();
|
||||
}
|
||||
|
||||
protected virtual string BuildRequestUri(
|
||||
RestCommand cmd, RestVerbs verbs, IParameterCollection parms, bool includeToken = true
|
||||
) {
|
||||
StringBuilder requestBuilder = new StringBuilder(cmd.UriTemplate);
|
||||
char separator = '?';
|
||||
foreach (IParameter paramImpl in parms)
|
||||
{
|
||||
Parameter param = (paramImpl as Parameter);
|
||||
if (param == null || (!includeToken && param.Name.Equals("token", StringComparison.InvariantCultureIgnoreCase)))
|
||||
continue;
|
||||
|
||||
requestBuilder.Append(separator);
|
||||
requestBuilder.Append(param.Name);
|
||||
requestBuilder.Append('=');
|
||||
requestBuilder.Append(param.Value);
|
||||
separator = '&';
|
||||
}
|
||||
|
||||
return requestBuilder.ToString();
|
||||
}
|
||||
|
||||
#region Dispose
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ You should have received a copy of the GNU General Public License
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using HttpServer;
|
||||
|
||||
using System.Text.RegularExpressions;
|
||||
using HttpServer;
|
||||
|
||||
namespace Rests
|
||||
{
|
||||
public class RestCommand
|
||||
|
|
@ -27,10 +27,10 @@ namespace Rests
|
|||
public string UriTemplate { get; protected set; }
|
||||
public string UriVerbMatch { get; protected set; }
|
||||
public string[] UriVerbs { get; protected set; }
|
||||
public virtual bool RequiresToken { get { return false; } }
|
||||
public virtual bool RequiresToken { get { return false; } }
|
||||
public bool DoLog { get; set; }
|
||||
|
||||
private RestCommandD callback;
|
||||
|
||||
private RestCommandD callback;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
|
@ -45,7 +45,7 @@ namespace Rests
|
|||
UriVerbMatch = string.Format("^{0}$", string.Join("([^/]*)", Regex.Split(uritemplate, "\\{[^\\{\\}]*\\}")));
|
||||
var matches = Regex.Matches(uritemplate, "\\{([^\\{\\}]*)\\}");
|
||||
UriVerbs = (from Match match in matches select match.Groups[1].Value).ToArray();
|
||||
this.callback = callback;
|
||||
this.callback = callback;
|
||||
DoLog = true;
|
||||
}
|
||||
|
||||
|
|
@ -62,44 +62,44 @@ namespace Rests
|
|||
public bool HasVerbs
|
||||
{
|
||||
get { return UriVerbs.Length > 0; }
|
||||
}
|
||||
|
||||
public virtual object Execute(RestVerbs verbs, IParameterCollection parameters)
|
||||
{
|
||||
return callback(verbs, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
public class SecureRestCommand: RestCommand
|
||||
{
|
||||
public override bool RequiresToken { get { return true; } }
|
||||
public string[] Permissions { get; set; }
|
||||
|
||||
private SecureRestCommandD callback;
|
||||
|
||||
public SecureRestCommand(string name, string uritemplate, SecureRestCommandD callback, params string[] permissions)
|
||||
|
||||
public virtual object Execute(RestVerbs verbs, IParameterCollection parameters)
|
||||
{
|
||||
return callback(verbs, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
public class SecureRestCommand: RestCommand
|
||||
{
|
||||
public override bool RequiresToken { get { return true; } }
|
||||
public string[] Permissions { get; set; }
|
||||
|
||||
private SecureRestCommandD callback;
|
||||
|
||||
public SecureRestCommand(string name, string uritemplate, SecureRestCommandD callback, params string[] permissions)
|
||||
: base(name, uritemplate, null)
|
||||
{
|
||||
this.callback = callback;
|
||||
{
|
||||
this.callback = callback;
|
||||
Permissions = permissions;
|
||||
}
|
||||
|
||||
public SecureRestCommand(string uritemplate, SecureRestCommandD callback, params string[] permissions)
|
||||
: this(string.Empty, uritemplate, callback, permissions)
|
||||
{
|
||||
}
|
||||
|
||||
public override object Execute(RestVerbs verbs, IParameterCollection parameters)
|
||||
{
|
||||
return new RestObject("401") { Error = "Not authorized. The specified API endpoint requires a token." };
|
||||
}
|
||||
|
||||
public object Execute(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
if (tokenData.Equals(SecureRest.TokenData.None))
|
||||
return new RestObject("401") { Error = "Not authorized. The specified API endpoint requires a token." };
|
||||
|
||||
return callback(verbs, parameters, tokenData);
|
||||
}
|
||||
}
|
||||
|
||||
public override object Execute(RestVerbs verbs, IParameterCollection parameters)
|
||||
{
|
||||
return new RestObject("401") { Error = "Not authorized. The specified API endpoint requires a token." };
|
||||
}
|
||||
|
||||
public object Execute(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
if (tokenData.Equals(SecureRest.TokenData.None))
|
||||
return new RestObject("401") { Error = "Not authorized. The specified API endpoint requires a token." };
|
||||
|
||||
return callback(verbs, parameters, tokenData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,8 +17,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using HttpServer;
|
||||
using Rests;
|
||||
|
|
@ -38,27 +38,27 @@ namespace TShockAPI
|
|||
|
||||
public void RegisterRestfulCommands()
|
||||
{
|
||||
// Server Commands
|
||||
if (TShock.Config.EnableTokenEndpointAuthentication)
|
||||
{
|
||||
// Server Commands
|
||||
if (TShock.Config.EnableTokenEndpointAuthentication)
|
||||
{
|
||||
Rest.Register(new SecureRestCommand("/v2/server/status", ServerStatusV2));
|
||||
Rest.Register(new SecureRestCommand("/status", ServerStatus));
|
||||
Rest.Register(new SecureRestCommand("/v3/server/motd", ServerMotd));
|
||||
Rest.Register(new SecureRestCommand("/v3/server/rules", ServerRules));
|
||||
}
|
||||
else
|
||||
{
|
||||
Rest.Register(new SecureRestCommand("/status", ServerStatus));
|
||||
Rest.Register(new SecureRestCommand("/v3/server/motd", ServerMotd));
|
||||
Rest.Register(new SecureRestCommand("/v3/server/rules", ServerRules));
|
||||
}
|
||||
else
|
||||
{
|
||||
Rest.Register(new RestCommand("/v2/server/status", (a, b) => this.ServerStatusV2(a, b, SecureRest.TokenData.None)));
|
||||
Rest.Register(new RestCommand("/status", (a, b) => this.ServerStatusV2(a, b, SecureRest.TokenData.None)));
|
||||
Rest.Register(new RestCommand("/v3/server/motd", (a, b) => this.ServerMotd(a, b, SecureRest.TokenData.None)));
|
||||
Rest.Register(new RestCommand("/v3/server/rules", (a, b) => this.ServerRules(a, b, SecureRest.TokenData.None)));
|
||||
}
|
||||
Rest.Register(new RestCommand("/status", (a, b) => this.ServerStatusV2(a, b, SecureRest.TokenData.None)));
|
||||
Rest.Register(new RestCommand("/v3/server/motd", (a, b) => this.ServerMotd(a, b, SecureRest.TokenData.None)));
|
||||
Rest.Register(new RestCommand("/v3/server/rules", (a, b) => this.ServerRules(a, b, SecureRest.TokenData.None)));
|
||||
}
|
||||
|
||||
Rest.Register(new SecureRestCommand("/v2/server/broadcast", ServerBroadcast));
|
||||
Rest.Register(new SecureRestCommand("/v3/server/reload", ServerReload, RestPermissions.restcfg));
|
||||
Rest.Register(new SecureRestCommand("/v2/server/off", ServerOff, RestPermissions.restmaintenance));
|
||||
Rest.Register(new SecureRestCommand("/v2/server/broadcast", ServerBroadcast));
|
||||
Rest.Register(new SecureRestCommand("/v3/server/reload", ServerReload, RestPermissions.restcfg));
|
||||
Rest.Register(new SecureRestCommand("/v2/server/off", ServerOff, RestPermissions.restmaintenance));
|
||||
Rest.Register(new SecureRestCommand("/v3/server/restart", ServerRestart, RestPermissions.restmaintenance));
|
||||
Rest.Register(new SecureRestCommand("/v2/server/rawcmd", ServerCommand, RestPermissions.restrawcommand));
|
||||
Rest.Register(new SecureRestCommand("/v2/server/rawcmd", ServerCommand, RestPermissions.restrawcommand));
|
||||
Rest.Register(new SecureRestCommand("/v3/server/rawcmd", ServerCommandV3, RestPermissions.restrawcommand));
|
||||
Rest.Register(new SecureRestCommand("/tokentest", ServerTokenTest));
|
||||
|
||||
|
|
@ -107,35 +107,35 @@ namespace TShockAPI
|
|||
private object ServerCommand(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(parameters["cmd"]))
|
||||
return RestMissingParam("cmd");
|
||||
|
||||
Group restPlayerGroup;
|
||||
return RestMissingParam("cmd");
|
||||
|
||||
Group restPlayerGroup;
|
||||
// TODO: Get rid of this when the old REST permission model is removed.
|
||||
if (TShock.Config.RestUseNewPermissionModel)
|
||||
restPlayerGroup = TShock.Groups.GetGroupByName(tokenData.UserGroupName);
|
||||
else
|
||||
restPlayerGroup = new SuperAdminGroup();
|
||||
if (TShock.Config.RestUseNewPermissionModel)
|
||||
restPlayerGroup = TShock.Groups.GetGroupByName(tokenData.UserGroupName);
|
||||
else
|
||||
restPlayerGroup = new SuperAdminGroup();
|
||||
|
||||
TSRestPlayer tr = new TSRestPlayer(tokenData.Username, restPlayerGroup);
|
||||
Commands.HandleCommand(tr, parameters["cmd"]);
|
||||
return RestResponse(string.Join("\n", tr.GetCommandOutput()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private object ServerCommandV3(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(parameters["cmd"]))
|
||||
return RestMissingParam("cmd");
|
||||
return RestMissingParam("cmd");
|
||||
|
||||
Group restPlayerGroup;
|
||||
Group restPlayerGroup;
|
||||
// TODO: Get rid of this when the old REST permission model is removed.
|
||||
if (TShock.Config.RestUseNewPermissionModel)
|
||||
restPlayerGroup = TShock.Groups.GetGroupByName(tokenData.UserGroupName);
|
||||
else
|
||||
restPlayerGroup = new SuperAdminGroup();
|
||||
|
||||
if (TShock.Config.RestUseNewPermissionModel)
|
||||
restPlayerGroup = TShock.Groups.GetGroupByName(tokenData.UserGroupName);
|
||||
else
|
||||
restPlayerGroup = new SuperAdminGroup();
|
||||
|
||||
TSRestPlayer tr = new TSRestPlayer(tokenData.Username, restPlayerGroup);
|
||||
Commands.HandleCommand(tr, parameters["cmd"]);
|
||||
return new RestObject()
|
||||
return new RestObject()
|
||||
{
|
||||
{"response", tr.GetCommandOutput()}
|
||||
};
|
||||
|
|
@ -151,8 +151,8 @@ namespace TShockAPI
|
|||
TShock.Utils.StopServer(!GetBool(parameters["nosave"], false), reason);
|
||||
|
||||
return RestResponse("The server is shutting down");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private object ServerRestart(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
if (!GetBool(parameters["confirm"], false))
|
||||
|
|
@ -163,10 +163,10 @@ namespace TShockAPI
|
|||
TShock.Utils.RestartServer(!GetBool(parameters["nosave"], false), reason);
|
||||
|
||||
return RestResponse("The server is shutting down and will attempt to restart");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private object ServerReload(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
{
|
||||
TShock.Utils.Reload(new TSRestPlayer(tokenData.Username, TShock.Groups.GetGroupByName(tokenData.UserGroupName)));
|
||||
|
||||
return RestResponse("Configuration, permissions, and regions reload complete. Some changes may require a server restart.");
|
||||
|
|
@ -179,29 +179,29 @@ namespace TShockAPI
|
|||
return RestMissingParam("msg");
|
||||
TShock.Utils.Broadcast(msg);
|
||||
return RestResponse("The message was broadcasted successfully");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private object ServerMotd(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
string motdFilePath = Path.Combine(TShock.SavePath, "motd.txt");
|
||||
if (!File.Exists(motdFilePath))
|
||||
return this.RestError("The motd.txt was not found.", "500");
|
||||
{
|
||||
string motdFilePath = Path.Combine(TShock.SavePath, "motd.txt");
|
||||
if (!File.Exists(motdFilePath))
|
||||
return this.RestError("The motd.txt was not found.", "500");
|
||||
|
||||
return new RestObject()
|
||||
{
|
||||
{"motd", File.ReadAllLines(motdFilePath)}
|
||||
return new RestObject()
|
||||
{
|
||||
{"motd", File.ReadAllLines(motdFilePath)}
|
||||
};
|
||||
}
|
||||
|
||||
private object ServerRules(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
string rulesFilePath = Path.Combine(TShock.SavePath, "rules.txt");
|
||||
if (!File.Exists(rulesFilePath))
|
||||
return this.RestError("The rules.txt was not found.", "500");
|
||||
}
|
||||
|
||||
return new RestObject()
|
||||
{
|
||||
{"rules", File.ReadAllLines(rulesFilePath)}
|
||||
private object ServerRules(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
string rulesFilePath = Path.Combine(TShock.SavePath, "rules.txt");
|
||||
if (!File.Exists(rulesFilePath))
|
||||
return this.RestError("The rules.txt was not found.", "500");
|
||||
|
||||
return new RestObject()
|
||||
{
|
||||
{"rules", File.ReadAllLines(rulesFilePath)}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -225,8 +225,8 @@ namespace TShockAPI
|
|||
{"port", TShock.Config.ServerPort},
|
||||
{"playercount", Main.player.Where(p => null != p && p.active).Count()},
|
||||
{"maxplayers", TShock.Config.MaxSlots},
|
||||
{"world", Main.worldName},
|
||||
{"uptime", (DateTime.Now - System.Diagnostics.Process.GetCurrentProcess().StartTime).ToString(@"d'.'hh':'mm':'ss")},
|
||||
{"world", Main.worldName},
|
||||
{"uptime", (DateTime.Now - System.Diagnostics.Process.GetCurrentProcess().StartTime).ToString(@"d'.'hh':'mm':'ss")},
|
||||
{"serverpassword", !string.IsNullOrEmpty(TShock.Config.ServerPassword)}
|
||||
};
|
||||
|
||||
|
|
@ -256,7 +256,7 @@ namespace TShockAPI
|
|||
rules.Add("HardcoreOnly", TShock.Config.HardcoreOnly);
|
||||
rules.Add("PvPMode", TShock.Config.PvPMode);
|
||||
rules.Add("SpawnProtection", TShock.Config.SpawnProtection);
|
||||
rules.Add("SpawnProtectionRadius", TShock.Config.SpawnProtectionRadius);
|
||||
rules.Add("SpawnProtectionRadius", TShock.Config.SpawnProtectionRadius);
|
||||
rules.Add("ServerSideInventory", TShock.Config.ServerSideInventory);
|
||||
|
||||
ret.Add("rules", rules);
|
||||
|
|
@ -265,10 +265,10 @@ namespace TShockAPI
|
|||
}
|
||||
|
||||
private object ServerTokenTest(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
return new RestObject()
|
||||
{
|
||||
return new RestObject()
|
||||
{
|
||||
{"response", "Token is valid and was passed through correctly."},
|
||||
{"response", "Token is valid and was passed through correctly."},
|
||||
{"associateduser", tokenData.Username}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,80 +14,80 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace Rests
|
||||
{
|
||||
public static class RestPermissions
|
||||
{
|
||||
*/
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace Rests
|
||||
{
|
||||
public static class RestPermissions
|
||||
{
|
||||
[Description("User can create REST tokens.")]
|
||||
public static readonly string restapi;
|
||||
|
||||
public static readonly string restapi;
|
||||
|
||||
[Description("User or REST user can destroy all REST tokens.")]
|
||||
public static readonly string restmanage;
|
||||
|
||||
|
||||
[Description("REST user can turn off / restart the server.")]
|
||||
public static readonly string restmaintenance;
|
||||
|
||||
[Description("REST user can reload configurations, save the world and set auto save settings.")]
|
||||
public static readonly string restcfg;
|
||||
|
||||
|
||||
[Description("REST user can list and get detailed information about users.")]
|
||||
public static readonly string restviewusers;
|
||||
|
||||
[Description("REST user can alter users.")]
|
||||
public static readonly string restmanageusers;
|
||||
|
||||
[Description("REST user can list and get detailed information about bans.")]
|
||||
public static readonly string restviewbans;
|
||||
|
||||
[Description("REST user can alter bans.")]
|
||||
public static readonly string restmanagebans;
|
||||
|
||||
[Description("REST user can list and get detailed information about groups.")]
|
||||
public static readonly string restviewgroups;
|
||||
|
||||
[Description("REST user can alter groups.")]
|
||||
public static readonly string restmanagegroups;
|
||||
|
||||
|
||||
[Description("REST user can get user information.")]
|
||||
public static readonly string restuserinfo;
|
||||
|
||||
[Description("REST user can kick players.")]
|
||||
public static readonly string restkick;
|
||||
|
||||
[Description("REST user can ban players.")]
|
||||
public static readonly string restban;
|
||||
|
||||
[Description("REST user can mute and unmute players.")]
|
||||
public static readonly string restmute;
|
||||
|
||||
[Description("REST user can kill players.")]
|
||||
public static readonly string restkill;
|
||||
|
||||
|
||||
[Description("REST user can drop meteors or change bloodmoon.")]
|
||||
public static readonly string restcauseevents;
|
||||
|
||||
[Description("REST user can butcher npcs.")]
|
||||
public static readonly string restbutcher;
|
||||
|
||||
|
||||
[Description("REST user can run raw TShock commands (the raw command permissions are also checked though).")]
|
||||
public static readonly string restrawcommand;
|
||||
|
||||
public static readonly string restmanage;
|
||||
|
||||
|
||||
[Description("REST user can turn off / restart the server.")]
|
||||
public static readonly string restmaintenance;
|
||||
|
||||
[Description("REST user can reload configurations, save the world and set auto save settings.")]
|
||||
public static readonly string restcfg;
|
||||
|
||||
|
||||
[Description("REST user can list and get detailed information about users.")]
|
||||
public static readonly string restviewusers;
|
||||
|
||||
[Description("REST user can alter users.")]
|
||||
public static readonly string restmanageusers;
|
||||
|
||||
[Description("REST user can list and get detailed information about bans.")]
|
||||
public static readonly string restviewbans;
|
||||
|
||||
[Description("REST user can alter bans.")]
|
||||
public static readonly string restmanagebans;
|
||||
|
||||
[Description("REST user can list and get detailed information about groups.")]
|
||||
public static readonly string restviewgroups;
|
||||
|
||||
[Description("REST user can alter groups.")]
|
||||
public static readonly string restmanagegroups;
|
||||
|
||||
|
||||
[Description("REST user can get user information.")]
|
||||
public static readonly string restuserinfo;
|
||||
|
||||
[Description("REST user can kick players.")]
|
||||
public static readonly string restkick;
|
||||
|
||||
[Description("REST user can ban players.")]
|
||||
public static readonly string restban;
|
||||
|
||||
[Description("REST user can mute and unmute players.")]
|
||||
public static readonly string restmute;
|
||||
|
||||
[Description("REST user can kill players.")]
|
||||
public static readonly string restkill;
|
||||
|
||||
|
||||
[Description("REST user can drop meteors or change bloodmoon.")]
|
||||
public static readonly string restcauseevents;
|
||||
|
||||
[Description("REST user can butcher npcs.")]
|
||||
public static readonly string restbutcher;
|
||||
|
||||
|
||||
[Description("REST user can run raw TShock commands (the raw command permissions are also checked though).")]
|
||||
public static readonly string restrawcommand;
|
||||
|
||||
static RestPermissions()
|
||||
{
|
||||
foreach (var field in typeof (RestPermissions).GetFields())
|
||||
{
|
||||
field.SetValue(null, field.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,35 +18,35 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using HttpServer;
|
||||
using TShockAPI;
|
||||
using TShockAPI.DB;
|
||||
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using HttpServer;
|
||||
using TShockAPI;
|
||||
using TShockAPI.DB;
|
||||
|
||||
namespace Rests
|
||||
{
|
||||
public class SecureRest : Rest
|
||||
{
|
||||
public struct TokenData
|
||||
{
|
||||
public static readonly TokenData None = default(TokenData);
|
||||
|
||||
public string Username { get; set; }
|
||||
public string UserGroupName { get; set; }
|
||||
}
|
||||
{
|
||||
public struct TokenData
|
||||
{
|
||||
public static readonly TokenData None = default(TokenData);
|
||||
|
||||
public string Username { get; set; }
|
||||
public string UserGroupName { get; set; }
|
||||
}
|
||||
|
||||
public Dictionary<string,TokenData> Tokens { get; protected set; }
|
||||
|
||||
public SecureRest(IPAddress ip, int port)
|
||||
: base(ip, port)
|
||||
{
|
||||
Tokens = new Dictionary<string, TokenData>();
|
||||
Tokens = new Dictionary<string, TokenData>();
|
||||
|
||||
Register(new RestCommand("/token/create/{username}/{password}", NewToken) { DoLog = false });
|
||||
Register(new RestCommand("/v2/token/create/{password}", NewTokenV2) { DoLog = false });
|
||||
Register(new SecureRestCommand("/token/destroy/{token}", DestroyToken));
|
||||
Register(new SecureRestCommand("/v3/token/destroy/all", DestroyAllTokens, RestPermissions.restmanage));
|
||||
Register(new SecureRestCommand("/token/destroy/{token}", DestroyToken));
|
||||
Register(new SecureRestCommand("/v3/token/destroy/all", DestroyAllTokens, RestPermissions.restmanage));
|
||||
|
||||
foreach (KeyValuePair<string, TokenData> t in TShockAPI.TShock.RESTStartupTokens)
|
||||
{
|
||||
|
|
@ -55,7 +55,7 @@ namespace Rests
|
|||
|
||||
// TODO: Get rid of this when the old REST permission model is removed.
|
||||
if (!TShock.Config.RestUseNewPermissionModel)
|
||||
{
|
||||
{
|
||||
string warningMessage = string.Concat(
|
||||
"You're using the old REST permission model which is highly vulnerable in matter of security. ",
|
||||
"The old model will be removed with the next maintenance release of TShock. In order to switch to the new model, ",
|
||||
|
|
@ -64,16 +64,16 @@ namespace Rests
|
|||
Log.Warn(warningMessage);
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(warningMessage);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
string warningMessage = string.Concat(
|
||||
"You're using the new more secure REST permission model which can lead to compatibility problems ",
|
||||
"with existing REST services. If compatibility problems occur, you can switch back to the unsecure permission ",
|
||||
"model by changing the config setting \"RestUseNewPermissionModel\" to false, which is not recommended."
|
||||
);
|
||||
Log.ConsoleInfo(warningMessage);
|
||||
Log.ConsoleInfo(warningMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -91,11 +91,11 @@ namespace Rests
|
|||
}
|
||||
return new RestObject()
|
||||
{ Response = "Requested token was successfully destroyed." };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private object DestroyAllTokens(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
Tokens.Clear();
|
||||
Tokens.Clear();
|
||||
|
||||
return new RestObject()
|
||||
{ Response = "All tokens were successfully destroyed." };
|
||||
|
|
@ -114,13 +114,13 @@ namespace Rests
|
|||
var user = verbs["username"];
|
||||
var pass = verbs["password"];
|
||||
|
||||
RestObject response = this.NewTokenInternal(user, pass);
|
||||
response["deprecated"] = "This endpoint is depracted and will be removed in the future.";
|
||||
RestObject response = this.NewTokenInternal(user, pass);
|
||||
response["deprecated"] = "This endpoint is depracted and will be removed in the future.";
|
||||
return response;
|
||||
}
|
||||
|
||||
private RestObject NewTokenInternal(string username, string password)
|
||||
{
|
||||
|
||||
private RestObject NewTokenInternal(string username, string password)
|
||||
{
|
||||
User userAccount = TShock.Users.GetUserByName(username);
|
||||
if (userAccount == null || !string.IsNullOrWhiteSpace(userAccount.Address))
|
||||
return new RestObject("401")
|
||||
|
|
@ -129,12 +129,12 @@ namespace Rests
|
|||
if (!TShock.Utils.HashPassword(password).Equals(userAccount.Password, StringComparison.InvariantCultureIgnoreCase))
|
||||
return new RestObject("401")
|
||||
{ Error = "Invalid username/password combination provided. Please re-submit your query with a correct pair." };
|
||||
|
||||
|
||||
Group userGroup = TShock.Utils.GetGroup(userAccount.Group);
|
||||
if (!userGroup.HasPermission(RestPermissions.restapi) && userAccount.Group != "superadmin")
|
||||
return new RestObject("403")
|
||||
{ Error = "Although your account was successfully found and identified, your account lacks the permission required to use the API. (restapi)" };
|
||||
|
||||
{ Error = "Although your account was successfully found and identified, your account lacks the permission required to use the API. (restapi)" };
|
||||
|
||||
string tokenHash;
|
||||
var rand = new Random();
|
||||
var randbytes = new byte[32];
|
||||
|
|
@ -145,53 +145,53 @@ namespace Rests
|
|||
} while (Tokens.ContainsKey(tokenHash));
|
||||
|
||||
Tokens.Add(tokenHash, new TokenData { Username = userAccount.Name, UserGroupName = userGroup.Name });
|
||||
|
||||
|
||||
RestObject response = new RestObject() { Response = "Successful login" };
|
||||
response["token"] = tokenHash;
|
||||
return response;
|
||||
return response;
|
||||
}
|
||||
|
||||
protected override object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms)
|
||||
{
|
||||
if (!cmd.RequiresToken)
|
||||
if (!cmd.RequiresToken)
|
||||
return base.ExecuteCommand(cmd, verbs, parms);
|
||||
|
||||
var token = parms["token"];
|
||||
if (token == null)
|
||||
return new RestObject("401")
|
||||
{ Error = "Not authorized. The specified API endpoint requires a token." };
|
||||
|
||||
|
||||
SecureRestCommand secureCmd = (SecureRestCommand)cmd;
|
||||
TokenData tokenData;
|
||||
if (!Tokens.TryGetValue(token, out tokenData))
|
||||
return new RestObject("403")
|
||||
{ Error = "Not authorized. The specified API endpoint requires a token, but the provided token was not valid." };
|
||||
|
||||
{ Error = "Not authorized. The specified API endpoint requires a token, but the provided token was not valid." };
|
||||
|
||||
// TODO: Get rid of this when the old REST permission model is removed.
|
||||
if (TShock.Config.RestUseNewPermissionModel) {
|
||||
Group userGroup = TShock.Groups.GetGroupByName(tokenData.UserGroupName);
|
||||
if (userGroup == null)
|
||||
{
|
||||
Tokens.Remove(token);
|
||||
|
||||
return new RestObject("403")
|
||||
{ Error = "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)))
|
||||
{
|
||||
return new RestObject("403")
|
||||
{ Error = string.Format("Not authorized. User \"{0}\" has no access to use the specified API endpoint.", tokenData.Username) };
|
||||
}
|
||||
}
|
||||
|
||||
object result = secureCmd.Execute(verbs, parms, tokenData);
|
||||
if (cmd.DoLog)
|
||||
TShock.Utils.SendLogs(string.Format(
|
||||
"\"{0}\" requested REST endpoint: {1}", tokenData.Username, this.BuildRequestUri(cmd, verbs, parms, false)),
|
||||
Color.PaleVioletRed);
|
||||
|
||||
return result;
|
||||
if (TShock.Config.RestUseNewPermissionModel) {
|
||||
Group userGroup = TShock.Groups.GetGroupByName(tokenData.UserGroupName);
|
||||
if (userGroup == null)
|
||||
{
|
||||
Tokens.Remove(token);
|
||||
|
||||
return new RestObject("403")
|
||||
{ Error = "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)))
|
||||
{
|
||||
return new RestObject("403")
|
||||
{ Error = string.Format("Not authorized. User \"{0}\" has no access to use the specified API endpoint.", tokenData.Username) };
|
||||
}
|
||||
}
|
||||
|
||||
object result = secureCmd.Execute(verbs, parms, tokenData);
|
||||
if (cmd.DoLog)
|
||||
TShock.Utils.SendLogs(string.Format(
|
||||
"\"{0}\" requested REST endpoint: {1}", tokenData.Username, this.BuildRequestUri(cmd, verbs, parms, false)),
|
||||
Color.PaleVioletRed);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,205 +1,205 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{49606449-072B-4CF5-8088-AA49DA586694}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>TShockAPI</RootNamespace>
|
||||
<AssemblyName>TShockAPI</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>bin\Debug\TShockAPI.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;COMPAT_SIGS</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>bin\Release\TShockAPI.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="HttpServer">
|
||||
<HintPath>..\HttpBins\HttpServer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Mono.Data.Sqlite">
|
||||
<HintPath>..\SqlBins\Mono.Data.Sqlite.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Data, Version=6.3.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\SqlBins\MySql.Data.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Web, Version=6.3.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\SqlBins\MySql.Web.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>.\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="TerrariaServer">
|
||||
<HintPath>..\TerrariaServerBins\TerrariaServer.exe</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BackupManager.cs" />
|
||||
<Compile Include="DB\RegionManager.cs" />
|
||||
<Compile Include="Hooks\GeneralHooks.cs" />
|
||||
<Compile Include="Hooks\PlayerHooks.cs" />
|
||||
<Compile Include="PaginationTools.cs" />
|
||||
<Compile Include="PluginUpdater\PluginUpdaterThread.cs" />
|
||||
<Compile Include="PluginUpdater\PluginVersionCheck.cs" />
|
||||
<Compile Include="PluginUpdater\VersionInfo.cs" />
|
||||
<Compile Include="Rest\RestPermissions.cs" />
|
||||
<Compile Include="SaveManager.cs" />
|
||||
<Compile Include="DB\BanManager.cs" />
|
||||
<Compile Include="DB\InventoryManager.cs" />
|
||||
<Compile Include="DB\IQueryBuilder.cs" />
|
||||
<Compile Include="DB\ItemManager.cs" />
|
||||
<Compile Include="DB\SqlColumn.cs" />
|
||||
<Compile Include="DB\SqlTable.cs" />
|
||||
<Compile Include="DB\SqlValue.cs" />
|
||||
<Compile Include="Extensions\DbExt.cs" />
|
||||
<Compile Include="DB\GroupManager.cs" />
|
||||
<Compile Include="DB\UserManager.cs" />
|
||||
<Compile Include="Extensions\RandomExt.cs" />
|
||||
<Compile Include="Extensions\StringExt.cs" />
|
||||
<Compile Include="GeoIPCountry.cs" />
|
||||
<Compile Include="HandlerList.cs" />
|
||||
<Compile Include="IPackable.cs" />
|
||||
<Compile Include="Commands.cs" />
|
||||
<Compile Include="ConfigFile.cs" />
|
||||
<Compile Include="FileTools.cs" />
|
||||
<Compile Include="GetDataHandlers.cs" />
|
||||
<Compile Include="Group.cs" />
|
||||
<Compile Include="Extensions\LinqExt.cs" />
|
||||
<Compile Include="Log.cs" />
|
||||
<Compile Include="Net\BaseMsg.cs" />
|
||||
<Compile Include="Net\DisconnectMsg.cs" />
|
||||
<Compile Include="Net\NetTile.cs" />
|
||||
<Compile Include="Net\ProjectileRemoveMsg.cs" />
|
||||
<Compile Include="Net\SpawnMsg.cs" />
|
||||
<Compile Include="Net\WorldInfoMsg.cs" />
|
||||
<Compile Include="PacketBufferer.cs" />
|
||||
<Compile Include="Permissions.cs" />
|
||||
<Compile Include="RconHandler.cs" />
|
||||
<Compile Include="DB\RememberedPosManager.cs" />
|
||||
<Compile Include="Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rest\Rest.cs" />
|
||||
<Compile Include="Rest\RestCommand.cs" />
|
||||
<Compile Include="Rest\RestManager.cs" />
|
||||
<Compile Include="Rest\RestObject.cs" />
|
||||
<Compile Include="Rest\RestVerbs.cs" />
|
||||
<Compile Include="Rest\SecureRest.cs" />
|
||||
<Compile Include="StatTracker.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
<Compile Include="TShock.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="TSPlayer.cs" />
|
||||
<Compile Include="UpdateManager.cs" />
|
||||
<Compile Include="DB\WarpsManager.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="config\groups.txt" />
|
||||
<None Include="TShockAPI.licenseheader" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="config\users.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.0">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Windows Installer 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="config\itembans.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>"$(ProjectDir)postbuild.bat"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties BuildVersion_UpdateAssemblyVersion="True" BuildVersion_UpdateFileVersion="True" BuildVersion_BuildAction="Both" BuildVersion_BuildVersioningStyle="None.None.None.MonthAndDayStamp" BuildVersion_StartDate="2011/6/17" BuildVersion_IncrementBeforeBuild="False" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{49606449-072B-4CF5-8088-AA49DA586694}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>TShockAPI</RootNamespace>
|
||||
<AssemblyName>TShockAPI</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>bin\Debug\TShockAPI.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;COMPAT_SIGS</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>bin\Release\TShockAPI.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="HttpServer">
|
||||
<HintPath>..\HttpBins\HttpServer.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Mono.Data.Sqlite">
|
||||
<HintPath>..\SqlBins\Mono.Data.Sqlite.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Data, Version=6.3.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\SqlBins\MySql.Data.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Web, Version=6.3.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\SqlBins\MySql.Web.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>.\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="TerrariaServer">
|
||||
<HintPath>..\TerrariaServerBins\TerrariaServer.exe</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BackupManager.cs" />
|
||||
<Compile Include="DB\RegionManager.cs" />
|
||||
<Compile Include="Hooks\GeneralHooks.cs" />
|
||||
<Compile Include="Hooks\PlayerHooks.cs" />
|
||||
<Compile Include="PaginationTools.cs" />
|
||||
<Compile Include="PluginUpdater\PluginUpdaterThread.cs" />
|
||||
<Compile Include="PluginUpdater\PluginVersionCheck.cs" />
|
||||
<Compile Include="PluginUpdater\VersionInfo.cs" />
|
||||
<Compile Include="Rest\RestPermissions.cs" />
|
||||
<Compile Include="SaveManager.cs" />
|
||||
<Compile Include="DB\BanManager.cs" />
|
||||
<Compile Include="DB\InventoryManager.cs" />
|
||||
<Compile Include="DB\IQueryBuilder.cs" />
|
||||
<Compile Include="DB\ItemManager.cs" />
|
||||
<Compile Include="DB\SqlColumn.cs" />
|
||||
<Compile Include="DB\SqlTable.cs" />
|
||||
<Compile Include="DB\SqlValue.cs" />
|
||||
<Compile Include="Extensions\DbExt.cs" />
|
||||
<Compile Include="DB\GroupManager.cs" />
|
||||
<Compile Include="DB\UserManager.cs" />
|
||||
<Compile Include="Extensions\RandomExt.cs" />
|
||||
<Compile Include="Extensions\StringExt.cs" />
|
||||
<Compile Include="GeoIPCountry.cs" />
|
||||
<Compile Include="HandlerList.cs" />
|
||||
<Compile Include="IPackable.cs" />
|
||||
<Compile Include="Commands.cs" />
|
||||
<Compile Include="ConfigFile.cs" />
|
||||
<Compile Include="FileTools.cs" />
|
||||
<Compile Include="GetDataHandlers.cs" />
|
||||
<Compile Include="Group.cs" />
|
||||
<Compile Include="Extensions\LinqExt.cs" />
|
||||
<Compile Include="Log.cs" />
|
||||
<Compile Include="Net\BaseMsg.cs" />
|
||||
<Compile Include="Net\DisconnectMsg.cs" />
|
||||
<Compile Include="Net\NetTile.cs" />
|
||||
<Compile Include="Net\ProjectileRemoveMsg.cs" />
|
||||
<Compile Include="Net\SpawnMsg.cs" />
|
||||
<Compile Include="Net\WorldInfoMsg.cs" />
|
||||
<Compile Include="PacketBufferer.cs" />
|
||||
<Compile Include="Permissions.cs" />
|
||||
<Compile Include="RconHandler.cs" />
|
||||
<Compile Include="DB\RememberedPosManager.cs" />
|
||||
<Compile Include="Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Rest\Rest.cs" />
|
||||
<Compile Include="Rest\RestCommand.cs" />
|
||||
<Compile Include="Rest\RestManager.cs" />
|
||||
<Compile Include="Rest\RestObject.cs" />
|
||||
<Compile Include="Rest\RestVerbs.cs" />
|
||||
<Compile Include="Rest\SecureRest.cs" />
|
||||
<Compile Include="StatTracker.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
<Compile Include="TShock.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="TSPlayer.cs" />
|
||||
<Compile Include="UpdateManager.cs" />
|
||||
<Compile Include="DB\WarpsManager.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="config\groups.txt" />
|
||||
<None Include="TShockAPI.licenseheader" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="config\users.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.0">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Windows Installer 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="config\itembans.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>"$(ProjectDir)postbuild.bat"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties BuildVersion_UpdateAssemblyVersion="True" BuildVersion_UpdateFileVersion="True" BuildVersion_BuildAction="Both" BuildVersion_BuildVersioningStyle="None.None.None.MonthAndDayStamp" BuildVersion_StartDate="2011/6/17" BuildVersion_IncrementBeforeBuild="False" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
-->
|
||||
</Project>
|
||||
|
|
@ -22,8 +22,8 @@ using System.Linq;
|
|||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using TShockAPI.DB;
|
||||
using System.Text;
|
||||
using TShockAPI.DB;
|
||||
using Terraria;
|
||||
|
||||
namespace TShockAPI
|
||||
|
|
@ -221,7 +221,7 @@ namespace TShockAPI
|
|||
/// Sends message to all players with 'logs' permission.
|
||||
/// </summary>
|
||||
/// <param name="log">Message to send</param>
|
||||
/// <param name="color">Color of the message</param>
|
||||
/// <param name="color">Color of the message</param>
|
||||
/// <param name="excludedPlayer">The player to not send the message to.</param>
|
||||
public void SendLogs(string log, Color color, TSPlayer excludedPlayer = null)
|
||||
{
|
||||
|
|
@ -229,7 +229,7 @@ namespace TShockAPI
|
|||
TSPlayer.Server.SendMessage(log, color);
|
||||
foreach (TSPlayer player in TShock.Players)
|
||||
{
|
||||
if (player != null && player != excludedPlayer && player.Active && player.Group.HasPermission(Permissions.logs) &&
|
||||
if (player != null && player != excludedPlayer && player.Active && player.Group.HasPermission(Permissions.logs) &&
|
||||
player.DisplayLogs && TShock.Config.DisableSpewLogs == false)
|
||||
player.SendMessage(log, color);
|
||||
}
|
||||
|
|
@ -560,10 +560,10 @@ namespace TShockAPI
|
|||
|
||||
// Disconnect after kick as that signifies server is exiting and could cause a race
|
||||
Netplay.disconnect = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops the server after kicking all players with a reason message, and optionally saving the world then attempts to
|
||||
/// Stops the server after kicking all players with a reason message, and optionally saving the world then attempts to
|
||||
/// restart it.
|
||||
/// </summary>
|
||||
/// <param name="save">bool perform a world save before stop (default: true)</param>
|
||||
|
|
@ -573,23 +573,23 @@ namespace TShockAPI
|
|||
if (TShock.Config.ServerSideInventory)
|
||||
foreach (TSPlayer player in TShock.Players)
|
||||
if (player != null && player.IsLoggedIn && !player.IgnoreActionsForClearingTrashCan)
|
||||
TShock.InventoryDB.InsertPlayerData(player);
|
||||
TShock.InventoryDB.InsertPlayerData(player);
|
||||
|
||||
StopServer(true, reason);
|
||||
System.Diagnostics.Process.Start(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reloads all configuration settings, groups, regions and raises the reload event.
|
||||
/// </summary>
|
||||
public void Reload(TSPlayer player)
|
||||
{
|
||||
/// </summary>
|
||||
public void Reload(TSPlayer player)
|
||||
{
|
||||
FileTools.SetupConfig();
|
||||
TShock.HandleCommandLinePostConfigLoad(Environment.GetCommandLineArgs());
|
||||
TShock.Groups.LoadPermisions();
|
||||
TShock.Regions.ReloadAllRegions();
|
||||
Hooks.GeneralHooks.OnReloadEvent(player);
|
||||
TShock.Regions.ReloadAllRegions();
|
||||
Hooks.GeneralHooks.OnReloadEvent(player);
|
||||
}
|
||||
|
||||
#if COMPAT_SIGS
|
||||
|
|
@ -879,19 +879,19 @@ namespace TShockAPI
|
|||
/// </summary>
|
||||
/// <param name="regionArea">The region's area to enumerate through.</param>
|
||||
/// <returns>The enumerated boundary points.</returns>
|
||||
public IEnumerable<Point> EnumerateRegionBoundaries(Rectangle regionArea)
|
||||
{
|
||||
for (int x = 0; x < regionArea.Width + 1; x++)
|
||||
{
|
||||
yield return new Point(regionArea.Left + x, regionArea.Top);
|
||||
yield return new Point(regionArea.Left + x, regionArea.Bottom);
|
||||
}
|
||||
|
||||
for (int y = 1; y < regionArea.Height; y++)
|
||||
{
|
||||
yield return new Point(regionArea.Left, regionArea.Top + y);
|
||||
yield return new Point(regionArea.Right, regionArea.Top + y);
|
||||
}
|
||||
public IEnumerable<Point> EnumerateRegionBoundaries(Rectangle regionArea)
|
||||
{
|
||||
for (int x = 0; x < regionArea.Width + 1; x++)
|
||||
{
|
||||
yield return new Point(regionArea.Left + x, regionArea.Top);
|
||||
yield return new Point(regionArea.Left + x, regionArea.Bottom);
|
||||
}
|
||||
|
||||
for (int y = 1; y < regionArea.Height; y++)
|
||||
{
|
||||
yield return new Point(regionArea.Left, regionArea.Top + y);
|
||||
yield return new Point(regionArea.Right, regionArea.Top + y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue