Merge pull request #1968 from Pryaxis/handlegolfpacket

Handlegolfpacket
This commit is contained in:
Chris 2020-06-02 19:34:48 +09:30 committed by GitHub
commit f1e8fbd8ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 186 additions and 0 deletions

View file

@ -8,6 +8,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin
* Add Emoji event to GetDataHandler. This packet is received when a player tries to display an emote.
* Adding EmojiHandler to handle an exploit. Adding `tshock.sendemoji` permission and checks. Added this permission to guest group by default.
* Handling SyncCavernMonsterType packet to prevent an exploit where players could modify the server's cavern monster types and make the server spawn any NPCs - including bosses - onto other players.
* Added LandGolfBallInCup event which is accessible for developers to work with, as well as LandGolfBallInCup handler to handle exploits where players could send direct packets to trigger and imitate golf ball cup landing anywhere in the game world. Added two public lists in Handlers.LandGolfBallInCupHandler: GolfBallProjectileIDs and GolfClubItemIDs. (@Patrikkk)
## TShock 4.4.0 (Pre-release 10)
* Fix all rope coils. (@Olink)

View file

@ -39,6 +39,7 @@ namespace TShockAPI
internal Handlers.SendTileSquareHandler STSHandler { get; set; }
internal Handlers.NetModules.NetModulePacketHandler NetModuleHandler { get; set; }
internal Handlers.EmojiHandler EmojiHandler { get; set; }
internal Handlers.LandGolfBallInCupHandler LandGolfBallInCupHandler { get; set; }
/// <summary>Constructor call initializes Bouncer and related functionality.</summary>
/// <returns>A new Bouncer.</returns>
@ -52,6 +53,9 @@ namespace TShockAPI
EmojiHandler = new Handlers.EmojiHandler();
GetDataHandlers.Emoji += EmojiHandler.OnReceive;
LandGolfBallInCupHandler = new Handlers.LandGolfBallInCupHandler();
GetDataHandlers.LandGolfBallInCup += LandGolfBallInCupHandler.OnLandGolfBallInCup;
// Setup hooks
GetDataHandlers.GetSection += OnGetSection;

View file

@ -153,6 +153,7 @@ namespace TShockAPI
{ PacketTypes.PlayerDeathV2, HandlePlayerKillMeV2 },
{ PacketTypes.Emoji, HandleEmoji },
{ PacketTypes.SyncRevengeMarker, HandleSyncRevengeMarker },
{ PacketTypes.LandGolfBallInCup, HandleLandGolfBallInCup },
{ PacketTypes.FishOutNPC, HandleFishOutNPC },
{ PacketTypes.FoodPlatterTryPlacing, HandleFoodPlatterTryPlacing },
{ PacketTypes.SyncCavernMonsterType, HandleSyncCavernMonsterType }
@ -1901,6 +1902,56 @@ namespace TShockAPI
Emoji.Invoke(null, args);
return args.Handled;
}
/// <summary>
/// For use in a LandBallInCup event.
/// </summary>
public class LandGolfBallInCupEventArgs : GetDataHandledEventArgs
{
/// <summary>
/// The player index in the packet, who puts the ball in the cup.
/// </summary>
public byte PlayerIndex { get; set; }
/// <summary>
/// The X tile position of where the ball lands in a cup.
/// </summary>
public ushort TileX { get; set; }
/// <summary>
/// The Y tile position of where the ball lands in a cup.
/// </summary>
public ushort TileY { get; set; }
/// <summary>
/// The amount of hits it took for the player to land the ball in the cup.
/// </summary>
public ushort Hits { get; set; }
/// <summary>
/// The type of the projectile that was landed in the cup. A golfball in legit cases.
/// </summary>
public ushort ProjectileType { get; set; }
}
/// <summary>
/// Called when a player lands a golf ball in a cup.
/// </summary>
public static HandlerList<LandGolfBallInCupEventArgs> LandGolfBallInCup = new HandlerList<LandGolfBallInCupEventArgs>();
private static bool OnLandGolfBallInCup(TSPlayer player, MemoryStream data, byte playerIndex, ushort tileX, ushort tileY, ushort hits, ushort projectileType )
{
if (LandGolfBallInCup == null)
return false;
var args = new LandGolfBallInCupEventArgs
{
Player = player,
Data = data,
PlayerIndex = playerIndex,
TileX = tileX,
TileY = tileY,
Hits = hits,
ProjectileType = projectileType
};
LandGolfBallInCup.Invoke(null, args);
return args.Handled;
}
/// <summary>
/// For use in a FishOutNPC event.
@ -3618,6 +3669,20 @@ namespace TShockAPI
return false;
}
private static bool HandleLandGolfBallInCup(GetDataHandlerArgs args)
{
byte playerIndex = args.Data.ReadInt8();
ushort tileX = args.Data.ReadUInt16();
ushort tileY = args.Data.ReadUInt16();
ushort hits = args.Data.ReadUInt16();
ushort projectileType = args.Data.ReadUInt16();
if (OnLandGolfBallInCup(args.Player, args.Data, playerIndex, tileX, tileY, hits, projectileType))
return true;
return false;
}
private static bool HandleFishOutNPC(GetDataHandlerArgs args)
{
ushort tileX = args.Data.ReadUInt16();

View file

@ -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
{
/// <summary>
/// Handles client side exploits of LandGolfBallInCup packet.
/// </summary>
public class LandGolfBallInCupHandler
{
/// <summary>
/// List of golf ball projectile IDs.
/// </summary>
public static readonly List<int> GolfBallProjectileIDs = new List<int>()
{
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
};
/// <summary>
/// List of golf club item IDs
/// </summary>
public static readonly List<int> GolfClubItemIDs = new List<int>()
{
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
};
/// <summary>
/// Invoked when a player lands a golf ball in a cup.
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
public void OnLandGolfBallInCup(object sender, GetDataHandlers.LandGolfBallInCupEventArgs args)
{
if (args.PlayerIndex != args.Player.Index)
{
TShock.Log.ConsoleDebug($"LandGolfBallInCupHandler: Packet rejected for ID spoofing. Expected {args.PlayerIndex} , received {args.PlayerIndex} from {args.Player.Name}.");
args.Handled = true;
return;
}
if (args.TileX > Main.maxTilesX || args.TileX < 0
|| args.TileY > Main.maxTilesY || args.TileY < 0)
{
TShock.Log.ConsoleDebug($"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.ConsoleDebug($"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.ConsoleDebug($"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.ConsoleDebug($"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.ConsoleDebug($"LandGolfBallInCupHandler: Item selected is not a golf club! - From {args.Player.Name}");
args.Handled = true;
return;
}
}
}
}

View file

@ -98,6 +98,7 @@
<Compile Include="Handlers\NetModules\NetModulePacketHandler.cs" />
<Compile Include="Handlers\NetModules\PylonHandler.cs" />
<Compile Include="Handlers\EmojiHandler.cs" />
<Compile Include="Handlers\LandGolfBallInCupHandler.cs" />
<Compile Include="Handlers\SendTileSquareHandler.cs" />
<Compile Include="Hooks\AccountHooks.cs" />
<Compile Include="Hooks\GeneralHooks.cs" />