From 50d8b0db307f6d5aed5d07c250d671eb63ba4fb1 Mon Sep 17 00:00:00 2001 From: Zaicon Kiroshu Date: Sat, 19 Nov 2016 17:05:08 -0600 Subject: [PATCH 1/4] 1.3.4.3 Update (API 1.26) --- TShockAPI/Commands.cs | 10 +- TShockAPI/GetDataHandlers.cs | 161 ++++++++++++++++++++++++++- TShockAPI/Permissions.cs | 3 + TShockAPI/Properties/AssemblyInfo.cs | 4 +- TShockAPI/Rest/RestManager.cs | 2 - TShockAPI/TSPlayer.cs | 4 +- TShockAPI/TSServerPlayer.cs | 5 +- 7 files changed, 178 insertions(+), 11 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 3575c807..754d6fab 100755 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -30,6 +30,7 @@ using Terraria.ID; using TShockAPI.DB; using TerrariaApi.Server; using TShockAPI.Hooks; +using Terraria.GameContent.Events; namespace TShockAPI { @@ -2053,7 +2054,7 @@ namespace TShockAPI TSPlayer.Server.SetPumpkinMoon(true); Main.bloodMoon = false; NPC.waveKills = 0f; - NPC.waveCount = wave; + NPC.waveNumber = wave; TSPlayer.All.SendInfoMessage("{0} started the pumpkin moon at wave {1}!", args.Player.Name, wave); break; @@ -2071,7 +2072,7 @@ namespace TShockAPI TSPlayer.Server.SetFrostMoon(true); Main.bloodMoon = false; NPC.waveKills = 0f; - NPC.waveCount = wave; + NPC.waveNumber = wave; TSPlayer.All.SendInfoMessage("{0} started the frost moon at wave {1}!", args.Player.Name, wave); break; @@ -2082,6 +2083,11 @@ namespace TShockAPI break; } } + else if (DD2Event.Ongoing) + { + DD2Event.StopInvasion(); + TSPlayer.All.SendInfoMessage("{0} has ended the Old One's Army event.", args.Player.Name); + } else { TSPlayer.All.SendInfoMessage("{0} has ended the invasion.", args.Player.Name); diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 819c4c24..82db3096 100755 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -1262,7 +1262,10 @@ namespace TShockAPI { PacketTypes.SyncExtraValue, HandleSyncExtraValue }, { PacketTypes.LoadNetModule, HandleLoadNetModule }, { PacketTypes.ToggleParty, HandleToggleParty }, - { PacketTypes.PlayerHealOther, HandleHealOther } + { PacketTypes.PlayerHealOther, HandleHealOther }, + { PacketTypes.CrystalInvasionStart, HandleOldOnesArmy }, + { PacketTypes.PlayerHurtV2, HandlePlayerDamageV2 }, + { PacketTypes.PlayerDeathV2, HandlePlayerKillMeV2 } }; } @@ -2922,6 +2925,72 @@ namespace TShockAPI return false; } + private static bool HandlePlayerKillMeV2(GetDataHandlerArgs args) + { + var id = args.Data.ReadInt8(); + PlayerDeathReason playerDeathReason = PlayerDeathReason.FromReader(new BinaryReader(args.Data)); + var dmg = args.Data.ReadInt16(); + 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) + { + return true; + } + + if (OnKillMe(id, direction, dmg, pvp)) + return true; + + if (playerDeathReason.GetDeathText().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.User.ID)) + { + TShock.CharacterDB.SeedInitialData(args.Player.User); + } + } + + return false; + } + private static bool HandleLiquidSet(GetDataHandlerArgs args) { int tileX = args.Data.ReadInt16(); @@ -3517,6 +3586,76 @@ namespace TShockAPI return false; } + private static bool HandlePlayerDamageV2(GetDataHandlerArgs args) + { + var id = args.Data.ReadInt8(); + PlayerDeathReason playerDeathReason = PlayerDeathReason.FromReader(new BinaryReader(args.Data)); + var dmg = args.Data.ReadInt16(); + var direction = (byte)(args.Data.ReadInt8() - 1); + var bits = (BitsByte)(args.Data.ReadByte()); + var crit = bits[0]; + var pvp = bits[1]; + + if (OnPlayerDamage(id, direction, dmg, pvp, crit)) + return true; + + if (id >= Main.maxPlayers || TShock.Players[id] == null) + { + return true; + } + + if (dmg > TShock.Config.MaxDamage && !args.Player.HasPermission(Permissions.ignoredamagecap) && id != args.Player.Index) + { + if (TShock.Config.KickOnDamageThresholdBroken) + { + TShock.Utils.Kick(args.Player, string.Format("Player damage exceeded {0}.", TShock.Config.MaxDamage)); + return true; + } + else + { + args.Player.Disable(String.Format("Player damage exceeded {0}.", TShock.Config.MaxDamage), DisableFlags.WriteToLogAndConsole); + } + args.Player.SendData(PacketTypes.PlayerHp, "", id); + args.Player.SendData(PacketTypes.PlayerUpdate, "", id); + return true; + } + + if (!TShock.Players[id].TPlayer.hostile && pvp && id != args.Player.Index) + { + args.Player.SendData(PacketTypes.PlayerHp, "", id); + args.Player.SendData(PacketTypes.PlayerUpdate, "", id); + return true; + } + + if (TShock.CheckIgnores(args.Player)) + { + args.Player.SendData(PacketTypes.PlayerHp, "", id); + args.Player.SendData(PacketTypes.PlayerUpdate, "", id); + return true; + } + + if (TShock.CheckRangePermission(args.Player, TShock.Players[id].TileX, TShock.Players[id].TileY, 100)) + { + args.Player.SendData(PacketTypes.PlayerHp, "", id); + args.Player.SendData(PacketTypes.PlayerUpdate, "", id); + return true; + } + + if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) + { + args.Player.SendData(PacketTypes.PlayerHp, "", id); + args.Player.SendData(PacketTypes.PlayerUpdate, "", id); + return true; + } + + if (TShock.Players[id].GodMode) + { + TShock.Players[id].Heal(args.TPlayer.statLifeMax); + } + + return false; + } + private static bool HandleNpcStrike(GetDataHandlerArgs args) { var id = args.Data.ReadInt16(); @@ -4237,5 +4376,25 @@ namespace TShockAPI return false; } + + private static bool HandleOldOnesArmy(GetDataHandlerArgs args) + { + if ((DateTime.UtcNow - args.Player.LastThreat).TotalMilliseconds < 5000) + { + return true; + } + + if (!args.Player.HasPermission(Permissions.startdd2)) + { + args.Player.SendErrorMessage("You don't have permission to start the Old One's Army event."); + return true; + } + + if (TShock.Config.AnonymousBossInvasions) + TShock.Utils.SendLogs(string.Format("{0} started the Old One's Army event!", args.Player.Name), Color.PaleVioletRed, args.Player); + else + TShock.Utils.Broadcast(string.Format("{0} started the Old One's Army event!", args.Player.Name), 175, 75, 255); + return false; + } } } diff --git a/TShockAPI/Permissions.cs b/TShockAPI/Permissions.cs index 8a80879f..3a5c3d34 100644 --- a/TShockAPI/Permissions.cs +++ b/TShockAPI/Permissions.cs @@ -212,6 +212,9 @@ namespace TShockAPI [Description("User can start invasions (Goblin/Snow Legion) using items.")] public static readonly string startinvasion = "tshock.npc.startinvasion"; + [Description("User can start the dd2 event.")] + public static readonly string startdd2 = "tshock.npc.startdd2"; + [Description("User can clear the list of users who have completed an angler quest that day.")] public static readonly string clearangler = "tshock.npc.clearanglerquests"; diff --git a/TShockAPI/Properties/AssemblyInfo.cs b/TShockAPI/Properties/AssemblyInfo.cs index bf2ea222..816fe778 100755 --- a/TShockAPI/Properties/AssemblyInfo.cs +++ b/TShockAPI/Properties/AssemblyInfo.cs @@ -53,5 +53,5 @@ using System.Runtime.InteropServices; // Also, be sure to release on github with the exact assembly version tag as below // so that the update manager works correctly (via the Github releases api and mimic) -[assembly: AssemblyVersion("4.3.20")] -[assembly: AssemblyFileVersion("4.3.20")] +[assembly: AssemblyVersion("4.3.21")] +[assembly: AssemblyFileVersion("4.3.21")] diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs index 81727580..b62fc9dd 100644 --- a/TShockAPI/Rest/RestManager.cs +++ b/TShockAPI/Rest/RestManager.cs @@ -676,8 +676,6 @@ namespace TShockAPI [Token] private object WorldMeteor(RestRequestArgs args) { - if (null == WorldGen.genRand) - WorldGen.genRand = new Random(); WorldGen.dropMeteor(); return RestResponse("Meteor has been spawned"); } diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index ed496ac2..96ba95af 100755 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -25,6 +25,7 @@ using System.Text; using System.Threading; using System.Timers; using Terraria; +using Terraria.DataStructures; using Terraria.ID; using TShockAPI.DB; using TShockAPI.Hooks; @@ -1018,8 +1019,7 @@ namespace TShockAPI /// The amount of damage the player will take. public virtual void DamagePlayer(int damage) { - NetMessage.SendData((int) PacketTypes.PlayerDamage, -1, -1, "", Index, ((new Random()).Next(-1, 1)), damage, - (float) 0); + NetMessage.SendPlayerHurt(Index, PlayerDeathReason.LegacyDefault(), damage, (new Random()).Next(-1, 1), false, false, 0, -1, -1); } /// diff --git a/TShockAPI/TSServerPlayer.cs b/TShockAPI/TSServerPlayer.cs index a69a4ca2..72517a52 100644 --- a/TShockAPI/TSServerPlayer.cs +++ b/TShockAPI/TSServerPlayer.cs @@ -16,9 +16,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -using System; +using System; using System.Collections.Generic; using Terraria; +using Terraria.Utilities; using TShockAPI; using TShockAPI.DB; @@ -158,7 +159,7 @@ namespace TShockAPI { // Main.rand is thread static. if (Main.rand == null) - Main.rand = new Random(); + Main.rand = new UnifiedRandom(); Main.npc[npcid].StrikeNPC(damage, knockBack, hitDirection); NetMessage.SendData((int)PacketTypes.NpcStrike, -1, -1, "", npcid, damage, knockBack, hitDirection); From 02815a23ef18dbe4805cfb3a9c6d93e8871d95f8 Mon Sep 17 00:00:00 2001 From: Zaicon Kiroshu Date: Sun, 20 Nov 2016 15:15:53 -0600 Subject: [PATCH 2/4] API Tick, Submodule Update, Changelog Update --- CHANGELOG.md | 6 ++++++ TShockAPI/TShock.cs | 9 +++------ TerrariaServerAPI | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a1aeea2..87c36bc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,12 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Added hardened stone to the whitelist of tiles editable by players (@DogooFalchion). * Added conversion system to send convert old MOTD format into smart text, while preserving initial line starting values to keep byte optimization for background colors Thanks to (@WhiteXZ, @Simon311, and especially @DogooFalchion) for the hard work on this issue. +## TShock 4.3.21 +* Compatibility with Terraria 1.3.3.4 (@Zaicon) +* API: Version tick 1.26 +* API: Depreciated PlayerDamage and PlayerKillMe packets (now uses PlayerHurtV2 and PlayerDeathV2) +* API: Main.rand now uses UnifiedRandom instead of Random + ## TShock 4.3.20 * Security improvement: The auth system is now automatically disabled if a superadmin exists in the database (@Enerdy). * Removed the `auth-verify` command since `auth` now serves its purpose when necessary (@Enerdy). diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 9e459ec2..36ae9ac3 100755 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -38,6 +38,7 @@ using TerrariaApi.Server; using TShockAPI.DB; using TShockAPI.Hooks; using TShockAPI.ServerSideCharacters; +using Terraria.Utilities; namespace TShockAPI { @@ -45,7 +46,7 @@ namespace TShockAPI /// This is the TShock main class. TShock is a plugin on the TerrariaServerAPI, so it extends the base TerrariaPlugin. /// TShock also complies with the API versioning system, and defines its required API version here. /// - [ApiVersion(1, 25)] + [ApiVersion(1, 26)] public class TShock : TerrariaPlugin { /// VersionNum - The version number the TerrariaAPI will return back to the API. We just use the Assembly info. @@ -1485,11 +1486,7 @@ namespace TShockAPI // Damn you ThreadStatic and Redigit if (Main.rand == null) { - Main.rand = new Random(); - } - if (WorldGen.genRand == null) - { - WorldGen.genRand = new Random(); + Main.rand = new UnifiedRandom(); } if (args.Command == "autosave") diff --git a/TerrariaServerAPI b/TerrariaServerAPI index b403f953..6486b608 160000 --- a/TerrariaServerAPI +++ b/TerrariaServerAPI @@ -1 +1 @@ -Subproject commit b403f9534f57690c0568ec8f8150afa417356cb8 +Subproject commit 6486b6083ba0d9c133489b3b7848f441384341f7 From 1331fd14fa6428844784ebce24a32ed1373f22ec Mon Sep 17 00:00:00 2001 From: Zaicon Kiroshu Date: Sun, 20 Nov 2016 19:16:51 -0600 Subject: [PATCH 3/4] API Tick, Submodule Update, Changelog Update (Part 2) --- CHANGELOG.md | 11 +++++------ TerrariaServerAPI | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87c36bc8..1efbed4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin ## Upcoming Changes +## TShock 4.3.21 +* Compatibility with Terraria 1.3.3.4 (@Patrikkk, @Zaicon). +* API: Version tick 1.26. +* API: Deprecated PlayerDamage and PlayerKillMe packets (now uses PlayerHurtV2 and PlayerDeathV2). +* API: Main.rand now uses UnifiedRandom instead of Random. This WILL break any existing plugin that uses Main.rand. * Fixed HealOtherPlayer packet exploit (@Simon311). * Added associated config option for HealOtherPlayer exploit prevention (@Simon311). * Added `/accountinfo` command to get account information for a given TShock account (@Simon311). @@ -22,12 +27,6 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Added hardened stone to the whitelist of tiles editable by players (@DogooFalchion). * Added conversion system to send convert old MOTD format into smart text, while preserving initial line starting values to keep byte optimization for background colors Thanks to (@WhiteXZ, @Simon311, and especially @DogooFalchion) for the hard work on this issue. -## TShock 4.3.21 -* Compatibility with Terraria 1.3.3.4 (@Zaicon) -* API: Version tick 1.26 -* API: Depreciated PlayerDamage and PlayerKillMe packets (now uses PlayerHurtV2 and PlayerDeathV2) -* API: Main.rand now uses UnifiedRandom instead of Random - ## TShock 4.3.20 * Security improvement: The auth system is now automatically disabled if a superadmin exists in the database (@Enerdy). * Removed the `auth-verify` command since `auth` now serves its purpose when necessary (@Enerdy). diff --git a/TerrariaServerAPI b/TerrariaServerAPI index 6486b608..ec4e59ea 160000 --- a/TerrariaServerAPI +++ b/TerrariaServerAPI @@ -1 +1 @@ -Subproject commit 6486b6083ba0d9c133489b3b7848f441384341f7 +Subproject commit ec4e59ea0c5fd5e21fbb4742c844863016a901a7 From 2eb4ee0c223a3fdb51a139bec198b3c1fac32337 Mon Sep 17 00:00:00 2001 From: Zaicon Kiroshu Date: Sun, 20 Nov 2016 19:18:52 -0600 Subject: [PATCH 4/4] Fix Version Typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1efbed4d..a9cd96f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin ## Upcoming Changes ## TShock 4.3.21 -* Compatibility with Terraria 1.3.3.4 (@Patrikkk, @Zaicon). +* Compatibility with Terraria 1.3.4.3 (@Patrikkk, @Zaicon). * API: Version tick 1.26. * API: Deprecated PlayerDamage and PlayerKillMe packets (now uses PlayerHurtV2 and PlayerDeathV2). * API: Main.rand now uses UnifiedRandom instead of Random. This WILL break any existing plugin that uses Main.rand.