diff --git a/CHANGELOG.md b/CHANGELOG.md index d08b8527..dc1a0b01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * `GetDataHandlers.SendTileSquare` hook now sends a `TSPlayer` and a `MemoryStream` of raw data. (@hakusaro) * Added `GetDataHandlers.HealOtherPlayer` hook. (@hakusaro) * Added `GetDataHandlers.PlaceObject` hook. (@hakusaro) - +* `GetDataHandlers.KillMe` now sends a `TSPlayer` and a `PlayerDeathReason`. (@hakusaro) ## TShock 4.3.24 * Updated OpenTerraria API to 1.3.5.3 (@DeathCradle) diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs index ed1caba1..6fc7f640 100644 --- a/TShockAPI/Bouncer.cs +++ b/TShockAPI/Bouncer.cs @@ -29,7 +29,7 @@ using static TShockAPI.GetDataHandlers; using TerrariaApi.Server; using Terraria.ObjectData; using Terraria.ID; - +using Terraria.DataStructures; namespace TShockAPI { @@ -42,6 +42,7 @@ namespace TShockAPI { // Setup hooks + GetDataHandlers.KillMe.Register(OnKillMe); GetDataHandlers.NewProjectile.Register(OnNewProjectile); GetDataHandlers.PlaceObject.Register(OnPlaceObject); GetDataHandlers.SendTileSquare.Register(OnSendTileSquare); @@ -49,6 +50,37 @@ namespace TShockAPI GetDataHandlers.TileEdit.Register(OnTileEdit); } + internal void OnKillMe(object sender, GetDataHandlers.KillMeEventArgs args) + { + short dmg = args.Damage; + short id = args.PlayerId; + PlayerDeathReason playerDeathReason = args.PlayerDeathReason; + + if (dmg > 20000) //Abnormal values have the potential to cause infinite loops in the server. + { + TShock.Utils.ForceKick(args.Player, "Crash Exploit Attempt", true); + TShock.Log.ConsoleError("Death Exploit Attempt: Damage {0}", dmg); + args.Handled = true; + return; + } + + if (id >= Main.maxPlayers) + { + args.Handled = true; + return; + } + + if (playerDeathReason != null) + { + if (playerDeathReason.GetDeathText(TShock.Players[id].Name).ToString().Length > 500) + { + TShock.Utils.Kick(TShock.Players[id], "Crash attempt", true); + args.Handled = true; + return; + } + } + } + internal void OnNewProjectile(object sender, GetDataHandlers.NewProjectileEventArgs args) { short ident = args.Identity; diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 0d59a7ec..c57ab351 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -389,6 +389,8 @@ namespace TShockAPI /// public class KillMeEventArgs : HandledEventArgs { + /// The TSPlayer that triggered the event. + public TSPlayer Player { get; set; } /// /// The Terraria playerID of the player /// @@ -405,23 +407,27 @@ namespace TShockAPI /// Player's current pvp setting /// public bool Pvp { get; set; } + /// The reason the player died. + public PlayerDeathReason PlayerDeathReason { get; set; } } /// /// KillMe - Terraria's crappy way of handling damage from players /// public static HandlerList KillMe; - private static bool OnKillMe(byte plr, byte direction, short damage, bool pvp) + private static bool OnKillMe(TSPlayer player, byte plr, byte direction, short damage, bool pvp, PlayerDeathReason playerDeathReason) { if (KillMe == null) return false; var args = new KillMeEventArgs { + Player = player, PlayerId = plr, Direction = direction, Damage = damage, Pvp = pvp, + PlayerDeathReason = playerDeathReason, }; KillMe.Invoke(null, args); return args.Handled; @@ -1341,7 +1347,6 @@ namespace TShockAPI { PacketTypes.TogglePvp, HandleTogglePvp }, { PacketTypes.PlayerTeam, HandlePlayerTeam }, { PacketTypes.TileKill, HandleTileKill }, - { PacketTypes.PlayerKillMe, HandlePlayerKillMe }, { PacketTypes.LiquidSet, HandleLiquidSet }, { PacketTypes.PlayerSpawn, HandleSpawn }, { PacketTypes.ChestGetContents, HandleChestOpen }, @@ -2315,71 +2320,6 @@ namespace TShockAPI return false; } - private static bool HandlePlayerKillMe(GetDataHandlerArgs args) - { - var id = args.Data.ReadInt8(); - var direction = (byte)(args.Data.ReadInt8() - 1); - var dmg = args.Data.ReadInt16(); - var pvp = args.Data.ReadInt8() == 0; - var text = args.Data.ReadString(); - if (dmg > 20000) //Abnormal values have the potential to cause infinite loops in the server. - { - TShock.Utils.ForceKick(args.Player, "Crash Exploit Attempt", true); - TShock.Log.ConsoleError("Death Exploit Attempt: Damage {0}", dmg); - return false; - } - - if (id >= Main.maxPlayers) - { - return true; - } - - if (OnKillMe(id, direction, dmg, pvp)) - return true; - - if (text.Length > 500) - { - TShock.Utils.Kick(TShock.Players[id], "Crash attempt", true); - return true; - } - - args.Player.Dead = true; - args.Player.RespawnTimer = TShock.Config.RespawnSeconds; - - foreach (NPC npc in Main.npc) - { - if (npc.active && (npc.boss || npc.type == 13 || npc.type == 14 || npc.type == 15) && - Math.Abs(args.TPlayer.Center.X - npc.Center.X) + Math.Abs(args.TPlayer.Center.Y - npc.Center.Y) < 4000f) - { - args.Player.RespawnTimer = TShock.Config.RespawnBossSeconds; - break; - } - } - - if (args.TPlayer.difficulty == 2 && (TShock.Config.KickOnHardcoreDeath || TShock.Config.BanOnHardcoreDeath)) - { - if (TShock.Config.BanOnHardcoreDeath) - { - if (!TShock.Utils.Ban(args.Player, TShock.Config.HardcoreBanReason, false, "hardcore-death")) - TShock.Utils.ForceKick(args.Player, "Death results in a ban, but you are immune to bans.", true); - } - else - { - TShock.Utils.ForceKick(args.Player, TShock.Config.HardcoreKickReason, true, false); - } - } - - if (args.TPlayer.difficulty == 2 && Main.ServerSideCharacter && args.Player.IsLoggedIn) - { - if (TShock.CharacterDB.RemovePlayer(args.Player.Account.ID)) - { - TShock.CharacterDB.SeedInitialData(args.Player.Account); - } - } - - return false; - } - private static bool HandlePlayerKillMeV2(GetDataHandlerArgs args) { var id = args.Data.ReadInt8(); @@ -2388,26 +2328,9 @@ namespace TShockAPI var direction = (byte)(args.Data.ReadInt8() - 1); BitsByte bits = (BitsByte)args.Data.ReadByte(); bool pvp = bits[0]; - if (dmg > 20000) //Abnormal values have the potential to cause infinite loops in the server. - { - TShock.Utils.ForceKick(args.Player, "Crash Exploit Attempt", true); - TShock.Log.ConsoleError("Death Exploit Attempt: Damage {0}", dmg); - return false; - } - if (id >= Main.maxPlayers) - { + if (OnKillMe(args.Player, id, direction, dmg, pvp, playerDeathReason)) return true; - } - - if (OnKillMe(id, direction, dmg, pvp)) - return true; - - if (playerDeathReason.GetDeathText(TShock.Players[id].Name).ToString().Length > 500) - { - TShock.Utils.Kick(TShock.Players[id], "Crash attempt", true); - return true; - } args.Player.Dead = true; args.Player.RespawnTimer = TShock.Config.RespawnSeconds;