Merge pull request #1943 from Pryaxis/fishoutnpc-event

Fishoutnpc event
This commit is contained in:
Chris 2020-06-01 19:03:43 +09:30 committed by GitHub
commit a049c6488f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 116 additions and 0 deletions

View file

@ -35,6 +35,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin
* The default group that gets this permission is `Guest` for the time being.
* To add this command to your guest group, give them `tshock.synclocalarea`, with `/group addperm guest tshock.synclocalarea`.
* This command may be removed at any time in the future (and will likely be removed when send tile square handling is fixed).
* Add FishOutNPC event handler, which is called whenever a player fishes out an NPC using a fishing rod. Added antihack to Bouncer, to prevent unathorized and invalid mob spawning, by checking player action, NPC IDs and range. (@Patrikkk, @moisterrific)
* Fixed smart door automatic door desync and deletion issue. (@hakusaro)
## TShock 4.4.0 (Pre-release 8)

View file

@ -71,6 +71,7 @@ namespace TShockAPI
GetDataHandlers.MassWireOperation += OnMassWireOperation;
GetDataHandlers.PlayerDamage += OnPlayerDamage;
GetDataHandlers.KillMe += OnKillMe;
GetDataHandlers.FishOutNPC += OnFishOutNPC;
GetDataHandlers.FoodPlatterTryPlacing += OnFoodPlatterTryPlacing;
}
@ -1882,6 +1883,34 @@ namespace TShockAPI
}
}
/// <summary>
/// Called when the player fishes out an NPC.
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
internal void OnFishOutNPC(object sender, GetDataHandlers.FishOutNPCEventArgs args)
{
var projectile = args.Player.RecentlyCreatedProjectiles.FirstOrDefault(p => Main.projectile[p.Index] != null && Main.projectile[p.Index].Name == "Bobber");
if (!FishingRodItemIDs.Contains(args.Player.SelectedItem.type) || Main.projectile[projectile.Index] == null || !FishableNpcIDs.Contains(args.NpcID))
{
TShock.Log.ConsoleDebug("Bouncer / OnFishOutNPC rejected invalid NPC spawning from {0}", args.Player.Name);
args.Handled = true;
return;
}
if (args.NpcID == NPCID.DukeFishron && !args.Player.HasPermission(Permissions.summonboss))
{
TShock.Log.ConsoleDebug("Bouncer / OnFishOutNPC rejected summon boss permissions from {0}", args.Player.Name);
args.Handled = true;
return;
}
if (args.Player.IsInRange(args.TileX, args.TileY, 55))
{
TShock.Log.ConsoleDebug("Bouncer / OnFishOutNPC rejected range checks from {0}", args.Player.Name);
args.Handled = true;
}
}
/// <summary>
/// Called when a player is trying to place an item into a food plate.
/// </summary>

View file

@ -151,6 +151,7 @@ namespace TShockAPI
{ PacketTypes.CrystalInvasionStart, HandleOldOnesArmy },
{ PacketTypes.PlayerHurtV2, HandlePlayerDamageV2 },
{ PacketTypes.PlayerDeathV2, HandlePlayerKillMeV2 },
{ PacketTypes.FishOutNPC, HandleFishOutNPC },
{ PacketTypes.FoodPlatterTryPlacing, HandleFoodPlatterTryPlacing },
{ PacketTypes.SyncRevengeMarker, HandleSyncRevengeMarker }
};
@ -1865,6 +1866,45 @@ namespace TShockAPI
return args.Handled;
}
/// <summary>
/// For use in a FishOutNPC event.
/// </summary>
public class FishOutNPCEventArgs : GetDataHandledEventArgs
{
/// <summary>
/// The X world position of the spawning NPC.
/// </summary>
public ushort TileX { get; set; }
/// <summary>
/// The Y world position of the spawning NPC.
/// </summary>
public ushort TileY { get; set; }
/// <summary>
/// The NPC type that is being spawned.
/// </summary>
public short NpcID { get; set; }
}
/// <summary>
/// Called when a player fishes out an NPC.
/// </summary>
public static HandlerList<FishOutNPCEventArgs> FishOutNPC = new HandlerList<FishOutNPCEventArgs>();
private static bool OnFishOutNPC(TSPlayer player, MemoryStream data, ushort tileX, ushort tileY, short npcID)
{
if (FishOutNPC == null)
return false;
var args = new FishOutNPCEventArgs
{
Player = player,
Data = data,
TileX = tileX,
TileY = tileY,
NpcID = npcID
};
FishOutNPC.Invoke(null, args);
return args.Handled;
}
public class FoodPlatterTryPlacingEventArgs : GetDataHandledEventArgs
{
/// <summary>
@ -3629,6 +3669,19 @@ namespace TShockAPI
return false;
}
private static bool HandleFishOutNPC(GetDataHandlerArgs args)
{
ushort tileX = args.Data.ReadUInt16();
ushort tileY = args.Data.ReadUInt16();
short npcType = args.Data.ReadInt16();
if (OnFishOutNPC(args.Player, args.Data, tileX, tileY, npcType))
return true;
return false;
}
private static bool HandleFoodPlatterTryPlacing(GetDataHandlerArgs args)
{
short tileX = args.Data.ReadInt16();
@ -3717,6 +3770,39 @@ namespace TShockAPI
TileID.Womannequin,
};
/// <summary>
/// List of Fishing rod item IDs.
/// </summary>
internal static readonly List<int> FishingRodItemIDs = new List<int>()
{
ItemID.WoodFishingPole,
ItemID.ReinforcedFishingPole,
ItemID.FiberglassFishingPole,
ItemID.FisherofSouls,
ItemID.GoldenFishingRod,
ItemID.MechanicsRod,
ItemID.SittingDucksFishingRod,
ItemID.Fleshcatcher,
ItemID.HotlineFishingHook,
ItemID.BloodFishingRod,
ItemID.ScarabFishingRod
};
/// <summary>
/// List of NPC IDs that can be fished out by the player.
/// </summary>
internal static readonly List<int> FishableNpcIDs = new List<int>()
{
NPCID.EyeballFlyingFish,
NPCID.ZombieMerman,
NPCID.GoblinShark,
NPCID.BloodEelHead,
NPCID.BloodEelBody,
NPCID.BloodEelTail,
NPCID.BloodNautilus,
NPCID.DukeFishron
};
/// <summary>
/// These projectiles create tiles on death.
/// </summary>