diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b0c0914..10a852f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin ## Upcoming Changes * New permission `tshock.tp.pylon` to enable teleporting via Teleportation Pylons (@QuiCM) * New permission `tshock.journey.research` to enable sharing research via item sacrifice (@QuiCM) +* 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. ## TShock 4.4.0 (Pre-release 10) * Fix all rope coils. (@Olink) diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs index 8bf5a11a..b9bb2e05 100644 --- a/TShockAPI/Bouncer.cs +++ b/TShockAPI/Bouncer.cs @@ -38,6 +38,7 @@ namespace TShockAPI { internal Handlers.SendTileSquareHandler STSHandler { get; set; } internal Handlers.NetModules.NetModulePacketHandler NetModuleHandler { get; set; } + internal Handlers.EmojiHandler EmojiHandler { get; set; } /// Constructor call initializes Bouncer and related functionality. /// A new Bouncer. @@ -49,6 +50,9 @@ namespace TShockAPI NetModuleHandler = new Handlers.NetModules.NetModulePacketHandler(); GetDataHandlers.ReadNetModule += NetModuleHandler.OnReceive; + EmojiHandler = new Handlers.EmojiHandler(); + GetDataHandlers.Emoji += EmojiHandler.OnReceiveEmoji; + // Setup hooks GetDataHandlers.GetSection += OnGetSection; GetDataHandlers.PlayerUpdate += OnPlayerUpdate; diff --git a/TShockAPI/DB/GroupManager.cs b/TShockAPI/DB/GroupManager.cs index 584ad374..3cff37a1 100644 --- a/TShockAPI/DB/GroupManager.cs +++ b/TShockAPI/DB/GroupManager.cs @@ -65,7 +65,8 @@ namespace TShockAPI.DB Permissions.canpartychat, Permissions.cantalkinthird, Permissions.canchat, - Permissions.synclocalarea)); + Permissions.synclocalarea, + Permissions.sendemoji)); AddDefaultGroup("default", "guest", string.Join(",", diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index a6c08a50..dee152b5 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -151,6 +151,7 @@ namespace TShockAPI { PacketTypes.CrystalInvasionStart, HandleOldOnesArmy }, { PacketTypes.PlayerHurtV2, HandlePlayerDamageV2 }, { PacketTypes.PlayerDeathV2, HandlePlayerKillMeV2 }, + { PacketTypes.Emoji, HandleEmoji }, { PacketTypes.FishOutNPC, HandleFishOutNPC }, { PacketTypes.FoodPlatterTryPlacing, HandleFoodPlatterTryPlacing }, { PacketTypes.SyncRevengeMarker, HandleSyncRevengeMarker } @@ -1866,6 +1867,40 @@ namespace TShockAPI return args.Handled; } + /// + /// For use in an Emoji event. + /// + public class EmojiEventArgs : GetDataHandledEventArgs + { + /// + /// The player index in the packet, who sends the emoji. + /// + public byte PlayerIndex { get; set; } + /// + /// The ID of the emoji, that is being received. + /// + public byte EmojiID { get; set; } + } + /// + /// Called when a player sends an emoji. + /// + public static HandlerList Emoji = new HandlerList(); + private static bool OnEmoji(TSPlayer player, MemoryStream data, byte playerIndex, byte emojiID) + { + if (Emoji == null) + return false; + + var args = new EmojiEventArgs + { + Player = player, + Data = data, + PlayerIndex = playerIndex, + EmojiID = emojiID + }; + Emoji.Invoke(null, args); + return args.Handled; + } + /// /// For use in a FishOutNPC event. /// @@ -3556,6 +3591,17 @@ namespace TShockAPI return false; } + private static bool HandleEmoji(GetDataHandlerArgs args) + { + byte playerIndex = args.Data.ReadInt8(); + byte emojiID = args.Data.ReadInt8(); + + if (OnEmoji(args.Player, args.Data, playerIndex, emojiID)) + return true; + + return false; + } + private static bool HandleFishOutNPC(GetDataHandlerArgs args) { ushort tileX = args.Data.ReadUInt16(); diff --git a/TShockAPI/Handlers/EmojiHandler.cs b/TShockAPI/Handlers/EmojiHandler.cs new file mode 100644 index 00000000..b21cd53e --- /dev/null +++ b/TShockAPI/Handlers/EmojiHandler.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TShockAPI.Handlers +{ + /// + /// Handles emoji packets and checks for validity and permissions + /// + public class EmojiHandler + { + public void OnReceiveEmoji(object sender, GetDataHandlers.EmojiEventArgs args) + { + if (args.PlayerIndex != args.Player.Index) + { + TShock.Log.ConsoleError($"EmojiHandler: Emoji packet rejected for ID spoofing. Expected {args.Player.Index}, received {args.PlayerIndex} from {args.Player.Name}."); + args.Handled = true; + return; + } + + if (!args.Player.HasPermission(Permissions.sendemoji)) + { + args.Player.SendErrorMessage("You do not have permission to send emotes!"); + args.Handled = true; + return; + } + } + } +} diff --git a/TShockAPI/Permissions.cs b/TShockAPI/Permissions.cs index 3b401004..643882f8 100644 --- a/TShockAPI/Permissions.cs +++ b/TShockAPI/Permissions.cs @@ -474,6 +474,9 @@ namespace TShockAPI [Description("Player can resync themselves with server state.")] public static readonly string synclocalarea = "tshock.synclocalarea"; + + [Description("Player can send emotes.")] + public static readonly string sendemoji = "tshock.sendemoji"; #endregion /// /// Lists all commands associated with a given permission diff --git a/TShockAPI/TShockAPI.csproj b/TShockAPI/TShockAPI.csproj index bc26b96d..fef6f380 100644 --- a/TShockAPI/TShockAPI.csproj +++ b/TShockAPI/TShockAPI.csproj @@ -97,6 +97,7 @@ +