From 4b77ca549ee2ac115ac44441a1d2c50bb78b4631 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Sun, 1 Jan 2012 18:46:06 -0700 Subject: [PATCH 01/18] Users shouldn't "leave" when they enter an incorrect password anymore. Just as soon as someone reimplements the OnLeave hook. --- TShockAPI/ConfigFile.cs | 2 +- TShockAPI/GetDataHandlers.cs | 2 +- TShockAPI/TSPlayer.cs | 1 + TShockAPI/TShock.cs | 6 +++++- TShockAPI/Utils.cs | 9 +++++++++ 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/TShockAPI/ConfigFile.cs b/TShockAPI/ConfigFile.cs index 67af949a..c708f7b3 100644 --- a/TShockAPI/ConfigFile.cs +++ b/TShockAPI/ConfigFile.cs @@ -83,7 +83,7 @@ namespace TShockAPI [Description("Not implemented")] public string RconPassword = ""; [Description("Not implemented")] public int RconPort = 7777; - [Description("Not implemented")] public string ServerName = ""; + [Description("Used when replying to a rest /status request.")] public string ServerName = ""; [Description("Not implemented")] public string MasterServer = "127.0.0.1"; [Description("Valid types are \"sqlite\" and \"mysql\"")] public string StorageType = "sqlite"; diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 558604ca..b67d184e 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -932,7 +932,7 @@ namespace TShockAPI Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user: " + args.Player.Name); return true; } - TShock.Utils.ForceKick(args.Player, "Incorrect User Account Password"); + TShock.Utils.ForceKick(args.Player, "Invalid user account password.", true); return true; } if (!string.IsNullOrEmpty(TShock.Config.ServerPassword)) diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 7752778f..974e5e35 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -73,6 +73,7 @@ namespace TShockAPI public bool IgnoreActionsForClearingTrashCan; public PlayerData PlayerData; public bool RequiresPassword; + public bool SilentKickInProgress; public bool RealPlayer { diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 39af00a7..9c258133 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -656,7 +656,11 @@ namespace TShockAPI if (tsplr != null && tsplr.ReceivedInfo) { - Utils.Broadcast(tsplr.Name + " has left", Color.Yellow); + if (!tsplr.SilentKickInProgress) + { + Utils.Broadcast(tsplr.Name + " left", Color.Yellow); + } + Log.Info(string.Format("{0} left.", tsplr.Name)); if (tsplr.IsLoggedIn) diff --git a/TShockAPI/Utils.cs b/TShockAPI/Utils.cs index b77f93f4..95338ba3 100644 --- a/TShockAPI/Utils.cs +++ b/TShockAPI/Utils.cs @@ -408,6 +408,15 @@ namespace TShockAPI Log.ConsoleInfo(string.Format("{0} was force kicked for : {1}", player.IP, reason)); } + public void ForceKick(TSPlayer player, string reason, bool silent) + { + player.SilentKickInProgress = true; + if (!player.ConnectionAlive) + return; + player.Disconnect(reason); + Log.ConsoleInfo(string.Format("{0} was force kicked for : {1}", player.IP, reason)); + } + /// /// Kicks a player from the server. /// From d14c7c40c949f5768f1834e25ede9799e3c8a089 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Sun, 1 Jan 2012 23:18:18 -0700 Subject: [PATCH 02/18] Fix players "leaving" when they never joined. --- TShockAPI/TShock.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 9c258133..7a7dbb5a 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -651,6 +651,7 @@ namespace TShockAPI private void OnLeave(int ply) { + var tsplr = Players[ply]; Players[ply] = null; From f71d2c1a64d5a5cd5e37ea2ba231133d96a0421b Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Mon, 2 Jan 2012 00:13:26 -0700 Subject: [PATCH 03/18] Add REST endpoint: - /v2/players/kill --- TShockAPI/Rest/RestManager.cs | 512 ++++++++++++++++++---------------- 1 file changed, 270 insertions(+), 242 deletions(-) diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs index 6013297b..ba531ddc 100644 --- a/TShockAPI/Rest/RestManager.cs +++ b/TShockAPI/Rest/RestManager.cs @@ -57,6 +57,7 @@ namespace TShockAPI Rest.Register(new RestCommand("/v2/players/read", PlayerReadV2) { RequiresToken = true }); Rest.Register(new RestCommand("/v2/players/kick", PlayerKickV2) { RequiresToken = true }); Rest.Register(new RestCommand("/v2/players/ban", PlayerBanV2) { RequiresToken = true }); + Rest.Register(new RestCommand("/v2/players/kill", PlayerKill) {RequiresToken = true}); #region Deprecated Endpoints Rest.Register(new RestCommand("/bans/read/{user}/info", BanInfo) { RequiresToken = true }); @@ -198,248 +199,6 @@ namespace TShockAPI #endregion - #region Deperecated endpoints - - private object UserUpdate(RestVerbs verbs, IParameterCollection parameters) - { - var returnBlock = new Dictionary(); - var password = parameters["password"]; - var group = parameters["group"]; - - if (group == null && password == null) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "No parameters were passed."); - return returnBlock; - } - - var user = TShock.Users.GetUserByName(verbs["user"]); - if (user == null) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "The specefied user doesn't exist."); - return returnBlock; - } - - if (password != null) - { - TShock.Users.SetUserPassword(user, password); - returnBlock.Add("password-response", "Password updated successfully."); - } - - if (group != null) - { - TShock.Users.SetUserGroup(user, group); - returnBlock.Add("group-response", "Group updated successfully."); - } - - returnBlock.Add("status", "200"); - returnBlock.Add("deprecated", "This endpoint is deprecated. It will be fully removed from code in TShock 3.6."); - return returnBlock; - } - - private object UserDestroy(RestVerbs verbs, IParameterCollection parameters) - { - var user = TShock.Users.GetUserByName(verbs["user"]); - if (user == null) - { - return new Dictionary { { "status", "400" }, { "error", "The specified user account does not exist." } }; - } - var returnBlock = new Dictionary(); - try - { - TShock.Users.RemoveUser(user); - } - catch (Exception) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "The specified user was unable to be removed."); - return returnBlock; - } - returnBlock.Add("status", "200"); - returnBlock.Add("response", "User deleted successfully."); - returnBlock.Add("deprecated", "This endpoint is deprecated. It will be fully removed from code in TShock 3.6."); - return returnBlock; - } - - private object UserInfo(RestVerbs verbs, IParameterCollection parameters) - { - var user = TShock.Users.GetUserByName(verbs["user"]); - if (user == null) - { - return new Dictionary { { "status", "400" }, { "error", "The specified user account does not exist." } }; - } - - var returnBlock = new Dictionary(); - returnBlock.Add("status", "200"); - returnBlock.Add("group", user.Group); - returnBlock.Add("id", user.ID.ToString()); - returnBlock.Add("deprecated", "This endpoint is deprecated. It will be fully removed from code in TShock 3.6."); - return returnBlock; - } - - private object BanDestroy(RestVerbs verbs, IParameterCollection parameters) - { - var returnBlock = new Dictionary(); - - var type = parameters["type"]; - if (type == null) - { - returnBlock.Add("Error", "Invalid Type"); - return returnBlock; - } - - var ban = new Ban(); - if (type == "ip") ban = TShock.Bans.GetBanByIp(verbs["user"]); - else if (type == "name") ban = TShock.Bans.GetBanByName(verbs["user"]); - else - { - returnBlock.Add("Error", "Invalid Type"); - return returnBlock; - } - - if (ban == null) - { - return new Dictionary { { "status", "400" }, { "error", "The specified ban does not exist." } }; - } - - try - { - TShock.Bans.RemoveBan(ban.IP); - } - catch (Exception) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "The specified ban was unable to be removed."); - return returnBlock; - } - returnBlock.Add("status", "200"); - returnBlock.Add("response", "Ban deleted successfully."); - returnBlock.Add("deprecated", "This endpoint is deprecated. It will be fully removed from code in TShock 3.6."); - return returnBlock; - } - - private object PlayerRead(RestVerbs verbs, IParameterCollection parameters) - { - var returnBlock = new Dictionary(); - var playerParam = verbs["player"]; - var found = TShock.Utils.FindPlayer(playerParam); - if (found.Count == 0) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "Name " + playerParam + " was not found"); - } - else if (found.Count > 1) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "Name " + playerParam + " matches " + playerParam.Count() + " players"); - } - else if (found.Count == 1) - { - var player = found[0]; - returnBlock.Add("status", "200"); - returnBlock.Add("nickname", player.Name); - returnBlock.Add("username", player.UserAccountName == null ? "" : player.UserAccountName); - returnBlock.Add("ip", player.IP); - returnBlock.Add("group", player.Group.Name); - returnBlock.Add("position", player.TileX + "," + player.TileY); - var activeItems = player.TPlayer.inventory.Where(p => p.active).ToList(); - returnBlock.Add("inventory", string.Join(", ", activeItems.Select(p => p.name))); - returnBlock.Add("buffs", string.Join(", ", player.TPlayer.buffType)); - } - returnBlock.Add("deprecated", "This endpoint is deprecated. It will be fully removed from code in TShock 3.6."); - return returnBlock; - } - - private object PlayerKick(RestVerbs verbs, IParameterCollection parameters) - { - var returnBlock = new Dictionary(); - var playerParam = verbs["player"]; - var found = TShock.Utils.FindPlayer(playerParam); - var reason = verbs["reason"]; - if (found.Count == 0) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "Name " + playerParam + " was not found"); - } - else if (found.Count > 1) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "Name " + playerParam + " matches " + playerParam.Count() + " players"); - } - else if (found.Count == 1) - { - var player = found[0]; - TShock.Utils.ForceKick(player, reason == null ? "Kicked via web" : reason); - returnBlock.Add("status", "200"); - returnBlock.Add("response", "Player " + player.Name + " was kicked"); - } - returnBlock.Add("deprecated", "This endpoint is deprecated. It will be fully removed from code in TShock 3.6."); - return returnBlock; - } - - private object PlayerBan(RestVerbs verbs, IParameterCollection parameters) - { - var returnBlock = new Dictionary(); - var playerParam = verbs["player"]; - var found = TShock.Utils.FindPlayer(playerParam); - var reason = verbs["reason"]; - if (found.Count == 0) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "Name " + playerParam + " was not found"); - } - else if (found.Count > 1) - { - returnBlock.Add("status", "400"); - returnBlock.Add("error", "Name " + playerParam + " matches " + playerParam.Count() + " players"); - } - else if (found.Count == 1) - { - var player = found[0]; - TShock.Bans.AddBan(player.IP, player.Name, reason == null ? "Banned via web" : reason); - TShock.Utils.ForceKick(player, reason == null ? "Banned via web" : reason); - returnBlock.Add("status", "200"); - returnBlock.Add("response", "Player " + player.Name + " was banned"); - } - returnBlock.Add("deprecated", "This endpoint is deprecated. It will be fully removed from code in TShock 3.6."); - return returnBlock; - } - - private object BanInfo(RestVerbs verbs, IParameterCollection parameters) - { - var returnBlock = new Dictionary(); - - var type = parameters["type"]; - if (type == null) - { - returnBlock.Add("Error", "Invalid Type"); - return returnBlock; - } - - var ban = new Ban(); - if (type == "ip") ban = TShock.Bans.GetBanByIp(verbs["user"]); - else if (type == "name") ban = TShock.Bans.GetBanByName(verbs["user"]); - else - { - returnBlock.Add("Error", "Invalid Type"); - return returnBlock; - } - - if (ban == null) - { - return new Dictionary { { "status", "400" }, { "error", "The specified ban does not exist." } }; - } - - returnBlock.Add("status", "200"); - returnBlock.Add("name", ban.Name); - returnBlock.Add("ip", ban.IP); - returnBlock.Add("reason", ban.Reason); - returnBlock.Add("deprecated", "This endpoint is deprecated. It will be fully removed from code in TShock 3.6."); - return returnBlock; - } - #endregion - #region RestBanMethods private object BanCreate(RestVerbs verbs, IParameterCollection parameters) @@ -704,6 +463,33 @@ namespace TShockAPI return returnBlock; } + private object PlayerKill(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); + var playerParam = parameters["player"]; + var found = TShock.Utils.FindPlayer(playerParam); + var from = verbs["from"]; + if (found.Count == 0) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " was not found"); + } + else if (found.Count > 1) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " matches " + playerParam.Count() + " players"); + } + else if (found.Count == 1) + { + var player = found[0]; + player.DamagePlayer(999999); + player.SendMessage(string.Format("{0} just killed you!", from)); + returnBlock.Add("status", "200"); + returnBlock.Add("response", "Player " + player.Name + " was killed."); + } + return returnBlock; + } + #endregion #region RestExampleMethods @@ -745,5 +531,247 @@ namespace TShockAPI } #endregion + + #region Deperecated endpoints + + private object UserUpdate(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); + var password = parameters["password"]; + var group = parameters["group"]; + + if (group == null && password == null) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "No parameters were passed."); + return returnBlock; + } + + var user = TShock.Users.GetUserByName(verbs["user"]); + if (user == null) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "The specefied user doesn't exist."); + return returnBlock; + } + + if (password != null) + { + TShock.Users.SetUserPassword(user, password); + returnBlock.Add("password-response", "Password updated successfully."); + } + + if (group != null) + { + TShock.Users.SetUserGroup(user, group); + returnBlock.Add("group-response", "Group updated successfully."); + } + + returnBlock.Add("status", "200"); + returnBlock.Add("deprecated", "This endpoint is deprecated. It will be fully removed from code in TShock 3.6."); + return returnBlock; + } + + private object UserDestroy(RestVerbs verbs, IParameterCollection parameters) + { + var user = TShock.Users.GetUserByName(verbs["user"]); + if (user == null) + { + return new Dictionary { { "status", "400" }, { "error", "The specified user account does not exist." } }; + } + var returnBlock = new Dictionary(); + try + { + TShock.Users.RemoveUser(user); + } + catch (Exception) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "The specified user was unable to be removed."); + return returnBlock; + } + returnBlock.Add("status", "200"); + returnBlock.Add("response", "User deleted successfully."); + returnBlock.Add("deprecated", "This endpoint is deprecated. It will be fully removed from code in TShock 3.6."); + return returnBlock; + } + + private object UserInfo(RestVerbs verbs, IParameterCollection parameters) + { + var user = TShock.Users.GetUserByName(verbs["user"]); + if (user == null) + { + return new Dictionary { { "status", "400" }, { "error", "The specified user account does not exist." } }; + } + + var returnBlock = new Dictionary(); + returnBlock.Add("status", "200"); + returnBlock.Add("group", user.Group); + returnBlock.Add("id", user.ID.ToString()); + returnBlock.Add("deprecated", "This endpoint is deprecated. It will be fully removed from code in TShock 3.6."); + return returnBlock; + } + + private object BanDestroy(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); + + var type = parameters["type"]; + if (type == null) + { + returnBlock.Add("Error", "Invalid Type"); + return returnBlock; + } + + var ban = new Ban(); + if (type == "ip") ban = TShock.Bans.GetBanByIp(verbs["user"]); + else if (type == "name") ban = TShock.Bans.GetBanByName(verbs["user"]); + else + { + returnBlock.Add("Error", "Invalid Type"); + return returnBlock; + } + + if (ban == null) + { + return new Dictionary { { "status", "400" }, { "error", "The specified ban does not exist." } }; + } + + try + { + TShock.Bans.RemoveBan(ban.IP); + } + catch (Exception) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "The specified ban was unable to be removed."); + return returnBlock; + } + returnBlock.Add("status", "200"); + returnBlock.Add("response", "Ban deleted successfully."); + returnBlock.Add("deprecated", "This endpoint is deprecated. It will be fully removed from code in TShock 3.6."); + return returnBlock; + } + + private object PlayerRead(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); + var playerParam = verbs["player"]; + var found = TShock.Utils.FindPlayer(playerParam); + if (found.Count == 0) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " was not found"); + } + else if (found.Count > 1) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " matches " + playerParam.Count() + " players"); + } + else if (found.Count == 1) + { + var player = found[0]; + returnBlock.Add("status", "200"); + returnBlock.Add("nickname", player.Name); + returnBlock.Add("username", player.UserAccountName == null ? "" : player.UserAccountName); + returnBlock.Add("ip", player.IP); + returnBlock.Add("group", player.Group.Name); + returnBlock.Add("position", player.TileX + "," + player.TileY); + var activeItems = player.TPlayer.inventory.Where(p => p.active).ToList(); + returnBlock.Add("inventory", string.Join(", ", activeItems.Select(p => p.name))); + returnBlock.Add("buffs", string.Join(", ", player.TPlayer.buffType)); + } + returnBlock.Add("deprecated", "This endpoint is deprecated. It will be fully removed from code in TShock 3.6."); + return returnBlock; + } + + private object PlayerKick(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); + var playerParam = verbs["player"]; + var found = TShock.Utils.FindPlayer(playerParam); + var reason = verbs["reason"]; + if (found.Count == 0) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " was not found"); + } + else if (found.Count > 1) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " matches " + playerParam.Count() + " players"); + } + else if (found.Count == 1) + { + var player = found[0]; + TShock.Utils.ForceKick(player, reason == null ? "Kicked via web" : reason); + returnBlock.Add("status", "200"); + returnBlock.Add("response", "Player " + player.Name + " was kicked"); + } + returnBlock.Add("deprecated", "This endpoint is deprecated. It will be fully removed from code in TShock 3.6."); + return returnBlock; + } + + private object PlayerBan(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); + var playerParam = verbs["player"]; + var found = TShock.Utils.FindPlayer(playerParam); + var reason = verbs["reason"]; + if (found.Count == 0) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " was not found"); + } + else if (found.Count > 1) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " matches " + playerParam.Count() + " players"); + } + else if (found.Count == 1) + { + var player = found[0]; + TShock.Bans.AddBan(player.IP, player.Name, reason == null ? "Banned via web" : reason); + TShock.Utils.ForceKick(player, reason == null ? "Banned via web" : reason); + returnBlock.Add("status", "200"); + returnBlock.Add("response", "Player " + player.Name + " was banned"); + } + returnBlock.Add("deprecated", "This endpoint is deprecated. It will be fully removed from code in TShock 3.6."); + return returnBlock; + } + + private object BanInfo(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); + + var type = parameters["type"]; + if (type == null) + { + returnBlock.Add("Error", "Invalid Type"); + return returnBlock; + } + + var ban = new Ban(); + if (type == "ip") ban = TShock.Bans.GetBanByIp(verbs["user"]); + else if (type == "name") ban = TShock.Bans.GetBanByName(verbs["user"]); + else + { + returnBlock.Add("Error", "Invalid Type"); + return returnBlock; + } + + if (ban == null) + { + return new Dictionary { { "status", "400" }, { "error", "The specified ban does not exist." } }; + } + + returnBlock.Add("status", "200"); + returnBlock.Add("name", ban.Name); + returnBlock.Add("ip", ban.IP); + returnBlock.Add("reason", ban.Reason); + returnBlock.Add("deprecated", "This endpoint is deprecated. It will be fully removed from code in TShock 3.6."); + return returnBlock; + } + #endregion } } \ No newline at end of file From 932dc9109cb0c5b0759020d55773e9cf5a9c0b03 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Mon, 2 Jan 2012 00:33:27 -0700 Subject: [PATCH 04/18] Added new REST endpoint: - /v2/world/butcher --- TShockAPI/Rest/RestManager.cs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs index ba531ddc..9bac6b9f 100644 --- a/TShockAPI/Rest/RestManager.cs +++ b/TShockAPI/Rest/RestManager.cs @@ -53,6 +53,7 @@ namespace TShockAPI Rest.Register(new RestCommand("/world/read", WorldRead) {RequiresToken = true}); Rest.Register(new RestCommand("/world/meteor", WorldMeteor) {RequiresToken = true}); Rest.Register(new RestCommand("/world/bloodmoon/{bool}", WorldBloodmoon) {RequiresToken = true}); + Rest.Register(new RestCommand("/v2/world/butcher", Butcher) {RequiresToken = true}); Rest.Register(new RestCommand("/v2/players/read", PlayerReadV2) { RequiresToken = true }); Rest.Register(new RestCommand("/v2/players/kick", PlayerKickV2) { RequiresToken = true }); @@ -321,6 +322,30 @@ namespace TShockAPI #region RestWorldMethods + private object Butcher(RestVerbs verbs, IParameterCollection parameters) + { + bool killFriendly; + if (!bool.TryParse(parameters["killfriendly"], out killFriendly)) + { + return new RestObject("500")["response"] = "The given value for killfriendly wasn't a boolean value."; + } + 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 new RestObject("200")["response"] = killcount + " NPCs have been killed."; + } + private object WorldRead(RestVerbs verbs, IParameterCollection parameters) { var returnBlock = new Dictionary(); @@ -415,7 +440,7 @@ namespace TShockAPI var returnBlock = new Dictionary(); var playerParam = parameters["player"]; var found = TShock.Utils.FindPlayer(playerParam); - var reason = verbs["reason"]; + var reason = parameters["reason"]; if (found.Count == 0) { returnBlock.Add("status", "400"); From 0498d30b4e36f230c2a441fcfe88569fa633bed8 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Mon, 2 Jan 2012 00:47:00 -0700 Subject: [PATCH 05/18] Add /v2/server/broadcast REST endpoint --- TShockAPI/Rest/RestManager.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs index 9bac6b9f..fbfd6f64 100644 --- a/TShockAPI/Rest/RestManager.cs +++ b/TShockAPI/Rest/RestManager.cs @@ -60,6 +60,8 @@ namespace TShockAPI Rest.Register(new RestCommand("/v2/players/ban", PlayerBanV2) { RequiresToken = true }); Rest.Register(new RestCommand("/v2/players/kill", PlayerKill) {RequiresToken = true}); + Rest.Register(new RestCommand("/v2/server/broadcast", Broadcast) { RequiresToken = true}); + #region Deprecated Endpoints Rest.Register(new RestCommand("/bans/read/{user}/info", BanInfo) { RequiresToken = true }); Rest.Register(new RestCommand("/bans/destroy/{user}", BanDestroy) { RequiresToken = true }); @@ -73,9 +75,22 @@ namespace TShockAPI Rest.Register(new RestCommand("/players/{player}/ban", PlayerBan) { RequiresToken = true }); #endregion - //RegisterExamples(); } + #region RestServerMethods + + private object Broadcast(RestVerbs verbs, IParameterCollection parameters) + { + if (parameters["msg"] != null && parameters["msg"].Trim() != "") + { + TShock.Utils.Broadcast(parameters["msg"]); + return new RestObject("200")["response"] = "The message was broadcasted to all connected clients successfully."; + } + return new RestObject("500")["response"] = "Invalid msg parameter passed to REST. Cowardly not broadcasting a blank message."; + } + + #endregion + #region RestMethods private object TokenTest(RestVerbs verbs, IParameterCollection parameters) From b9df823f417e72a95070475e63f973b96b434c47 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Mon, 2 Jan 2012 00:57:03 -0700 Subject: [PATCH 06/18] Add the /v2/server/off endpoint --- TShockAPI/Rest/RestManager.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs index fbfd6f64..e7ea0425 100644 --- a/TShockAPI/Rest/RestManager.cs +++ b/TShockAPI/Rest/RestManager.cs @@ -61,6 +61,7 @@ namespace TShockAPI Rest.Register(new RestCommand("/v2/players/kill", PlayerKill) {RequiresToken = true}); Rest.Register(new RestCommand("/v2/server/broadcast", Broadcast) { RequiresToken = true}); + Rest.Register(new RestCommand("/v2/server/off", Off) {RequiresToken = true}); #region Deprecated Endpoints Rest.Register(new RestCommand("/bans/read/{user}/info", BanInfo) { RequiresToken = true }); @@ -79,6 +80,21 @@ namespace TShockAPI #region RestServerMethods + private object Off(RestVerbs verbs, IParameterCollection parameters) + { + bool confirm; + bool.TryParse(parameters["confirm"], out confirm); + bool nosave; + bool.TryParse(parameters["nosave"], out nosave); + if (confirm == true) + { + if (!nosave) + WorldGen.saveWorld(); + Netplay.disconnect = true; + } + return new RestObject("200")["response"] = "The server will shut down only if the parameter 'confirm' is set to true in this REST call. You will not recieve a reply."; + } + private object Broadcast(RestVerbs verbs, IParameterCollection parameters) { if (parameters["msg"] != null && parameters["msg"].Trim() != "") From 42f8978e8fe260aef5901cb59ab8d07cc4c86ee9 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Mon, 2 Jan 2012 00:58:58 -0700 Subject: [PATCH 07/18] Remove old UpdateNow method --- TShockAPI/Commands.cs | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index de663943..e31a02d9 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -953,39 +953,6 @@ namespace TShockAPI ThreadPool.QueueUserWorkItem(UpdateManager.CheckUpdate); } - [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] - private static void UpdateNow(CommandArgs args) - { - Process TServer = Process.GetCurrentProcess(); - - using (var sw = new StreamWriter("pid")) - { - sw.Write(TServer.Id); - } - - using (var sw = new StreamWriter("pn")) - { - sw.Write(TServer.ProcessName + " " + Environment.CommandLine); - } - - using (var client = new WebClient()) - { - client.Headers.Add("user-agent", "TShock"); - byte[] updatefile = client.DownloadData("http://tsupdate.shankshock.com/UpdateTShock.exe"); - - using (var bw = new BinaryWriter(new FileStream("UpdateTShock.exe", FileMode.Create))) - { - bw.Write(updatefile); - } - } - - Process.Start(new ProcessStartInfo("UpdateTShock.exe")); - - TShock.Utils.ForceKickAll("Server shutting down for update!"); - WorldGen.saveWorld(); - Netplay.disconnect = true; - } - #endregion Server Maintenence Commands #region Cause Events and Spawn Monsters Commands From e813ac8f87f990351b2db6cbcbae4b419336f29e Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Mon, 2 Jan 2012 01:49:01 -0700 Subject: [PATCH 08/18] Fix /v2/players/ban using verb instead of param (thanks @radishes) --- TShockAPI/Rest/RestManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs index e7ea0425..c53b69eb 100644 --- a/TShockAPI/Rest/RestManager.cs +++ b/TShockAPI/Rest/RestManager.cs @@ -497,7 +497,7 @@ namespace TShockAPI var returnBlock = new Dictionary(); var playerParam = parameters["player"]; var found = TShock.Utils.FindPlayer(playerParam); - var reason = verbs["reason"]; + var reason = parameters["reason"]; if (found.Count == 0) { returnBlock.Add("status", "400"); From 4f07567eeb40a56ca8d04fc2277ead2bd2b493fe Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Mon, 2 Jan 2012 02:07:19 -0700 Subject: [PATCH 09/18] Add REST endpoints: - /v2/players/mute - /v2/players/unmute --- TShockAPI/Rest/RestManager.cs | 56 +++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs index c53b69eb..a0fd3c2e 100644 --- a/TShockAPI/Rest/RestManager.cs +++ b/TShockAPI/Rest/RestManager.cs @@ -59,6 +59,8 @@ namespace TShockAPI Rest.Register(new RestCommand("/v2/players/kick", PlayerKickV2) { RequiresToken = true }); Rest.Register(new RestCommand("/v2/players/ban", PlayerBanV2) { RequiresToken = true }); Rest.Register(new RestCommand("/v2/players/kill", PlayerKill) {RequiresToken = true}); + Rest.Register(new RestCommand("/v2/players/mute", PlayerMute) {RequiresToken = true}); + Rest.Register(new RestCommand("/v2/players/unmute", PlayerUnMute) {RequiresToken = true}); Rest.Register(new RestCommand("/v2/server/broadcast", Broadcast) { RequiresToken = true}); Rest.Register(new RestCommand("/v2/server/off", Off) {RequiresToken = true}); @@ -426,6 +428,60 @@ namespace TShockAPI #region RestPlayerMethods + private object PlayerUnMute(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); + var playerParam = parameters["player"]; + var found = TShock.Utils.FindPlayer(playerParam); + var reason = parameters["reason"]; + if (found.Count == 0) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " was not found"); + } + else if (found.Count > 1) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " matches " + playerParam.Count() + " players"); + } + else if (found.Count == 1) + { + var player = found[0]; + player.mute = false; + player.SendMessage("You have been remotely unmuted."); + returnBlock.Add("status", "200"); + returnBlock.Add("response", "Player " + player.Name + " was muted."); + } + return returnBlock; + } + + private object PlayerMute(RestVerbs verbs, IParameterCollection parameters) + { + var returnBlock = new Dictionary(); + var playerParam = parameters["player"]; + var found = TShock.Utils.FindPlayer(playerParam); + var reason = parameters["reason"]; + if (found.Count == 0) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " was not found"); + } + else if (found.Count > 1) + { + returnBlock.Add("status", "400"); + returnBlock.Add("error", "Name " + playerParam + " matches " + playerParam.Count() + " players"); + } + else if (found.Count == 1) + { + var player = found[0]; + player.mute = true; + player.SendMessage("You have been remotely muted."); + returnBlock.Add("status", "200"); + returnBlock.Add("response", "Player " + player.Name + " was muted."); + } + return returnBlock; + } + private object PlayerList(RestVerbs verbs, IParameterCollection parameters) { var activeplayers = Main.player.Where(p => p != null && p.active).ToList(); From a7cc75082e383073f310e3be3f3714a4e3bc66d1 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Mon, 2 Jan 2012 02:11:49 -0700 Subject: [PATCH 10/18] Test commit --- TShockAPI/Rest/RestManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs index a0fd3c2e..f5c049f9 100644 --- a/TShockAPI/Rest/RestManager.cs +++ b/TShockAPI/Rest/RestManager.cs @@ -60,7 +60,7 @@ namespace TShockAPI Rest.Register(new RestCommand("/v2/players/ban", PlayerBanV2) { RequiresToken = true }); Rest.Register(new RestCommand("/v2/players/kill", PlayerKill) {RequiresToken = true}); Rest.Register(new RestCommand("/v2/players/mute", PlayerMute) {RequiresToken = true}); - Rest.Register(new RestCommand("/v2/players/unmute", PlayerUnMute) {RequiresToken = true}); + Rest.Register(new RestCommand("/v2/players/unmute", PlayerUnMute) {RequiresToken = true}); // Rest.Register(new RestCommand("/v2/server/broadcast", Broadcast) { RequiresToken = true}); Rest.Register(new RestCommand("/v2/server/off", Off) {RequiresToken = true}); From f04b9d7a6dcfad0532ab98743525f633703241ef Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Mon, 2 Jan 2012 02:12:45 -0700 Subject: [PATCH 11/18] Remove test commit --- TShockAPI/Rest/RestManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs index f5c049f9..a0fd3c2e 100644 --- a/TShockAPI/Rest/RestManager.cs +++ b/TShockAPI/Rest/RestManager.cs @@ -60,7 +60,7 @@ namespace TShockAPI Rest.Register(new RestCommand("/v2/players/ban", PlayerBanV2) { RequiresToken = true }); Rest.Register(new RestCommand("/v2/players/kill", PlayerKill) {RequiresToken = true}); Rest.Register(new RestCommand("/v2/players/mute", PlayerMute) {RequiresToken = true}); - Rest.Register(new RestCommand("/v2/players/unmute", PlayerUnMute) {RequiresToken = true}); // + Rest.Register(new RestCommand("/v2/players/unmute", PlayerUnMute) {RequiresToken = true}); Rest.Register(new RestCommand("/v2/server/broadcast", Broadcast) { RequiresToken = true}); Rest.Register(new RestCommand("/v2/server/off", Off) {RequiresToken = true}); From f82f05064a1b156f615a3bab003e8ed622f364a8 Mon Sep 17 00:00:00 2001 From: Zack Piispanen Date: Mon, 2 Jan 2012 16:42:55 -0500 Subject: [PATCH 12/18] Added stack count to /v2/player/read --- TShockAPI/Rest/RestManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs index a0fd3c2e..08855cbc 100644 --- a/TShockAPI/Rest/RestManager.cs +++ b/TShockAPI/Rest/RestManager.cs @@ -516,7 +516,7 @@ namespace TShockAPI returnBlock.Add("group", player.Group.Name); returnBlock.Add("position", player.TileX + "," + player.TileY); var activeItems = player.TPlayer.inventory.Where(p => p.active).ToList(); - returnBlock.Add("inventory", string.Join(", ", activeItems.Select(p => p.name))); + returnBlock.Add("inventory", string.Join(", ", activeItems.Select(p => (p.name + ":" + p.stack)))); returnBlock.Add("buffs", string.Join(", ", player.TPlayer.buffType)); } return returnBlock; From b8e4dffd74f3d6abdb4e88ea7ba4de8fb089621c Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Mon, 2 Jan 2012 22:14:30 -0700 Subject: [PATCH 13/18] Add new REST endpoint: - /v2/server/rawcmd Takes parameters: - cmd Commands have to start with /, some commands aren't written properly, and may not return any more output than a status code. --- TShockAPI/PacketBufferer.cs | 50 ++++++++++++++-------------- TShockAPI/Properties/AssemblyInfo.cs | 4 +-- TShockAPI/Rest/RestManager.cs | 17 ++++++++++ TShockAPI/TSPlayer.cs | 30 +++++++++++++++++ 4 files changed, 74 insertions(+), 27 deletions(-) diff --git a/TShockAPI/PacketBufferer.cs b/TShockAPI/PacketBufferer.cs index 4bf7c7eb..28325e0c 100644 --- a/TShockAPI/PacketBufferer.cs +++ b/TShockAPI/PacketBufferer.cs @@ -40,8 +40,8 @@ namespace TShockAPI private int[] Compressed = new int[52]; #if DEBUG_NET - Command dump; - Command flush; + Command dump; + Command flush; #endif public PacketBufferer() @@ -51,10 +51,10 @@ namespace TShockAPI buffers[i] = new PacketBuffer(); #if DEBUG_NET - dump = new Command("superadmin", Dump, "netdump"); - flush = new Command("superadmin", Flush, "netflush"); - Commands.ChatCommands.Add(dump); - Commands.ChatCommands.Add(flush); + dump = new Command("superadmin", Dump, "netdump"); + flush = new Command("superadmin", Flush, "netflush"); + Commands.ChatCommands.Add(dump); + Commands.ChatCommands.Add(flush); #endif NetHooks.SendBytes += ServerHooks_SendBytes; @@ -78,8 +78,8 @@ namespace TShockAPI if (disposing) { #if DEBUG_NET - Commands.ChatCommands.Remove(dump); - Commands.ChatCommands.Remove(flush); + Commands.ChatCommands.Remove(dump); + Commands.ChatCommands.Remove(flush); #endif NetHooks.SendBytes -= ServerHooks_SendBytes; ServerHooks.SocketReset -= ServerHooks_SocketReset; @@ -94,7 +94,7 @@ namespace TShockAPI for (int i = 1; i < Bytes.Length; i++) { sb.AppendLine("{0,-25}{1,-25}{2,-25}{3}".SFormat(Enum.GetName(typeof (PacketTypes), i) + ":", Packets[i], Bytes[i], - Compressed[i])); + Compressed[i])); } File.WriteAllText(Path.Combine(TShock.SavePath, "dmp.txt"), sb.ToString()); } @@ -167,12 +167,12 @@ namespace TShockAPI lock (buffers[socket.whoAmI]) { #if DEBUG_NET - int size = (count - offset); - var pt = buffer[offset + 4]; + int size = (count - offset); + var pt = buffer[offset + 4]; - Packets[pt]++; - Bytes[pt] += size; - Compressed[pt] += Compress(buffer, offset, count); + Packets[pt]++; + Bytes[pt] += size; + Compressed[pt] += Compress(buffer, offset, count); #endif using (var ms = new MemoryStream(buffer, offset, count)) { @@ -213,17 +213,17 @@ namespace TShockAPI } #if DEBUG_NET - static int Compress(byte[] buffer, int offset, int count) - { - using (var ms = new MemoryStream()) - { - using (var gzip = new GZipStream(ms, CompressionMode.Compress, true)) - { - gzip.Write(buffer, offset, count); - } - return (int)ms.Length; - } - } + static int Compress(byte[] buffer, int offset, int count) + { + using (var ms = new MemoryStream()) + { + using (var gzip = new GZipStream(ms, CompressionMode.Compress, true)) + { + gzip.Write(buffer, offset, count); + } + return (int)ms.Length; + } + } #endif } diff --git a/TShockAPI/Properties/AssemblyInfo.cs b/TShockAPI/Properties/AssemblyInfo.cs index 76cbefd2..6ccd4fac 100644 --- a/TShockAPI/Properties/AssemblyInfo.cs +++ b/TShockAPI/Properties/AssemblyInfo.cs @@ -48,5 +48,5 @@ using System.Runtime.InteropServices; // Build Number // MMdd of the build -[assembly: AssemblyVersion("3.4.2.0101")] -[assembly: AssemblyFileVersion("3.4.2.0101")] \ No newline at end of file +[assembly: AssemblyVersion("3.4.2.0102")] +[assembly: AssemblyFileVersion("3.4.2.0102")] \ No newline at end of file diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs index a0fd3c2e..4ec71c04 100644 --- a/TShockAPI/Rest/RestManager.cs +++ b/TShockAPI/Rest/RestManager.cs @@ -64,6 +64,7 @@ namespace TShockAPI Rest.Register(new RestCommand("/v2/server/broadcast", Broadcast) { RequiresToken = true}); Rest.Register(new RestCommand("/v2/server/off", Off) {RequiresToken = true}); + Rest.Register(new RestCommand("/v2/server/rawcmd", ServerCommand) {RequiresToken = true}); #region Deprecated Endpoints Rest.Register(new RestCommand("/bans/read/{user}/info", BanInfo) { RequiresToken = true }); @@ -82,6 +83,22 @@ namespace TShockAPI #region RestServerMethods + private object ServerCommand(RestVerbs verbs, IParameterCollection parameters) + { + if (parameters["cmd"] != null && parameters["cmd"].Trim() != "") + { + TSRESTPlayer tr = new TSRESTPlayer(); + RestObject ro = new RestObject("200"); + Commands.HandleCommand(tr, parameters["cmd"]); + foreach (string s in tr.GetCommandOutput()) + { + ro.Add("response", s); + } + return ro; + } + return new RestObject("500")["response"] = "Invalid cmd parameter passed to REST. Cowardly not running a blank command."; + } + private object Off(RestVerbs verbs, IParameterCollection parameters) { bool confirm; diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 974e5e35..46bb3c19 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -405,6 +405,36 @@ namespace TShockAPI } } + public class TSRestPlayer : TSServerPlayer + { + internal List CommandReturn = new List(); + + public TSRestPlayer() + { + Group = new SuperAdminGroup(); + } + + public override void SendMessage(string msg) + { + SendMessage(msg, 0, 255, 0); + } + + public override void SendMessage(string msg, Color color) + { + SendMessage(msg, color.R, color.G, color.B); + } + + public override void SendMessage(string msg, byte red, byte green, byte blue) + { + CommandReturn.Add(msg); + } + + public List GetCommandOutput() + { + return CommandReturn; + } + } + public class TSServerPlayer : TSPlayer { public TSServerPlayer() From e8acdb0b963617b86452344d89b7dc00e35ee879 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Mon, 2 Jan 2012 22:39:04 -0700 Subject: [PATCH 14/18] Fixing some silly mistakes. --- TShockAPI/Rest/RestManager.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs index 390936fa..fe822c00 100644 --- a/TShockAPI/Rest/RestManager.cs +++ b/TShockAPI/Rest/RestManager.cs @@ -87,7 +87,7 @@ namespace TShockAPI { if (parameters["cmd"] != null && parameters["cmd"].Trim() != "") { - TSRESTPlayer tr = new TSRESTPlayer(); + TSRestPlayer tr = new TSRestPlayer(); RestObject ro = new RestObject("200"); Commands.HandleCommand(tr, parameters["cmd"]); foreach (string s in tr.GetCommandOutput()) @@ -110,6 +110,7 @@ namespace TShockAPI if (!nosave) WorldGen.saveWorld(); Netplay.disconnect = true; + return new RestObject("200")["response"] = "Server is shutting down."; } return new RestObject("200")["response"] = "The server will shut down only if the parameter 'confirm' is set to true in this REST call. You will not recieve a reply."; } From d8e92e5ed01efc89c0157bfebb70b82c08df5bf0 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Mon, 2 Jan 2012 22:52:23 -0700 Subject: [PATCH 15/18] Fixed 'shank forgot how to assign variables to an array' error on several rest calls. --- TShockAPI/Rest/RestManager.cs | 72 ++++++++++++----------------------- 1 file changed, 24 insertions(+), 48 deletions(-) diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs index fe822c00..b6b0a896 100644 --- a/TShockAPI/Rest/RestManager.cs +++ b/TShockAPI/Rest/RestManager.cs @@ -96,23 +96,30 @@ namespace TShockAPI } return ro; } - return new RestObject("500")["response"] = "Invalid cmd parameter passed to REST. Cowardly not running a blank command."; + RestObject fail = new RestObject("400"); + fail["response"] = "Missing or blank cmd parameter."; + return fail; } private object Off(RestVerbs verbs, IParameterCollection parameters) { bool confirm; - bool.TryParse(parameters["confirm"], out confirm); + bool.TryParse(parameters["confirm"], out confirm); bool nosave; bool.TryParse(parameters["nosave"], out nosave); + if (confirm == true) { if (!nosave) WorldGen.saveWorld(); Netplay.disconnect = true; - return new RestObject("200")["response"] = "Server is shutting down."; + RestObject reply = new RestObject("200"); + reply["response"] = "The server is shutting down."; + return reply; } - return new RestObject("200")["response"] = "The server will shut down only if the parameter 'confirm' is set to true in this REST call. You will not recieve a reply."; + RestObject fail = new RestObject("400"); + fail["response"] = "Invalid/missing confirm switch, and/or missing nosave switch."; + return fail; } private object Broadcast(RestVerbs verbs, IParameterCollection parameters) @@ -120,9 +127,13 @@ namespace TShockAPI if (parameters["msg"] != null && parameters["msg"].Trim() != "") { TShock.Utils.Broadcast(parameters["msg"]); - return new RestObject("200")["response"] = "The message was broadcasted to all connected clients successfully."; + RestObject reply = new RestObject("200"); + reply["response"] = "The message was broadcasted successfully."; + return reply; } - return new RestObject("500")["response"] = "Invalid msg parameter passed to REST. Cowardly not broadcasting a blank message."; + RestObject fail = new RestObject("400"); + fail["response"] = "Broadcast failed."; + return fail; } #endregion @@ -378,7 +389,9 @@ namespace TShockAPI bool killFriendly; if (!bool.TryParse(parameters["killfriendly"], out killFriendly)) { - return new RestObject("500")["response"] = "The given value for killfriendly wasn't a boolean value."; + RestObject fail = new RestObject("400"); + fail["response"] = "The given value for killfriendly wasn't a boolean value."; + return fail; } if (killFriendly) { @@ -394,7 +407,10 @@ namespace TShockAPI killcount++; } } - return new RestObject("200")["response"] = killcount + " NPCs have been killed."; + + RestObject rj = new RestObject("200"); + rj["response"] = killcount + " NPCs have been killed."; + return rj; } private object WorldRead(RestVerbs verbs, IParameterCollection parameters) @@ -622,46 +638,6 @@ namespace TShockAPI #endregion - #region RestExampleMethods - - public void RegisterExamples() - { - Rest.Register(new RestCommand("/HelloWorld/name/{username}", UserTest) {RequiresToken = false}); - Rest.Register(new RestCommand("/wizard/{username}", Wizard) {RequiresToken = false}); - } - - //The Wizard example, for demonstrating the response convention: - private object Wizard(RestVerbs verbs, IParameterCollection parameters) - { - var returnBack = new Dictionary(); - returnBack.Add("status", "200"); //Keep this in everything, 200 = ok, etc. Standard http status codes. - returnBack.Add("error", "(If this failed, you would have a different status code and provide the error object.)"); - //And only include this if the status isn't 200 or a failure - returnBack.Add("Verified Wizard", "You're a wizard, " + verbs["username"]); - //Outline any api calls and possible responses in some form of documentation somewhere - return returnBack; - } - - //http://127.0.0.1:8080/HelloWorld/name/{username}?type=status - private object UserTest(RestVerbs verbs, IParameterCollection parameters) - { - var ret = new Dictionary(); - var type = parameters["type"]; - if (type == null) - { - ret.Add("Error", "Invalid Type"); - return ret; - } - if (type == "status") - { - ret.Add("Users", "Info here"); - return ret; - } - return null; - } - - #endregion - #region Deperecated endpoints private object UserUpdate(RestVerbs verbs, IParameterCollection parameters) From e1d11ca96a71496c9709f9392a05bdc4aea0394e Mon Sep 17 00:00:00 2001 From: Deathmax Date: Tue, 3 Jan 2012 15:31:38 +0800 Subject: [PATCH 16/18] Provide feedback when using hardmode commands --- TShockAPI/Commands.cs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index e31a02d9..8c7eef08 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -1246,15 +1246,19 @@ namespace TShockAPI } } - private static void StartHardMode(CommandArgs args) - { - WorldGen.StartHardmode(); - } + private static void StartHardMode(CommandArgs args) + { + if (!TShock.Config.DisableHardmode) + WorldGen.StartHardmode(); + else + args.Player.SendMessage("Hardmode is disabled via config", Color.Red); + } - private static void DisableHardMode(CommandArgs args) - { - Main.hardMode = false; - } + private static void DisableHardMode(CommandArgs args) + { + Main.hardMode = false; + args.Player.SendMessage("Hardmode is now disabled", Color.Green); + } private static void ConvertCorruption(CommandArgs args) { From 5d61a56fcd9a1d0391fa4d7cf30cb585485c5ee6 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Tue, 3 Jan 2012 15:18:05 -0700 Subject: [PATCH 17/18] Add new REST endpoint: - /v2/token/password?username={user} TSHOCKPLUGINS-1 #resolve #time 5m #comment Deprecating old token create syntax, new endpoint added as a replacement. --- TShockAPI/Rest/Rest.cs | 4 ++-- TShockAPI/Rest/SecureRest.cs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/TShockAPI/Rest/Rest.cs b/TShockAPI/Rest/Rest.cs index c8229644..ac1d1563 100644 --- a/TShockAPI/Rest/Rest.cs +++ b/TShockAPI/Rest/Rest.cs @@ -116,8 +116,8 @@ namespace Rests if (obj == null) throw new NullReferenceException("obj"); - //if (OnRestRequestCall(e)) - // return; + if (OnRestRequestCall(e)) + return; var str = JsonConvert.SerializeObject(obj, Formatting.Indented); e.Response.Connection.Type = ConnectionType.Close; diff --git a/TShockAPI/Rest/SecureRest.cs b/TShockAPI/Rest/SecureRest.cs index 6af31523..bf41e2cd 100644 --- a/TShockAPI/Rest/SecureRest.cs +++ b/TShockAPI/Rest/SecureRest.cs @@ -41,6 +41,7 @@ namespace Rests { Tokens = new Dictionary(); Register(new RestCommand("/token/create/{username}/{password}", NewToken) {RequiresToken = false}); + Register(new RestCommand("/v2/token/create/{password}", NewTokenV2) { RequiresToken = false }); Register(new RestCommand("/token/destroy/{token}", DestroyToken) {RequiresToken = true}); } @@ -60,6 +61,36 @@ namespace Rests {{"status", "200"}, {"response", "Requested token was successfully destroyed."}}; } + private object NewTokenV2(RestVerbs verbs, IParameterCollection parameters) + { + var user = parameters["username"]; + var pass = verbs["password"]; + + RestObject obj = null; + if (Verify != null) + obj = Verify(user, pass); + + if (obj == null) + obj = new RestObject("401") { Error = "Invalid username/password combination provided. Please re-submit your query with a correct pair." }; + + if (obj.Error != null) + return obj; + + string hash; + var rand = new Random(); + var randbytes = new byte[32]; + do + { + rand.NextBytes(randbytes); + hash = randbytes.Aggregate("", (s, b) => s + b.ToString("X2")); + } while (Tokens.ContainsKey(hash)); + + Tokens.Add(hash, user); + + obj["token"] = hash; + return obj; + } + private object NewToken(RestVerbs verbs, IParameterCollection parameters) { var user = verbs["username"]; @@ -88,6 +119,7 @@ namespace Rests Tokens.Add(hash, user); obj["token"] = hash; + obj["deprecated"] = "This method will be removed from TShock in 3.6."; return obj; } From 264e6332021ba62facf841b7072bde01ff6a2be2 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Tue, 3 Jan 2012 15:29:36 -0700 Subject: [PATCH 18/18] TSHOCKPLUGINS-2 #resolve #comment Added. --- TShockAPI/Rest/Rest.cs | 55 ++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/TShockAPI/Rest/Rest.cs b/TShockAPI/Rest/Rest.cs index ac1d1563..719c501d 100644 --- a/TShockAPI/Rest/Rest.cs +++ b/TShockAPI/Rest/Rest.cs @@ -128,31 +128,44 @@ namespace Rests protected virtual object ProcessRequest(object sender, RequestEventArgs e) { - var uri = e.Request.Uri.AbsolutePath; - uri = uri.TrimEnd('/'); - - foreach (var com in commands) + try { - var verbs = new RestVerbs(); - if (com.HasVerbs) - { - var match = Regex.Match(uri, com.UriVerbMatch); - if (!match.Success) - continue; - if ((match.Groups.Count - 1) != com.UriVerbs.Length) - continue; + var uri = e.Request.Uri.AbsolutePath; + uri = uri.TrimEnd('/'); - for (int i = 0; i < com.UriVerbs.Length; i++) - verbs.Add(com.UriVerbs[i], match.Groups[i + 1].Value); - } - else if (com.UriTemplate.ToLower() != uri.ToLower()) + foreach (var com in commands) { - continue; - } + var verbs = new RestVerbs(); + if (com.HasVerbs) + { + var match = Regex.Match(uri, com.UriVerbMatch); + if (!match.Success) + continue; + if ((match.Groups.Count - 1) != com.UriVerbs.Length) + continue; - var obj = ExecuteCommand(com, verbs, e.Request.Parameters); - if (obj != null) - return obj; + for (int i = 0; i < com.UriVerbs.Length; i++) + verbs.Add(com.UriVerbs[i], match.Groups[i + 1].Value); + } + else if (com.UriTemplate.ToLower() != uri.ToLower()) + { + continue; + } + + var obj = ExecuteCommand(com, verbs, e.Request.Parameters); + if (obj != null) + return obj; + } + } + catch (Exception exception) + { + return new Dictionary + { + {"status", "500"}, + {"error", "Internal server error."}, + {"errormsg", exception.Message}, + {"stacktrace", exception.StackTrace}, + }; } return new Dictionary {