diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs index b5dae813..c2ea252e 100644 --- a/TShockAPI/Bouncer.cs +++ b/TShockAPI/Bouncer.cs @@ -303,11 +303,20 @@ namespace TShockAPI args.Handled = true; return; } + + if (selectedItem.placeStyle != style) + { + TShock.Log.ConsoleError(string.Format("Bouncer / OnTileEdit rejected from (placestyle) {0} {1} {2} placeStyle: {3} expectedStyle: {4}", + args.Player.Name, action, editData, style, selectedItem.placeStyle)); + args.Player.SendTileSquare(tileX, tileY, 1); + args.Handled = true; + return; + } } if (action == EditAction.KillTile && !Main.tileCut[tile.type] && !breakableTiles.Contains(tile.type)) { - //TPlayer.mount.Type 8 => Drill Containment Unit. + // TPlayer.mount.Type 8 => Drill Containment Unit. // If the tile is an axe tile and they aren't selecting an axe, they're hacking. if (Main.tileAxe[tile.type] && ((args.Player.TPlayer.mount.Type != 8 && selectedItem.axe == 0) && !ItemID.Sets.Explosives[selectedItem.netID] && args.Player.RecentFuse == 0)) @@ -327,7 +336,7 @@ namespace TShockAPI } // If the tile is a pickaxe tile and they aren't selecting a pickaxe, they're hacking. // Item frames can be modified without pickaxe tile. - //also add an exception for snake coils, they can be removed when the player places a new one or after x amount of time + // also add an exception for snake coils, they can be removed when the player places a new one or after x amount of time else if (tile.type != TileID.ItemFrame && tile.type != TileID.MysticSnakeRope && !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) { @@ -354,9 +363,9 @@ namespace TShockAPI } else if (CoilTileIds.Contains(editData)) { - /// Handle placement if the user is placing rope that comes from a ropecoil, - /// but have not created the ropecoil projectile recently or the projectile was not at the correct coordinate, or the tile that the projectile places does not match the rope it is suposed to place - /// projectile should be the same X coordinate as all tile places (Note by @Olink) + // Handle placement if the user is placing rope that comes from a ropecoil, + // but have not created the ropecoil projectile recently or the projectile was not at the correct coordinate, or the tile that the projectile places does not match the rope it is suposed to place + // projectile should be the same X coordinate as all tile places (Note by @Olink) if (ropeCoilPlacements.ContainsKey(selectedItem.netID) && !args.Player.RecentlyCreatedProjectiles.Any(p => GetDataHandlers.projectileCreatesTile.ContainsKey(p.Type) && GetDataHandlers.projectileCreatesTile[p.Type] == editData && !p.Killed && Math.Abs((int)(Main.projectile[p.Index].position.X / 16f) - tileX) <= Math.Abs(Main.projectile[p.Index].velocity.X))) @@ -1106,6 +1115,7 @@ namespace TShockAPI int tileX = args.TileX; int tileY = args.TileY; int flag = args.Flag; + short style = args.Style; if (!TShock.Utils.TilePlacementValid(tileX, tileY) || (args.Player.Dead && TShock.Config.Settings.PreventDeadModification)) { @@ -1122,6 +1132,14 @@ namespace TShockAPI return; } + 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.Handled = true; + return; + } + if (flag != 0 && flag != 4 // if no container or container2 placement && Main.tile[tileX, tileY].type != TileID.Containers && Main.tile[tileX, tileY].type != TileID.Dressers @@ -1630,8 +1648,6 @@ namespace TShockAPI short y = args.Y; short type = args.Type; short style = args.Style; - byte alternate = args.Alternate; - bool direction = args.Direction; if (type < 0 || type >= Main.maxTileSets) { @@ -1654,6 +1670,13 @@ namespace TShockAPI return; } + if (args.Player.SelectedItem.placeStyle != style) + { + TShock.Log.ConsoleError(string.Format("Bouncer / OnPlaceObject rejected object placement with invalid style from {0}", args.Player.Name)); + args.Handled = true; + return; + } + //style 52 and 53 are used by ItemID.Fake_newchest1 and ItemID.Fake_newchest2 //These two items cause localised lag and rendering issues if (type == TileID.FakeContainers && (style == 52 || style == 53)) diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 879e02ce..3345b582 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -939,12 +939,16 @@ namespace TShockAPI /// The Y coordinate /// public int TileY { get; set; } + /// + /// Place style used + /// + public short Style { get; set; } } /// /// When a chest is added or removed from the world. /// public static HandlerList PlaceChest = new HandlerList(); - private static bool OnPlaceChest(TSPlayer player, MemoryStream data, int flag, int tilex, int tiley) + private static bool OnPlaceChest(TSPlayer player, MemoryStream data, int flag, int tilex, int tiley, short style) { if (PlaceChest == null) return false; @@ -956,6 +960,7 @@ namespace TShockAPI Flag = flag, TileX = tilex, TileY = tiley, + Style = style }; PlaceChest.Invoke(null, args); return args.Handled; @@ -2881,9 +2886,9 @@ namespace TShockAPI int flag = args.Data.ReadByte(); int tileX = args.Data.ReadInt16(); int tileY = args.Data.ReadInt16(); - args.Data.ReadInt16(); // Ignore style + short style = args.Data.ReadInt16(); - if (OnPlaceChest(args.Player, args.Data, flag, tileX, tileY)) + if (OnPlaceChest(args.Player, args.Data, flag, tileX, tileY, style)) return true; return false;