diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs index 8d3d7636..76ffc3cd 100644 --- a/TShockAPI/Bouncer.cs +++ b/TShockAPI/Bouncer.cs @@ -416,6 +416,18 @@ namespace TShockAPI CanBeAddedWithoutHostile = false, CanOnlyBeAppliedToSender = false }; + PlayerAddBuffWhitelist[BuffID.ShadowCandle] = new BuffLimit + { + MaxTicks = 2, + CanBeAddedWithoutHostile = true, + CanOnlyBeAppliedToSender = true + }; + PlayerAddBuffWhitelist[BuffID.BrainOfConfusionBuff] = new BuffLimit + { + MaxTicks = 240, + CanBeAddedWithoutHostile = true, + CanOnlyBeAppliedToSender = true + }; #endregion Whitelist } @@ -1867,41 +1879,57 @@ namespace TShockAPI int type = args.Type; int time = args.Time; + void Reject(bool shouldResync = true) + { + args.Handled = true; + + if (shouldResync) + args.Player.SendData(PacketTypes.PlayerBuff, number: id); + } + if (id >= Main.maxPlayers) { - TShock.Log.ConsoleDebug(GetString("Bouncer / OnPlayerBuff rejected player cap from {0}", args.Player.Name)); - args.Handled = true; + TShock.Log.ConsoleDebug(GetString( + "Bouncer / OnPlayerBuff rejected {0} ({1}) applying buff {2} to {3} for {4} ticks: target ID out of bounds", + args.Player.Name, args.Player.Index, type, id, time)); + Reject(false); return; } if (TShock.Players[id] == null) { - TShock.Log.ConsoleDebug(GetString("Bouncer / OnPlayerBuff rejected null check from {0}", args.Player.Name)); - args.Handled = true; + TShock.Log.ConsoleDebug(GetString( + "Bouncer / OnPlayerBuff rejected {0} ({1}) applying buff {2} to {3} for {4} ticks: target is null", args.Player.Name, + args.Player.Index, type, id, time)); + Reject(false); return; } if (type >= Terraria.ID.BuffID.Count) { - TShock.Log.ConsoleDebug(GetString("Bouncer / OnPlayerBuff rejected invalid buff type {0}", args.Player.Name)); - args.Player.SendData(PacketTypes.PlayerBuff, "", id); - args.Handled = true; + TShock.Log.ConsoleDebug(GetString( + "Bouncer / OnPlayerBuff rejected {0} ({1}) applying buff {2} to {3} for {4} ticks: invalid buff type", args.Player.Name, + args.Player.Index, type, id, time)); + Reject(false); return; } if (args.Player.IsBeingDisabled()) { - TShock.Log.ConsoleDebug(GetString("Bouncer / OnPlayerBuff rejected disabled from {0}", args.Player.Name)); - args.Player.SendData(PacketTypes.PlayerBuff, "", id); - args.Handled = true; + TShock.Log.ConsoleDebug(GetString( + "Bouncer / OnPlayerBuff rejected {0} ({1}) applying buff {2} to {3} for {4} ticks: sender is being disabled", + args.Player.Name, args.Player.Index, type, id, time)); + Reject(); return; } if (args.Player.IsBouncerThrottled()) { - TShock.Log.ConsoleDebug(GetString("Bouncer / OnPlayerBuff rejected throttled from {0}", args.Player.Name)); - args.Player.SendData(PacketTypes.PlayerBuff, "", id); - args.Handled = true; + TShock.Log.ConsoleDebug(GetString( + "Bouncer / OnPlayerBuff rejected {0} ({1}) applying buff {2} to {3} for {4} ticks: sender is being throttled", + args.Player.Name, args.Player.Index, type, id, time)); + Reject(); + return; } @@ -1910,41 +1938,46 @@ namespace TShockAPI if (!args.Player.IsInRange(targetPlayer.TileX, targetPlayer.TileY, 50)) { - TShock.Log.ConsoleDebug(GetString("Bouncer / OnPlayerBuff rejected range check from {0}", args.Player.Name)); - args.Player.SendData(PacketTypes.PlayerBuff, "", id); - args.Handled = true; + TShock.Log.ConsoleDebug(GetString( + "Bouncer / OnPlayerBuff rejected {0} ({1}) applying buff {2} to {3} for {4} ticks: sender is not in range of target", + args.Player.Name, args.Player.Index, type, id, time)); + Reject(); return; } if (buffLimit == null) { - TShock.Log.ConsoleDebug(GetString("Bouncer / OnPlayerBuff rejected non-whitelisted buff {0}", args.Player.Name)); - args.Player.SendData(PacketTypes.PlayerBuff, "", id); - args.Handled = true; + TShock.Log.ConsoleDebug(GetString( + "Bouncer / OnPlayerBuff rejected {0} ({1}) applying buff {2} to {3} for {4} ticks: buff is not whitelisted", + args.Player.Name, args.Player.Index, type, id, time)); + Reject(); return; } if (buffLimit.CanOnlyBeAppliedToSender && id != args.Player.Index) { - TShock.Log.ConsoleDebug(GetString("Bouncer / OnPlayerBuff rejected applied to non-sender from {0}", args.Player.Name)); - args.Player.SendData(PacketTypes.PlayerBuff, "", id); - args.Handled = true; + TShock.Log.ConsoleDebug(GetString( + "Bouncer / OnPlayerBuff rejected {0} ({1}) applying buff {2} to {3} for {4} ticks: buff cannot be applied to non-senders", + args.Player.Name, args.Player.Index, type, id, time)); + Reject(); return; } if (!buffLimit.CanBeAddedWithoutHostile && !targetPlayer.TPlayer.hostile) { - TShock.Log.ConsoleDebug(GetString("Bouncer / OnPlayerBuff rejected hostile/pvp from {0}", args.Player.Name)); - args.Player.SendData(PacketTypes.PlayerBuff, "", id); - args.Handled = true; + TShock.Log.ConsoleDebug(GetString( + "Bouncer / OnPlayerBuff rejected {0} ({1}) applying buff {2} to {3} for {4} ticks: buff cannot be applied without pvp", + args.Player.Name, args.Player.Index, type, id, time)); + Reject(); return; } if (time <= 0 || time > buffLimit.MaxTicks) { - TShock.Log.ConsoleDebug(GetString("Bouncer / OnPlayerBuff rejected time too long from {0}", args.Player.Name)); - args.Player.SendData(PacketTypes.PlayerBuff, "", id); - args.Handled = true; + TShock.Log.ConsoleDebug(GetString( + "Bouncer / OnPlayerBuff rejected {0} ({1}) applying buff {2} to {3} for {4} ticks: buff cannot be applied for that long", + args.Player.Name, args.Player.Index, type, id, time)); + Reject(); return; } } diff --git a/docs/changelog.md b/docs/changelog.md index bef17eca..35e8c596 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -79,6 +79,9 @@ Use past tense when adding new entries; sign your name off when you add or chang ## Upcoming changes * 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) +* Improved rejection message and code duplication in `OnPlayerBuff` (@drunderscore) + * This will make it so Bouncer rejections regarding `PlayerAddBuff` will now always include the sender index, buff type, receiver index, and time in ticks, allowing much faster triage of buff whitelist issues. ## TShock 5.1.3 * Added support for Terraria 1.4.4.9 via OTAPI 3.1.20. (@SignatureBeef)