From d3c566db83d1b273b8108d3f177337fc3f901633 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Sun, 10 Dec 2017 10:04:27 -0700 Subject: [PATCH] Move a large majority of OnPlayerUpdate to Bouncer I really really don't understand why we're doing Terraria's data sync for them (see HandlePlayerUpdate). Someone know why? --- TShockAPI/Bouncer.cs | 104 +++++++++++++++++++++++++++++++++++ TShockAPI/GetDataHandlers.cs | 98 +++++---------------------------- 2 files changed, 119 insertions(+), 83 deletions(-) diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs index 3d5d5ebe..e99233a9 100644 --- a/TShockAPI/Bouncer.cs +++ b/TShockAPI/Bouncer.cs @@ -42,6 +42,7 @@ namespace TShockAPI { // Setup hooks + GetDataHandlers.PlayerUpdate.Register(OnPlayerUpdate); GetDataHandlers.KillMe.Register(OnKillMe); GetDataHandlers.NewProjectile.Register(OnNewProjectile); GetDataHandlers.PlaceObject.Register(OnPlaceObject); @@ -50,6 +51,109 @@ namespace TShockAPI GetDataHandlers.TileEdit.Register(OnTileEdit); } + /// Handles disabling enforcement & minor anti-exploit stuff + /// The object that triggered the event. + /// The packet arguments that the event has. + internal void OnPlayerUpdate(object sender, GetDataHandlers.PlayerUpdateEventArgs args) + { + byte plr = args.PlayerId; + BitsByte control = args.Control; + BitsByte pulley = args.Pulley; + byte item = args.Item; + var pos = args.Position; + var vel = args.Velocity; + + if (pos.X < 0 || pos.Y < 0 || pos.X >= Main.maxTilesX * 16 - 16 || pos.Y >= Main.maxTilesY * 16 - 16) + { + args.Handled = true; + return; + } + + if (item < 0 || item >= args.Player.TPlayer.inventory.Length) + { + args.Handled = true; + return; + } + + if (args.Player.LastNetPosition == Vector2.Zero) + { + args.Handled = true; + return; + } + + if (!pos.Equals(args.Player.LastNetPosition)) + { + float distance = Vector2.Distance(new Vector2(pos.X / 16f, pos.Y / 16f), + new Vector2(args.Player.LastNetPosition.X / 16f, args.Player.LastNetPosition.Y / 16f)); + + if (TShock.CheckIgnores(args.Player)) + { + // If the player has moved outside the disabled zone... + if (distance > TShock.Config.MaxRangeForDisabled) + { + // We need to tell them they were disabled and why, then revert the change. + if (args.Player.IgnoreActionsForCheating != "none") + { + args.Player.SendErrorMessage("Disabled for cheating: " + args.Player.IgnoreActionsForCheating); + } + else if (args.Player.IgnoreActionsForDisabledArmor != "none") + { + args.Player.SendErrorMessage("Disabled for banned armor: " + args.Player.IgnoreActionsForDisabledArmor); + } + else if (args.Player.IgnoreActionsForInventory != "none") + { + args.Player.SendErrorMessage("Disabled for Server Side Inventory: " + args.Player.IgnoreActionsForInventory); + } + else if (TShock.Config.RequireLogin && !args.Player.IsLoggedIn) + { + args.Player.SendErrorMessage("Please /register or /login to play!"); + } + else if (args.Player.IgnoreActionsForClearingTrashCan) + { + args.Player.SendErrorMessage("You need to rejoin to ensure your trash can is cleared!"); + } + + // ?? + var lastTileX = args.Player.LastNetPosition.X; + var lastTileY = args.Player.LastNetPosition.Y - 48; + if (!args.Player.Teleport(lastTileX, lastTileY)) + { + args.Player.Spawn(); + } + args.Handled = true; + return; + } + args.Handled = true; + return; + } + + // Corpses don't move + if (args.Player.Dead) + { + args.Handled = true; + return; + } + + // Noclip detection + if (!args.Player.HasPermission(Permissions.ignorenoclipdetection) && + TSCheckNoclip(pos, args.Player.TPlayer.width, args.Player.TPlayer.height - (args.Player.TPlayer.mount.Active ? args.Player.TPlayer.mount.HeightBoost : 0)) && !TShock.Config.IgnoreNoClip + && !args.Player.TPlayer.tongued) + { + var lastTileX = args.Player.LastNetPosition.X; + var lastTileY = args.Player.LastNetPosition.Y; + if (!args.Player.Teleport(lastTileX, lastTileY)) + { + args.Player.SendErrorMessage("You got stuck in a solid object, Sent to spawn point."); + args.Player.Spawn(); + } + args.Handled = true; + return; + } + } + + return; + } + /// Bouncer's KillMe hook stops crash exploits from out of bounds values. /// The object that triggered the event. /// The packet arguments that the event has. diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index c57ab351..fb1ac16b 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -438,16 +438,18 @@ namespace TShockAPI /// public class PlayerUpdateEventArgs : HandledEventArgs { + /// The TSPlayer object that triggered the event + public TSPlayer Player { get; set; } /// /// The Terraria playerID of the player /// public byte PlayerId { get; set; } /// - /// ??? + /// Control direction (BitFlags) /// public byte Control { get; set; } /// - /// Current item? + /// Selected item /// public byte Item { get; set; } /// @@ -458,7 +460,7 @@ namespace TShockAPI /// Velocity of the player /// public Vector2 Velocity { get; set; } - + /// Pulley update (BitFlags) public byte Pulley { get; set; } } /// @@ -466,14 +468,15 @@ namespace TShockAPI /// public static HandlerList PlayerUpdate; - private static bool OnPlayerUpdate(byte player, byte control, byte item, Vector2 position, Vector2 velocity, byte pulley) + private static bool OnPlayerUpdate(TSPlayer player, byte plr, byte control, byte item, Vector2 position, Vector2 velocity, byte pulley) { if (PlayerUpdate == null) return false; var args = new PlayerUpdateEventArgs { - PlayerId = player, + Player = player, + PlayerId = plr, Control = control, Item = item, Position = position, @@ -2034,6 +2037,9 @@ namespace TShockAPI { if (args.Player == null || args.TPlayer == null || args.Data == null) { + // Is this really the best option? + // If we're getting a packet that doesn't have a player or a TPlayer or data... + // Should we really let it through? return false; } @@ -2046,86 +2052,12 @@ namespace TShockAPI if (pulley[2]) vel = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); - if (OnPlayerUpdate(plr, control, item, pos, vel, pulley)) + if (OnPlayerUpdate(args.Player, plr, control, item, pos, vel, pulley)) return true; - if (pos.X < 0 || pos.Y < 0 || pos.X >= Main.maxTilesX * 16 - 16 || pos.Y >= Main.maxTilesY * 16 - 16) - { - return true; - } - - if (item < 0 || item >= args.TPlayer.inventory.Length) - { - return true; - } - - if (args.Player.LastNetPosition == Vector2.Zero) - { - return true; - } - - if (!pos.Equals(args.Player.LastNetPosition)) - { - float distance = Vector2.Distance(new Vector2(pos.X / 16f, pos.Y / 16f), - new Vector2(args.Player.LastNetPosition.X / 16f, args.Player.LastNetPosition.Y / 16f)); - if (TShock.CheckIgnores(args.Player)) - { - if (distance > TShock.Config.MaxRangeForDisabled) - { - if (args.Player.IgnoreActionsForCheating != "none") - { - args.Player.SendErrorMessage("Disabled for cheating: " + args.Player.IgnoreActionsForCheating); - } - else if (args.Player.IgnoreActionsForDisabledArmor != "none") - { - args.Player.SendErrorMessage("Disabled for banned armor: " + args.Player.IgnoreActionsForDisabledArmor); - } - else if (args.Player.IgnoreActionsForInventory != "none") - { - args.Player.SendErrorMessage("Disabled for Server Side Inventory: " + args.Player.IgnoreActionsForInventory); - } - else if (TShock.Config.RequireLogin && !args.Player.IsLoggedIn) - { - args.Player.SendErrorMessage("Please /register or /login to play!"); - } - else if (args.Player.IgnoreActionsForClearingTrashCan) - { - args.Player.SendErrorMessage("You need to rejoin to ensure your trash can is cleared!"); - } - var lastTileX = args.Player.LastNetPosition.X; - var lastTileY = args.Player.LastNetPosition.Y - 48; - if (!args.Player.Teleport(lastTileX, lastTileY)) - { - args.Player.Spawn(); - } - return true; - } - return true; - } - - if (args.Player.Dead) - { - return true; - } - - if (!args.Player.HasPermission(Permissions.ignorenoclipdetection) && - TSCheckNoclip(pos, args.TPlayer.width, args.TPlayer.height - (args.TPlayer.mount.Active ? args.Player.TPlayer.mount.HeightBoost : 0)) && !TShock.Config.IgnoreNoClip - && !args.TPlayer.tongued) - { - var lastTileX = args.Player.LastNetPosition.X; - var lastTileY = args.Player.LastNetPosition.Y; - if (!args.Player.Teleport(lastTileX, lastTileY)) - { - args.Player.SendErrorMessage("You got stuck in a solid object, Sent to spawn point."); - args.Player.Spawn(); - } - return true; - } - args.Player.LastNetPosition = pos; - } - if (control[5]) { + // ItemBan system string itemName = args.TPlayer.inventory[item].Name; if (TShock.Itembans.ItemIsBanned(EnglishLanguage.GetItemNameById(args.TPlayer.inventory[item].netID), args.Player)) { @@ -2134,6 +2066,7 @@ namespace TShockAPI args.Player.SendErrorMessage("You cannot use {0} on this server. Your actions are being ignored.", itemName); } + // Reimplementation of normal Terraria stuff? if (args.TPlayer.inventory[item].Name == "Mana Crystal" && args.Player.TPlayer.statManaMax <= 180) { args.Player.TPlayer.statMana += 20; @@ -2154,6 +2087,7 @@ namespace TShockAPI } } + // Where we rebuild sync data for Terraria? args.TPlayer.selectedItem = item; args.TPlayer.position = pos; args.TPlayer.oldVelocity = args.TPlayer.velocity; @@ -2210,7 +2144,6 @@ namespace TShockAPI args.TPlayer.direction = -1; } - if (args.Player.Confused && Main.ServerSideCharacter && args.Player.IsLoggedIn) { if (args.TPlayer.controlUp) @@ -2235,7 +2168,6 @@ namespace TShockAPI args.TPlayer.controlLeft = true; } - args.TPlayer.Update(args.TPlayer.whoAmI); NetMessage.SendData((int)PacketTypes.PlayerUpdate, -1, -1, NetworkText.Empty, args.Player.Index); return true;