From 95d157fd5d24f8997578ca9a4d67f988b6b7d7f1 Mon Sep 17 00:00:00 2001 From: ATFGK <62204605+ATFGK@users.noreply.github.com> Date: Tue, 6 Dec 2022 13:45:37 +0800 Subject: [PATCH] Fix Terra Blade triggered MaxProjDamage, other net changes (#2852) * update * update * update * Update changelog.md * Update changelog.md Fixed syntax errors. * Update SpawnMsg.cs Use insteadUpperCamelCase * Update changelog.md * Update TSPlayer.cs * Update TSPlayer.cs Missing letters due to input method problems. * Update `docs/changelog.md` Co-authored-by: James Puleo --- TShockAPI/GetDataHandlers.cs | 95 ++++++++++++++++++++++++++---------- TShockAPI/Net/SpawnMsg.cs | 4 ++ TShockAPI/TSPlayer.cs | 6 ++- docs/changelog.md | 13 +++++ 4 files changed, 91 insertions(+), 27 deletions(-) diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 9f955c95..0aa2dce6 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -856,6 +856,14 @@ namespace TShockAPI /// public int RespawnTimer { get; set; } /// + /// Number Of Deaths PVE + /// + public int NumberOfDeathsPVE { get; set; } + /// + /// Number Of Deaths PVP + /// + public int NumberOfDeathsPVP { get; set; } + /// /// Context of where the player is spawning from. /// public PlayerSpawnContext SpawnContext { get; set; } @@ -864,7 +872,7 @@ namespace TShockAPI /// PlayerSpawn - When a player spawns /// public static HandlerList PlayerSpawn = new HandlerList(); - private static bool OnPlayerSpawn(TSPlayer player, MemoryStream data, byte pid, int spawnX, int spawnY, int respawnTimer, PlayerSpawnContext spawnContext) + private static bool OnPlayerSpawn(TSPlayer player, MemoryStream data, byte pid, int spawnX, int spawnY, int respawnTimer, int numberOfDeathsPVE, int numberOfDeathsPVP, PlayerSpawnContext spawnContext) { if (PlayerSpawn == null) return false; @@ -877,6 +885,8 @@ namespace TShockAPI SpawnX = spawnX, SpawnY = spawnY, RespawnTimer = respawnTimer, + NumberOfDeathsPVE = numberOfDeathsPVE, + NumberOfDeathsPVP = numberOfDeathsPVP, SpawnContext = spawnContext }; PlayerSpawn.Invoke(null, args); @@ -1033,12 +1043,16 @@ namespace TShockAPI /// 0 = Old One's Army, 1 = Granite, 2 = Marble, 3 = Hive, 4 = Gem Cave, 5 = Lihzhard Temple, 6 = Graveyard /// public BitsByte Zone4 { get; set; } + /// + /// 0 = The Aether + /// + public BitsByte Zone5 { get; set; } } /// /// PlayerZone - When the player sends it's zone/biome information to the server /// public static HandlerList PlayerZone = new HandlerList(); - private static bool OnPlayerZone(TSPlayer player, MemoryStream data, byte plr, BitsByte zone1, BitsByte zone2, BitsByte zone3, BitsByte zone4) + private static bool OnPlayerZone(TSPlayer player, MemoryStream data, byte plr, BitsByte zone1, BitsByte zone2, BitsByte zone3, BitsByte zone4, BitsByte zone5) { if (PlayerZone == null) return false; @@ -1051,7 +1065,8 @@ namespace TShockAPI Zone1 = zone1, Zone2 = zone2, Zone3 = zone3, - Zone4 = zone4 + Zone4 = zone4, + Zone5 = zone5 }; PlayerZone.Invoke(null, args); return args.Handled; @@ -1519,12 +1534,16 @@ namespace TShockAPI /// Type /// public byte type { get; set; } + /// + /// Paint Coat Tile + /// + public byte coatTile { get; set; } } /// /// NPCStrike - Called when an NPC is attacked /// public static HandlerList PaintTile = new HandlerList(); - private static bool OnPaintTile(TSPlayer player, MemoryStream data, Int32 x, Int32 y, byte t) + private static bool OnPaintTile(TSPlayer player, MemoryStream data, Int32 x, Int32 y, byte t, byte ct) { if (PaintTile == null) return false; @@ -1535,7 +1554,8 @@ namespace TShockAPI Data = data, X = x, Y = y, - type = t + type = t, + coatTile = ct }; PaintTile.Invoke(null, args); return args.Handled; @@ -1558,12 +1578,16 @@ namespace TShockAPI /// Type /// public byte type { get; set; } + /// + /// Paint Coat Wall + /// + public byte coatWall { get; set; } } /// /// Called When a wall is painted /// public static HandlerList PaintWall = new HandlerList(); - private static bool OnPaintWall(TSPlayer player, MemoryStream data, Int32 x, Int32 y, byte t) + private static bool OnPaintWall(TSPlayer player, MemoryStream data, Int32 x, Int32 y, byte t, byte cw) { if (PaintWall == null) return false; @@ -1574,7 +1598,8 @@ namespace TShockAPI Data = data, X = x, Y = y, - type = t + type = t, + coatWall = cw }; PaintWall.Invoke(null, args); return args.Handled; @@ -1734,12 +1759,15 @@ namespace TShockAPI /// Alternate variation of the object placed. public byte Alternate { get; set; } + /// Related to Rubblemaker. + public sbyte Random { get; set; } + /// The direction the object was placed. public bool Direction { get; set; } } /// Fired when an object is placed in the world. public static HandlerList PlaceObject = new HandlerList(); - private static bool OnPlaceObject(TSPlayer player, MemoryStream data, short x, short y, short type, short style, byte alternate, bool direction) + private static bool OnPlaceObject(TSPlayer player, MemoryStream data, short x, short y, short type, short style, byte alternate, sbyte random, bool direction) { if (PlaceObject == null) return false; @@ -1753,6 +1781,7 @@ namespace TShockAPI Type = type, Style = style, Alternate = alternate, + Random = random, Direction = direction }; @@ -1980,6 +2009,10 @@ namespace TShockAPI /// Is the damage critical? /// public bool Critical { get; set; } + /// + /// Cooldown Counter + /// + public sbyte CooldownCounter { get; set; } /// The reason the player took damage and/or died. public PlayerDeathReason PlayerDeathReason { get; set; } } @@ -1987,7 +2020,7 @@ namespace TShockAPI /// PlayerDamage - Called when a player is damaged /// public static HandlerList PlayerDamage = new HandlerList(); - private static bool OnPlayerDamage(TSPlayer player, MemoryStream data, byte id, byte dir, short dmg, bool pvp, bool crit, PlayerDeathReason playerDeathReason) + private static bool OnPlayerDamage(TSPlayer player, MemoryStream data, byte id, byte dir, short dmg, bool pvp, bool crit, sbyte cooldownCounter, PlayerDeathReason playerDeathReason) { if (PlayerDamage == null) return false; @@ -2001,6 +2034,7 @@ namespace TShockAPI Damage = dmg, PVP = pvp, Critical = crit, + CooldownCounter = cooldownCounter, PlayerDeathReason = playerDeathReason, }; PlayerDamage.Invoke(null, args); @@ -2687,9 +2721,11 @@ namespace TShockAPI short spawnx = args.Data.ReadInt16(); short spawny = args.Data.ReadInt16(); int respawnTimer = args.Data.ReadInt32(); + short numberOfDeathsPVE = args.Data.ReadInt16(); + short numberOfDeathsPVP = args.Data.ReadInt16(); PlayerSpawnContext context = (PlayerSpawnContext)args.Data.ReadByte(); - if (OnPlayerSpawn(args.Player, args.Data, player, spawnx, spawny, respawnTimer, context)) + if (OnPlayerSpawn(args.Player, args.Data, player, spawnx, spawny, respawnTimer, numberOfDeathsPVE, numberOfDeathsPVP, context)) return true; if ((Main.ServerSideCharacter) && (spawnx == -1 && spawny == -1)) //this means they want to spawn to vanilla spawn @@ -2912,17 +2948,19 @@ namespace TShockAPI Vector2 vel = args.Data.ReadVector2(); byte owner = args.Data.ReadInt8(); short type = args.Data.ReadInt16(); - NewProjectileData bits = new NewProjectileData((BitsByte)args.Data.ReadByte()); + BitsByte bitsByte = (BitsByte)args.Data.ReadByte(); + BitsByte bitsByte2 = (BitsByte)(bitsByte[2] ? args.Data.ReadByte() : 0); float[] ai = new float[Projectile.maxAI]; - for (int i = 0; i < Projectile.maxAI; ++i) - ai[i] = !bits.AI[i] ? 0.0f : args.Data.ReadSingle(); - ushort bannerId = bits.HasBannerIdToRespondTo ? args.Data.ReadUInt16() : (ushort)0; - short dmg = bits.HasDamage ? args.Data.ReadInt16() : (short)0; - float knockback = bits.HasKnockback ? args.Data.ReadSingle() : 0.0f; - short origDmg = bits.HasOriginalDamage ? args.Data.ReadInt16() : (short)0; - short projUUID = bits.HasUUUID ? args.Data.ReadInt16() : (short)-1; - if (projUUID >= 1000) - projUUID = -1; + for (int i = 0; i < Projectile.maxAI; ++i) ai[i] = 0f; + ai[0] = bitsByte[0] ? args.Data.ReadSingle() : 0f; + ai[1] = bitsByte[1] ? args.Data.ReadSingle() : 0f; + ushort bannerId = (ushort)(bitsByte[3] ? args.Data.ReadUInt16() : 0); + short dmg = (short)(bitsByte[4] ? args.Data.ReadInt16() : 0); + float knockback = bitsByte[5] ? args.Data.ReadSingle() : 0f; + short origDmg = (short)(bitsByte[6] ? args.Data.ReadInt16() : 0); + short projUUID = (short)(bitsByte[7] ? args.Data.ReadInt16() : -1); + if (projUUID >= 1000) projUUID = -1; + ai[2] = (bitsByte2[0] ? args.Data.ReadSingle() : 0f); var index = TShock.Utils.SearchProjectile(ident, owner); @@ -3150,8 +3188,9 @@ namespace TShockAPI BitsByte zone2 = args.Data.ReadInt8(); BitsByte zone3 = args.Data.ReadInt8(); BitsByte zone4 = args.Data.ReadInt8(); + BitsByte zone5 = args.Data.ReadInt8(); - if (OnPlayerZone(args.Player, args.Data, plr, zone1, zone2, zone3, zone4)) + if (OnPlayerZone(args.Player, args.Data, plr, zone1, zone2, zone3, zone4, zone5)) return true; return false; @@ -3616,13 +3655,14 @@ namespace TShockAPI var x = args.Data.ReadInt16(); var y = args.Data.ReadInt16(); var t = args.Data.ReadInt8(); + var ct = args.Data.ReadInt8();//PaintCoatTile if (x < 0 || y < 0 || x >= Main.maxTilesX || y >= Main.maxTilesY || t > Main.numTileColors) { TShock.Log.ConsoleDebug(GetString("GetDataHandlers / HandlePaintTile rejected range check {0}", args.Player.Name)); return true; } - if (OnPaintTile(args.Player, args.Data, x, y, t)) + if (OnPaintTile(args.Player, args.Data, x, y, t, ct)) { return true; } @@ -3663,13 +3703,14 @@ namespace TShockAPI var x = args.Data.ReadInt16(); var y = args.Data.ReadInt16(); var t = args.Data.ReadInt8(); + var cw = args.Data.ReadInt8();//PaintCoatWall if (x < 0 || y < 0 || x >= Main.maxTilesX || y >= Main.maxTilesY || t > Main.numTileColors) { TShock.Log.ConsoleDebug(GetString("GetDataHandlers / HandlePaintWall rejected range check {0}", args.Player.Name)); return true; } - if (OnPaintWall(args.Player, args.Data, x, y, t)) + if (OnPaintWall(args.Player, args.Data, x, y, t, cw)) { return true; } @@ -3928,9 +3969,10 @@ namespace TShockAPI short type = args.Data.ReadInt16(); short style = args.Data.ReadInt16(); byte alternate = args.Data.ReadInt8(); + sbyte random = (sbyte)args.Data.ReadInt8(); bool direction = args.Data.ReadBoolean(); - if (OnPlaceObject(args.Player, args.Data, x, y, type, style, alternate, direction)) + if (OnPlaceObject(args.Player, args.Data, x, y, type, style, alternate, random, direction)) return true; return false; @@ -4068,7 +4110,7 @@ namespace TShockAPI private static bool HandleNpcTeleportPortal(GetDataHandlerArgs args) { - var npcIndex = args.Data.ReadByte(); + var npcIndex = args.Data.ReadUInt16(); var portalColorIndex = args.Data.ReadInt16(); var newPosition = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); var velocity = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); @@ -4162,8 +4204,9 @@ namespace TShockAPI var bits = (BitsByte)(args.Data.ReadByte()); var crit = bits[0]; var pvp = bits[1]; + var cooldownCounter = (sbyte)args.Data.ReadInt8(); - if (OnPlayerDamage(args.Player, args.Data, id, direction, dmg, pvp, crit, playerDeathReason)) + if (OnPlayerDamage(args.Player, args.Data, id, direction, dmg, pvp, crit, cooldownCounter, playerDeathReason)) return true; return false; diff --git a/TShockAPI/Net/SpawnMsg.cs b/TShockAPI/Net/SpawnMsg.cs index 8f0d2752..241a42fa 100644 --- a/TShockAPI/Net/SpawnMsg.cs +++ b/TShockAPI/Net/SpawnMsg.cs @@ -33,6 +33,8 @@ namespace TShockAPI.Net public short TileX { get; set; } public short TileY { get; set; } public int RespawnTimer { get; set; } + public short NumberOfDeathsPVE { get; set; } + public short NumberOfDeathsPVP { get; set; } public PlayerSpawnContext PlayerSpawnContext { get; set; } public override void Pack(Stream stream) @@ -41,6 +43,8 @@ namespace TShockAPI.Net stream.WriteInt16(TileX); stream.WriteInt16(TileY); stream.WriteInt32(RespawnTimer); + stream.WriteInt16(NumberOfDeathsPVE); + stream.WriteInt16(NumberOfDeathsPVP); stream.WriteByte((byte) PlayerSpawnContext); } } diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 553ab9d9..ef5c3c22 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -1394,7 +1394,9 @@ namespace TShockAPI /// The Y coordinate. /// The PlayerSpawnContext. /// The respawn timer, will be Player.respawnTimer if parameter is null. - public void Spawn(int tilex, int tiley, PlayerSpawnContext context, int? respawnTimer = null) + /// The number of deaths PVE, will be TPlayer.numberOfDeathsPVE if parameter is null. + /// The number of deaths PVP, will be TPlayer.numberOfDeathsPVP if parameter is null. + public void Spawn(int tilex, int tiley, PlayerSpawnContext context, int? respawnTimer = null, short? numberOfDeathsPVE = null, short? numberOfDeathsPVP = null) { using (var ms = new MemoryStream()) { @@ -1404,6 +1406,8 @@ namespace TShockAPI TileX = (short)tilex, TileY = (short)tiley, RespawnTimer = respawnTimer ?? TShock.Players[Index].RespawnTimer * 60, + NumberOfDeathsPVE = numberOfDeathsPVE ?? (short)TPlayer.numberOfDeathsPVE, + NumberOfDeathsPVP = numberOfDeathsPVP ?? (short)TPlayer.numberOfDeathsPVP, PlayerSpawnContext = context, }; msg.PackFull(ms); diff --git a/docs/changelog.md b/docs/changelog.md index cd74676e..6bb0c295 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -78,6 +78,18 @@ Use past tense when adding new entries; sign your name off when you add or chang * If there is no section called "Upcoming changes" below this line, please add one with `## Upcoming changes` as the first line, and then a bulleted item directly after with the first change. --> ## Upcoming changes +* Corrected and updated deserialization of the following packets (@ATFGK): + * `ProjectileNew`: Read the third `AI` value. + * Before this change, it was previously possible for the projectile damage limit to falsely trigger, such as when using the Terra Balde and Fire Gauntlet together. + * `PlayerSpawn`: Read the `NumberOfDeathsPVE` and `NumberOfDeathsPVP` values. + * Before this change, the `PlayerSpawnContext` was always read incorrectly, due to the values above being placed in the middle of the existing structure. + * `NpcTeleportPortal`: Read the NPC index as a `ushort` instead of a `byte`. + * `PlaceObject`: Read the `Random` value. + * Before this change, the `Direction` was always read incorrectly, due to the value above being placed in the middle of the existing structure. + * `Zones`: Read the `zone5` value. + * `PaintTile` and `PaintWall`: Read the `coatTile` and `coatWall` values. + * `PlayerHurtV2`: Read the `cooldownCounter` value. +* Updated `SpawnMsg` to include the `NumberOfDeathsPVE` and `NumberOfDeathsPVP`, and allow them to be optionally used in `TSPlayer.Spawn`. (@ATFGK) * Added `WorldTileProvider` to the tshock config with values `default`, `constileation` or `heaptile`. This allows tile providers to be changed in environments where CLI args cannot be altered. See the documentation website for more info about these providers. (@SignatureBeef) * Updated the Utils.FindByIdOrName to follow same logic. Now fuzzy match fallback to `StartsWith` and then `Contains`. (@sgkoishi) * Added `ShadowCandle` and `BrainOfConfusionBuff` (BoC dodge buff) to the `PlayerAddBuffWhitelist` (@drunderscore) @@ -89,6 +101,7 @@ Use past tense when adding new entries; sign your name off when you add or chang * Increased whitelisted duration of the Mighty Wind (`WindPushed`) buff (from sandstorms). (@drunderscore) * Allowed the Hellfire (`OnFire3`) buff. (@drunderscore) + ## TShock 5.1.3 * Added support for Terraria 1.4.4.9 via OTAPI 3.1.20. (@SignatureBeef)