From 4944ee3144f14f92dc1b25527a62ab259c71c2bb Mon Sep 17 00:00:00 2001 From: Patrikkk Date: Mon, 1 Jun 2020 12:59:40 +0200 Subject: [PATCH] Implement Handler.LandGolfBalInCupHandler and handle packet exploits. Added multiple checks to prevent clients from sending the golfball packet directly, without having golf play actions. --- TShockAPI/Bouncer.cs | 4 + .../Handlers/LandGolfBallInCupHandler.cs | 115 ++++++++++++++++++ TShockAPI/TShockAPI.csproj | 1 + 3 files changed, 120 insertions(+) create mode 100644 TShockAPI/Handlers/LandGolfBallInCupHandler.cs diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs index 395bfddd..7cf7b87f 100644 --- a/TShockAPI/Bouncer.cs +++ b/TShockAPI/Bouncer.cs @@ -37,6 +37,7 @@ namespace TShockAPI internal sealed class Bouncer { internal Handlers.SendTileSquareHandler STSHandler { get; set; } + internal Handlers.LandGolfBallInCupHandler LandGolfBallInCupHandler { get; set; } /// Constructor call initializes Bouncer and related functionality. /// A new Bouncer. @@ -45,6 +46,9 @@ namespace TShockAPI STSHandler = new Handlers.SendTileSquareHandler(); GetDataHandlers.SendTileSquare += STSHandler.OnReceiveSendTileSquare; + LandGolfBallInCupHandler = new Handlers.LandGolfBallInCupHandler(); + GetDataHandlers.LandGolfBallInCup += LandGolfBallInCupHandler.OnLandGolfBallInCup; + // Setup hooks GetDataHandlers.GetSection += OnGetSection; GetDataHandlers.PlayerUpdate += OnPlayerUpdate; diff --git a/TShockAPI/Handlers/LandGolfBallInCupHandler.cs b/TShockAPI/Handlers/LandGolfBallInCupHandler.cs new file mode 100644 index 00000000..4ab7cbc9 --- /dev/null +++ b/TShockAPI/Handlers/LandGolfBallInCupHandler.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Terraria; +using Terraria.ID; + +namespace TShockAPI.Handlers +{ + /// + /// Handles client side exploits of LandGolfBallInCup packet. + /// + public class LandGolfBallInCupHandler + { + /// + /// List of golf ball projectile IDs. + /// + public static readonly List GolfBallProjectileIDs = new List() + { + ProjectileID.DirtGolfBall, + ProjectileID.GolfBallDyedBlack, + ProjectileID.GolfBallDyedBlue, + ProjectileID.GolfBallDyedBrown, + ProjectileID.GolfBallDyedCyan, + ProjectileID.GolfBallDyedGreen, + ProjectileID.GolfBallDyedLimeGreen, + ProjectileID.GolfBallDyedOrange, + ProjectileID.GolfBallDyedPink, + ProjectileID.GolfBallDyedPurple, + ProjectileID.GolfBallDyedRed, + ProjectileID.GolfBallDyedSkyBlue, + ProjectileID.GolfBallDyedTeal, + ProjectileID.GolfBallDyedViolet, + ProjectileID.GolfBallDyedYellow + }; + + /// + /// List of golf club item IDs + /// + public static readonly List GolfClubItemIDs = new List() + { + ItemID.GolfClubChlorophyteDriver, + ItemID.GolfClubDiamondWedge, + ItemID.GolfClubShroomitePutter, + ItemID.Fake_BambooChest, + ItemID.GolfClubTitaniumIron, + ItemID.GolfClubGoldWedge, + ItemID.GolfClubLeadPutter, + ItemID.GolfClubMythrilIron, + ItemID.GolfClubWoodDriver, + ItemID.GolfClubBronzeWedge, + ItemID.GolfClubRustyPutter, + ItemID.GolfClubStoneIron, + ItemID.GolfClubPearlwoodDriver, + ItemID.GolfClubIron, + ItemID.GolfClubDriver, + ItemID.GolfClubWedge, + ItemID.GolfClubPutter + }; + + /// + /// Invoked when a player lands a golf ball in a cup. + /// + /// + /// + public void OnLandGolfBallInCup(object sender, GetDataHandlers.LandGolfBallInCupEventArgs args) + { + if (args.PlayerIndex != args.Player.Index) + { + TShock.Log.ConsoleError($"LandGolfBallInCupHandler: Packet is spoofing to be player ID {args.PlayerIndex}! - From [{args.Player.Index}]{args.Player.Name}"); + args.Handled = true; + return; + } + + if (args.TileX > Main.maxTilesX || args.TileX < 0 + || args.TileY > Main.maxTilesY || args.TileY < 0) + { + TShock.Log.ConsoleError($"LandGolfBallInCupHandler: X and Y position is out of world bounds! - From {args.Player.Name}"); + args.Handled = true; + return; + } + + if (!Main.tile[args.TileX, args.TileY].active() && Main.tile[args.TileX, args.TileY].type != TileID.GolfHole) + { + TShock.Log.ConsoleError($"LandGolfBallInCupHandler: Tile at packet position X:{args.TileX} Y:{args.TileY} is not a golf hole! - From {args.Player.Name}"); + args.Handled = true; + return; + } + + if (!GolfBallProjectileIDs.Contains(args.ProjectileType)) + { + TShock.Log.ConsoleError($"LandGolfBallInCupHandler: Invalid golf ball projectile ID {args.ProjectileType}! - From {args.Player.Name}"); + args.Handled = true; + return; + } + + var usedGolfBall = args.Player.RecentlyCreatedProjectiles.Any(e => GolfBallProjectileIDs.Contains(e.Type)); + var usedGolfClub = args.Player.RecentlyCreatedProjectiles.Any(e => e.Type == ProjectileID.GolfClubHelper); + if (!usedGolfClub && !usedGolfBall) + { + TShock.Log.ConsoleError($"GolfPacketHandler: Player did not have create a golf club projectile the last 5 seconds! - From {args.Player.Name}"); + args.Handled = true; + return; + } + + if (!GolfClubItemIDs.Contains(args.Player.SelectedItem.type)) + { + TShock.Log.ConsoleError($"LandGolfBallInCupHandler: Item selected is not a golf club! - From {args.Player.Name}"); + args.Handled = true; + return; + } + } + } +} diff --git a/TShockAPI/TShockAPI.csproj b/TShockAPI/TShockAPI.csproj index ea6f4f48..fedc3f0b 100644 --- a/TShockAPI/TShockAPI.csproj +++ b/TShockAPI/TShockAPI.csproj @@ -88,6 +88,7 @@ +