From e9b86b8f624b68fd6737dd0b17f98832f5ccbbda Mon Sep 17 00:00:00 2001 From: James Puleo Date: Fri, 16 Jul 2021 02:09:36 -0400 Subject: [PATCH 01/18] Improved the `/grow` command to reduce code duplication, use `TileID` constants for less ambiguous types. --- CHANGELOG.md | 3 + TShockAPI/Commands.cs | 329 +++++++++++++----------------------------- 2 files changed, 104 insertions(+), 228 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7a1e596..9afbf709 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Do not forget to sign every line you change with your name. (@hakusaro) * If there is no section called "Upcoming changes" below this line, please add one with `## Upcoming changes` as the first line, and then a bulleted item directly after with the first change. +## Upcoming changes +* Improved the `/grow` command to reduce code duplication, use `TileID` constants for less ambiguous types. (@drunderscore) + ## TShock 4.5.12 * Fixed the ability to spawn Zenith projectile with non-original items. (@AgaSpace) * Added hook `GetDataHandlers.OnNpcTalk` for NpcTalk and a handler for it that stops unregistered and logged out players from interacting with NPCs, preventing them from smuggling or duplicating items via NPC item slots. (@tru321) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 71e10a9d..57e99513 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -6301,7 +6301,7 @@ namespace TShockAPI public static void Grow(CommandArgs args) { - bool growevilAmb = args.Player.HasPermission(Permissions.growevil); + bool canGrowEvil = args.Player.HasPermission(Permissions.growevil); string subcmd = args.Parameters.Count == 0 ? "help" : args.Parameters[0].ToLower(); var name = "Fail"; @@ -6343,284 +6343,163 @@ namespace TShockAPI } break; - case "basic": - for (int i = x - 2; i < x + 3; i++) + bool rejectCannotGrowEvil() { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 2; - Main.tile[i, y].wall = 0; + if(!canGrowEvil) + { + args.Player.SendErrorMessage("You do not have permission to grow this tree type"); + return false; + } + + return true; } - Main.tile[x, y - 1].wall = 0; - WorldGen.GrowTree(x, y); - name = "Basic Tree"; + + bool prepareAreaForGrow(ushort groundType = TileID.Grass, bool evil = false) + { + if(evil && !rejectCannotGrowEvil()) + return false; + + for (var i = x - 2; i < x + 3; i++) + { + Main.tile[i, y].active(true); + Main.tile[i, y].type = groundType; + Main.tile[i, y].wall = WallID.None; + } + Main.tile[x, y - 1].wall = WallID.None; + + return true; + } + + bool growTree(ushort groundType, string fancyName, bool evil = false) + { + if(!prepareAreaForGrow(groundType, evil)) + return false; + WorldGen.GrowTree(x, y); + name = fancyName; + + return true; + } + + bool growTreeByType(ushort groundType, string fancyName, ushort typeToPrepare = 2, bool evil = false) + { + if(!prepareAreaForGrow(typeToPrepare, evil)) + return false; + WorldGen.TryGrowingTreeByType(groundType, x, y); + name = fancyName; + + return true; + } + + bool growPalmTree(ushort sandType, ushort supportingType, string properName, bool evil = false) + { + if(evil && !rejectCannotGrowEvil()) + return false; + + for (int i = x - 2; i < x + 3; i++) + { + Main.tile[i, y].active(true); + Main.tile[i, y].type = sandType; + Main.tile[i, y].wall = WallID.None; + } + for (int i = x - 2; i < x + 3; i++) + { + Main.tile[i, y + 1].active(true); + Main.tile[i, y + 1].type = supportingType; + Main.tile[i, y + 1].wall = WallID.None; + } + + Main.tile[x, y - 1].wall = WallID.None; + WorldGen.GrowPalmTree(x, y); + + name = properName; + + return true; + } + + case "basic": + growTree(TileID.Grass, "Basic Tree"); break; case "boreal": - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 147; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.GrowTree(x, y); - name = "Boreal Tree"; + growTree(TileID.SnowBlock, "Boreal Tree"); break; case "mahogany": - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 60; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.GrowTree(x, y); - name = "Rich Mahogany"; + growTree(TileID.JungleGrass, "Rich Mahogany"); break; case "sakura": - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 2; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.TryGrowingTreeByType(596, x, y); - name = "Sakura Tree"; + growTreeByType(TileID.VanityTreeSakura, "Sakura Tree"); break; case "willow": - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 2; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.TryGrowingTreeByType(616, x, y); - name = "Willow Tree"; + growTreeByType(TileID.VanityTreeYellowWillow, "Willow Tree"); break; case "shadewood": - if (growevilAmb) - { - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 199; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.GrowTree(x, y); - name = "Shadewood tree"; - } - else args.Player.SendErrorMessage("You do not have permission to grow this tree type"); + if(!growTree(TileID.CrimsonGrass, "Shadewood Tree", true)) + return; break; case "ebonwood": - if (growevilAmb) - { - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 23; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.GrowTree(x, y); - name = "Ebonwood Tree"; - } - else args.Player.SendErrorMessage("You do not have permission to grow this tree type"); + if(!growTree(TileID.CorruptGrass, "Ebonwood Tree", true)) + return; break; case "pearlwood": - if (growevilAmb) - { - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 109; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.GrowTree(x, y); - name = "Pearlwood Tree"; - } - else args.Player.SendErrorMessage("You do not have permission to grow this tree type"); + if(!growTree(TileID.HallowedGrass, "Pearlwood Tree", true)) + return; break; case "palm": - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 53; - Main.tile[i, y].wall = 0; - } - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y + 1].active(true); - Main.tile[i, y + 1].type = 397; - Main.tile[i, y + 1].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.GrowPalmTree(x, y); - name = "Desert Palm"; + growPalmTree(TileID.Sand, TileID.HardenedSand, "Desert Palm"); break; case "hallowpalm": - if (growevilAmb) - { - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 116; - Main.tile[i, y].wall = 0; - } - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y + 1].active(true); - Main.tile[i, y + 1].type = 402; - Main.tile[i, y + 1].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.GrowPalmTree(x, y); - name = "Hallow Palm"; - } - else args.Player.SendErrorMessage("You do not have permission to grow this tree type"); + if(!growPalmTree(TileID.Pearlsand, TileID.HallowHardenedSand, "Hallow Palm", true)) + return; break; case "crimsonpalm": - if (growevilAmb) - { - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 234; - Main.tile[i, y].wall = 0; - } - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y + 1].active(true); - Main.tile[i, y + 1].type = 399; - Main.tile[i, y + 1].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.GrowPalmTree(x, y); - name = "Crimson Palm"; - } - else args.Player.SendErrorMessage("You do not have permission to grow this tree type"); + if(!growPalmTree(TileID.Crimsand, TileID.CrimsonHardenedSand, "Crimson Palm", true)) + return; break; case "corruptpalm": - if (growevilAmb) - { - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 112; - Main.tile[i, y].wall = 0; - } - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y + 1].active(true); - Main.tile[i, y + 1].type = 398; - Main.tile[i, y + 1].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.GrowPalmTree(x, y); - name = "Corruption Palm"; - } - else args.Player.SendErrorMessage("You do not have permission to grow this tree type"); + if(!growPalmTree(TileID.Ebonsand, TileID.CorruptHardenedSand, "Corruption Palm", true)) + return; break; case "topaz": - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 1; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.TryGrowingTreeByType(583, x, y); - name = "Topaz Gemtree"; + growTreeByType(TileID.TreeTopaz, "Topaz Gemtree", 1); break; case "amethyst": - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 1; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.TryGrowingTreeByType(584, x, y); - name = "Amethyst Gemtree"; + growTreeByType(TileID.TreeAmethyst, "Amethyst Gemtree", 1); break; case "sapphire": - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 1; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.TryGrowingTreeByType(585, x, y); - name = "Sapphire Gemtree"; + growTreeByType(TileID.TreeSapphire, "Sapphire Gemtree", 1); break; case "emerald": - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 1; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.TryGrowingTreeByType(586, x, y); - name = "Emerald Gemtree"; + growTreeByType(TileID.TreeEmerald, "Emerald Gemtree", 1); break; case "ruby": - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 1; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.TryGrowingTreeByType(587, x, y); - name = "Ruby Gemtree"; + growTreeByType(TileID.TreeRuby, "Ruby Gemtree", 1); break; case "diamond": - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 1; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.TryGrowingTreeByType(588, x, y); - name = "Diamond Gemtree"; + growTreeByType(TileID.TreeDiamond, "Diamond Gemtree", 1); break; case "amber": - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 1; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; - WorldGen.TryGrowingTreeByType(589, x, y); - name = "Amber Gemtree"; + growTreeByType(TileID.TreeAmber, "Amber Gemtree", 1); break; case "cactus": - Main.tile[x, y].type = 53; + Main.tile[x, y].type = TileID.Sand; WorldGen.GrowCactus(x, y); name = "Cactus"; break; @@ -6628,19 +6507,13 @@ namespace TShockAPI case "herb": Main.tile[x, y].active(true); Main.tile[x, y].frameX = 36; - Main.tile[x, y].type = 83; + Main.tile[x, y].type = TileID.MatureHerbs; WorldGen.GrowAlch(x, y); name = "Herb"; break; case "mushroom": - for (int i = x - 2; i < x + 3; i++) - { - Main.tile[i, y].active(true); - Main.tile[i, y].type = 70; - Main.tile[i, y].wall = 0; - } - Main.tile[x, y - 1].wall = 0; + prepareAreaForGrow(TileID.MushroomGrass); WorldGen.GrowShroom(x, y); name = "Glowing Mushroom Tree"; break; From 5e5444581861cdff07521e68d1d9a8efeda2df55 Mon Sep 17 00:00:00 2001 From: 0x3fcf1bbd <81617230+0x3fcf1bbd@users.noreply.github.com> Date: Sat, 15 Jan 2022 23:49:37 +0100 Subject: [PATCH 02/18] Added lanterns night event to the worldevent command. --- TShockAPI/Commands.cs | 18 +++++++++++++++++- TShockAPI/Permissions.cs | 3 +++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 71e10a9d..6d7caa06 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -2060,7 +2060,8 @@ namespace TShockAPI "eclipse", "invasion", "sandstorm", - "rain" + "rain", + "lanternsnight" }; static readonly List _validInvasions = new List() { @@ -2159,6 +2160,15 @@ namespace TShockAPI Rain(args); return; + case "lanternsnight": + case "lanterns": + if (!args.Player.HasPermission(Permissions.managelanternsnightevent)) + { + FailedPermissionCheck(); + } + LanternsNight(args); + return; + default: args.Player.SendErrorMessage("Invalid event type! Valid event types: {0}", String.Join(", ", _validEvents)); return; @@ -2374,6 +2384,12 @@ namespace TShockAPI } } + private static void LanternsNight(CommandArgs args) + { + LanternNight.ToggleManualLanterns(); + args.Player.SendInfoMessage("{0}ed a lantern night.", LanternNight.LanternsUp ? "Start" : "Stop"); + } + private static void ClearAnglerQuests(CommandArgs args) { if (args.Parameters.Count > 0) diff --git a/TShockAPI/Permissions.cs b/TShockAPI/Permissions.cs index 7de195d2..378f79fd 100644 --- a/TShockAPI/Permissions.cs +++ b/TShockAPI/Permissions.cs @@ -307,6 +307,9 @@ namespace TShockAPI [Description("User can use the 'rain' subcommand of the 'worldevent' command")] public static readonly string managerainevent = "tshock.world.events.rain"; + [Description("User can use the 'lanternsnight' subcommand of the 'worldevent' command")] + public static readonly string managelanternsnightevent = "tshock.world.events.lanternsnight"; + [Description("User can change expert state.")] public static readonly string toggleexpert = "tshock.world.toggleexpert"; From c0ab5ae98f3e239616446309b1f1161b58708711 Mon Sep 17 00:00:00 2001 From: 0x3fcf1bbd <81617230+0x3fcf1bbd@users.noreply.github.com> Date: Sun, 16 Jan 2022 00:00:14 +0100 Subject: [PATCH 03/18] Updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c423850c..37fc3328 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin ## Upcoming changes * Added hook `GetDataHandlers.OnReleaseNpc` to handling ReleaseNPC packet and a bouncer to stops unregistered and logged out players on SSC servers from releasing critters NPC. The bouncer has additional filter to stops players who tried to release different critter using crafted packet, e.g. using bunny item to release golden bunny. (@tru321) * Added filter in `GetDataHandlers.HandleCatchNpc` that stops unregistered and logged out players on SSC servers to catch critters. (@tru321) +* Added the lanterns night event to the `/worldmode` command. (@0x3fcf1bbd) ## Upcoming changes * Fixed rejection check inside of `HandlePaintTile` to account for the Paint Sprayer (or Architect Gizmo Pack) being inside your inventory, rather than on an accessory slot. (@drunderscore) From 29c6260d79510d2d2c61aa3c150ea33b27aca1fb Mon Sep 17 00:00:00 2001 From: 0x3fcf1bbd <81617230+0x3fcf1bbd@users.noreply.github.com> Date: Sun, 16 Jan 2022 17:13:57 +0100 Subject: [PATCH 04/18] Fixed permission being ignored for lanterns event. --- TShockAPI/Commands.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 6d7caa06..97ed6f6e 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -2165,6 +2165,7 @@ namespace TShockAPI if (!args.Player.HasPermission(Permissions.managelanternsnightevent)) { FailedPermissionCheck(); + return; } LanternsNight(args); return; From fc164955289fe49892c8101eb68f450cc56cd041 Mon Sep 17 00:00:00 2001 From: 0x3fcf1bbd <81617230+0x3fcf1bbd@users.noreply.github.com> Date: Sat, 22 Jan 2022 13:47:19 +0100 Subject: [PATCH 05/18] Fixed silent support for lanterns world event. And fixed smol typo. --- TShockAPI/Commands.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 97ed6f6e..a92994ab 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -2388,7 +2388,15 @@ namespace TShockAPI private static void LanternsNight(CommandArgs args) { LanternNight.ToggleManualLanterns(); - args.Player.SendInfoMessage("{0}ed a lantern night.", LanternNight.LanternsUp ? "Start" : "Stop"); + string msg = $" st{(LanternNight.LanternsUp ? "art" : "opp")}ed a lantern night."; + if (args.Silent) + { + args.Player.SendInfoMessage("You" + msg); + } + else + { + TSPlayer.All.SendInfoMessage(args.Player.Name + msg); + } } private static void ClearAnglerQuests(CommandArgs args) From 2b64c04b7f96069387ff21241e96a724fc0f4904 Mon Sep 17 00:00:00 2001 From: 0x3fcf1bbd <81617230+0x3fcf1bbd@users.noreply.github.com> Date: Sun, 23 Jan 2022 16:10:43 +0100 Subject: [PATCH 06/18] Fixed CHANGELOG.md Also merged the two "Upcoming changes" headers. --- CHANGELOG.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37fc3328..792052f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,10 +14,8 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin ## Upcoming changes * Added hook `GetDataHandlers.OnReleaseNpc` to handling ReleaseNPC packet and a bouncer to stops unregistered and logged out players on SSC servers from releasing critters NPC. The bouncer has additional filter to stops players who tried to release different critter using crafted packet, e.g. using bunny item to release golden bunny. (@tru321) * Added filter in `GetDataHandlers.HandleCatchNpc` that stops unregistered and logged out players on SSC servers to catch critters. (@tru321) -* Added the lanterns night event to the `/worldmode` command. (@0x3fcf1bbd) - -## Upcoming changes * Fixed rejection check inside of `HandlePaintTile` to account for the Paint Sprayer (or Architect Gizmo Pack) being inside your inventory, rather than on an accessory slot. (@drunderscore) +* Added the lanterns night event to the `/worldevent` command. (@0x3fcf1bbd) ## TShock 4.5.12 * Fixed the ability to spawn Zenith projectile with non-original items. (@AgaSpace) From af99c4cb8d7bab0775d8225b6c895cae83c2e924 Mon Sep 17 00:00:00 2001 From: 0x3fcf1bbd <81617230+0x3fcf1bbd@users.noreply.github.com> Date: Wed, 26 Jan 2022 14:17:27 +0100 Subject: [PATCH 07/18] Fixed STS not being centered. Inferring from the usage of it, this method was expected by its callers to be a square centered around the given coordinates (x, y), hence this being a fix. --- TShockAPI/TSPlayer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 00ff790b..c4c094e9 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -1311,7 +1311,7 @@ namespace TShockAPI /// true if the tile square was sent successfully, else false public virtual bool SendTileSquare(int x, int y, int size = 10) { - return SendTileRect((short)x, (short)y, (byte)size, (byte)size); + return SendTileRect((short)(x-(size/2)), (short)(y-(size/2)), (byte)size, (byte)size); } /// From 7f0daba593f5ceace6a3bd8f76948295a83e847e Mon Sep 17 00:00:00 2001 From: 0x3fcf1bbd <81617230+0x3fcf1bbd@users.noreply.github.com> Date: Wed, 26 Jan 2022 14:23:06 +0100 Subject: [PATCH 08/18] Updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 792052f8..596bb4b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Added filter in `GetDataHandlers.HandleCatchNpc` that stops unregistered and logged out players on SSC servers to catch critters. (@tru321) * Fixed rejection check inside of `HandlePaintTile` to account for the Paint Sprayer (or Architect Gizmo Pack) being inside your inventory, rather than on an accessory slot. (@drunderscore) * Added the lanterns night event to the `/worldevent` command. (@0x3fcf1bbd) +* Fixed `TSPlayer.SendTileSquare` not being centered around the passed coordinates. (@0x3fcf1bbd) ## TShock 4.5.12 * Fixed the ability to spawn Zenith projectile with non-original items. (@AgaSpace) From 874b3b27461011a2e030eee9e4294959632e3c91 Mon Sep 17 00:00:00 2001 From: 0x3fcf1bbd <81617230+0x3fcf1bbd@users.noreply.github.com> Date: Tue, 1 Feb 2022 16:00:05 +0100 Subject: [PATCH 09/18] Reverted STS change, added STSC, fixed STS/STSC usage. --- TShockAPI/Bouncer.cs | 108 +++++++++++++++++------------------ TShockAPI/Commands.cs | 8 +-- TShockAPI/GetDataHandlers.cs | 2 +- TShockAPI/ItemBans.cs | 4 +- TShockAPI/RegionHandler.cs | 4 +- TShockAPI/TSPlayer.cs | 26 ++++++++- TShockAPI/TSServerPlayer.cs | 2 +- 7 files changed, 87 insertions(+), 67 deletions(-) diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs index 7f3894c1..dae66461 100644 --- a/TShockAPI/Bouncer.cs +++ b/TShockAPI/Bouncer.cs @@ -406,7 +406,7 @@ namespace TShockAPI ((action == EditAction.PlaceWall || action == EditAction.ReplaceWall) && editData >= Main.maxWallTypes)) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from editData out of bounds {0} {1} {2}", args.Player.Name, action, editData); - args.Player.SendTileSquare(tileX, tileY, 4); + args.Player.SendTileSquareCentered(tileX, tileY, 4); args.Handled = true; return; } @@ -421,7 +421,7 @@ namespace TShockAPI if (args.Player.Dead && TShock.Config.Settings.PreventDeadModification) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (pdm) {0} {1} {2}", args.Player.Name, action, editData); - args.Player.SendTileSquare(tileX, tileY, 4); + args.Player.SendTileSquareCentered(tileX, tileY, 4); args.Handled = true; return; } @@ -435,7 +435,7 @@ namespace TShockAPI if (TShock.TileBans.TileIsBanned(editData, args.Player)) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (tb) {0} {1} {2}", args.Player.Name, action, editData); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Player.SendErrorMessage("You do not have permission to place this tile."); args.Handled = true; return; @@ -458,7 +458,7 @@ namespace TShockAPI { TShock.Log.ConsoleError("Bouncer / OnTileEdit rejected from (placestyle) {0} {1} {2} placeStyle: {3} expectedStyle: {4}", args.Player.Name, action, editData, requestedPlaceStyle, actualItemPlaceStyle); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -469,7 +469,7 @@ namespace TShockAPI { TShock.Log.ConsoleError("Bouncer / OnTileEdit rejected from (placestyle) {0} {1} {2} placeStyle: {3} expectedStyle: {4}", args.Player.Name, action, editData, requestedPlaceStyle, correctedPlaceStyle); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -484,7 +484,7 @@ namespace TShockAPI if (Main.tileAxe[tile.type] && ((args.Player.TPlayer.mount.Type != 8 && selectedItem.axe == 0) && !ItemID.Sets.Explosives[selectedItem.netID] && args.Player.RecentFuse == 0)) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (axe) {0} {1} {2}", args.Player.Name, action, editData); - args.Player.SendTileSquare(tileX, tileY, 4); + args.Player.SendTileSquareCentered(tileX, tileY, 4); args.Handled = true; return; } @@ -492,7 +492,7 @@ namespace TShockAPI else if (Main.tileHammer[tile.type] && ((args.Player.TPlayer.mount.Type != 8 && selectedItem.hammer == 0) && !ItemID.Sets.Explosives[selectedItem.netID] && args.Player.RecentFuse == 0)) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (hammer) {0} {1} {2}", args.Player.Name, action, editData); - args.Player.SendTileSquare(tileX, tileY, 4); + args.Player.SendTileSquareCentered(tileX, tileY, 4); args.Handled = true; return; } @@ -503,7 +503,7 @@ namespace TShockAPI && !Main.tileAxe[tile.type] && !Main.tileHammer[tile.type] && tile.wall == 0 && args.Player.TPlayer.mount.Type != 8 && selectedItem.pick == 0 && selectedItem.type != ItemID.GravediggerShovel && !ItemID.Sets.Explosives[selectedItem.netID] && args.Player.RecentFuse == 0) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (pick) {0} {1} {2}", args.Player.Name, action, editData); - args.Player.SendTileSquare(tileX, tileY, 4); + args.Player.SendTileSquareCentered(tileX, tileY, 4); args.Handled = true; return; } @@ -514,7 +514,7 @@ namespace TShockAPI if (selectedItem.hammer == 0 && !ItemID.Sets.Explosives[selectedItem.netID] && args.Player.RecentFuse == 0 && selectedItem.createWall == 0) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (hammer2) {0} {1} {2}", args.Player.Name, action, editData); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -533,7 +533,7 @@ namespace TShockAPI !p.Killed && Math.Abs((int)(Main.projectile[p.Index].position.X / 16f) - tileX) <= Math.Abs(Main.projectile[p.Index].velocity.X))) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (inconceivable rope coil) {0} {1} {2} selectedItem:{3} itemCreateTile:{4}", args.Player.Name, action, editData, selectedItem.netID, selectedItem.createTile); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -544,7 +544,7 @@ namespace TShockAPI requestedPlaceStyle > GetMaxPlaceStyle(editData)) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (ms1) {0} {1} {2}", args.Player.Name, action, editData); - args.Player.SendTileSquare(tileX, tileY, 4); + args.Player.SendTileSquareCentered(tileX, tileY, 4); args.Handled = true; return; } @@ -553,7 +553,7 @@ namespace TShockAPI if (selectedItem.netID == ItemID.IceRod && editData != TileID.MagicalIceBlock) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from using ice rod but not placing ice block {0} {1} {2}", args.Player.Name, action, editData); - args.Player.SendTileSquare(tileX, tileY, 4); + args.Player.SendTileSquareCentered(tileX, tileY, 4); args.Handled = true; } /// If they aren't selecting the item which creates the tile, they're hacking. @@ -563,7 +563,7 @@ namespace TShockAPI if (selectedItem.netID != ItemID.IceRod && selectedItem.netID != ItemID.DirtBomb && selectedItem.netID != ItemID.StickyBomb) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from tile placement not matching selected item createTile {0} {1} {2} selectedItemID:{3} createTile:{4}", args.Player.Name, action, editData, selectedItem.netID, selectedItem.createTile); - args.Player.SendTileSquare(tileX, tileY, 4); + args.Player.SendTileSquareCentered(tileX, tileY, 4); args.Handled = true; return; } @@ -572,7 +572,7 @@ namespace TShockAPI if ((action == EditAction.PlaceWall || action == EditAction.ReplaceWall) && editData != selectedItem.createWall) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from wall placement not matching selected item createWall {0} {1} {2} selectedItemID:{3} createWall:{4}", args.Player.Name, action, editData, selectedItem.netID, selectedItem.createWall); - args.Player.SendTileSquare(tileX, tileY, 4); + args.Player.SendTileSquareCentered(tileX, tileY, 4); args.Handled = true; return; } @@ -582,7 +582,7 @@ namespace TShockAPI { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (chestcap) {0} {1} {2}", args.Player.Name, action, editData); args.Player.SendErrorMessage("The world's chest limit has been reached - unable to place more."); - args.Player.SendTileSquare(tileX, tileY, 3); + args.Player.SendTileSquareCentered(tileX, tileY, 3); args.Handled = true; return; } @@ -600,7 +600,7 @@ namespace TShockAPI && selectedItem.type != ItemID.WireKite) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from place wire from {0} {1} {2}", args.Player.Name, action, editData); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -614,7 +614,7 @@ namespace TShockAPI && selectedItem.type != ItemID.MulticolorWrench) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from wire cutter from {0} {1} {2}", args.Player.Name, action, editData); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -625,7 +625,7 @@ namespace TShockAPI if (selectedItem.type != ItemID.Actuator && !args.Player.TPlayer.autoActuator) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from actuator/presserator from {0} {1} {2}", args.Player.Name, action, editData); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -635,7 +635,7 @@ namespace TShockAPI if (action == EditAction.KillWall || action == EditAction.ReplaceWall) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from sts allow cut from {0} {1} {2}", args.Player.Name, action, editData); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -646,7 +646,7 @@ namespace TShockAPI if (args.Player.IsBeingDisabled()) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from disable from {0} {1} {2}", args.Player.Name, action, editData); - args.Player.SendTileSquare(tileX, tileY, 4); + args.Player.SendTileSquareCentered(tileX, tileY, 4); args.Handled = true; return; } @@ -685,7 +685,7 @@ namespace TShockAPI } TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from explosives/fuses from {0} {1} {2}", args.Player.Name, action, editData); - args.Player.SendTileSquare(tileX, tileY, 4); + args.Player.SendTileSquareCentered(tileX, tileY, 4); args.Handled = true; return; } @@ -699,7 +699,7 @@ namespace TShockAPI else { args.Player.Disable("Reached TileKill threshold.", DisableFlags.WriteToLogAndConsole); - args.Player.SendTileSquare(tileX, tileY, 4); + args.Player.SendTileSquareCentered(tileX, tileY, 4); } TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from tile kill threshold from {0}, (value: {1})", args.Player.Name, args.Player.TileKillThreshold); @@ -717,7 +717,7 @@ namespace TShockAPI else { args.Player.Disable("Reached TilePlace threshold.", DisableFlags.WriteToLogAndConsole); - args.Player.SendTileSquare(tileX, tileY, 4); + args.Player.SendTileSquareCentered(tileX, tileY, 4); } TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from tile place threshold from {0}, (value: {1})", args.Player.Name, args.Player.TilePlaceThreshold); @@ -729,7 +729,7 @@ namespace TShockAPI if (args.Player.IsBouncerThrottled()) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from throttled from {0} {1} {2}", args.Player.Name, action, editData); - args.Player.SendTileSquare(tileX, tileY, 4); + args.Player.SendTileSquareCentered(tileX, tileY, 4); args.Handled = true; return; } @@ -763,7 +763,7 @@ namespace TShockAPI { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from weird confusing flow control from {0}", args.Player.Name); TShock.Log.ConsoleDebug("If you're seeing this message and you know what that player did, please report it to TShock for further investigation."); - args.Player.SendTileSquare(tileX, tileY, 4); + args.Player.SendTileSquareCentered(tileX, tileY, 4); args.Handled = true; return; } @@ -1318,7 +1318,7 @@ namespace TShockAPI if (args.Player.IsBeingDisabled()) { TShock.Log.ConsoleDebug("Bouncer / OnPlaceChest rejected from disabled from {0}", args.Player.Name); - args.Player.SendTileSquare(tileX, tileY, 3); + args.Player.SendTileSquareCentered(tileX, tileY, 3); args.Handled = true; return; } @@ -1326,7 +1326,7 @@ namespace TShockAPI if (args.Player.SelectedItem.placeStyle != style) { TShock.Log.ConsoleError(string.Format("Bouncer / OnPlaceChest / rejected from invalid place style from {0}", args.Player.Name)); - args.Player.SendTileSquare(tileX, tileY, 3); + args.Player.SendTileSquareCentered(tileX, tileY, 3); args.Handled = true; return; } @@ -1338,7 +1338,7 @@ namespace TShockAPI && (!TShock.Utils.HasWorldReachedMaxChests() && Main.tile[tileX, tileY].type != TileID.Dirt)) //Chest { TShock.Log.ConsoleDebug("Bouncer / OnPlaceChest rejected from weird check from {0}", args.Player.Name); - args.Player.SendTileSquare(tileX, tileY, 3); + args.Player.SendTileSquareCentered(tileX, tileY, 3); args.Handled = true; return; } @@ -1350,7 +1350,7 @@ namespace TShockAPI { TShock.Log.ConsoleDebug("Bouncer / OnPlaceChest rejected from weird placement check from {0}", args.Player.Name); //Prevent a dresser from being placed on a teleporter, as this can cause client and server crashes. - args.Player.SendTileSquare(tileX, tileY, 3); + args.Player.SendTileSquareCentered(tileX, tileY, 3); args.Handled = true; return; } @@ -1359,7 +1359,7 @@ namespace TShockAPI if (!args.Player.HasBuildPermission(tileX, tileY)) { TShock.Log.ConsoleDebug("Bouncer / OnPlaceChest rejected from invalid permission from {0}", args.Player.Name); - args.Player.SendTileSquare(tileX, tileY, 3); + args.Player.SendTileSquareCentered(tileX, tileY, 3); args.Handled = true; return; } @@ -1367,7 +1367,7 @@ namespace TShockAPI if (!args.Player.IsInRange(tileX, tileY)) { TShock.Log.ConsoleDebug("Bouncer / OnPlaceChest rejected from range check from {0}", args.Player.Name); - args.Player.SendTileSquare(tileX, tileY, 3); + args.Player.SendTileSquareCentered(tileX, tileY, 3); args.Handled = true; return; } @@ -1452,7 +1452,7 @@ namespace TShockAPI if (args.Player.IsBeingDisabled()) { TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected disabled from {0}", args.Player.Name); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -1466,7 +1466,7 @@ namespace TShockAPI else { args.Player.Disable("Reached TileLiquid threshold.", DisableFlags.WriteToLogAndConsole); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); } TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected from liquid threshold from {0} {1}/{2}", args.Player.Name, args.Player.TileLiquidThreshold, TShock.Config.Settings.TileLiquidThreshold); @@ -1539,7 +1539,7 @@ namespace TShockAPI TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 1 from {0}", args.Player.Name); args.Player.SendErrorMessage("You do not have permission to perform this action."); args.Player.Disable("Spreading lava without holding a lava bucket", DisableFlags.WriteToLogAndConsole); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -1549,7 +1549,7 @@ namespace TShockAPI TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected lava bucket from {0}", args.Player.Name); args.Player.SendErrorMessage("You do not have permission to perform this action."); args.Player.Disable("Using banned lava bucket without permissions", DisableFlags.WriteToLogAndConsole); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -1559,7 +1559,7 @@ namespace TShockAPI TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 2 from {0}", args.Player.Name); args.Player.SendErrorMessage("You do not have permission to perform this action."); args.Player.Disable("Spreading water without holding a water bucket", DisableFlags.WriteToLogAndConsole); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -1569,7 +1569,7 @@ namespace TShockAPI TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 3 from {0}", args.Player.Name); args.Player.SendErrorMessage("You do not have permission to perform this action."); args.Player.Disable("Using banned water bucket without permissions", DisableFlags.WriteToLogAndConsole); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -1579,7 +1579,7 @@ namespace TShockAPI TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 4 from {0}", args.Player.Name); args.Player.SendErrorMessage("You do not have permission to perform this action."); args.Player.Disable("Spreading honey without holding a honey bucket", DisableFlags.WriteToLogAndConsole); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -1589,7 +1589,7 @@ namespace TShockAPI TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected bucket check 5 from {0}", args.Player.Name); args.Player.SendErrorMessage("You do not have permission to perform this action."); args.Player.Disable("Using banned honey bucket without permissions", DisableFlags.WriteToLogAndConsole); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -1598,7 +1598,7 @@ namespace TShockAPI if (!args.Player.HasBuildPermission(tileX, tileY)) { TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected build permission from {0}", args.Player.Name); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -1606,7 +1606,7 @@ namespace TShockAPI if (!wasThereABombNearby && !args.Player.IsInRange(tileX, tileY, 16)) { TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected range checks from {0}", args.Player.Name); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -1614,7 +1614,7 @@ namespace TShockAPI if (args.Player.IsBouncerThrottled()) { TShock.Log.ConsoleDebug("Bouncer / OnLiquidSet rejected throttle from {0}", args.Player.Name); - args.Player.SendTileSquare(tileX, tileY, 1); + args.Player.SendTileSquareCentered(tileX, tileY, 1); args.Handled = true; return; } @@ -1926,7 +1926,7 @@ namespace TShockAPI if (type == TileID.FakeContainers && (style == 52 || style == 53)) { TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected fake containers from {0}", args.Player.Name); - args.Player.SendTileSquare(x, y, 4); + args.Player.SendTileSquareCentered(x, y, 4); args.Handled = true; return; } @@ -1935,7 +1935,7 @@ namespace TShockAPI if (TShock.TileBans.TileIsBanned(type, args.Player)) { TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected banned tiles from {0}", args.Player.Name); - args.Player.SendTileSquare(x, y, 1); + args.Player.SendTileSquareCentered(x, y, 1); args.Player.SendErrorMessage("You do not have permission to place this tile."); args.Handled = true; return; @@ -1944,7 +1944,7 @@ namespace TShockAPI if (args.Player.Dead && TShock.Config.Settings.PreventDeadModification) { TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected dead people don't do things from {0}", args.Player.Name); - args.Player.SendTileSquare(x, y, 4); + args.Player.SendTileSquareCentered(x, y, 4); args.Handled = true; return; } @@ -1952,7 +1952,7 @@ namespace TShockAPI if (args.Player.IsBeingDisabled()) { TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected disabled from {0}", args.Player.Name); - args.Player.SendTileSquare(x, y, 4); + args.Player.SendTileSquareCentered(x, y, 4); args.Handled = true; return; } @@ -1963,7 +1963,7 @@ namespace TShockAPI if (type != args.Player.TPlayer.inventory[args.Player.TPlayer.selectedItem].createTile) { TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected awkward tile creation/selection from {0}", args.Player.Name); - args.Player.SendTileSquare(x, y, 4); + args.Player.SendTileSquareCentered(x, y, 4); args.Handled = true; return; } @@ -1987,7 +1987,7 @@ namespace TShockAPI && !args.Player.HasBuildPermission(i, j)) { TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected mad loop from {0}", args.Player.Name); - args.Player.SendTileSquare(i, j, 4); + args.Player.SendTileSquareCentered(i, j, 4); args.Handled = true; return; } @@ -2003,7 +2003,7 @@ namespace TShockAPI && !args.Player.IsInRange(x, y)) { TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected range checks from {0}", args.Player.Name); - args.Player.SendTileSquare(x, y, 4); + args.Player.SendTileSquareCentered(x, y, 4); args.Handled = true; return; } @@ -2012,7 +2012,7 @@ namespace TShockAPI { TShock.Log.ConsoleDebug("Bouncer / OnPlaceObject rejected tile place threshold from {0} {1}/{2}", args.Player.Name, args.Player.TilePlaceThreshold, TShock.Config.Settings.TilePlaceThreshold); args.Player.Disable("Reached TilePlace threshold.", DisableFlags.WriteToLogAndConsole); - args.Player.SendTileSquare(x, y, 4); + args.Player.SendTileSquareCentered(x, y, 4); args.Handled = true; return; } @@ -2410,7 +2410,7 @@ namespace TShockAPI if ((args.Player.SelectedItem.type != args.ItemID && args.Player.ItemInHand.type != args.ItemID)) { TShock.Log.ConsoleDebug("Bouncer / OnFoodPlatterTryPlacing rejected item not placed by hand from {0}", args.Player.Name); - args.Player.SendTileSquare(args.TileX, args.TileY, 1); + args.Player.SendTileSquareCentered(args.TileX, args.TileY, 1); args.Handled = true; return; } @@ -2420,7 +2420,7 @@ namespace TShockAPI Item item = new Item(); item.netDefaults(args.ItemID); args.Player.GiveItemCheck(args.ItemID, item.Name, args.Stack, args.Prefix); - args.Player.SendTileSquare(args.TileX, args.TileY, 1); + args.Player.SendTileSquareCentered(args.TileX, args.TileY, 1); args.Handled = true; return; } @@ -2431,7 +2431,7 @@ namespace TShockAPI Item item = new Item(); item.netDefaults(args.ItemID); args.Player.GiveItemCheck(args.ItemID, item.Name, args.Stack, args.Prefix); - args.Player.SendTileSquare(args.TileX, args.TileY, 1); + args.Player.SendTileSquareCentered(args.TileX, args.TileY, 1); args.Handled = true; return; } @@ -2439,7 +2439,7 @@ namespace TShockAPI if (!args.Player.IsInRange(args.TileX, args.TileY, range: 13)) // To my knowledge, max legit tile reach with accessories. { TShock.Log.ConsoleDebug("Bouncer / OnFoodPlatterTryPlacing rejected range checks from {0}", args.Player.Name); - args.Player.SendTileSquare(args.TileX, args.TileY, 1); + args.Player.SendTileSquareCentered(args.TileX, args.TileY, 1); args.Handled = true; return; } diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index a92994ab..ff0ed1ac 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -4899,7 +4899,7 @@ namespace TShockAPI try { - args.Player.SendTileSquare(boundaryPoint.X, boundaryPoint.Y, 1); + args.Player.SendTileSquareCentered(boundaryPoint.X, boundaryPoint.Y, 1); } finally { @@ -4913,7 +4913,7 @@ namespace TShockAPI { foreach (Point boundaryPoint in Utils.Instance.EnumerateRegionBoundaries(regionArea)) if ((boundaryPoint.X + boundaryPoint.Y & 1) == 0) - args.Player.SendTileSquare(boundaryPoint.X, boundaryPoint.Y, 1); + args.Player.SendTileSquareCentered(boundaryPoint.X, boundaryPoint.Y, 1); Debug.Assert(boundaryHideTimer != null); boundaryHideTimer.Dispose(); @@ -5670,7 +5670,7 @@ namespace TShockAPI private static void SyncLocalArea(CommandArgs args) { - args.Player.SendTileSquare((int) args.Player.TileX, (int) args.Player.TileY, 32); + args.Player.SendTileSquareCentered(args.Player.TileX, args.Player.TileY, 32); args.Player.SendWarningMessage("Sync'd!"); return; } @@ -6676,7 +6676,7 @@ namespace TShockAPI } if (args.Parameters.Count == 1) { - args.Player.SendTileSquare(x - 2, y - 20, 25); + args.Player.SendTileSquareCentered(x - 2, y - 20, 25); args.Player.SendSuccessMessage("Tried to grow a " + name + "."); } } diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index e2ab3a47..72770c93 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -3895,7 +3895,7 @@ namespace TShockAPI if (TShock.TileBans.TileIsBanned((short)TileID.LogicSensor, args.Player)) { - args.Player.SendTileSquare(x, y, 1); + args.Player.SendTileSquareCentered(x, y, 1); args.Player.SendErrorMessage("You do not have permission to place Logic Sensors."); return true; } diff --git a/TShockAPI/ItemBans.cs b/TShockAPI/ItemBans.cs index 3556d38c..2fa9e85e 100644 --- a/TShockAPI/ItemBans.cs +++ b/TShockAPI/ItemBans.cs @@ -199,7 +199,7 @@ namespace TShockAPI { if (args.Player.TPlayer.autoActuator && DataModel.ItemIsBanned("Actuator", args.Player)) { - args.Player.SendTileSquare(args.X, args.Y, 1); + args.Player.SendTileSquareCentered(args.X, args.Y, 1); args.Player.SendErrorMessage("You do not have permission to place actuators."); args.Handled = true; return; @@ -207,7 +207,7 @@ namespace TShockAPI if (DataModel.ItemIsBanned(EnglishLanguage.GetItemNameById(args.Player.SelectedItem.netID), args.Player)) { - args.Player.SendTileSquare(args.X, args.Y, 4); + args.Player.SendTileSquareCentered(args.X, args.Y, 4); args.Handled = true; return; } diff --git a/TShockAPI/RegionHandler.cs b/TShockAPI/RegionHandler.cs index 671e9933..48d5421a 100644 --- a/TShockAPI/RegionHandler.cs +++ b/TShockAPI/RegionHandler.cs @@ -171,7 +171,7 @@ namespace TShockAPI } // Revert all tile changes and handle the event - player.SendTileSquare(e.X, e.Y, 4); + player.SendTileSquareCentered(e.X, e.Y, 4); e.Handled = true; } @@ -190,7 +190,7 @@ namespace TShockAPI player.AwaitingTempPoint = 0; // Revert all tile changes and handle the event - player.SendTileSquare(e.X, e.Y, 4); + player.SendTileSquareCentered(e.X, e.Y, 4); e.Handled = true; } diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index c4c094e9..414bc62a 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -1227,7 +1227,7 @@ namespace TShockAPI y = 992; } - SendTileSquare((int)(x / 16), (int)(y / 16), 15); + SendTileSquareCentered((int)(x / 16), (int)(y / 16), 15); TPlayer.Teleport(new Vector2(x, y), style); NetMessage.SendData((int)PacketTypes.Teleport, -1, -1, NetworkText.Empty, 0, TPlayer.whoAmI, x, y, style); return true; @@ -1309,9 +1309,25 @@ namespace TShockAPI /// The y coordinate to send. /// The size square set of tiles to send. /// true if the tile square was sent successfully, else false + [Obsolete("This method may not send tiles the way you would expect it to. The (x,y) coordinates are the top left corner of the tile square, switch to " + nameof(SendTileSquareCentered) + " if you wish for the coordindates to be the center of the square.")] public virtual bool SendTileSquare(int x, int y, int size = 10) { - return SendTileRect((short)(x-(size/2)), (short)(y-(size/2)), (byte)size, (byte)size); + return SendTileRect((short)x, (short)y, (byte)size, (byte)size); + } + + /// + /// Sends a tile square at a center location with a given size. + /// Typically used to revert changes by Bouncer through sending the + /// "old" version of modified data back to a client. + /// Prevents desync issues. + /// + /// The x coordinates of the center of the square. + /// The y coordinates of the center of the square. + /// The size square set of tiles to send. + /// true if the tile square was sent successfully, else false + public virtual bool SendTileSquareCentered(int x, int y, byte size = 10) + { + return SendTileRect((short)(x - (size / 2)), (short)(y - (size / 2)), size, size); } /// @@ -1327,6 +1343,10 @@ namespace TShockAPI { try { + x = TShock.Utils.Clamp(x, Main.maxTilesX, 0); + y = TShock.Utils.Clamp(y, Main.maxTilesY, 0); + width = TShock.Utils.Clamp(x + width, Main.maxTilesX, 1) - x; + length = TShock.Utils.Clamp(y + length, Main.maxTilesY, 1) - x; NetMessage.SendTileSquare(Index, x, y, width, length, changeType); return true; } @@ -1348,7 +1368,7 @@ namespace TShockAPI public bool GiveItemCheck(int type, string name, int stack, int prefix = 0) { if ((TShock.ItemBans.DataModel.ItemIsBanned(name) && TShock.Config.Settings.PreventBannedItemSpawn) && - (TShock.ItemBans.DataModel.ItemIsBanned(name, this) || !TShock.Config.Settings.AllowAllowedGroupsToSpawnBannedItems)) + (TShock.ItemBans.DataModel.ItemIsBanned(name, this) || !TShock.Config.Settings.AllowAllowedGroupsToSpawnBannedItems)) return false; GiveItem(type, stack, prefix); diff --git a/TShockAPI/TSServerPlayer.cs b/TShockAPI/TSServerPlayer.cs index 9f59da49..d414d424 100644 --- a/TShockAPI/TSServerPlayer.cs +++ b/TShockAPI/TSServerPlayer.cs @@ -190,7 +190,7 @@ namespace TShockAPI // Send all players updated tile squares foreach (Vector2 coords in tiles.Keys) { - All.SendTileSquare((int)coords.X, (int)coords.Y, 3); + All.SendTileSquareCentered((int)coords.X, (int)coords.Y, 3); } } From a48bac3631e81d2f4357da6d2542684ccf8e7b93 Mon Sep 17 00:00:00 2001 From: 0x3fcf1bbd <81617230+0x3fcf1bbd@users.noreply.github.com> Date: Tue, 1 Feb 2022 16:06:34 +0100 Subject: [PATCH 10/18] Updated CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 596bb4b4..68936187 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,8 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Added filter in `GetDataHandlers.HandleCatchNpc` that stops unregistered and logged out players on SSC servers to catch critters. (@tru321) * Fixed rejection check inside of `HandlePaintTile` to account for the Paint Sprayer (or Architect Gizmo Pack) being inside your inventory, rather than on an accessory slot. (@drunderscore) * Added the lanterns night event to the `/worldevent` command. (@0x3fcf1bbd) -* Fixed `TSPlayer.SendTileSquare` not being centered around the passed coordinates. (@0x3fcf1bbd) +* Marked `TSPlayer.SendTileSquare` as deprecated, and created `TSPlayer.SendTileSquareCentered` that sends a tile square centered around the passed coordinates. (@0x3fcf1bbd) +* Added coordinates clamping to `TSPlayer.SendTileRect` so as to avoid OOBs. (@0x3fcf1bbd) ## TShock 4.5.12 * Fixed the ability to spawn Zenith projectile with non-original items. (@AgaSpace) From 958913ef134bd45a7ad446b99bec4f1566417482 Mon Sep 17 00:00:00 2001 From: ELI JOSEPH BRADLEY Date: Mon, 14 Feb 2022 12:22:31 -0600 Subject: [PATCH 11/18] Remove extraneous space. Remove space following backslash in multi-line command, causing failure in Bash 5.1. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 93d08ba6..ebc852bb 100644 --- a/README.md +++ b/README.md @@ -207,7 +207,7 @@ You need to re-run the patcher any time `OTAPI` updates. You need to rebuild `Te $ cd ./TerrariaServerAPI/TShock.Modifications.Bootstrapper/bin/$BUILD_MODE/ $ mono TShock.Modifications.Bootstrapper.exe -in=OTAPI.dll \ - -mod=../../../TShock.Modifications.**/bin/$BUILD_MODE/TShock.Modifications.*.dll \ + -mod=../../../TShock.Modifications.**/bin/$BUILD_MODE/TShock.Modifications.*.dll \ -o=Output/OTAPI.dll 1. Verify that non-zero modifications ran successfully. Then, build the Terraria Server API executable. From 86527974de59e74b86c4fc567a74b2fc05b00299 Mon Sep 17 00:00:00 2001 From: ELI JOSEPH BRADLEY Date: Mon, 14 Feb 2022 12:25:31 -0600 Subject: [PATCH 12/18] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 792052f8..4650c02d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Fixed the ability to create custom messages with your death (or the death of another player) (@AgaSpace) * Added the `OnSignRead` handler in `GetDataHandler`, and added the `SignRead` event. Added check to ensure the sign being read is within world bounds `(x >= 0 && y >= 0 && x < Main.maxTilesX && y < Main.maxTilesY)`. (@drunderscore) * Added check to `HandleNpcTalk` to ensure the passed NPC index is within bounds (>= -1 && < `Main.maxNPCs`). (@drunderscore) +* Removed extraneous space causing build commands in README to fail. (@EtherTyper) ## TShock 4.5.11 * Add the new allowed buff TentacleSpike to NPC buff cheat detection bouncer. (@sgkoishi) From 956b5a5243d97c4c52eac46f0c5d4680cf69b23b Mon Sep 17 00:00:00 2001 From: ELI JOSEPH BRADLEY Date: Mon, 14 Feb 2022 13:06:34 -0600 Subject: [PATCH 13/18] Move to correct section of CHANGELOG. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4650c02d..49b2e774 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Added filter in `GetDataHandlers.HandleCatchNpc` that stops unregistered and logged out players on SSC servers to catch critters. (@tru321) * Fixed rejection check inside of `HandlePaintTile` to account for the Paint Sprayer (or Architect Gizmo Pack) being inside your inventory, rather than on an accessory slot. (@drunderscore) * Added the lanterns night event to the `/worldevent` command. (@0x3fcf1bbd) +* Removed extraneous space causing build commands in README to fail. (@EtherTyper) ## TShock 4.5.12 * Fixed the ability to spawn Zenith projectile with non-original items. (@AgaSpace) @@ -23,7 +24,6 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Fixed the ability to create custom messages with your death (or the death of another player) (@AgaSpace) * Added the `OnSignRead` handler in `GetDataHandler`, and added the `SignRead` event. Added check to ensure the sign being read is within world bounds `(x >= 0 && y >= 0 && x < Main.maxTilesX && y < Main.maxTilesY)`. (@drunderscore) * Added check to `HandleNpcTalk` to ensure the passed NPC index is within bounds (>= -1 && < `Main.maxNPCs`). (@drunderscore) -* Removed extraneous space causing build commands in README to fail. (@EtherTyper) ## TShock 4.5.11 * Add the new allowed buff TentacleSpike to NPC buff cheat detection bouncer. (@sgkoishi) From 9bc936053bf9a16f938dab7d87c431e9337d6316 Mon Sep 17 00:00:00 2001 From: 0x3fcf1bbd <81617230+0x3fcf1bbd@users.noreply.github.com> Date: Wed, 16 Feb 2022 11:32:43 +0100 Subject: [PATCH 14/18] Fixed STR width & length clamping being incorrect. The main game should however clamp it itself too before sending, so there shouldn't be issues. --- TShockAPI/TSPlayer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 414bc62a..47f4e714 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -1345,8 +1345,8 @@ namespace TShockAPI { x = TShock.Utils.Clamp(x, Main.maxTilesX, 0); y = TShock.Utils.Clamp(y, Main.maxTilesY, 0); - width = TShock.Utils.Clamp(x + width, Main.maxTilesX, 1) - x; - length = TShock.Utils.Clamp(y + length, Main.maxTilesY, 1) - x; + width = TShock.Utils.Clamp(x + width, Main.maxTilesX, 0) - x; + length = TShock.Utils.Clamp(y + length, Main.maxTilesY, 0) - x; NetMessage.SendTileSquare(Index, x, y, width, length, changeType); return true; } From c6b04053a3327c24d1a31ab40e02e658e56a79e0 Mon Sep 17 00:00:00 2001 From: 0x3fcf1bbd <81617230+0x3fcf1bbd@users.noreply.github.com> Date: Wed, 16 Feb 2022 12:12:50 +0100 Subject: [PATCH 15/18] Removed clamping as the game does it itself. --- TShockAPI/TSPlayer.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 47f4e714..6a04bf0c 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -1343,10 +1343,6 @@ namespace TShockAPI { try { - x = TShock.Utils.Clamp(x, Main.maxTilesX, 0); - y = TShock.Utils.Clamp(y, Main.maxTilesY, 0); - width = TShock.Utils.Clamp(x + width, Main.maxTilesX, 0) - x; - length = TShock.Utils.Clamp(y + length, Main.maxTilesY, 0) - x; NetMessage.SendTileSquare(Index, x, y, width, length, changeType); return true; } From 5820c5344e33330124903fe48ffcbc112ca615e2 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Wed, 16 Feb 2022 18:15:23 -0800 Subject: [PATCH 16/18] Add SignatureBeef (nee DeathCradle) to funding.yml --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 0c7beb84..8275735a 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1,2 @@ # These are supported funding model platforms -github: [DeathCradle, hakusaro, Stealownz, QuiCM] +github: [SignatureBeef, hakusaro, Stealownz, QuiCM] From 6591b455fc791e39a521cbdf52c7ad79f8a43021 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Wed, 16 Feb 2022 19:45:57 -0800 Subject: [PATCH 17/18] Version tick: 4.5.13 --- CHANGELOG.md | 3 ++- TShockAPI/TShock.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ddd198e3..9671fbf5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,8 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Do not insert tabs into this file, under any circumstances, ever. * Do not forget to sign every line you change with your name. (@hakusaro) * If there is no section called "Upcoming changes" below this line, please add one with `## Upcoming changes` as the first line, and then a bulleted item directly after with the first change. -## Upcoming changes + +## TShock 4.5.13 * Added hook `GetDataHandlers.OnReleaseNpc` to handling ReleaseNPC packet and a bouncer to stops unregistered and logged out players on SSC servers from releasing critters NPC. The bouncer has additional filter to stops players who tried to release different critter using crafted packet, e.g. using bunny item to release golden bunny. (@tru321) * Added filter in `GetDataHandlers.HandleCatchNpc` that stops unregistered and logged out players on SSC servers to catch critters. (@tru321) * Fixed rejection check inside of `HandlePaintTile` to account for the Paint Sprayer (or Architect Gizmo Pack) being inside your inventory, rather than on an accessory slot. (@drunderscore) diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 7e15128c..337899d1 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -58,7 +58,7 @@ namespace TShockAPI /// VersionNum - The version number the TerrariaAPI will return back to the API. We just use the Assembly info. public static readonly Version VersionNum = Assembly.GetExecutingAssembly().GetName().Version; /// VersionCodename - The version codename is displayed when the server starts. Inspired by software codenames conventions. - public static readonly string VersionCodename = "Herrscher of Logic"; + public static readonly string VersionCodename = "Let us know if you're using this on raspberry pi or we might drop support for it"; /// SavePath - This is the path TShock saves its data in. This path is relative to the TerrariaServer.exe (not in ServerPlugins). public static string SavePath = "tshock"; From 4cb6a5eb4b622343e6876710a2f2f1f38adc64c4 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Wed, 16 Feb 2022 19:55:06 -0800 Subject: [PATCH 18/18] Really version tick to 4.5.13 this time. --- TShockAPI/Properties/AssemblyInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TShockAPI/Properties/AssemblyInfo.cs b/TShockAPI/Properties/AssemblyInfo.cs index df44eb86..d3abb901 100644 --- a/TShockAPI/Properties/AssemblyInfo.cs +++ b/TShockAPI/Properties/AssemblyInfo.cs @@ -53,5 +53,5 @@ using System.Runtime.InteropServices; // Also, be sure to release on github with the exact assembly version tag as below // so that the update manager works correctly (via the Github releases api and mimic) -[assembly: AssemblyVersion("4.5.12")] -[assembly: AssemblyFileVersion("4.5.12")] +[assembly: AssemblyVersion("4.5.13")] +[assembly: AssemblyFileVersion("4.5.13")]