TShock/TShockAPI/Rest/RestManager.cs
Zack Piispanen 856def83b3 Added basic framework for allowing for ban durations and banning admin.
Added BanningUser, Date(of ban), and Expiration to the db
On join, Expiration is checked, if ban is expired we remove it and the user is allowed on.
When running the ban command, your UAN is used as the banning user, and the date is that moment, with no expiration.
#531
2013-09-22 16:04:12 -04:00

897 lines
29 KiB
C#

/*
TShock, a server mod for Terraria
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using HttpServer;
using Rests;
using Terraria;
using TShockAPI.DB;
namespace TShockAPI
{
public class RestManager
{
private Rest Rest;
public RestManager(Rest rest)
{
Rest = rest;
}
public void RegisterRestfulCommands()
{
// 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 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 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("/v3/server/rawcmd", ServerCommandV3, RestPermissions.restrawcommand));
Rest.Register(new SecureRestCommand("/tokentest", ServerTokenTest));
// User Commands
Rest.Register(new SecureRestCommand("/v2/users/activelist", UserActiveListV2, RestPermissions.restviewusers));
Rest.Register(new SecureRestCommand("/v2/users/create", UserCreateV2, RestPermissions.restmanageusers) { DoLog = false });
Rest.Register(new SecureRestCommand("/v2/users/list", UserListV2, RestPermissions.restviewusers));
Rest.Register(new SecureRestCommand("/v2/users/read", UserInfoV2, RestPermissions.restviewusers));
Rest.Register(new SecureRestCommand("/v2/users/destroy", UserDestroyV2, RestPermissions.restmanageusers));
Rest.Register(new SecureRestCommand("/v2/users/update", UserUpdateV2, RestPermissions.restmanageusers) { DoLog = false });
// Ban Commands
Rest.Register(new SecureRestCommand("/bans/create", BanCreate, RestPermissions.restmanagebans));
Rest.Register(new SecureRestCommand("/v2/bans/list", BanListV2, RestPermissions.restviewbans));
Rest.Register(new SecureRestCommand("/v2/bans/read", BanInfoV2, RestPermissions.restviewbans));
Rest.Register(new SecureRestCommand("/v2/bans/destroy", BanDestroyV2, RestPermissions.restmanagebans));
// World Commands
Rest.Register(new SecureRestCommand("/world/read", WorldRead));
Rest.Register(new SecureRestCommand("/world/meteor", WorldMeteor, RestPermissions.restcauseevents));
Rest.Register(new SecureRestCommand("/world/bloodmoon/{bool}", WorldBloodmoon, RestPermissions.restcauseevents));
Rest.Register(new SecureRestCommand("/v2/world/save", WorldSave, RestPermissions.restcfg));
Rest.Register(new SecureRestCommand("/v2/world/autosave/state/{bool}", WorldChangeSaveSettings, RestPermissions.restcfg));
Rest.Register(new SecureRestCommand("/v2/world/butcher", WorldButcher, RestPermissions.restbutcher));
// Player Commands
Rest.Register(new SecureRestCommand("/lists/players", PlayerList));
Rest.Register(new SecureRestCommand("/v2/players/list", PlayerListV2));
Rest.Register(new SecureRestCommand("/v2/players/read", PlayerReadV2, RestPermissions.restuserinfo));
Rest.Register(new SecureRestCommand("/v2/players/kick", PlayerKickV2, RestPermissions.restkick));
Rest.Register(new SecureRestCommand("/v2/players/ban", PlayerBanV2, RestPermissions.restban, RestPermissions.restmanagebans));
Rest.Register(new SecureRestCommand("/v2/players/kill", PlayerKill, RestPermissions.restkill));
Rest.Register(new SecureRestCommand("/v2/players/mute", PlayerMute, RestPermissions.restmute));
Rest.Register(new SecureRestCommand("/v2/players/unmute", PlayerUnMute, RestPermissions.restmute));
// Group Commands
Rest.Register(new SecureRestCommand("/v2/groups/list", GroupList, RestPermissions.restviewgroups));
Rest.Register(new SecureRestCommand("/v2/groups/read", GroupInfo, RestPermissions.restviewgroups));
Rest.Register(new SecureRestCommand("/v2/groups/destroy", GroupDestroy, RestPermissions.restmanagegroups));
Rest.Register(new SecureRestCommand("/v2/groups/create", GroupCreate, RestPermissions.restmanagegroups));
Rest.Register(new SecureRestCommand("/v2/groups/update", GroupUpdate, RestPermissions.restmanagegroups));
}
#region RestServerMethods
private object ServerCommand(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
if (string.IsNullOrWhiteSpace(parameters["cmd"]))
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();
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");
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();
TSRestPlayer tr = new TSRestPlayer(tokenData.Username, restPlayerGroup);
Commands.HandleCommand(tr, parameters["cmd"]);
return new RestObject()
{
{"response", tr.GetCommandOutput()}
};
}
private object ServerOff(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
if (!GetBool(parameters["confirm"], false))
return RestInvalidParam("confirm");
// Inform players the server is shutting down
var reason = string.IsNullOrWhiteSpace(parameters["message"]) ? "Server is shutting down" : parameters["message"];
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))
return RestInvalidParam("confirm");
// Inform players the server is shutting down
var reason = string.IsNullOrWhiteSpace(parameters["message"]) ? "Server is restarting" : parameters["message"];
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.");
}
private object ServerBroadcast(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var msg = parameters["msg"];
if (string.IsNullOrWhiteSpace(msg))
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");
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 ServerStatus(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var activeplayers = Main.player.Where(p => null != p && p.active).ToList();
return new RestObject()
{
{"name", TShock.Config.ServerName},
{"port", Convert.ToString(Netplay.serverPort)},
{"playercount", Convert.ToString(activeplayers.Count())},
{"players", string.Join(", ", activeplayers.Select(p => p.name))},
};
}
private object ServerStatusV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var ret = new RestObject()
{
{"name", TShock.Config.ServerName},
{"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")},
{"serverpassword", !string.IsNullOrEmpty(TShock.Config.ServerPassword)}
};
if (GetBool(parameters["players"], false))
{
var players = new ArrayList();
foreach (TSPlayer tsPlayer in TShock.Players.Where(p => null != p))
{
var p = PlayerFilter(tsPlayer, parameters);
if (null != p)
players.Add(p);
}
ret.Add("players", players);
}
if (GetBool(parameters["rules"], false))
{
var rules = new Dictionary<string,object>();
rules.Add("AutoSave", TShock.Config.AutoSave);
rules.Add("DisableBuild", TShock.Config.DisableBuild);
rules.Add("DisableClownBombs", TShock.Config.DisableClownBombs);
rules.Add("DisableDungeonGuardian", TShock.Config.DisableDungeonGuardian);
rules.Add("DisableInvisPvP", TShock.Config.DisableInvisPvP);
rules.Add("DisableSnowBalls", TShock.Config.DisableSnowBalls);
rules.Add("DisableTombstones", TShock.Config.DisableTombstones);
rules.Add("EnableWhitelist", TShock.Config.EnableWhitelist);
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("ServerSideInventory", TShock.Config.ServerSideInventory);
ret.Add("rules", rules);
}
return ret;
}
private object ServerTokenTest(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
return new RestObject()
{
{"response", "Token is valid and was passed through correctly."},
{"associateduser", tokenData.Username}
};
}
#endregion
#region RestUserMethods
private object UserActiveListV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
return new RestObject() { { "activeusers", string.Join("\t", TShock.Players.Where(p => null != p && null != p.UserAccountName && p.Active).Select(p => p.UserAccountName)) } };
}
private object UserListV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
return new RestObject() { { "users", TShock.Users.GetUsers().Select(p => new Dictionary<string,object>(){
{"name", p.Name},
{"id", p.ID},
{"group", p.Group},
}) } };
}
private object UserCreateV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var username = parameters["user"];
if (string.IsNullOrWhiteSpace(username))
return RestMissingParam("user");
var group = parameters["group"];
if (string.IsNullOrWhiteSpace(group))
group = TShock.Config.DefaultRegistrationGroupName;
var password = parameters["password"];
if (string.IsNullOrWhiteSpace(password))
return RestMissingParam("password");
// NOTE: ip can be blank
User user = new User(username, password, group, "", "");
try
{
TShock.Users.AddUser(user);
}
catch (Exception e)
{
return RestError(e.Message);
}
return RestResponse("User was successfully created");
}
private object UserUpdateV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var ret = UserFind(parameters);
if (ret is RestObject)
return ret;
var password = parameters["password"];
var group = parameters["group"];
if (string.IsNullOrWhiteSpace(group) && string.IsNullOrWhiteSpace(password))
return RestMissingParam("group", "password");
User user = (User)ret;
var response = new RestObject();
if (!string.IsNullOrWhiteSpace(password))
{
try
{
TShock.Users.SetUserPassword(user, password);
response.Add("password-response", "Password updated successfully");
}
catch (Exception e)
{
return RestError("Failed to update user password (" + e.Message + ")");
}
}
if (!string.IsNullOrWhiteSpace(group))
{
try
{
TShock.Users.SetUserGroup(user, group);
response.Add("group-response", "Group updated successfully");
}
catch (Exception e)
{
return RestError("Failed to update user group (" + e.Message + ")");
}
}
return response;
}
private object UserDestroyV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var ret = UserFind(parameters);
if (ret is RestObject)
return ret;
try
{
TShock.Users.RemoveUser((User)ret);
}
catch (Exception e)
{
return RestError(e.Message);
}
return RestResponse("User deleted successfully");
}
private object UserInfoV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var ret = UserFind(parameters);
if (ret is RestObject)
return ret;
User user = (User)ret;
return new RestObject() { { "group", user.Group }, { "id", user.ID.ToString() }, { "name", user.Name } };
}
#endregion
#region RestBanMethods
private object BanCreate(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var ip = parameters["ip"];
var name = parameters["name"];
if (string.IsNullOrWhiteSpace(ip) && string.IsNullOrWhiteSpace(name))
return RestMissingParam("ip", "name");
try
{
TShock.Bans.AddBan(ip, name, parameters["reason"], true, tokenData.Username);
}
catch (Exception e)
{
return RestError(e.Message);
}
return RestResponse("Ban created successfully");
}
private object BanDestroyV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var ret = BanFind(parameters);
if (ret is RestObject)
return ret;
try
{
Ban ban = (Ban)ret;
switch (parameters["type"])
{
case "ip":
if (!TShock.Bans.RemoveBan(ban.IP, false, false, true))
return RestResponse("Failed to delete ban (already deleted?)");
break;
case "name":
if (!TShock.Bans.RemoveBan(ban.Name, true, GetBool(parameters["caseinsensitive"], true)))
return RestResponse("Failed to delete ban (already deleted?)");
break;
default:
return RestError("Invalid Type: '" + parameters["type"] + "'");
}
}
catch (Exception e)
{
return RestError(e.Message);
}
return RestResponse("Ban deleted successfully");
}
private object BanInfoV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var ret = BanFind(parameters);
if (ret is RestObject)
return ret;
Ban ban = (Ban)ret;
return new RestObject() {
{"name", null == ban.Name ? "" : ban.Name},
{"ip", null == ban.IP ? "" : ban.IP},
{"reason", null == ban.Reason ? "" : ban.Reason},
};
}
private object BanListV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var banList = new ArrayList();
foreach (var ban in TShock.Bans.GetBans())
{
banList.Add(
new Dictionary<string, string>
{
{"name", null == ban.Name ? "" : ban.Name},
{"ip", null == ban.IP ? "" : ban.IP},
{"reason", null == ban.Reason ? "" : ban.Reason},
}
);
}
return new RestObject() { { "bans", banList } };
}
#endregion
#region RestWorldMethods
private object WorldChangeSaveSettings(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
bool autoSave;
if (!bool.TryParse(verbs["bool"], out autoSave))
return RestInvalidParam("state");
TShock.Config.AutoSave = autoSave;
return RestResponse("AutoSave has been set to " + autoSave);
}
private object WorldSave(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
SaveManager.Instance.SaveWorld();
return RestResponse("World saved");
}
private object WorldButcher(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
bool killFriendly;
if (!bool.TryParse(parameters["killfriendly"], out killFriendly))
return RestInvalidParam("killfriendly");
if (killFriendly)
killFriendly = !killFriendly;
int killcount = 0;
for (int i = 0; i < Main.npc.Length; i++)
{
if (Main.npc[i].active && Main.npc[i].type != 0 && !Main.npc[i].townNPC && (!Main.npc[i].friendly || killFriendly))
{
TSPlayer.Server.StrikeNPC(i, 99999, 90f, 1);
killcount++;
}
}
return RestResponse(killcount + " NPCs have been killed");
}
private object WorldRead(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
return new RestObject()
{
{"name", Main.worldName},
{"size", Main.maxTilesX + "*" + Main.maxTilesY},
{"time", Main.time},
{"daytime", Main.dayTime},
{"bloodmoon", Main.bloodMoon},
{"invasionsize", Main.invasionSize}
};
}
private object WorldMeteor(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
if (null == WorldGen.genRand)
WorldGen.genRand = new Random();
WorldGen.dropMeteor();
return RestResponse("Meteor has been spawned");
}
private object WorldBloodmoon(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
bool bloodmoon;
if (!bool.TryParse(verbs["bool"], out bloodmoon))
return RestInvalidParam("bloodmoon");
Main.bloodMoon = bloodmoon;
return RestResponse("Blood Moon has been set to " + bloodmoon);
}
#endregion
#region RestPlayerMethods
private object PlayerUnMute(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
return PlayerSetMute(parameters, false);
}
private object PlayerMute(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
return PlayerSetMute(parameters, true);
}
private object PlayerList(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var activeplayers = Main.player.Where(p => null != p && p.active).ToList();
return new RestObject() { { "players", string.Join(", ", activeplayers.Select(p => p.name)) } };
}
private object PlayerListV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var playerList = new ArrayList();
foreach (TSPlayer tsPlayer in TShock.Players.Where(p => null != p))
{
var p = PlayerFilter(tsPlayer, parameters);
if (null != p)
playerList.Add(p);
}
return new RestObject() { { "players", playerList } };
}
private object PlayerReadV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var ret = PlayerFind(parameters);
if (ret is RestObject)
return ret;
TSPlayer player = (TSPlayer)ret;
var activeItems = player.TPlayer.inventory.Where(p => p.active).ToList();
return new RestObject()
{
{"nickname", player.Name},
{"username", null == player.UserAccountName ? "" : player.UserAccountName},
{"ip", player.IP},
{"group", player.Group.Name},
{"position", player.TileX + "," + player.TileY},
{"inventory", string.Join(", ", activeItems.Select(p => (p.name + ":" + p.stack)))},
{"buffs", string.Join(", ", player.TPlayer.buffType)}
};
}
private object PlayerKickV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var ret = PlayerFind(parameters);
if (ret is RestObject)
return ret;
TSPlayer player = (TSPlayer)ret;
TShock.Utils.ForceKick(player, null == parameters["reason"] ? "Kicked via web" : parameters["reason"], false, true);
return RestResponse("Player " + player.Name + " was kicked");
}
private object PlayerBanV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var ret = PlayerFind(parameters);
if (ret is RestObject)
return ret;
TSPlayer player = (TSPlayer)ret;
var reason = null == parameters["reason"] ? "Banned via web" : parameters["reason"];
TShock.Bans.AddBan(player.IP, player.Name, reason);
TShock.Utils.ForceKick(player, reason, false, true);
return RestResponse("Player " + player.Name + " was banned");
}
private object PlayerKill(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var ret = PlayerFind(parameters);
if (ret is RestObject)
return ret;
TSPlayer player = (TSPlayer)ret;
player.DamagePlayer(999999);
var from = string.IsNullOrWhiteSpace(parameters["from"]) ? "Server Admin" : parameters["from"];
player.SendMessage(string.Format("{0} just killed you!", from));
return RestResponse("Player " + player.Name + " was killed");
}
#endregion
#region RestGroupMethods
private object GroupList(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var groups = new ArrayList();
foreach (Group group in TShock.Groups)
{
groups.Add(new Dictionary<string, object> {{"name", group.Name}, {"parent", group.ParentName}, {"chatcolor", group.ChatColor}});
}
return new RestObject() { { "groups", groups } };
}
private object GroupInfo(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var ret = GroupFind(parameters);
if (ret is RestObject)
return ret;
Group group = (Group)ret;
return new RestObject() {
{"name", group.Name},
{"parent", group.ParentName},
{"chatcolor", string.Format("{0},{1},{2}", group.R, group.G, group.B)},
{"permissions", group.permissions},
{"negatedpermissions", group.negatedpermissions},
{"totalpermissions", group.TotalPermissions}
};
}
private object GroupDestroy(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var ret = GroupFind(parameters);
if (ret is RestObject)
return ret;
Group group = (Group)ret;
try
{
TShock.Groups.DeleteGroup(group.Name, true);
}
catch (Exception e)
{
return RestError(e.Message);
}
return RestResponse("Group '" + group.Name + "' deleted successfully");
}
private object GroupCreate(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var name = parameters["group"];
if (string.IsNullOrWhiteSpace(name))
return RestMissingParam("group");
try
{
TShock.Groups.AddGroup(name, parameters["parent"], parameters["permissions"], parameters["chatcolor"], true);
}
catch (Exception e)
{
return RestError(e.Message);
}
return RestResponse("Group '" + name + "' created successfully");
}
private object GroupUpdate(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
{
var ret = GroupFind(parameters);
if (ret is RestObject)
return ret;
Group group = (Group)ret;
var parent = (null == parameters["parent"]) ? group.ParentName : parameters["parent"];
var chatcolor = (null == parameters["chatcolor"]) ? string.Format("{0}.{1}.{2}", group.R, group.G, group.B) : parameters["chatcolor"];
var permissions = (null == parameters["permissions"]) ? group.Permissions : parameters["permissions"];
try
{
TShock.Groups.UpdateGroup(group.Name, parent, permissions, chatcolor);
}
catch (Exception e)
{
return RestError(e.Message);
}
return RestResponse("Group '" + group.Name + "' updated successfully");
}
#endregion
#region Utility Methods
private RestObject RestError(string message, string status = "400")
{
return new RestObject(status) {Error = message};
}
private RestObject RestResponse(string message, string status = "200")
{
return new RestObject(status) {Response = message};
}
private RestObject RestMissingParam(string var)
{
return RestError("Missing or empty " + var + " parameter");
}
private RestObject RestMissingParam(params string[] vars)
{
return RestMissingParam(string.Join(", ", vars));
}
private RestObject RestInvalidParam(string var)
{
return RestError("Missing or invalid " + var + " parameter");
}
private bool GetBool(string val, bool def)
{
bool ret;
return bool.TryParse(val, out ret) ? ret : def;
}
private object PlayerFind(IParameterCollection parameters)
{
string name = parameters["player"];
if (string.IsNullOrWhiteSpace(name))
return RestMissingParam("player");
var found = TShock.Utils.FindPlayer(name);
switch(found.Count)
{
case 1:
return found[0];
case 0:
return RestError("Player " + name + " was not found");
default:
return RestError("Player " + name + " matches " + found.Count + " players");
}
}
private object UserFind(IParameterCollection parameters)
{
string name = parameters["user"];
if (string.IsNullOrWhiteSpace(name))
return RestMissingParam("user");
User user;
string type = parameters["type"];
try
{
switch (type)
{
case null:
case "name":
type = "name";
user = TShock.Users.GetUserByName(name);
break;
case "id":
user = TShock.Users.GetUserByID(Convert.ToInt32(name));
break;
default:
return RestError("Invalid Type: '" + type + "'");
}
}
catch (Exception e)
{
return RestError(e.Message);
}
if (null == user)
return RestError(String.Format("User {0} '{1}' doesn't exist", type, name));
return user;
}
private object BanFind(IParameterCollection parameters)
{
string name = parameters["ban"];
if (string.IsNullOrWhiteSpace(name))
return RestMissingParam("ban");
string type = parameters["type"];
if (string.IsNullOrWhiteSpace(type))
return RestMissingParam("type");
Ban ban;
switch (type)
{
case "ip":
ban = TShock.Bans.GetBanByIp(name);
break;
case "name":
ban = TShock.Bans.GetBanByName(name, GetBool(parameters["caseinsensitive"], true));
break;
default:
return RestError("Invalid Type: '" + type + "'");
}
if (null == ban)
return RestError("Ban " + type + " '" + name + "' doesn't exist");
return ban;
}
private object GroupFind(IParameterCollection parameters)
{
var name = parameters["group"];
if (string.IsNullOrWhiteSpace(name))
return RestMissingParam("group");
var group = TShock.Groups.GetGroupByName(name);
if (null == group)
return RestError("Group '" + name + "' doesn't exist");
return group;
}
private Dictionary<string, object> PlayerFilter(TSPlayer tsPlayer, IParameterCollection parameters)
{
var player = new Dictionary<string, object>
{
{"nickname", tsPlayer.Name},
{"username", null == tsPlayer.UserAccountName ? "" : tsPlayer.UserAccountName},
{"ip", tsPlayer.IP},
{"group", tsPlayer.Group.Name},
{"active", tsPlayer.Active},
{"state", tsPlayer.State},
{"team", tsPlayer.Team},
};
foreach (IParameter filter in parameters)
{
if (player.ContainsKey(filter.Name) && !player[filter.Name].Equals(filter.Value))
return null;
}
return player;
}
private object PlayerSetMute(IParameterCollection parameters, bool mute)
{
var ret = PlayerFind(parameters);
if (ret is RestObject)
return ret;
TSPlayer player = (TSPlayer)ret;
player.mute = mute;
var verb = mute ? "muted" : "unmuted";
player.SendMessage("You have been remotely " + verb);
return RestResponse("Player " + player.Name + " was " + verb);
}
#endregion
}
}