diff --git a/CHANGELOG.md b/CHANGELOG.md index 78c6dce3..b2b13893 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,17 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin ## Upcoming changes * Installed new sprinklers! * Organized parameters by category and relevance in the `config.json` file. (@kubedzero) +* Fix multiple holes in Bouncer OnTileData. (@Patrikkk, @hakusaro) + * Issue where players could replace tiles with banned tiles without permission. + * Including replace action in TilePlace threshold incrementation, so players cannot bypass the threshold while replacing tiles/walls. + * Including check for maxTileSets when player is replacing tiles, so players cannot send invalid tile data through the replace tile action. + * Including a check for ReplaceWall when the tile is a Breakable/CutTile. +* Adding checks in Bouncer OnNewProjectile (@Patrikkk): + * For valid golf club and golf ball creation. + * Renamed stabProjectile to directionalProjectile for a more accurate naming. + * Adding staff projectiles to the directionalProjectiles Dictionary to include staffs in the valid projectile creation check. + * Adding GolfBallItemIDs list in Handlers.LandGolfBallInCupHandler.cs +* Fixed an issue in the SendTileSquare handler that was rejecting valid tile objects (@QuiCM) ## TShock 4.4.0 (Pre-release 11) * New permission `tshock.tp.pylon` to enable teleporting via Teleportation Pylons (@QuiCM) diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs index 117c8aac..3d6e7521 100644 --- a/TShockAPI/Bouncer.cs +++ b/TShockAPI/Bouncer.cs @@ -259,7 +259,7 @@ namespace TShockAPI int lastKilledProj = args.Player.LastKilledProjectile; ITile tile = Main.tile[tileX, tileY]; - if (action == EditAction.PlaceTile) + if (action == EditAction.PlaceTile || action == EditAction.ReplaceTile) { if (TShock.TileBans.TileIsBanned(editData, args.Player)) { @@ -330,7 +330,7 @@ namespace TShockAPI return; } } - else if (action == EditAction.PlaceTile || action == EditAction.PlaceWall) + else if (action == EditAction.PlaceTile || action == EditAction.ReplaceTile || action == EditAction.PlaceWall || action == EditAction.ReplaceWall) { if ((action == EditAction.PlaceTile && TShock.Config.PreventInvalidPlaceStyle) && (MaxPlaceStyles.ContainsKey(editData) && style > MaxPlaceStyles[editData]) && @@ -358,7 +358,7 @@ namespace TShockAPI } } - if (editData >= (action == EditAction.PlaceTile ? Main.maxTileSets : Main.maxWallTypes)) + if (editData >= ((action == EditAction.PlaceTile || action == EditAction.ReplaceTile) ? Main.maxTileSets : Main.maxWallTypes)) { TShock.Log.ConsoleDebug("Bouncer / OnTileEdit rejected from (ms3) {0} {1} {2}", args.Player.Name, action, editData); args.Player.SendTileSquare(tileX, tileY, 4); @@ -437,7 +437,7 @@ namespace TShockAPI } if (TShock.Config.AllowCutTilesAndBreakables && Main.tileCut[tile.type]) { - if (action == EditAction.KillWall) + 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); @@ -536,7 +536,7 @@ namespace TShockAPI return; } - if ((action == EditAction.PlaceTile || action == EditAction.PlaceWall) && !args.Player.HasPermission(Permissions.ignoreplacetiledetection)) + if ((action == EditAction.PlaceTile || action == EditAction.ReplaceTile || action == EditAction.PlaceWall || action == EditAction.ReplaceWall) && !args.Player.HasPermission(Permissions.ignoreplacetiledetection)) { args.Player.TilePlaceThreshold++; var coords = new Vector2(tileX, tileY); @@ -545,7 +545,7 @@ namespace TShockAPI args.Player.TilesCreated.Add(coords, Main.tile[tileX, tileY]); } - if ((action == EditAction.KillTile || action == EditAction.KillTileNoItem || action == EditAction.KillWall) && Main.tileSolid[Main.tile[tileX, tileY].type] && + if ((action == EditAction.KillTile || action == EditAction.KillTileNoItem || action == EditAction.ReplaceTile || action == EditAction.KillWall || action == EditAction.ReplaceWall) && Main.tileSolid[Main.tile[tileX, tileY].type] && !args.Player.HasPermission(Permissions.ignorekilltiledetection)) { args.Player.TileKillThreshold++; @@ -717,15 +717,32 @@ namespace TShockAPI return; } - if (stabProjectile.ContainsKey(type)) + /// If the projectile is a directional projectile, check if the player is holding their respected item to validate the projectile creation. + if (directionalProjectiles.ContainsKey(type)) { - if (stabProjectile[type] == args.Player.TPlayer.HeldItem.type) + if (directionalProjectiles[type] == args.Player.TPlayer.HeldItem.type) { args.Handled = false; return; } } + /// If the created projectile is a golf club, check if the player is holding one of the golf club items to validate the projectile creation. + if (type == ProjectileID.GolfClubHelper && Handlers.LandGolfBallInCupHandler.GolfClubItemIDs.Contains(args.Player.TPlayer.HeldItem.type)) + { + args.Handled = false; + return; + } + + /// If the created projectile is a golf ball and the player is not holding a golf club item and neither a golf ball item and neither they have had a golf club projectile created recently. + if (Handlers.LandGolfBallInCupHandler.GolfBallProjectileIDs.Contains(type) && + !Handlers.LandGolfBallInCupHandler.GolfClubItemIDs.Contains(args.Player.TPlayer.HeldItem.type) && + !Handlers.LandGolfBallInCupHandler.GolfBallItemIDs.Contains(args.Player.TPlayer.HeldItem.type) && + !args.Player.RecentlyCreatedProjectiles.Any(p => p.Type == ProjectileID.GolfClubHelper)) + { + TShock.Log.ConsoleDebug("Bouncer / OnNewProjectile please report to tshock about this! normally this is a reject from {0} {1} (golf)", args.Player.Name, type); + } + // Main.projHostile contains projectiles that can harm players // without PvP enabled and belong to enemy mobs, so they shouldn't be // possible for players to create. (Source: Ijwu, QuiCM) @@ -2118,9 +2135,33 @@ namespace TShockAPI TileID.Campfire }; - private static Dictionary stabProjectile = new Dictionary() + /// + /// These projectiles have been added or modified with Terraria 1.4. + /// They come from normal items, but to have the directional functionality, they must be projectiles. + /// + private static Dictionary directionalProjectiles = new Dictionary() { - { ProjectileID.GladiusStab, ItemID.Gladius }, + ///Spears + { ProjectileID.DarkLance, ItemID.DarkLance}, + { ProjectileID.Trident, ItemID.Trident}, + { ProjectileID.Spear, ItemID.Spear}, + { ProjectileID.MythrilHalberd, ItemID.MythrilHalberd}, + { ProjectileID.AdamantiteGlaive, ItemID.AdamantiteGlaive}, + { ProjectileID.CobaltNaginata, ItemID.CobaltNaginata}, + { ProjectileID.Gungnir, ItemID.Gungnir}, + { ProjectileID.MushroomSpear, ItemID.MushroomSpear}, + { ProjectileID.TheRottedFork, ItemID.TheRottedFork}, + { ProjectileID.PalladiumPike, ItemID.PalladiumPike}, + { ProjectileID.OrichalcumHalberd, ItemID.OrichalcumHalberd}, + { ProjectileID.TitaniumTrident, ItemID.TitaniumTrident}, + { ProjectileID.ChlorophytePartisan, ItemID.ChlorophytePartisan}, + { ProjectileID.NorthPoleWeapon, ItemID.NorthPole}, + { ProjectileID.ObsidianSwordfish, ItemID.ObsidianSwordfish}, + { ProjectileID.Swordfish, ItemID.Swordfish}, + { ProjectileID.MonkStaffT2, ItemID.MonkStaffT2}, + { ProjectileID.ThunderSpear, ItemID.ThunderSpear}, + { ProjectileID.GladiusStab, ItemID.Gladius}, + /// ShortSwords { ProjectileID.RulerStab, ItemID.Ruler }, { ProjectileID.CopperShortswordStab, ItemID.CopperShortsword }, { ProjectileID.TinShortswordStab, ItemID.TinShortsword }, diff --git a/TShockAPI/Handlers/LandGolfBallInCupHandler.cs b/TShockAPI/Handlers/LandGolfBallInCupHandler.cs index 43e95a35..1038d27e 100644 --- a/TShockAPI/Handlers/LandGolfBallInCupHandler.cs +++ b/TShockAPI/Handlers/LandGolfBallInCupHandler.cs @@ -59,6 +59,26 @@ namespace TShockAPI.Handlers ItemID.GolfClubWedge, ItemID.GolfClubPutter }; + /// + /// List of golf ball item IDs. + /// + public static readonly List GolfBallItemIDs = new List() + { + ItemID.GolfBall, + ItemID.GolfBallDyedBlack, + ItemID.GolfBallDyedBlue, + ItemID.GolfBallDyedBrown, + ItemID.GolfBallDyedCyan, + ItemID.GolfBallDyedGreen, + ItemID.GolfBallDyedLimeGreen, + ItemID.GolfBallDyedOrange, + ItemID.GolfBallDyedPink, + ItemID.GolfBallDyedPurple, + ItemID.GolfBallDyedRed, + ItemID.GolfBallDyedSkyBlue, + ItemID.GolfBallDyedTeal, + ItemID.GolfBallDyedViolet + }; /// /// Invoked when a player lands a golf ball in a cup. diff --git a/TShockAPI/Handlers/SendTileSquareHandler.cs b/TShockAPI/Handlers/SendTileSquareHandler.cs index 2bf0c729..c7449087 100644 --- a/TShockAPI/Handlers/SendTileSquareHandler.cs +++ b/TShockAPI/Handlers/SendTileSquareHandler.cs @@ -470,7 +470,7 @@ namespace TShockAPI.Handlers return false; } - if (x + width >= size || y + height + offsetY >= size) + if (x + width > size || y + height + offsetY > size) { // This is ugly, but we want to mark all these tiles as processed so that we're not hitting this check multiple times for one dodgy tile object for (int i = x; i < size; i++)