diff --git a/paper-server/nms-patches/net/minecraft/server/level/PlayerChunkMap.patch b/paper-server/nms-patches/net/minecraft/server/level/PlayerChunkMap.patch index df4b686a13..7f21fd8f03 100644 --- a/paper-server/nms-patches/net/minecraft/server/level/PlayerChunkMap.patch +++ b/paper-server/nms-patches/net/minecraft/server/level/PlayerChunkMap.patch @@ -99,11 +99,11 @@ + boolean needsRemoval = false; + net.minecraft.server.dedicated.DedicatedServer server = worldserver.getCraftServer().getServer(); + if (!server.areNpcsEnabled() && entity instanceof net.minecraft.world.entity.npc.NPC) { -+ entity.discard(); ++ entity.discard(null); // CraftBukkit - add Bukkit remove cause + needsRemoval = true; + } + if (!server.isSpawningAnimals() && (entity instanceof net.minecraft.world.entity.animal.EntityAnimal || entity instanceof net.minecraft.world.entity.animal.EntityWaterAnimal)) { -+ entity.discard(); ++ entity.discard(null); // CraftBukkit - add Bukkit remove cause + needsRemoval = true; + } + return !needsRemoval; diff --git a/paper-server/nms-patches/net/minecraft/server/level/WorldServer.patch b/paper-server/nms-patches/net/minecraft/server/level/WorldServer.patch index 2def431f84..5d14ea6723 100644 --- a/paper-server/nms-patches/net/minecraft/server/level/WorldServer.patch +++ b/paper-server/nms-patches/net/minecraft/server/level/WorldServer.patch @@ -394,10 +394,14 @@ return true; } } -@@ -968,10 +1111,32 @@ - entityplayer.remove(entity_removalreason); +@@ -965,13 +1108,35 @@ } + public void removePlayerImmediately(EntityPlayer entityplayer, Entity.RemovalReason entity_removalreason) { +- entityplayer.remove(entity_removalreason); ++ entityplayer.remove(entity_removalreason, null); // CraftBukkit - add Bukkit remove cause ++ } ++ + // CraftBukkit start + public boolean strikeLightning(Entity entitylightning) { + return this.strikeLightning(entitylightning, LightningStrikeEvent.Cause.UNKNOWN); @@ -411,9 +415,9 @@ + } + + return this.addFreshEntity(entitylightning); -+ } + } + // CraftBukkit end -+ + @Override public void destroyBlockProgress(int i, BlockPosition blockposition, int j) { Iterator iterator = this.server.getPlayerList().getPlayers().iterator(); diff --git a/paper-server/nms-patches/net/minecraft/server/players/PlayerList.patch b/paper-server/nms-patches/net/minecraft/server/players/PlayerList.patch index 2dafb72373..498424c95f 100644 --- a/paper-server/nms-patches/net/minecraft/server/players/PlayerList.patch +++ b/paper-server/nms-patches/net/minecraft/server/players/PlayerList.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -101,6 +101,26 @@ +@@ -101,6 +101,27 @@ import net.minecraft.world.scores.ScoreboardTeam; import org.slf4j.Logger; @@ -15,6 +15,7 @@ +import org.bukkit.craftbukkit.util.CraftChatMessage; +import org.bukkit.craftbukkit.util.CraftLocation; +import org.bukkit.entity.Player; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.player.PlayerChangedWorldEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerLoginEvent; @@ -27,7 +28,7 @@ public abstract class PlayerList { public static final File USERBANLIST_FILE = new File("banned-players.json"); -@@ -113,14 +133,16 @@ +@@ -113,14 +134,16 @@ private static final int SEND_PLAYER_INFO_INTERVAL = 600; private static final SimpleDateFormat BAN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z"); private final MinecraftServer server; @@ -47,7 +48,7 @@ public final WorldNBTStorage playerIo; private boolean doWhiteList; private final LayeredRegistryAccess registries; -@@ -131,13 +153,23 @@ +@@ -131,13 +154,23 @@ private static final boolean ALLOW_LOGOUTIVATOR = false; private int sendAllPlayerInfoIn; @@ -73,7 +74,7 @@ this.server = minecraftserver; this.registries = layeredregistryaccess; this.maxPlayers = i; -@@ -160,15 +192,21 @@ +@@ -160,15 +193,21 @@ NBTTagCompound nbttagcompound = this.load(entityplayer); ResourceKey resourcekey; @@ -98,7 +99,7 @@ } ResourceKey resourcekey1 = resourcekey; -@@ -185,7 +223,8 @@ +@@ -185,7 +224,8 @@ entityplayer.setServerLevel(worldserver1); String s1 = networkmanager.getLoggableAddress(this.server.logIPs()); @@ -108,7 +109,7 @@ WorldData worlddata = worldserver1.getLevelData(); entityplayer.loadGameTypes(nbttagcompound); -@@ -196,6 +235,7 @@ +@@ -196,6 +236,7 @@ boolean flag2 = gamerules.getBoolean(GameRules.RULE_LIMITED_CRAFTING); playerconnection.send(new PacketPlayOutLogin(entityplayer.getId(), worlddata.isHardcore(), this.server.levelKeys(), this.getMaxPlayers(), this.viewDistance, this.simulationDistance, flag1, !flag, flag2, entityplayer.createCommonSpawnInfo(worldserver1))); @@ -116,7 +117,7 @@ playerconnection.send(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); playerconnection.send(new PacketPlayOutAbilities(entityplayer.getAbilities())); playerconnection.send(new PacketPlayOutHeldItemSlot(entityplayer.getInventory().selected)); -@@ -212,8 +252,10 @@ +@@ -212,8 +253,10 @@ } else { ichatmutablecomponent = IChatBaseComponent.translatable("multiplayer.player.joined.renamed", entityplayer.getDisplayName(), s); } @@ -128,7 +129,7 @@ playerconnection.teleport(entityplayer.getX(), entityplayer.getY(), entityplayer.getZ(), entityplayer.getYRot(), entityplayer.getXRot()); ServerPing serverping = this.server.getStatus(); -@@ -221,13 +263,64 @@ +@@ -221,13 +264,64 @@ entityplayer.sendServerStatus(serverping); } @@ -197,7 +198,7 @@ Iterator iterator = entityplayer.getActiveEffects().iterator(); while (iterator.hasNext()) { -@@ -238,8 +331,11 @@ +@@ -238,8 +332,11 @@ if (nbttagcompound != null && nbttagcompound.contains("RootVehicle", 10)) { NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("RootVehicle"); @@ -211,7 +212,21 @@ }); if (entity != null) { -@@ -282,6 +378,8 @@ +@@ -270,18 +367,20 @@ + + if (!entityplayer.isPassenger()) { + PlayerList.LOGGER.warn("Couldn't reattach entity to player"); +- entity.discard(); ++ entity.discard(null); // CraftBukkit - add Bukkit remove cause + iterator1 = entity.getIndirectPassengers().iterator(); + + while (iterator1.hasNext()) { + entity1 = (Entity) iterator1.next(); +- entity1.discard(); ++ entity1.discard(null); // CraftBukkit - add Bukkit remove cause + } + } + } } entityplayer.initInventoryMenu(); @@ -220,7 +235,7 @@ } public void updateEntireScoreboard(ScoreboardServer scoreboardserver, EntityPlayer entityplayer) { -@@ -318,30 +416,31 @@ +@@ -318,30 +417,31 @@ } public void addWorldborderListener(WorldServer worldserver) { @@ -257,7 +272,7 @@ } @Override -@@ -369,14 +468,15 @@ +@@ -369,14 +469,15 @@ } protected void save(EntityPlayer entityplayer) { @@ -275,7 +290,7 @@ if (advancementdataplayer != null) { advancementdataplayer.save(); -@@ -384,10 +484,24 @@ +@@ -384,10 +485,24 @@ } @@ -301,7 +316,16 @@ this.save(entityplayer); if (entityplayer.isPassenger()) { Entity entity = entityplayer.getRootVehicle(); -@@ -411,18 +525,66 @@ +@@ -396,7 +511,7 @@ + PlayerList.LOGGER.debug("Removing player mount"); + entityplayer.stopRiding(); + entity.getPassengersAndSelf().forEach((entity1) -> { +- entity1.setRemoved(Entity.RemovalReason.UNLOADED_WITH_PLAYER); ++ entity1.setRemoved(Entity.RemovalReason.UNLOADED_WITH_PLAYER, EntityRemoveEvent.Cause.PLAYER_QUIT); // CraftBukkit - add Bukkit remove cause + }); + } + } +@@ -411,18 +526,66 @@ if (entityplayer1 == entityplayer) { this.playersByUUID.remove(uuid); @@ -374,7 +398,7 @@ GameProfileBanEntry gameprofilebanentry = (GameProfileBanEntry) this.bans.get(gameprofile); ichatmutablecomponent = IChatBaseComponent.translatable("multiplayer.disconnect.banned.reason", gameprofilebanentry.getReason()); -@@ -430,10 +592,12 @@ +@@ -430,10 +593,12 @@ ichatmutablecomponent.append((IChatBaseComponent) IChatBaseComponent.translatable("multiplayer.disconnect.banned.expiration", PlayerList.BAN_DATE_FORMAT.format(gameprofilebanentry.getExpires()))); } @@ -390,7 +414,7 @@ IpBanEntry ipbanentry = this.ipBans.get(socketaddress); ichatmutablecomponent = IChatBaseComponent.translatable("multiplayer.disconnect.banned_ip.reason", ipbanentry.getReason()); -@@ -441,17 +605,32 @@ +@@ -441,17 +606,32 @@ ichatmutablecomponent.append((IChatBaseComponent) IChatBaseComponent.translatable("multiplayer.disconnect.banned_ip.expiration", PlayerList.BAN_DATE_FORMAT.format(ipbanentry.getExpires()))); } @@ -403,13 +427,13 @@ + if (this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile)) { + event.disallow(PlayerLoginEvent.Result.KICK_FULL, "The server is full"); + } - } ++ } + + cserver.getPluginManager().callEvent(event); + if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) { + loginlistener.disconnect(event.getKickMessage()); + return null; -+ } + } + return entity; } @@ -428,7 +452,7 @@ UUID uuid = gameprofile.getId(); Set set = Sets.newIdentityHashSet(); Iterator iterator = this.players.iterator(); -@@ -479,14 +658,24 @@ +@@ -479,14 +659,24 @@ } return !set.isEmpty(); @@ -454,7 +478,7 @@ WorldServer worldserver = this.server.getLevel(entityplayer.getRespawnDimension()); Optional optional; -@@ -498,6 +687,11 @@ +@@ -498,6 +688,11 @@ WorldServer worldserver1 = worldserver != null && optional.isPresent() ? worldserver : this.server.overworld(); EntityPlayer entityplayer1 = new EntityPlayer(this.server, worldserver1, entityplayer.getGameProfile(), entityplayer.clientInformation()); @@ -466,7 +490,7 @@ entityplayer1.connection = entityplayer.connection; entityplayer1.restoreFrom(entityplayer, flag); -@@ -513,28 +707,66 @@ +@@ -513,28 +708,66 @@ boolean flag2 = false; @@ -549,7 +573,7 @@ entityplayer1.setPos(entityplayer1.getX(), entityplayer1.getY() + 1.0D, entityplayer1.getZ()); } -@@ -543,21 +775,43 @@ +@@ -543,21 +776,43 @@ WorldData worlddata = worldserver2.getLevelData(); entityplayer1.connection.send(new PacketPlayOutRespawn(entityplayer1.createCommonSpawnInfo(worldserver2), (byte) i)); @@ -598,7 +622,7 @@ return entityplayer1; } -@@ -570,7 +824,18 @@ +@@ -570,7 +825,18 @@ public void tick() { if (++this.sendAllPlayerInfoIn > 600) { @@ -618,7 +642,7 @@ this.sendAllPlayerInfoIn = 0; } -@@ -587,6 +852,25 @@ +@@ -587,6 +853,25 @@ } @@ -644,7 +668,7 @@ public void broadcastAll(Packet packet, ResourceKey resourcekey) { Iterator iterator = this.players.iterator(); -@@ -665,7 +949,7 @@ +@@ -665,7 +950,7 @@ } public void deop(GameProfile gameprofile) { @@ -653,7 +677,7 @@ EntityPlayer entityplayer = this.getPlayer(gameprofile.getId()); if (entityplayer != null) { -@@ -689,6 +973,7 @@ +@@ -689,6 +974,7 @@ entityplayer.connection.send(new PacketPlayOutEntityStatus(entityplayer, b0)); } @@ -661,7 +685,7 @@ this.server.getCommands().sendCommands(entityplayer); } -@@ -719,6 +1004,12 @@ +@@ -719,6 +1005,12 @@ for (int i = 0; i < this.players.size(); ++i) { EntityPlayer entityplayer = (EntityPlayer) this.players.get(i); @@ -674,7 +698,7 @@ if (entityplayer != entityhuman && entityplayer.level().dimension() == resourcekey) { double d4 = d0 - entityplayer.getX(); double d5 = d1 - entityplayer.getY(); -@@ -758,15 +1049,19 @@ +@@ -758,15 +1050,19 @@ public void reloadWhiteList() {} public void sendLevelInfo(EntityPlayer entityplayer, WorldServer worldserver) { @@ -698,7 +722,7 @@ } entityplayer.connection.send(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.LEVEL_CHUNKS_LOAD_START, 0.0F)); -@@ -775,8 +1070,16 @@ +@@ -775,8 +1071,16 @@ public void sendAllPlayerInfo(EntityPlayer entityplayer) { entityplayer.inventoryMenu.sendAllDataToRemote(); @@ -716,7 +740,7 @@ } public int getPlayerCount() { -@@ -832,12 +1135,22 @@ +@@ -832,12 +1136,22 @@ } public void removeAll() { @@ -741,7 +765,7 @@ public void broadcastSystemMessage(IChatBaseComponent ichatbasecomponent, boolean flag) { this.broadcastSystemMessage(ichatbasecomponent, (entityplayer) -> { return ichatbasecomponent; -@@ -895,16 +1208,23 @@ +@@ -895,16 +1209,23 @@ return playerchatmessage.hasSignature() && !playerchatmessage.hasExpiredServer(Instant.now()); } @@ -769,7 +793,7 @@ Path path = file2.toPath(); if (FileUtils.isPathNormalized(path) && FileUtils.isPathPortable(path) && path.startsWith(file.getPath()) && file2.isFile()) { -@@ -913,7 +1233,7 @@ +@@ -913,7 +1234,7 @@ } serverstatisticmanager = new ServerStatisticManager(this.server, file1); @@ -778,7 +802,7 @@ } return serverstatisticmanager; -@@ -921,13 +1241,13 @@ +@@ -921,13 +1242,13 @@ public AdvancementDataPlayer getPlayerAdvancements(EntityPlayer entityplayer) { UUID uuid = entityplayer.getUUID(); @@ -794,7 +818,7 @@ } advancementdataplayer.setPlayer(entityplayer); -@@ -978,13 +1298,20 @@ +@@ -978,13 +1299,20 @@ } public void reloadResources() { diff --git a/paper-server/nms-patches/net/minecraft/util/SpawnUtil.patch b/paper-server/nms-patches/net/minecraft/util/SpawnUtil.patch index 150612747c..e76f3ef697 100644 --- a/paper-server/nms-patches/net/minecraft/util/SpawnUtil.patch +++ b/paper-server/nms-patches/net/minecraft/util/SpawnUtil.patch @@ -13,7 +13,7 @@ BlockPosition.MutableBlockPosition blockposition_mutableblockposition = blockposition.mutable(); for (int l = 0; l < i; ++l) { -@@ -29,11 +35,11 @@ +@@ -29,15 +35,15 @@ blockposition_mutableblockposition.setWithOffset(blockposition, i1, k, j1); if (worldserver.getWorldBorder().isWithinBounds((BlockPosition) blockposition_mutableblockposition) && moveToPossibleSpawnPosition(worldserver, k, blockposition_mutableblockposition, spawnutil_a)) { @@ -27,3 +27,8 @@ return Optional.of(t0); } +- t0.discard(); ++ t0.discard(null); // CraftBukkit - add Bukkit remove cause + } + } + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/Entity.patch b/paper-server/nms-patches/net/minecraft/world/entity/Entity.patch index 5e6edd69f1..52f6534e9e 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/Entity.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/Entity.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -126,8 +126,67 @@ +@@ -126,8 +126,68 @@ import org.joml.Vector3f; import org.slf4j.Logger; @@ -33,6 +33,7 @@ +import org.bukkit.event.entity.EntityMountEvent; +import org.bukkit.event.entity.EntityPortalEvent; +import org.bukkit.event.entity.EntityPoseChangeEvent; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.plugin.PluginManager; +// CraftBukkit end @@ -68,7 +69,7 @@ private static final Logger LOGGER = LogUtils.getLogger(); public static final String ID_TAG = "id"; public static final String PASSENGERS_TAG = "Passengers"; -@@ -242,6 +301,29 @@ +@@ -242,6 +302,29 @@ public boolean hasVisualFire; @Nullable private IBlockData feetBlockState; @@ -98,7 +99,41 @@ public Entity(EntityTypes entitytypes, World world) { this.id = Entity.ENTITY_COUNTER.incrementAndGet(); -@@ -375,6 +457,12 @@ +@@ -346,12 +429,18 @@ + } + + public void kill() { +- this.remove(Entity.RemovalReason.KILLED); ++ this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause + this.gameEvent(GameEvent.ENTITY_DIE); + } + + public final void discard() { +- this.remove(Entity.RemovalReason.DISCARDED); ++ // CraftBukkit start - add Bukkit remove cause ++ this.discard(null); ++ } ++ ++ public final void discard(EntityRemoveEvent.Cause cause) { ++ this.remove(Entity.RemovalReason.DISCARDED, cause); ++ // CraftBukkit end + } + + protected abstract void defineSynchedData(); +@@ -369,12 +458,24 @@ + } + + public void remove(Entity.RemovalReason entity_removalreason) { +- this.setRemoved(entity_removalreason); ++ // CraftBukkit start - add Bukkit remove cause ++ this.setRemoved(entity_removalreason, null); ++ } ++ ++ public void remove(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { ++ this.setRemoved(entity_removalreason, cause); ++ // CraftBukkit end + } + public void onClientRemoval() {} public void setPose(EntityPose entitypose) { @@ -111,7 +146,7 @@ this.entityData.set(Entity.DATA_POSE, entitypose); } -@@ -399,6 +487,33 @@ +@@ -399,6 +500,33 @@ } protected void setRot(float f, float f1) { @@ -145,7 +180,7 @@ this.setYRot(f % 360.0F); this.setXRot(f1 % 360.0F); } -@@ -440,6 +555,15 @@ +@@ -440,6 +568,15 @@ this.baseTick(); } @@ -161,7 +196,7 @@ public void baseTick() { this.level().getProfiler().push("entityBaseTick"); this.feetBlockState = null; -@@ -454,7 +578,7 @@ +@@ -454,7 +591,7 @@ this.walkDistO = this.walkDist; this.xRotO = this.getXRot(); this.yRotO = this.getYRot(); @@ -170,7 +205,7 @@ if (this.canSpawnSprintParticle()) { this.spawnSprintParticle(); } -@@ -489,6 +613,10 @@ +@@ -489,6 +626,10 @@ if (this.isInLava()) { this.lavaHurt(); this.fallDistance *= 0.5F; @@ -181,7 +216,7 @@ } this.checkBelowWorld(); -@@ -540,15 +668,47 @@ +@@ -540,15 +681,47 @@ public void lavaHurt() { if (!this.fireImmune()) { @@ -231,7 +266,16 @@ int j = i * 20; if (this instanceof EntityLiving) { -@@ -699,6 +859,28 @@ +@@ -574,7 +747,7 @@ + } + + protected void onBelowWorld() { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.OUT_OF_WORLD); // CraftBukkit - add Bukkit remove cause + } + + public boolean isFree(double d0, double d1, double d2) { +@@ -699,6 +872,28 @@ block.updateEntityAfterFallOn(this.level(), this); } @@ -260,7 +304,7 @@ if (this.onGround()) { block.stepOn(this.level(), blockposition, iblockdata, this); } -@@ -1026,6 +1208,20 @@ +@@ -1026,6 +1221,20 @@ return SoundEffects.GENERIC_SPLASH; } @@ -281,7 +325,7 @@ protected void checkInsideBlocks() { AxisAlignedBB axisalignedbb = this.getBoundingBox(); BlockPosition blockposition = BlockPosition.containing(axisalignedbb.minX + 1.0E-7D, axisalignedbb.minY + 1.0E-7D, axisalignedbb.minZ + 1.0E-7D); -@@ -1440,6 +1636,7 @@ +@@ -1440,6 +1649,7 @@ this.yo = d1; this.zo = d4; this.setPos(d3, d1, d4); @@ -289,7 +333,7 @@ } public void moveTo(Vec3D vec3d) { -@@ -1634,6 +1831,12 @@ +@@ -1634,6 +1844,12 @@ return false; } @@ -302,7 +346,7 @@ public void awardKillScore(Entity entity, int i, DamageSource damagesource) { if (entity instanceof EntityPlayer) { CriterionTriggers.ENTITY_KILLED_PLAYER.trigger((EntityPlayer) entity, this, damagesource); -@@ -1662,16 +1865,22 @@ +@@ -1662,16 +1878,22 @@ } public boolean saveAsPassenger(NBTTagCompound nbttagcompound) { @@ -327,7 +371,7 @@ return true; } } -@@ -1682,16 +1891,38 @@ +@@ -1682,16 +1904,38 @@ } public NBTTagCompound saveWithoutId(NBTTagCompound nbttagcompound) { @@ -370,7 +414,7 @@ nbttagcompound.put("Rotation", this.newFloatList(this.getYRot(), this.getXRot())); nbttagcompound.putFloat("FallDistance", this.fallDistance); nbttagcompound.putShort("Fire", (short) this.remainingFireTicks); -@@ -1699,7 +1930,28 @@ +@@ -1699,7 +1943,28 @@ nbttagcompound.putBoolean("OnGround", this.onGround()); nbttagcompound.putBoolean("Invulnerable", this.invulnerable); nbttagcompound.putInt("PortalCooldown", this.portalCooldown); @@ -400,7 +444,7 @@ IChatBaseComponent ichatbasecomponent = this.getCustomName(); if (ichatbasecomponent != null) { -@@ -1748,7 +2000,7 @@ +@@ -1748,7 +2013,7 @@ nbttagcompound.put("Tags", nbttaglist); } @@ -409,7 +453,7 @@ if (this.isVehicle()) { nbttaglist = new NBTTagList(); iterator = this.getPassengers().iterator(); -@@ -1757,7 +2009,7 @@ +@@ -1757,7 +2022,7 @@ Entity entity = (Entity) iterator.next(); NBTTagCompound nbttagcompound1 = new NBTTagCompound(); @@ -418,7 +462,7 @@ nbttaglist.add(nbttagcompound1); } } -@@ -1767,6 +2019,11 @@ +@@ -1767,6 +2032,11 @@ } } @@ -430,7 +474,7 @@ return nbttagcompound; } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT"); -@@ -1850,6 +2107,45 @@ +@@ -1850,6 +2120,45 @@ } else { throw new IllegalStateException("Entity has invalid position"); } @@ -476,7 +520,7 @@ } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT"); CrashReportSystemDetails crashreportsystemdetails = crashreport.addCategory("Entity being loaded"); -@@ -1871,6 +2167,12 @@ +@@ -1871,6 +2180,12 @@ return entitytypes.canSerialize() && minecraftkey != null ? minecraftkey.toString() : null; } @@ -489,7 +533,7 @@ protected abstract void readAdditionalSaveData(NBTTagCompound nbttagcompound); protected abstract void addAdditionalSaveData(NBTTagCompound nbttagcompound); -@@ -1925,9 +2227,22 @@ +@@ -1925,9 +2240,22 @@ } else if (this.level().isClientSide) { return null; } else { @@ -512,7 +556,7 @@ this.level().addFreshEntity(entityitem); return entityitem; } -@@ -2025,6 +2340,27 @@ +@@ -2025,6 +2353,27 @@ if (!flag && (!this.canRide(entity) || !entity.canAddPassenger(this))) { return false; } else { @@ -540,7 +584,7 @@ if (this.isPassenger()) { this.stopRiding(); } -@@ -2058,7 +2394,7 @@ +@@ -2058,7 +2407,7 @@ Entity entity = this.vehicle; this.vehicle = null; @@ -549,7 +593,7 @@ } } -@@ -2089,10 +2425,38 @@ +@@ -2089,10 +2438,38 @@ } } @@ -589,7 +633,7 @@ if (this.passengers.size() == 1 && this.passengers.get(0) == entity) { this.passengers = ImmutableList.of(); } else { -@@ -2104,6 +2468,7 @@ +@@ -2104,6 +2481,7 @@ entity.boardingCooldown = 60; this.gameEvent(GameEvent.ENTITY_DISMOUNT, entity); } @@ -597,7 +641,7 @@ } protected boolean canAddPassenger(Entity entity) { -@@ -2190,14 +2555,20 @@ +@@ -2190,14 +2568,20 @@ if (this.isInsidePortal) { MinecraftServer minecraftserver = worldserver.getServer(); @@ -621,7 +665,7 @@ this.level().getProfiler().pop(); } -@@ -2321,6 +2692,13 @@ +@@ -2321,6 +2705,13 @@ } public void setSwimming(boolean flag) { @@ -635,7 +679,7 @@ this.setSharedFlag(4, flag); } -@@ -2370,8 +2748,12 @@ +@@ -2370,8 +2761,12 @@ return this.getTeam() != null ? this.getTeam().isAlliedTo(scoreboardteambase) : false; } @@ -649,7 +693,7 @@ } public boolean getSharedFlag(int i) { -@@ -2390,7 +2772,7 @@ +@@ -2390,7 +2785,7 @@ } public int getMaxAirSupply() { @@ -658,7 +702,7 @@ } public int getAirSupply() { -@@ -2398,7 +2780,18 @@ +@@ -2398,7 +2793,18 @@ } public void setAirSupply(int i) { @@ -678,7 +722,7 @@ } public int getTicksFrozen() { -@@ -2425,11 +2818,40 @@ +@@ -2425,11 +2831,40 @@ public void thunderHit(WorldServer worldserver, EntityLightning entitylightning) { this.setRemainingFireTicks(this.remainingFireTicks + 1); @@ -721,7 +765,7 @@ } public void onAboveBubbleCol(boolean flag) { -@@ -2594,15 +3016,38 @@ +@@ -2594,15 +3029,38 @@ @Nullable public Entity changeDimension(WorldServer worldserver) { @@ -762,7 +806,7 @@ this.level().getProfiler().popPush("reloading"); Entity entity = this.getType().create(worldserver); -@@ -2610,10 +3055,22 @@ +@@ -2610,10 +3068,22 @@ entity.restoreFrom(this); entity.moveTo(shapedetectorshape.pos.x, shapedetectorshape.pos.y, shapedetectorshape.pos.z, shapedetectorshape.yRot, entity.getXRot()); entity.setDeltaMovement(shapedetectorshape.speed); @@ -788,7 +832,13 @@ } this.removeAfterChangingDimensions(); -@@ -2634,20 +3091,34 @@ +@@ -2629,25 +3099,39 @@ + } + + protected void removeAfterChangingDimensions() { +- this.setRemoved(Entity.RemovalReason.CHANGED_DIMENSION); ++ this.setRemoved(Entity.RemovalReason.CHANGED_DIMENSION, null); // CraftBukkit - add Bukkit remove cause + } @Nullable protected ShapeDetectorShape findDimensionEntryPoint(WorldServer worldserver) { @@ -828,7 +878,7 @@ IBlockData iblockdata = this.level().getBlockState(this.portalEntrancePos); EnumDirection.EnumAxis enumdirection_enumaxis; Vec3D vec3d; -@@ -2664,8 +3135,8 @@ +@@ -2664,8 +3148,8 @@ vec3d = new Vec3D(0.5D, 0.0D, 0.0D); } @@ -839,7 +889,7 @@ } } else { BlockPosition blockposition1; -@@ -2675,8 +3146,14 @@ +@@ -2675,8 +3159,14 @@ } else { blockposition1 = worldserver.getHeightmapPos(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, worldserver.getSharedSpawnPos()); } @@ -855,7 +905,7 @@ } } -@@ -2684,8 +3161,23 @@ +@@ -2684,8 +3174,23 @@ return BlockPortalShape.getRelativePosition(blockutil_rectangle, enumdirection_enumaxis, this.position(), this.getDimensions(this.getPose())); } @@ -881,7 +931,7 @@ } public boolean canChangeDimensions() { -@@ -2806,6 +3298,12 @@ +@@ -2806,6 +3311,12 @@ } } @@ -894,11 +944,13 @@ public boolean teleportTo(WorldServer worldserver, double d0, double d1, double d2, Set set, float f, float f1) { float f2 = MathHelper.clamp(f1, -90.0F, 90.0F); -@@ -2825,7 +3323,11 @@ +@@ -2824,8 +3335,12 @@ + entity.restoreFrom(this); entity.moveTo(d0, d1, d2, f, f2); entity.setYHeadRot(f); - this.setRemoved(Entity.RemovalReason.CHANGED_DIMENSION); +- this.setRemoved(Entity.RemovalReason.CHANGED_DIMENSION); - worldserver.addDuringTeleport(entity); ++ this.setRemoved(Entity.RemovalReason.CHANGED_DIMENSION, null); // CraftBukkit - add Bukkit remove cause + // CraftBukkit start - Don't spawn the new entity if the current entity isn't spawned + if (inWorld) { + worldserver.addDuringTeleport(entity); @@ -907,7 +959,7 @@ } return true; -@@ -2931,7 +3433,26 @@ +@@ -2931,7 +3446,26 @@ } public final void setBoundingBox(AxisAlignedBB axisalignedbb) { @@ -935,7 +987,7 @@ } protected float getEyeHeight(EntityPose entitypose, EntitySize entitysize) { -@@ -3246,6 +3767,11 @@ +@@ -3246,6 +3780,11 @@ vec3d = vec3d.add(vec3d1); ++k1; } @@ -947,3 +999,18 @@ } } } +@@ -3517,6 +4056,14 @@ + + @Override + public final void setRemoved(Entity.RemovalReason entity_removalreason) { ++ // CraftBukkit start - add Bukkit remove cause ++ setRemoved(entity_removalreason, null); ++ } ++ ++ @Override ++ public final void setRemoved(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { ++ CraftEventFactory.callEntityRemoveEvent(this, cause); ++ // CraftBukkit end + if (this.removalReason == null) { + this.removalReason = entity_removalreason; + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/EntityAreaEffectCloud.patch b/paper-server/nms-patches/net/minecraft/world/entity/EntityAreaEffectCloud.patch index 90305ddb11..f10363dae0 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/EntityAreaEffectCloud.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/EntityAreaEffectCloud.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/EntityAreaEffectCloud.java +++ b/net/minecraft/world/entity/EntityAreaEffectCloud.java -@@ -31,6 +31,12 @@ +@@ -31,6 +31,13 @@ import net.minecraft.world.level.material.EnumPistonReaction; import org.slf4j.Logger; @@ -8,12 +8,31 @@ +import net.minecraft.resources.MinecraftKey; +import org.bukkit.craftbukkit.entity.CraftLivingEntity; +import org.bukkit.entity.LivingEntity; ++import org.bukkit.event.entity.EntityRemoveEvent; +// CraftBukkit end + public class EntityAreaEffectCloud extends Entity implements TraceableEntity { private static final Logger LOGGER = LogUtils.getLogger(); -@@ -264,6 +270,7 @@ +@@ -216,7 +223,7 @@ + } + } else { + if (this.tickCount >= this.waitTime + this.duration) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + return; + } + +@@ -233,7 +240,7 @@ + if (this.radiusPerTick != 0.0F) { + f += this.radiusPerTick; + if (f < 0.5F) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + return; + } + +@@ -264,6 +271,7 @@ if (!list1.isEmpty()) { Iterator iterator1 = list1.iterator(); @@ -21,7 +40,7 @@ while (iterator1.hasNext()) { EntityLiving entityliving = (EntityLiving) iterator1.next(); -@@ -273,6 +280,17 @@ +@@ -273,6 +281,17 @@ double d8 = d6 * d6 + d7 * d7; if (d8 <= (double) (f * f)) { @@ -39,7 +58,7 @@ this.victims.put(entityliving, this.tickCount + this.reapplicationDelay); Iterator iterator2 = list.iterator(); -@@ -282,7 +300,7 @@ +@@ -282,14 +301,14 @@ if (mobeffect1.getEffect().isInstantenous()) { mobeffect1.getEffect().applyInstantenousEffect(this, this.getOwner(), entityliving, mobeffect1.getAmplifier(), 0.5D); } else { @@ -48,3 +67,20 @@ } } + if (this.radiusOnUse != 0.0F) { + f += this.radiusOnUse; + if (f < 0.5F) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + return; + } + +@@ -299,7 +318,7 @@ + if (this.durationOnUse != 0) { + this.duration += this.durationOnUse; + if (this.duration <= 0) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + return; + } + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/EntityExperienceOrb.patch b/paper-server/nms-patches/net/minecraft/world/entity/EntityExperienceOrb.patch index 54d5acc771..8d0823f904 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/EntityExperienceOrb.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/EntityExperienceOrb.patch @@ -1,11 +1,12 @@ --- a/net/minecraft/world/entity/EntityExperienceOrb.java +++ b/net/minecraft/world/entity/EntityExperienceOrb.java -@@ -21,6 +21,13 @@ +@@ -21,6 +21,14 @@ import net.minecraft.world.phys.AxisAlignedBB; import net.minecraft.world.phys.Vec3D; +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.player.PlayerExpCooldownChangeEvent; @@ -14,7 +15,7 @@ public class EntityExperienceOrb extends Entity { private static final int LIFETIME = 6000; -@@ -59,6 +66,7 @@ +@@ -59,6 +67,7 @@ @Override public void tick() { super.tick(); @@ -22,7 +23,7 @@ this.xo = this.getX(); this.yo = this.getY(); this.zo = this.getZ(); -@@ -84,7 +92,22 @@ +@@ -84,7 +93,22 @@ this.followingPlayer = null; } @@ -46,7 +47,34 @@ Vec3D vec3d = new Vec3D(this.followingPlayer.getX() - this.getX(), this.followingPlayer.getY() + (double) this.followingPlayer.getEyeHeight() / 2.0D - this.getY(), this.followingPlayer.getZ() - this.getZ()); double d0 = vec3d.lengthSqr(); -@@ -227,12 +250,12 @@ +@@ -109,7 +133,7 @@ + + ++this.age; + if (this.age >= 6000) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } + + } +@@ -178,7 +202,7 @@ + private void merge(EntityExperienceOrb entityexperienceorb) { + this.count += entityexperienceorb.count; + this.age = Math.min(this.age, entityexperienceorb.age); +- entityexperienceorb.discard(); ++ entityexperienceorb.discard(EntityRemoveEvent.Cause.MERGE); // CraftBukkit - add Bukkit remove cause + } + + private void setUnderwaterMovement() { +@@ -200,7 +224,7 @@ + this.markHurt(); + this.health = (int) ((float) this.health - f); + if (this.health <= 0) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause + } + + return true; +@@ -227,17 +251,17 @@ public void playerTouch(EntityHuman entityhuman) { if (!this.level().isClientSide) { if (entityhuman.takeXpDelay == 0) { @@ -61,7 +89,13 @@ } --this.count; -@@ -250,9 +273,17 @@ + if (this.count == 0) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + } + } + +@@ -250,9 +274,17 @@ if (entry != null) { ItemStack itemstack = (ItemStack) entry.getValue(); int j = Math.min(this.xpToDurability(i), itemstack.getDamageValue()); @@ -79,7 +113,7 @@ return k > 0 ? this.repairPlayerItems(entityhuman, k) : 0; } else { -@@ -277,6 +308,24 @@ +@@ -277,6 +309,24 @@ } public static int getExperienceValue(int i) { diff --git a/paper-server/nms-patches/net/minecraft/world/entity/EntityInsentient.patch b/paper-server/nms-patches/net/minecraft/world/entity/EntityInsentient.patch index 7f93eabcd2..6c044ca683 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/EntityInsentient.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/EntityInsentient.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/EntityInsentient.java +++ b/net/minecraft/world/entity/EntityInsentient.java -@@ -76,6 +76,19 @@ +@@ -76,6 +76,20 @@ import net.minecraft.world.level.pathfinder.PathType; import net.minecraft.world.phys.AxisAlignedBB; @@ -10,6 +10,7 @@ +import org.bukkit.craftbukkit.entity.CraftLivingEntity; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.EntityCombustByEntityEvent; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.entity.EntityTransformEvent; @@ -20,7 +21,7 @@ public abstract class EntityInsentient extends EntityLiving implements Targeting { private static final DataWatcherObject DATA_MOB_FLAGS_ID = DataWatcher.defineId(EntityInsentient.class, DataWatcherRegistry.BYTE); -@@ -123,6 +136,8 @@ +@@ -123,6 +137,8 @@ private BlockPosition restrictCenter; private float restrictRadius; @@ -29,7 +30,7 @@ protected EntityInsentient(EntityTypes entitytypes, World world) { super(entitytypes, world); this.handItems = NonNullList.withSize(2, ItemStack.EMPTY); -@@ -148,6 +163,12 @@ +@@ -148,6 +164,12 @@ } @@ -42,7 +43,7 @@ protected void registerGoals() {} public static AttributeProvider.Builder createMobAttributes() { -@@ -259,7 +280,38 @@ +@@ -259,7 +281,38 @@ } public void setTarget(@Nullable EntityLiving entityliving) { @@ -81,7 +82,7 @@ } @Override -@@ -399,6 +451,12 @@ +@@ -399,6 +452,12 @@ return null; } @@ -94,7 +95,7 @@ @Override public void addAdditionalSaveData(NBTTagCompound nbttagcompound) { super.addAdditionalSaveData(nbttagcompound); -@@ -457,7 +515,7 @@ +@@ -457,7 +516,7 @@ } nbttagcompound.put("HandDropChances", nbttaglist3); @@ -103,7 +104,7 @@ nbttagcompound2 = new NBTTagCompound(); if (this.leashHolder instanceof EntityLiving) { UUID uuid = this.leashHolder.getUUID(); -@@ -488,16 +546,26 @@ +@@ -488,16 +547,26 @@ nbttagcompound.putBoolean("NoAI", this.isNoAi()); } @@ -132,7 +133,7 @@ NBTTagList nbttaglist; int i; -@@ -544,6 +612,11 @@ +@@ -544,6 +613,11 @@ } this.setNoAi(nbttagcompound.getBoolean("NoAI")); @@ -144,7 +145,7 @@ } @Override -@@ -611,7 +684,7 @@ +@@ -611,20 +685,26 @@ protected void pickUpItem(EntityItem entityitem) { ItemStack itemstack = entityitem.getItem(); @@ -153,7 +154,14 @@ if (!itemstack1.isEmpty()) { this.onItemPickup(entityitem); -@@ -625,6 +698,12 @@ + this.take(entityitem, itemstack1.getCount()); + itemstack.shrink(itemstack1.getCount()); + if (itemstack.isEmpty()) { +- entityitem.discard(); ++ entityitem.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + } + } + } public ItemStack equipItemIfPossible(ItemStack itemstack) { @@ -166,7 +174,7 @@ EnumItemSlot enumitemslot = getEquipmentSlotForItem(itemstack); ItemStack itemstack1 = this.getItemBySlot(enumitemslot); boolean flag = this.canReplaceCurrentItem(itemstack, itemstack1); -@@ -635,11 +714,19 @@ +@@ -635,11 +715,19 @@ flag = itemstack1.isEmpty(); } @@ -187,7 +195,33 @@ } if (enumitemslot.isArmor() && itemstack.getCount() > 1) { -@@ -791,6 +878,7 @@ +@@ -760,7 +848,7 @@ + @Override + public void checkDespawn() { + if (this.level().getDifficulty() == EnumDifficulty.PEACEFUL && this.shouldDespawnInPeaceful()) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } else if (!this.isPersistenceRequired() && !this.requiresCustomPersistence()) { + EntityHuman entityhuman = this.level().getNearestPlayer(this, -1.0D); + +@@ -770,14 +858,14 @@ + int j = i * i; + + if (d0 > (double) j && this.removeWhenFarAway(d0)) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } + + int k = this.getType().getCategory().getNoDespawnDistance(); + int l = k * k; + + if (this.noActionTime > 600 && this.random.nextInt(800) == 0 && d0 > (double) l && this.removeWhenFarAway(d0)) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } else if (d0 < (double) l) { + this.noActionTime = 0; + } +@@ -791,6 +879,7 @@ @Override protected final void serverAiStep() { ++this.noActionTime; @@ -195,7 +229,7 @@ this.level().getProfiler().push("sensing"); this.sensing.tick(); this.level().getProfiler().pop(); -@@ -1184,6 +1272,12 @@ +@@ -1184,6 +1273,12 @@ if (!this.isAlive()) { return EnumInteractionResult.PASS; } else if (this.getLeashHolder() == entityhuman) { @@ -208,7 +242,7 @@ this.dropLeash(true, !entityhuman.getAbilities().instabuild); this.gameEvent(GameEvent.ENTITY_INTERACT, entityhuman); return EnumInteractionResult.sidedSuccess(this.level().isClientSide); -@@ -1209,6 +1303,12 @@ +@@ -1209,6 +1304,12 @@ ItemStack itemstack = entityhuman.getItemInHand(enumhand); if (itemstack.is(Items.LEAD) && this.canBeLeashed(entityhuman)) { @@ -221,7 +255,7 @@ this.setLeashedTo(entityhuman, true); itemstack.shrink(1); return EnumInteractionResult.sidedSuccess(this.level().isClientSide); -@@ -1224,7 +1324,7 @@ +@@ -1224,7 +1325,7 @@ if (itemstack.getItem() instanceof ItemMonsterEgg) { if (this.level() instanceof WorldServer) { ItemMonsterEgg itemmonsteregg = (ItemMonsterEgg) itemstack.getItem(); @@ -230,7 +264,7 @@ optional.ifPresent((entityinsentient) -> { this.onOffspringSpawnedFromEgg(entityhuman, entityinsentient); -@@ -1274,12 +1374,19 @@ +@@ -1274,12 +1375,19 @@ return this.restrictRadius != -1.0F; } @@ -251,7 +285,7 @@ if (t0 == null) { return null; -@@ -1313,7 +1420,12 @@ +@@ -1313,7 +1421,12 @@ } } @@ -265,7 +299,16 @@ if (this.isPassenger()) { Entity entity = this.getVehicle(); -@@ -1334,7 +1446,8 @@ +@@ -1321,7 +1434,7 @@ + t0.startRiding(entity, true); + } + +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.TRANSFORMATION); // CraftBukkit - add Bukkit remove cause + return t0; + } + } +@@ -1334,7 +1447,8 @@ if (this.leashHolder != null) { if (!this.isAlive() || !this.leashHolder.isAlive()) { @@ -275,7 +318,7 @@ } } -@@ -1345,7 +1458,9 @@ +@@ -1345,7 +1459,9 @@ this.leashHolder = null; this.leashInfoTag = null; if (!this.level().isClientSide && flag1) { @@ -285,7 +328,7 @@ } if (!this.level().isClientSide && flag && this.level() instanceof WorldServer) { -@@ -1395,6 +1510,7 @@ +@@ -1395,6 +1511,7 @@ boolean flag1 = super.startRiding(entity, flag); if (flag1 && this.isLeashed()) { @@ -293,7 +336,7 @@ this.dropLeash(true, true); } -@@ -1419,7 +1535,9 @@ +@@ -1419,7 +1536,9 @@ } if (this.tickCount > 100) { @@ -303,7 +346,7 @@ this.leashInfoTag = null; } } -@@ -1501,14 +1619,21 @@ +@@ -1501,14 +1620,21 @@ int i = EnchantmentManager.getFireAspect(this); if (i > 0) { @@ -327,7 +370,7 @@ this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D)); } -@@ -1576,6 +1701,7 @@ +@@ -1576,6 +1702,7 @@ @Override protected void removeAfterChangingDimensions() { super.removeAfterChangingDimensions(); diff --git a/paper-server/nms-patches/net/minecraft/world/entity/EntityLightning.patch b/paper-server/nms-patches/net/minecraft/world/entity/EntityLightning.patch index a6705430a4..5ad8ee3d48 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/EntityLightning.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/EntityLightning.patch @@ -1,17 +1,27 @@ --- a/net/minecraft/world/entity/EntityLightning.java +++ b/net/minecraft/world/entity/EntityLightning.java -@@ -29,6 +29,10 @@ +@@ -29,6 +29,11 @@ import net.minecraft.world.phys.AxisAlignedBB; import net.minecraft.world.phys.Vec3D; +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityRemoveEvent; +// CraftBukkit end + public class EntityLightning extends Entity { private static final int START_LIFE = 2; -@@ -129,7 +133,7 @@ +@@ -120,7 +125,7 @@ + } + } + +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } else if (this.life < -this.random.nextInt(10)) { + --this.flashes; + this.life = 1; +@@ -129,7 +134,7 @@ } } @@ -20,7 +30,7 @@ if (!(this.level() instanceof WorldServer)) { this.level().setSkyFlashTime(2); } else if (!this.visualOnly) { -@@ -163,8 +167,12 @@ +@@ -163,8 +168,12 @@ IBlockData iblockdata = BlockFireAbstract.getState(this.level(), blockposition); if (this.level().getBlockState(blockposition).isAir() && iblockdata.canSurvive(this.level(), blockposition)) { @@ -35,7 +45,7 @@ } for (int j = 0; j < i; ++j) { -@@ -172,8 +180,12 @@ +@@ -172,8 +181,12 @@ iblockdata = BlockFireAbstract.getState(this.level(), blockposition1); if (this.level().getBlockState(blockposition1).isAir() && iblockdata.canSurvive(this.level(), blockposition1)) { @@ -50,7 +60,7 @@ } } -@@ -237,8 +249,9 @@ +@@ -237,8 +250,9 @@ iblockdata = world.getBlockState(blockposition1); } while (!(iblockdata.getBlock() instanceof WeatheringCopper)); diff --git a/paper-server/nms-patches/net/minecraft/world/entity/EntityLiving.patch b/paper-server/nms-patches/net/minecraft/world/entity/EntityLiving.patch index b4ab26f8cf..811b4aa937 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/EntityLiving.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/EntityLiving.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/EntityLiving.java +++ b/net/minecraft/world/entity/EntityLiving.java -@@ -119,6 +119,31 @@ +@@ -119,6 +119,32 @@ import net.minecraft.world.scores.ScoreboardTeam; import org.slf4j.Logger; @@ -24,6 +24,7 @@ +import org.bukkit.event.entity.EntityKnockbackEvent; +import org.bukkit.event.entity.EntityPotionEffectEvent; +import org.bukkit.event.entity.EntityRegainHealthEvent; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.entity.EntityResurrectEvent; +import org.bukkit.event.entity.EntityTeleportEvent; +import org.bukkit.event.player.PlayerItemConsumeEvent; @@ -32,7 +33,7 @@ public abstract class EntityLiving extends Entity implements Attackable { private static final Logger LOGGER = LogUtils.getLogger(); -@@ -225,7 +250,21 @@ +@@ -225,7 +251,21 @@ private float swimAmount; private float swimAmountO; protected BehaviorController brain; @@ -55,7 +56,7 @@ protected EntityLiving(EntityTypes entitytypes, World world) { super(entitytypes, world); -@@ -238,7 +277,9 @@ +@@ -238,7 +278,9 @@ this.useItem = ItemStack.EMPTY; this.lastClimbablePos = Optional.empty(); this.attributes = new AttributeMapBase(AttributeDefaults.getSupplier(entitytypes)); @@ -66,7 +67,7 @@ this.blocksBuilding = true; this.rotA = (float) ((Math.random() + 1.0D) * 0.009999999776482582D); this.reapplyPosition(); -@@ -317,7 +358,13 @@ +@@ -317,7 +359,13 @@ double d7 = Math.min((double) (0.2F + f / 15.0F), 2.5D); int i = (int) (150.0D * d7); @@ -81,7 +82,16 @@ } super.checkFallDamage(d0, flag, iblockdata, blockposition); -@@ -672,13 +719,19 @@ +@@ -573,7 +621,7 @@ + ++this.deathTime; + if (this.deathTime >= 20 && !this.level().isClientSide() && !this.isRemoved()) { + this.level().broadcastEntityEvent(this, (byte) 60); +- this.remove(Entity.RemovalReason.KILLED); ++ this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause + } + + } +@@ -672,13 +720,19 @@ } public void onEquipItem(EnumItemSlot enumitemslot, ItemStack itemstack, ItemStack itemstack1) { @@ -102,7 +112,23 @@ this.level().playSound((EntityHuman) null, this.getX(), this.getY(), this.getZ(), equipable.getEquipSound(), this.getSoundSource(), 1.0F, 1.0F); } -@@ -752,6 +805,17 @@ +@@ -692,7 +746,14 @@ + + @Override + public void remove(Entity.RemovalReason entity_removalreason) { +- super.remove(entity_removalreason); ++ // CraftBukkit start - add Bukkit remove cause ++ this.remove(entity_removalreason, null); ++ } ++ ++ @Override ++ public void remove(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { ++ super.remove(entity_removalreason, cause); ++ // CraftBukkit end + this.brain.clearMemories(); + } + +@@ -752,6 +813,17 @@ } } @@ -120,7 +146,7 @@ if (nbttagcompound.contains("Health", 99)) { this.setHealth(nbttagcompound.getFloat("Health")); } -@@ -789,9 +853,32 @@ +@@ -789,9 +861,32 @@ } @@ -153,7 +179,7 @@ try { while (iterator.hasNext()) { MobEffectList mobeffectlist = (MobEffectList) iterator.next(); -@@ -801,6 +888,12 @@ +@@ -801,6 +896,12 @@ this.onEffectUpdated(mobeffect, true, (Entity) null); })) { if (!this.level().isClientSide) { @@ -166,7 +192,7 @@ iterator.remove(); this.onEffectRemoved(mobeffect); } -@@ -811,6 +904,17 @@ +@@ -811,6 +912,17 @@ } catch (ConcurrentModificationException concurrentmodificationexception) { ; } @@ -184,7 +210,7 @@ if (this.effectsDirty) { if (!this.level().isClientSide) { -@@ -937,7 +1041,13 @@ +@@ -937,7 +1049,13 @@ this.entityData.set(EntityLiving.DATA_EFFECT_COLOR_ID, 0); } @@ -198,7 +224,7 @@ if (this.level().isClientSide) { return false; } else { -@@ -946,7 +1056,14 @@ +@@ -946,7 +1064,14 @@ boolean flag; for (flag = false; iterator.hasNext(); flag = true) { @@ -214,7 +240,7 @@ iterator.remove(); } -@@ -975,19 +1092,49 @@ +@@ -975,19 +1100,49 @@ return this.addEffect(mobeffect, (Entity) null); } @@ -265,7 +291,7 @@ flag = true; } -@@ -1025,13 +1172,39 @@ +@@ -1025,13 +1180,39 @@ return this.getMobType() == EnumMonsterType.UNDEAD; } @@ -306,7 +332,7 @@ if (mobeffect != null) { this.onEffectRemoved(mobeffect); -@@ -1129,20 +1302,55 @@ +@@ -1129,20 +1310,55 @@ } @@ -363,7 +389,7 @@ this.entityData.set(EntityLiving.DATA_HEALTH_ID, MathHelper.clamp(f, 0.0F, this.getMaxHealth())); } -@@ -1156,7 +1364,7 @@ +@@ -1156,7 +1372,7 @@ return false; } else if (this.level().isClientSide) { return false; @@ -372,7 +398,7 @@ return false; } else if (damagesource.is(DamageTypeTags.IS_FIRE) && this.hasEffect(MobEffects.FIRE_RESISTANCE)) { return false; -@@ -1167,10 +1375,11 @@ +@@ -1167,10 +1383,11 @@ this.noActionTime = 0; float f1 = f; @@ -386,7 +412,7 @@ this.hurtCurrentlyUsedShield(f); f2 = f; f = 0.0F; -@@ -1194,23 +1403,33 @@ +@@ -1194,23 +1411,33 @@ this.walkAnimation.setSpeed(1.5F); boolean flag1 = true; @@ -425,7 +451,7 @@ this.hurtHelmet(damagesource, f); f *= 0.75F; } -@@ -1269,7 +1488,7 @@ +@@ -1269,7 +1496,7 @@ d0 = (Math.random() - Math.random()) * 0.01D; } @@ -434,7 +460,7 @@ if (!flag) { this.indicateDamage(d0, d1); } -@@ -1317,7 +1536,7 @@ +@@ -1317,7 +1544,7 @@ } protected void blockedByShield(EntityLiving entityliving) { @@ -443,7 +469,7 @@ } private boolean checkTotemDeathProtection(DamageSource damagesource) { -@@ -1328,19 +1547,32 @@ +@@ -1328,19 +1555,32 @@ EnumHand[] aenumhand = EnumHand.values(); int i = aenumhand.length; @@ -480,7 +506,7 @@ EntityPlayer entityplayer = (EntityPlayer) this; entityplayer.awardStat(StatisticList.ITEM_USED.get(Items.TOTEM_OF_UNDYING)); -@@ -1349,14 +1581,16 @@ +@@ -1349,14 +1589,16 @@ } this.setHealth(1.0F); @@ -502,7 +528,7 @@ } } -@@ -1463,14 +1697,22 @@ +@@ -1463,14 +1705,22 @@ IBlockData iblockdata = Blocks.WITHER_ROSE.defaultBlockState(); if (this.level().getBlockState(blockposition).isAir() && iblockdata.canSurvive(this.level(), blockposition)) { @@ -527,7 +553,7 @@ this.level().addFreshEntity(entityitem); } } -@@ -1490,21 +1732,40 @@ +@@ -1490,21 +1740,40 @@ boolean flag = this.lastHurtByPlayerTime > 0; @@ -571,7 +597,7 @@ } -@@ -1533,13 +1794,25 @@ +@@ -1533,13 +1802,25 @@ } public void knockback(double d0, double d1, double d2) { @@ -600,7 +626,7 @@ } } -@@ -1596,6 +1869,28 @@ +@@ -1596,6 +1877,28 @@ return itemstack.getEatingSound(); } @@ -629,7 +655,7 @@ public Optional getLastClimbablePos() { return this.lastClimbablePos; } -@@ -1642,9 +1937,14 @@ +@@ -1642,9 +1945,14 @@ int i = this.calculateFallDamage(f, f1); if (i > 0) { @@ -645,7 +671,7 @@ return true; } else { return flag; -@@ -1696,7 +1996,7 @@ +@@ -1696,7 +2004,7 @@ protected float getDamageAfterArmorAbsorb(DamageSource damagesource, float f) { if (!damagesource.is(DamageTypeTags.BYPASSES_ARMOR)) { @@ -654,7 +680,7 @@ f = CombatMath.getDamageAfterAbsorb(f, (float) this.getArmorValue(), (float) this.getAttributeValue(GenericAttributes.ARMOR_TOUGHNESS)); } -@@ -1709,7 +2009,8 @@ +@@ -1709,7 +2017,8 @@ } else { int i; @@ -664,7 +690,7 @@ i = (this.getEffect(MobEffects.DAMAGE_RESISTANCE).getAmplifier() + 1) * 5; int j = 25 - i; float f1 = f * (float) j; -@@ -1742,16 +2043,125 @@ +@@ -1742,16 +2051,125 @@ } } @@ -770,7 +796,7 @@ + if (damagesource.is(DamageTypeTags.DAMAGES_HELMET) && !this.getItemBySlot(EnumItemSlot.HEAD).isEmpty()) { + this.hurtHelmet(damagesource, f); + } -+ + + // Apply damage to armor + if (!damagesource.is(DamageTypeTags.BYPASSES_ARMOR)) { + float armorDamage = (float) (event.getDamage() + event.getDamage(DamageModifier.BLOCKING) + event.getDamage(DamageModifier.HARD_HAT)); @@ -791,14 +817,14 @@ + absorptionModifier = (float) -event.getDamage(DamageModifier.ABSORPTION); + this.setAbsorptionAmount(Math.max(this.getAbsorptionAmount() - absorptionModifier, 0.0F)); + float f2 = absorptionModifier; - ++ + if (f2 > 0.0F && f2 < 3.4028235E37F && this instanceof EntityHuman) { + ((EntityHuman) this).awardStat(StatisticList.DAMAGE_ABSORBED, Math.round(f2 * 10.0F)); + } if (f2 > 0.0F && f2 < 3.4028235E37F) { Entity entity = damagesource.getEntity(); -@@ -1762,13 +2172,47 @@ +@@ -1762,13 +2180,47 @@ } } @@ -848,7 +874,7 @@ } public CombatTracker getCombatTracker() { -@@ -1793,8 +2237,18 @@ +@@ -1793,8 +2245,18 @@ } public final void setArrowCount(int i) { @@ -868,7 +894,7 @@ public final int getStingerCount() { return (Integer) this.entityData.get(EntityLiving.DATA_STINGER_COUNT_ID); -@@ -2036,6 +2490,12 @@ +@@ -2036,6 +2498,12 @@ public abstract ItemStack getItemBySlot(EnumItemSlot enumitemslot); @@ -881,7 +907,7 @@ @Override public abstract void setItemSlot(EnumItemSlot enumitemslot, ItemStack itemstack); -@@ -2270,6 +2730,7 @@ +@@ -2270,6 +2738,7 @@ } if (this.onGround() && !this.level().isClientSide) { @@ -889,7 +915,7 @@ this.setSharedFlag(7, false); } } else { -@@ -2440,7 +2901,7 @@ +@@ -2440,7 +2909,7 @@ } } @@ -898,7 +924,7 @@ if (this.tickCount % 20 == 0) { this.getCombatTracker().recheckStatus(); } -@@ -2537,7 +2998,7 @@ +@@ -2537,7 +3006,7 @@ this.refreshDirtyAttributes(); } @@ -907,7 +933,7 @@ Map map = this.collectEquipmentChanges(); if (map != null) { -@@ -2839,6 +3300,7 @@ +@@ -2839,6 +3308,7 @@ } if (!this.level().isClientSide) { @@ -915,7 +941,7 @@ this.setSharedFlag(7, flag); } -@@ -3029,13 +3491,20 @@ +@@ -3029,14 +3499,21 @@ @Override public boolean isPickable() { @@ -927,18 +953,19 @@ public boolean isPushable() { - return this.isAlive() && !this.isSpectator() && !this.onClimbable(); + return this.isAlive() && !this.isSpectator() && !this.onClimbable() && this.collides; // CraftBukkit -+ } -+ + } + + // CraftBukkit start - collidable API + @Override + public boolean canCollideWithBukkit(Entity entity) { + return isPushable() && this.collides != this.collidableExemptions.contains(entity.getUUID()); - } ++ } + // CraftBukkit end - ++ @Override public float getYHeadRot() { -@@ -3231,7 +3700,26 @@ + return this.yHeadRot; +@@ -3231,7 +3708,26 @@ } else { if (!this.useItem.isEmpty() && this.isUsingItem()) { this.triggerItemUseEffects(this.useItem, 16); @@ -966,7 +993,7 @@ if (itemstack != this.useItem) { this.setItemInHand(enumhand, itemstack); -@@ -3309,6 +3797,12 @@ +@@ -3309,6 +3805,12 @@ } public boolean randomTeleport(double d0, double d1, double d2, boolean flag) { @@ -979,7 +1006,7 @@ double d3 = this.getX(); double d4 = this.getY(); double d5 = this.getZ(); -@@ -3333,16 +3827,41 @@ +@@ -3333,16 +3835,41 @@ } if (flag2) { @@ -1024,7 +1051,7 @@ } else { if (flag) { world.broadcastEntityEvent(this, (byte) 46); -@@ -3354,7 +3873,7 @@ +@@ -3354,7 +3881,7 @@ entitycreature.getNavigation().stop(); } @@ -1033,7 +1060,7 @@ } } -@@ -3443,7 +3962,7 @@ +@@ -3443,7 +3970,7 @@ } public void stopSleeping() { @@ -1042,7 +1069,7 @@ World world = this.level(); java.util.Objects.requireNonNull(world); -@@ -3477,7 +3996,7 @@ +@@ -3477,7 +4004,7 @@ @Nullable public EnumDirection getBedOrientation() { @@ -1051,7 +1078,7 @@ return blockposition != null ? BlockBed.getBedOrientation(this.level(), blockposition) : null; } -@@ -3525,7 +4044,7 @@ +@@ -3525,7 +4052,7 @@ Pair pair = (Pair) iterator.next(); if (!world.isClientSide && pair.getFirst() != null && world.random.nextFloat() < (Float) pair.getSecond()) { diff --git a/paper-server/nms-patches/net/minecraft/world/entity/ai/behavior/warden/Digging.patch b/paper-server/nms-patches/net/minecraft/world/entity/ai/behavior/warden/Digging.patch new file mode 100644 index 0000000000..24f78f89dc --- /dev/null +++ b/paper-server/nms-patches/net/minecraft/world/entity/ai/behavior/warden/Digging.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/world/entity/ai/behavior/warden/Digging.java ++++ b/net/minecraft/world/entity/ai/behavior/warden/Digging.java +@@ -10,6 +10,10 @@ + import net.minecraft.world.entity.ai.memory.MemoryStatus; + import net.minecraft.world.entity.monster.warden.Warden; + ++// CraftBukkit start - imports ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class Digging extends Behavior { + + public Digging(int i) { +@@ -37,7 +41,7 @@ + + protected void stop(WorldServer worldserver, E e0, long i) { + if (e0.getRemovalReason() == null) { +- e0.remove(Entity.RemovalReason.DISCARDED); ++ e0.remove(Entity.RemovalReason.DISCARDED, EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - Add bukkit remove cause + } + + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/animal/Bucketable.patch b/paper-server/nms-patches/net/minecraft/world/entity/animal/Bucketable.patch index 9fd8543e5a..2c9dc3c83a 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/animal/Bucketable.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/animal/Bucketable.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Bucketable.java +++ b/net/minecraft/world/entity/animal/Bucketable.java -@@ -15,6 +15,14 @@ +@@ -15,6 +15,15 @@ import net.minecraft.world.item.Items; import net.minecraft.world.level.World; @@ -9,13 +9,14 @@ +import net.minecraft.network.protocol.game.PacketPlayOutSpawnEntity; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.player.PlayerBucketEntityEvent; +// CraftBukkit end + public interface Bucketable { boolean fromBucket(); -@@ -94,10 +102,22 @@ +@@ -94,10 +103,22 @@ ItemStack itemstack = entityhuman.getItemInHand(enumhand); if (itemstack.getItem() == Items.WATER_BUCKET && t0.isAlive()) { @@ -39,3 +40,12 @@ ItemStack itemstack2 = ItemLiquidUtil.createFilledResult(itemstack, entityhuman, itemstack1, false); entityhuman.setItemInHand(enumhand, itemstack2); +@@ -107,7 +128,7 @@ + CriterionTriggers.FILLED_BUCKET.trigger((EntityPlayer) entityhuman, itemstack1); + } + +- t0.discard(); ++ t0.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + return Optional.of(EnumInteractionResult.sidedSuccess(world.isClientSide)); + } else { + return Optional.empty(); diff --git a/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityDolphin.patch b/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityDolphin.patch index c5e7b5f4cd..83f59f4eca 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityDolphin.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityDolphin.patch @@ -1,12 +1,13 @@ --- a/net/minecraft/world/entity/animal/EntityDolphin.java +++ b/net/minecraft/world/entity/animal/EntityDolphin.java -@@ -61,8 +61,19 @@ +@@ -61,8 +61,20 @@ import net.minecraft.world.level.pathfinder.PathMode; import net.minecraft.world.phys.Vec3D; +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.EntityPotionEffectEvent; ++import org.bukkit.event.entity.EntityRemoveEvent; +// CraftBukkit end + public class EntityDolphin extends EntityWaterAnimal { @@ -20,7 +21,7 @@ private static final DataWatcherObject TREASURE_POS = DataWatcher.defineId(EntityDolphin.class, DataWatcherRegistry.BLOCK_POS); private static final DataWatcherObject GOT_FISH = DataWatcher.defineId(EntityDolphin.class, DataWatcherRegistry.BOOLEAN); private static final DataWatcherObject MOISTNESS_LEVEL = DataWatcher.defineId(EntityDolphin.class, DataWatcherRegistry.INT); -@@ -185,7 +196,7 @@ +@@ -185,7 +197,7 @@ @Override public int getMaxAirSupply() { @@ -29,7 +30,7 @@ } @Override -@@ -226,6 +237,12 @@ +@@ -226,11 +238,17 @@ ItemStack itemstack = entityitem.getItem(); if (this.canHoldItem(itemstack)) { @@ -42,7 +43,13 @@ this.onItemPickup(entityitem); this.setItemSlot(EnumItemSlot.MAINHAND, itemstack); this.setGuaranteedDrop(EnumItemSlot.MAINHAND); -@@ -484,7 +501,7 @@ + this.take(entityitem, itemstack.getCount()); +- entityitem.discard(); ++ entityitem.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + } + } + +@@ -484,7 +502,7 @@ @Override public void start() { @@ -51,7 +58,7 @@ } @Override -@@ -503,7 +520,7 @@ +@@ -503,7 +521,7 @@ } if (this.player.isSwimming() && this.player.level().random.nextInt(6) == 0) { diff --git a/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityFox.patch b/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityFox.patch index ec69250917..837665f9a3 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityFox.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityFox.patch @@ -1,6 +1,17 @@ --- a/net/minecraft/world/entity/animal/EntityFox.java +++ b/net/minecraft/world/entity/animal/EntityFox.java -@@ -523,7 +523,8 @@ +@@ -94,6 +94,10 @@ + import net.minecraft.world.phys.Vec3D; + import org.joml.Vector3f; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class EntityFox extends EntityAnimal implements VariantHolder { + + private static final DataWatcherObject DATA_TYPE_ID = DataWatcher.defineId(EntityFox.class, DataWatcherRegistry.INT); +@@ -523,7 +527,8 @@ protected void pickUpItem(EntityItem entityitem) { ItemStack itemstack = entityitem.getItem(); @@ -10,7 +21,16 @@ int i = itemstack.getCount(); if (i > 1) { -@@ -883,6 +884,16 @@ +@@ -535,7 +540,7 @@ + this.setItemSlot(EnumItemSlot.MAINHAND, itemstack.split(1)); + this.setGuaranteedDrop(EnumItemSlot.MAINHAND); + this.take(entityitem, itemstack.getCount()); +- entityitem.discard(); ++ entityitem.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + this.ticksSinceEaten = 0; + } + +@@ -883,6 +888,16 @@ if (entityplayer1 != null && entityplayer != entityplayer1) { entityfox.addTrustedUUID(entityplayer1.getUUID()); } @@ -27,7 +47,7 @@ if (entityplayer2 != null) { entityplayer2.awardStat(StatisticList.ANIMALS_BRED); -@@ -893,12 +904,14 @@ +@@ -893,12 +908,14 @@ this.partner.setAge(6000); this.animal.resetLove(); this.partner.resetLove(); @@ -46,7 +66,7 @@ } } -@@ -1294,6 +1307,11 @@ +@@ -1294,6 +1311,11 @@ int i = (Integer) iblockdata.getValue(BlockSweetBerryBush.AGE); iblockdata.setValue(BlockSweetBerryBush.AGE, 1); @@ -58,7 +78,7 @@ int j = 1 + EntityFox.this.level().random.nextInt(2) + (i == 3 ? 1 : 0); ItemStack itemstack = EntityFox.this.getItemBySlot(EnumItemSlot.MAINHAND); -@@ -1451,7 +1469,7 @@ +@@ -1451,7 +1473,7 @@ private EntityLiving trustedLastHurt; private int timestamp; diff --git a/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityMushroomCow.patch b/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityMushroomCow.patch index 7cd4698081..8e9990640a 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityMushroomCow.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityMushroomCow.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/EntityMushroomCow.java +++ b/net/minecraft/world/entity/animal/EntityMushroomCow.java -@@ -42,13 +42,20 @@ +@@ -42,13 +42,21 @@ import net.minecraft.world.level.block.state.IBlockData; import net.minecraft.world.level.gameevent.GameEvent; @@ -8,6 +8,7 @@ +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.EntityDropItemEvent; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.entity.EntityTransformEvent; +// CraftBukkit end + @@ -22,7 +23,7 @@ @Nullable private UUID lastLightningBoltUUID; -@@ -114,6 +121,11 @@ +@@ -114,6 +122,11 @@ this.playSound(soundeffect, 1.0F, 1.0F); return EnumInteractionResult.sidedSuccess(this.level().isClientSide); } else if (itemstack.is(Items.SHEARS) && this.readyForShearing()) { @@ -34,7 +35,7 @@ this.shear(SoundCategory.PLAYERS); this.gameEvent(GameEvent.SHEAR, entityhuman); if (!this.level().isClientSide) { -@@ -161,7 +173,7 @@ +@@ -161,7 +174,7 @@ if (entitycow != null) { ((WorldServer) this.level()).sendParticles(Particles.EXPLOSION, this.getX(), this.getY(0.5D), this.getZ(), 1, 0.0D, 0.0D, 0.0D, 0.0D); @@ -43,7 +44,7 @@ entitycow.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot()); entitycow.setHealth(this.getHealth()); entitycow.yBodyRot = this.yBodyRot; -@@ -175,10 +187,25 @@ +@@ -175,10 +188,25 @@ } entitycow.setInvulnerable(this.isInvulnerable()); @@ -54,7 +55,7 @@ + } + this.level().addFreshEntity(entitycow, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SHEARED); + -+ this.discard(); // CraftBukkit - from above ++ this.discard(EntityRemoveEvent.Cause.TRANSFORMATION); // CraftBukkit - from above and add Bukkit remove cause + // CraftBukkit end for (int i = 0; i < 5; ++i) { diff --git a/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityPanda.patch b/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityPanda.patch index 7d72eaafc1..31b836da5b 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityPanda.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityPanda.patch @@ -1,18 +1,19 @@ --- a/net/minecraft/world/entity/animal/EntityPanda.java +++ b/net/minecraft/world/entity/animal/EntityPanda.java -@@ -67,6 +67,11 @@ +@@ -67,6 +67,12 @@ import net.minecraft.world.phys.Vec3D; import org.joml.Vector3f; +// CraftBukkit start; +import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.entity.EntityTargetEvent; +// CraftBukkit end + public class EntityPanda extends EntityAnimal { private static final DataWatcherObject UNHAPPY_COUNTER = DataWatcher.defineId(EntityPanda.class, DataWatcherRegistry.INT); -@@ -534,7 +539,7 @@ +@@ -534,14 +540,14 @@ @Override protected void pickUpItem(EntityItem entityitem) { @@ -21,7 +22,15 @@ this.onItemPickup(entityitem); ItemStack itemstack = entityitem.getItem(); -@@ -870,10 +875,10 @@ + this.setItemSlot(EnumItemSlot.MAINHAND, itemstack); + this.setGuaranteedDrop(EnumItemSlot.MAINHAND); + this.take(entityitem, itemstack.getCount()); +- entityitem.discard(); ++ entityitem.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + } + + } +@@ -870,10 +876,10 @@ private final EntityPanda panda; public c(EntityPanda entitypanda, Class oclass, float f, double d0, double d1) { @@ -35,7 +44,7 @@ this.panda = entitypanda; } -@@ -1112,7 +1117,7 @@ +@@ -1112,7 +1118,7 @@ @Override protected void alertOther(EntityInsentient entityinsentient, EntityLiving entityliving) { if (entityinsentient instanceof EntityPanda && entityinsentient.isAggressive()) { diff --git a/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityPerchable.patch b/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityPerchable.patch new file mode 100644 index 0000000000..2c2acfed73 --- /dev/null +++ b/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityPerchable.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/world/entity/animal/EntityPerchable.java ++++ b/net/minecraft/world/entity/animal/EntityPerchable.java +@@ -6,6 +6,10 @@ + import net.minecraft.world.entity.EntityTypes; + import net.minecraft.world.level.World; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public abstract class EntityPerchable extends EntityTameableAnimal { + + private static final int RIDE_COOLDOWN = 100; +@@ -21,7 +25,7 @@ + nbttagcompound.putString("id", this.getEncodeId()); + this.saveWithoutId(nbttagcompound); + if (entityplayer.setEntityOnShoulder(nbttagcompound)) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + return true; + } else { + return false; diff --git a/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityPig.patch b/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityPig.patch index 9066083a4d..c54ff861ae 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityPig.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/animal/EntityPig.patch @@ -1,21 +1,23 @@ --- a/net/minecraft/world/entity/animal/EntityPig.java +++ b/net/minecraft/world/entity/animal/EntityPig.java -@@ -51,6 +51,10 @@ +@@ -51,6 +51,11 @@ import net.minecraft.world.phys.Vec3D; import org.joml.Vector3f; +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityRemoveEvent; +// CraftBukkit end + public class EntityPig extends EntityAnimal implements ISteerable, ISaddleable { private static final DataWatcherObject DATA_SADDLE_ID = DataWatcher.defineId(EntityPig.class, DataWatcherRegistry.BOOLEAN); -@@ -252,7 +256,13 @@ +@@ -252,8 +257,14 @@ } entitypigzombie.setPersistenceRequired(); - worldserver.addFreshEntity(entitypigzombie); +- this.discard(); + // CraftBukkit start + if (CraftEventFactory.callPigZapEvent(this, entitylightning, entitypigzombie).isCancelled()) { + return; @@ -23,6 +25,7 @@ + // CraftBukkit - added a reason for spawning this creature + worldserver.addFreshEntity(entitypigzombie, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); + // CraftBukkit end - this.discard(); ++ this.discard(EntityRemoveEvent.Cause.TRANSFORMATION); // CraftBukkit - add Bukkit remove cause } else { super.thunderHit(worldserver, entitylightning); + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/animal/frog/ShootTongue.patch b/paper-server/nms-patches/net/minecraft/world/entity/animal/frog/ShootTongue.patch new file mode 100644 index 0000000000..bbd20a8372 --- /dev/null +++ b/paper-server/nms-patches/net/minecraft/world/entity/animal/frog/ShootTongue.patch @@ -0,0 +1,40 @@ +--- a/net/minecraft/world/entity/animal/frog/ShootTongue.java ++++ b/net/minecraft/world/entity/animal/frog/ShootTongue.java +@@ -20,6 +20,10 @@ + import net.minecraft.world.level.pathfinder.PathEntity; + import net.minecraft.world.phys.Vec3D; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class ShootTongue extends Behavior { + + public static final int TIME_OUT_DURATION = 100; +@@ -64,7 +68,7 @@ + + BehaviorUtil.lookAtEntity(frog, entityliving); + frog.setTongueTarget(entityliving); +- frog.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (Object) (new MemoryTarget(entityliving.position(), 2.0F, 0))); ++ frog.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (new MemoryTarget(entityliving.position(), 2.0F, 0))); // CraftBukkit - decompile error + this.calculatePathCounter = 10; + this.state = ShootTongue.a.MOVE_TO_TARGET; + } +@@ -85,7 +89,7 @@ + if (entity.isAlive()) { + frog.doHurtTarget(entity); + if (!entity.isAlive()) { +- entity.remove(Entity.RemovalReason.KILLED); ++ entity.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause + } + } + } +@@ -106,7 +110,7 @@ + this.eatAnimationTimer = 0; + this.state = ShootTongue.a.CATCH_ANIMATION; + } else if (this.calculatePathCounter <= 0) { +- frog.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (Object) (new MemoryTarget(entityliving.position(), 2.0F, 0))); ++ frog.getBrain().setMemory(MemoryModuleType.WALK_TARGET, (new MemoryTarget(entityliving.position(), 2.0F, 0))); // CraftBukkit - decompile error + this.calculatePathCounter = 10; + } else { + --this.calculatePathCounter; diff --git a/paper-server/nms-patches/net/minecraft/world/entity/animal/frog/Tadpole.patch b/paper-server/nms-patches/net/minecraft/world/entity/animal/frog/Tadpole.patch index f8e7f4762b..c727c9defe 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/animal/frog/Tadpole.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/animal/frog/Tadpole.patch @@ -1,6 +1,17 @@ --- a/net/minecraft/world/entity/animal/frog/Tadpole.java +++ b/net/minecraft/world/entity/animal/frog/Tadpole.java -@@ -68,7 +68,7 @@ +@@ -35,6 +35,10 @@ + import net.minecraft.world.item.Items; + import net.minecraft.world.level.World; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class Tadpole extends EntityFish { + + @VisibleForTesting +@@ -68,7 +72,7 @@ @Override public BehaviorController getBrain() { @@ -9,7 +20,7 @@ } @Override -@@ -233,8 +233,14 @@ +@@ -233,9 +237,15 @@ } frog.setPersistenceRequired(); @@ -21,7 +32,9 @@ + // CraftBukkit end this.playSound(SoundEffects.TADPOLE_GROW_UP, 0.15F, 1.0F); - worldserver.addFreshEntityWithPassengers(frog); +- this.discard(); + worldserver.addFreshEntityWithPassengers(frog, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.METAMORPHOSIS); // CraftBukkit - add SpawnReason - this.discard(); ++ this.discard(EntityRemoveEvent.Cause.TRANSFORMATION); // CraftBukkit - add Bukkit remove cause } } + diff --git a/paper-server/nms-patches/net/minecraft/world/entity/animal/horse/EntityHorseSkeleton.patch b/paper-server/nms-patches/net/minecraft/world/entity/animal/horse/EntityHorseSkeleton.patch new file mode 100644 index 0000000000..368a17ea37 --- /dev/null +++ b/paper-server/nms-patches/net/minecraft/world/entity/animal/horse/EntityHorseSkeleton.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/world/entity/animal/horse/EntityHorseSkeleton.java ++++ b/net/minecraft/world/entity/animal/horse/EntityHorseSkeleton.java +@@ -27,6 +27,10 @@ + import net.minecraft.world.level.World; + import org.joml.Vector3f; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class EntityHorseSkeleton extends EntityHorseAbstract { + + private final PathfinderGoalHorseTrap skeletonTrapGoal = new PathfinderGoalHorseTrap(this); +@@ -126,7 +130,7 @@ + public void aiStep() { + super.aiStep(); + if (this.isTrap() && this.trapTime++ >= 18000) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } + + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/animal/horse/EntityLlamaTrader.patch b/paper-server/nms-patches/net/minecraft/world/entity/animal/horse/EntityLlamaTrader.patch index 25306fc4b9..1c56c4bdd9 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/animal/horse/EntityLlamaTrader.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/animal/horse/EntityLlamaTrader.patch @@ -1,6 +1,26 @@ --- a/net/minecraft/world/entity/animal/horse/EntityLlamaTrader.java +++ b/net/minecraft/world/entity/animal/horse/EntityLlamaTrader.java -@@ -153,7 +153,7 @@ +@@ -19,6 +19,10 @@ + import net.minecraft.world.level.World; + import net.minecraft.world.level.WorldAccess; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class EntityLlamaTrader extends EntityLlama { + + private int despawnDelay = 47999; +@@ -87,7 +91,7 @@ + this.despawnDelay = this.isLeashedToWanderingTrader() ? ((EntityVillagerTrader) this.getLeashHolder()).getDespawnDelay() - 1 : this.despawnDelay - 1; + if (this.despawnDelay <= 0) { + this.dropLeash(true, false); +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } + + } +@@ -153,7 +157,7 @@ @Override public void start() { diff --git a/paper-server/nms-patches/net/minecraft/world/entity/boss/enderdragon/EntityEnderCrystal.patch b/paper-server/nms-patches/net/minecraft/world/entity/boss/enderdragon/EntityEnderCrystal.patch index cf987efb76..db877da98a 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/boss/enderdragon/EntityEnderCrystal.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/boss/enderdragon/EntityEnderCrystal.patch @@ -1,18 +1,19 @@ --- a/net/minecraft/world/entity/boss/enderdragon/EntityEnderCrystal.java +++ b/net/minecraft/world/entity/boss/enderdragon/EntityEnderCrystal.java -@@ -20,6 +20,11 @@ +@@ -20,6 +20,12 @@ import net.minecraft.world.level.block.BlockFireAbstract; import net.minecraft.world.level.dimension.end.EnderDragonBattle; +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.entity.ExplosionPrimeEvent; +// CraftBukkit end + public class EntityEnderCrystal extends Entity { private static final DataWatcherObject> DATA_BEAM_TARGET = DataWatcher.defineId(EntityEnderCrystal.class, DataWatcherRegistry.OPTIONAL_BLOCK_POS); -@@ -55,7 +60,11 @@ +@@ -55,7 +61,11 @@ BlockPosition blockposition = this.blockPosition(); if (((WorldServer) this.level()).getDragonFight() != null && this.level().getBlockState(blockposition).isAir()) { @@ -25,16 +26,16 @@ } } -@@ -95,11 +104,23 @@ +@@ -95,12 +105,26 @@ return false; } else { if (!this.isRemoved() && !this.level().isClientSide) { +- this.remove(Entity.RemovalReason.KILLED); + // CraftBukkit start - All non-living entities need this + if (CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f, false)) { + return false; + } + // CraftBukkit end - this.remove(Entity.RemovalReason.KILLED); if (!damagesource.is(DamageTypeTags.IS_EXPLOSION)) { DamageSource damagesource1 = damagesource.getEntity() != null ? this.damageSources().explosion(this, damagesource.getEntity()) : null; @@ -42,11 +43,15 @@ + // CraftBukkit start + ExplosionPrimeEvent event = CraftEventFactory.callExplosionPrimeEvent(this, 6.0F, false); + if (event.isCancelled()) { -+ this.unsetRemoved(); + return false; + } ++ ++ this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause + this.level().explode(this, damagesource1, (ExplosionDamageCalculator) null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), World.a.BLOCK); -+ // CraftBukkit end ++ } else { ++ this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause } ++ // CraftBukkit end this.onDestroyedBy(damagesource); + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/boss/enderdragon/EntityEnderDragon.patch b/paper-server/nms-patches/net/minecraft/world/entity/boss/enderdragon/EntityEnderDragon.patch index 745512736f..93fdccc4e6 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/boss/enderdragon/EntityEnderDragon.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/boss/enderdragon/EntityEnderDragon.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/boss/enderdragon/EntityEnderDragon.java +++ b/net/minecraft/world/entity/boss/enderdragon/EntityEnderDragon.java -@@ -53,6 +53,19 @@ +@@ -53,6 +53,20 @@ import org.joml.Vector3f; import org.slf4j.Logger; @@ -15,12 +15,13 @@ +import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.EntityRegainHealthEvent; ++import org.bukkit.event.entity.EntityRemoveEvent; +// CraftBukkit end + public class EntityEnderDragon extends EntityInsentient implements IMonster { private static final Logger LOGGER = LogUtils.getLogger(); -@@ -90,6 +103,7 @@ +@@ -90,6 +104,7 @@ private final PathPoint[] nodes; private final int[] nodeAdjacency; private final Path openSet; @@ -28,7 +29,7 @@ public EntityEnderDragon(EntityTypes entitytypes, World world) { super(EntityTypes.ENDER_DRAGON, world); -@@ -111,6 +125,7 @@ +@@ -111,6 +126,7 @@ this.noPhysics = true; this.noCulling = true; this.phaseManager = new DragonControllerManager(this); @@ -36,7 +37,7 @@ } public void setDragonFight(EnderDragonBattle enderdragonbattle) { -@@ -258,7 +273,7 @@ +@@ -258,7 +274,7 @@ Vec3D vec3d1 = idragoncontroller.getFlyTargetLocation(); @@ -45,7 +46,7 @@ double d0 = vec3d1.x - this.getX(); double d1 = vec3d1.y - this.getY(); double d2 = vec3d1.z - this.getZ(); -@@ -399,7 +414,14 @@ +@@ -399,7 +415,14 @@ if (this.nearestCrystal.isRemoved()) { this.nearestCrystal = null; } else if (this.tickCount % 10 == 0 && this.getHealth() < this.getMaxHealth()) { @@ -61,7 +62,7 @@ } } -@@ -474,6 +496,9 @@ +@@ -474,6 +497,9 @@ int j1 = MathHelper.floor(axisalignedbb.maxZ); boolean flag = false; boolean flag1 = false; @@ -71,7 +72,7 @@ for (int k1 = i; k1 <= l; ++k1) { for (int l1 = j; l1 <= i1; ++l1) { -@@ -483,7 +508,11 @@ +@@ -483,7 +509,11 @@ if (!iblockdata.isAir() && !iblockdata.is(TagsBlock.DRAGON_TRANSPARENT)) { if (this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !iblockdata.is(TagsBlock.DRAGON_IMMUNE)) { @@ -84,7 +85,7 @@ } else { flag = true; } -@@ -492,6 +521,51 @@ +@@ -492,6 +522,51 @@ } } @@ -136,7 +137,16 @@ if (flag1) { BlockPosition blockposition1 = new BlockPosition(i + this.random.nextInt(l - i + 1), j + this.random.nextInt(i1 - j + 1), k + this.random.nextInt(j1 - k + 1)); -@@ -556,6 +630,21 @@ +@@ -547,7 +622,7 @@ + + @Override + public void kill() { +- this.remove(Entity.RemovalReason.KILLED); ++ this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause + this.gameEvent(GameEvent.ENTITY_DIE); + if (this.dragonFight != null) { + this.dragonFight.updateDragon(this); +@@ -556,6 +631,21 @@ } @@ -158,7 +168,7 @@ @Override protected void tickDeath() { if (this.dragonFight != null) { -@@ -571,15 +660,20 @@ +@@ -571,15 +661,20 @@ this.level().addParticle(Particles.EXPLOSION_EMITTER, this.getX() + (double) f, this.getY() + 2.0D + (double) f1, this.getZ() + (double) f2, 0.0D, 0.0D, 0.0D); } @@ -180,7 +190,7 @@ EntityExperienceOrb.award((WorldServer) this.level(), this.position(), MathHelper.floor((float) short0 * 0.08F)); } -@@ -590,7 +684,7 @@ +@@ -590,7 +685,7 @@ this.move(EnumMoveType.SELF, new Vec3D(0.0D, 0.10000000149011612D, 0.0D)); if (this.dragonDeathTime == 200 && this.level() instanceof WorldServer) { @@ -189,7 +199,16 @@ EntityExperienceOrb.award((WorldServer) this.level(), this.position(), MathHelper.floor((float) short0 * 0.2F)); } -@@ -811,6 +905,7 @@ +@@ -598,7 +693,7 @@ + this.dragonFight.setDragonKilled(this); + } + +- this.remove(Entity.RemovalReason.KILLED); ++ this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause + this.gameEvent(GameEvent.ENTITY_DIE); + } + +@@ -811,6 +906,7 @@ super.addAdditionalSaveData(nbttagcompound); nbttagcompound.putInt("DragonPhase", this.phaseManager.getCurrentPhase().getPhase().getId()); nbttagcompound.putInt("DragonDeathTime", this.dragonDeathTime); @@ -197,7 +216,7 @@ } @Override -@@ -824,6 +919,11 @@ +@@ -824,6 +920,11 @@ this.dragonDeathTime = nbttagcompound.getInt("DragonDeathTime"); } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/boss/enderdragon/phases/DragonControllerLandedFlame.patch b/paper-server/nms-patches/net/minecraft/world/entity/boss/enderdragon/phases/DragonControllerLandedFlame.patch new file mode 100644 index 0000000000..8718435f45 --- /dev/null +++ b/paper-server/nms-patches/net/minecraft/world/entity/boss/enderdragon/phases/DragonControllerLandedFlame.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/world/entity/boss/enderdragon/phases/DragonControllerLandedFlame.java ++++ b/net/minecraft/world/entity/boss/enderdragon/phases/DragonControllerLandedFlame.java +@@ -10,6 +10,10 @@ + import net.minecraft.world.entity.boss.enderdragon.EntityEnderDragon; + import net.minecraft.world.phys.Vec3D; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class DragonControllerLandedFlame extends AbstractDragonControllerLanded { + + private static final int FLAME_DURATION = 200; +@@ -99,7 +103,7 @@ + @Override + public void end() { + if (this.flame != null) { +- this.flame.discard(); ++ this.flame.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + this.flame = null; + } + diff --git a/paper-server/nms-patches/net/minecraft/world/entity/boss/wither/EntityWither.patch b/paper-server/nms-patches/net/minecraft/world/entity/boss/wither/EntityWither.patch index 8c4356d20e..2d683a0b57 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/boss/wither/EntityWither.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/boss/wither/EntityWither.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/boss/wither/EntityWither.java +++ b/net/minecraft/world/entity/boss/wither/EntityWither.java -@@ -55,6 +55,17 @@ +@@ -55,6 +55,18 @@ import net.minecraft.world.level.block.state.IBlockData; import net.minecraft.world.phys.Vec3D; @@ -11,6 +11,7 @@ +import net.minecraft.world.level.block.Blocks; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.EntityRegainHealthEvent; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.entity.ExplosionPrimeEvent; +// CraftBukkit end @@ -18,7 +19,7 @@ public class EntityWither extends EntityMonster implements PowerableMob, IRangedEntity { private static final DataWatcherObject DATA_TARGET_A = DataWatcher.defineId(EntityWither.class, DataWatcherRegistry.INT); -@@ -248,15 +259,40 @@ +@@ -248,15 +260,40 @@ i = this.getInvulnerableTicks() - 1; this.bossEvent.setProgress(1.0F - (float) i / 220.0F); if (i <= 0) { @@ -62,7 +63,7 @@ } } else { -@@ -301,6 +337,7 @@ +@@ -301,6 +338,7 @@ if (!list.isEmpty()) { EntityLiving entityliving1 = (EntityLiving) list.get(this.random.nextInt(list.size())); @@ -70,7 +71,7 @@ this.setAlternativeTarget(i, entityliving1.getId()); } } -@@ -331,6 +368,11 @@ +@@ -331,6 +369,11 @@ IBlockData iblockdata = this.level().getBlockState(blockposition); if (canDestroy(iblockdata)) { @@ -82,7 +83,7 @@ flag = this.level().destroyBlock(blockposition, true, this) || flag; } } -@@ -344,7 +386,7 @@ +@@ -344,7 +387,7 @@ } if (this.tickCount % 20 == 0) { @@ -91,3 +92,12 @@ } this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth()); +@@ -498,7 +541,7 @@ + @Override + public void checkDespawn() { + if (this.level().getDifficulty() == EnumDifficulty.PEACEFUL && this.shouldDespawnInPeaceful()) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } else { + this.noActionTime = 0; + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/decoration/EntityArmorStand.patch b/paper-server/nms-patches/net/minecraft/world/entity/decoration/EntityArmorStand.patch index a379f5ffa3..0f6906959b 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/decoration/EntityArmorStand.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/decoration/EntityArmorStand.patch @@ -1,10 +1,11 @@ --- a/net/minecraft/world/entity/decoration/EntityArmorStand.java +++ b/net/minecraft/world/entity/decoration/EntityArmorStand.java -@@ -44,6 +44,15 @@ +@@ -44,6 +44,16 @@ import net.minecraft.world.phys.AxisAlignedBB; import net.minecraft.world.phys.Vec3D; +// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.craftbukkit.CraftEquipmentSlot; +import org.bukkit.craftbukkit.inventory.CraftItemStack; @@ -16,7 +17,7 @@ public class EntityArmorStand extends EntityLiving { public static final int WOBBLE_TIME = 5; -@@ -106,6 +115,13 @@ +@@ -106,6 +116,13 @@ this.setPos(d0, d1, d2); } @@ -30,7 +31,7 @@ @Override public void refreshDimensions() { double d0 = this.getX(); -@@ -161,13 +177,20 @@ +@@ -161,13 +178,20 @@ @Override public void setItemSlot(EnumItemSlot enumitemslot, ItemStack itemstack) { @@ -53,7 +54,7 @@ } } -@@ -402,7 +425,25 @@ +@@ -402,7 +426,25 @@ return false; } else if (itemstack1.isEmpty() && (this.disabledSlots & 1 << enumitemslot.getFilterFlag() + 16) != 0) { return false; @@ -80,7 +81,7 @@ this.setItemSlot(enumitemslot, itemstack.copyWithCount(1)); return true; } else if (!itemstack.isEmpty() && itemstack.getCount() > 1) { -@@ -417,15 +458,26 @@ +@@ -417,15 +459,26 @@ entityhuman.setItemInHand(enumhand, itemstack1); return true; } @@ -108,16 +109,16 @@ if (damagesource.is(DamageTypeTags.IS_EXPLOSION)) { this.brokenByAnything(damagesource); this.kill(); -@@ -473,7 +525,7 @@ +@@ -473,7 +526,7 @@ } else { this.brokenByPlayer(damagesource); this.showBreakingParticles(); - this.kill(); -+ this.discard(); // CraftBukkit - SPIGOT-4890: remain as this.discard() since above damagesource method will call death event ++ this.discard(EntityRemoveEvent.Cause.DEATH); // CraftBukkit - SPIGOT-4890: remain as this.discard() since above damagesource method will call death event } return true; -@@ -541,13 +593,13 @@ +@@ -541,13 +594,13 @@ itemstack.setHoverName(this.getCustomName()); } @@ -133,7 +134,7 @@ ItemStack itemstack; int i; -@@ -555,7 +607,7 @@ +@@ -555,7 +608,7 @@ for (i = 0; i < this.handItems.size(); ++i) { itemstack = (ItemStack) this.handItems.get(i); if (!itemstack.isEmpty()) { @@ -142,7 +143,7 @@ this.handItems.set(i, ItemStack.EMPTY); } } -@@ -563,10 +615,11 @@ +@@ -563,10 +616,11 @@ for (i = 0; i < this.armorItems.size(); ++i) { itemstack = (ItemStack) this.armorItems.get(i); if (!itemstack.isEmpty()) { @@ -155,7 +156,7 @@ } -@@ -662,8 +715,16 @@ +@@ -662,9 +716,17 @@ return this.isSmall(); } @@ -168,7 +169,9 @@ + @Override public void kill() { +- this.remove(Entity.RemovalReason.KILLED); + org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, drops); // CraftBukkit - call event - this.remove(Entity.RemovalReason.KILLED); ++ this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause this.gameEvent(GameEvent.ENTITY_DIE); } + diff --git a/paper-server/nms-patches/net/minecraft/world/entity/decoration/EntityHanging.patch b/paper-server/nms-patches/net/minecraft/world/entity/decoration/EntityHanging.patch index 82589f5909..4c27214075 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/decoration/EntityHanging.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/decoration/EntityHanging.patch @@ -1,12 +1,13 @@ --- a/net/minecraft/world/entity/decoration/EntityHanging.java +++ b/net/minecraft/world/entity/decoration/EntityHanging.java -@@ -26,6 +26,13 @@ +@@ -26,6 +26,14 @@ import org.apache.commons.lang3.Validate; import org.slf4j.Logger; +// CraftBukkit start +import net.minecraft.tags.DamageTypeTags; +import org.bukkit.entity.Hanging; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.hanging.HangingBreakByEntityEvent; +import org.bukkit.event.hanging.HangingBreakEvent; +// CraftBukkit end @@ -14,7 +15,7 @@ public abstract class EntityHanging extends Entity { private static final Logger LOGGER = LogUtils.getLogger(); -@@ -60,26 +67,37 @@ +@@ -60,26 +68,37 @@ protected void recalculateBoundingBox() { if (this.direction != null) { @@ -65,7 +66,7 @@ d8 = 1.0D; } else { d6 = 1.0D; -@@ -88,11 +106,12 @@ +@@ -88,11 +107,12 @@ d6 /= 32.0D; d7 /= 32.0D; d8 /= 32.0D; @@ -80,10 +81,11 @@ return i % 32 == 0 ? 0.5D : 0.0D; } -@@ -103,6 +122,24 @@ +@@ -103,7 +123,25 @@ if (this.checkInterval++ == 100) { this.checkInterval = 0; if (!this.isRemoved() && !this.survives()) { +- this.discard(); + // CraftBukkit start - fire break events + IBlockData material = this.level().getBlockState(this.blockPosition()); + HangingBreakEvent.RemoveCause cause; @@ -102,10 +104,11 @@ + return; + } + // CraftBukkit end - this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause this.dropItem((Entity) null); } -@@ -166,6 +203,22 @@ + } +@@ -166,6 +204,22 @@ return false; } else { if (!this.isRemoved() && !this.level().isClientSide) { @@ -128,7 +131,7 @@ this.kill(); this.markHurt(); this.dropItem(damagesource.getEntity()); -@@ -178,6 +231,18 @@ +@@ -178,6 +232,18 @@ @Override public void move(EnumMoveType enummovetype, Vec3D vec3d) { if (!this.level().isClientSide && !this.isRemoved() && vec3d.lengthSqr() > 0.0D) { @@ -147,7 +150,7 @@ this.kill(); this.dropItem((Entity) null); } -@@ -186,13 +251,22 @@ +@@ -186,13 +252,22 @@ @Override public void push(double d0, double d1, double d2) { diff --git a/paper-server/nms-patches/net/minecraft/world/entity/decoration/EntityLeash.patch b/paper-server/nms-patches/net/minecraft/world/entity/decoration/EntityLeash.patch index e07f3e2b8b..02a9c4b3d5 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/decoration/EntityLeash.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/decoration/EntityLeash.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/decoration/EntityLeash.java +++ b/net/minecraft/world/entity/decoration/EntityLeash.java -@@ -26,6 +26,12 @@ +@@ -26,6 +26,13 @@ import net.minecraft.world.phys.AxisAlignedBB; import net.minecraft.world.phys.Vec3D; @@ -8,12 +8,13 @@ +import net.minecraft.network.protocol.game.PacketPlayOutAttachEntity; +import net.minecraft.server.level.EntityPlayer; +import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityRemoveEvent; +// CraftBukkit end + public class EntityLeash extends EntityHanging { public static final double OFFSET_Y = 0.375D; -@@ -96,6 +102,12 @@ +@@ -96,6 +103,12 @@ EntityInsentient entityinsentient = (EntityInsentient) iterator.next(); if (entityinsentient.getLeashHolder() == entityhuman) { @@ -26,7 +27,7 @@ entityinsentient.setLeashedTo(this, true); flag = true; } -@@ -104,18 +116,32 @@ +@@ -104,18 +117,32 @@ boolean flag1 = false; if (!flag) { @@ -56,7 +57,7 @@ } + // CraftBukkit start + if (die) { -+ this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause + } + // CraftBukkit end } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/item/EntityFallingBlock.patch b/paper-server/nms-patches/net/minecraft/world/entity/item/EntityFallingBlock.patch index 49cc457662..bf86a43753 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/item/EntityFallingBlock.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/item/EntityFallingBlock.patch @@ -1,17 +1,18 @@ --- a/net/minecraft/world/entity/item/EntityFallingBlock.java +++ b/net/minecraft/world/entity/item/EntityFallingBlock.java -@@ -49,6 +49,10 @@ +@@ -49,6 +49,11 @@ import net.minecraft.world.phys.Vec3D; import org.slf4j.Logger; +// CraftBukkit start; +import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityRemoveEvent; +// CraftBukkit end + public class EntityFallingBlock extends Entity { private static final Logger LOGGER = LogUtils.getLogger(); -@@ -83,10 +87,17 @@ +@@ -83,10 +88,17 @@ } public static EntityFallingBlock fall(World world, BlockPosition blockposition, IBlockData iblockdata) { @@ -30,16 +31,61 @@ return entityfallingblock; } -@@ -169,6 +180,12 @@ +@@ -121,7 +133,7 @@ + @Override + public void tick() { + if (this.blockState.isAir()) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } else { + Block block = this.blockState.getBlock(); + +@@ -152,7 +164,7 @@ + this.spawnAtLocation((IMaterial) block); + } + +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause + } + } else { + IBlockData iblockdata = this.level().getBlockState(blockposition); +@@ -169,9 +181,15 @@ this.blockState = (IBlockData) this.blockState.setValue(BlockProperties.WATERLOGGED, true); } + // CraftBukkit start + if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, this.blockState)) { -+ this.discard(); // SPIGOT-6586 called before the event in previous versions ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // SPIGOT-6586 called before the event in previous versions + return; + } + // CraftBukkit end if (this.level().setBlock(blockposition, this.blockState, 3)) { ((WorldServer) this.level()).getChunkSource().chunkMap.broadcast(this, new PacketPlayOutBlockChange(blockposition, this.level().getBlockState(blockposition))); - this.discard(); +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); + if (block instanceof Fallable) { + ((Fallable) block).onLand(this.level(), blockposition, this.blockState, iblockdata, this); + } +@@ -199,19 +217,19 @@ + } + } + } else if (this.dropItem && this.level().getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause + this.callOnBrokenAfterFall(block, blockposition); + this.spawnAtLocation((IMaterial) block); + } + } else { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause + if (this.dropItem && this.level().getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { + this.callOnBrokenAfterFall(block, blockposition); + this.spawnAtLocation((IMaterial) block); + } + } + } else { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + this.callOnBrokenAfterFall(block, blockposition); + } + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/item/EntityItem.patch b/paper-server/nms-patches/net/minecraft/world/entity/item/EntityItem.patch index 2960be8781..5b99a6716c 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/item/EntityItem.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/item/EntityItem.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/item/EntityItem.java +++ b/net/minecraft/world/entity/item/EntityItem.java -@@ -31,6 +31,14 @@ +@@ -31,6 +31,15 @@ import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.phys.Vec3D; @@ -9,13 +9,14 @@ +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityPickupItemEvent; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +// CraftBukkit end + public class EntityItem extends Entity implements TraceableEntity { private static final DataWatcherObject DATA_ITEM = DataWatcher.defineId(EntityItem.class, DataWatcherRegistry.ITEM_STACK); -@@ -47,6 +55,7 @@ +@@ -47,6 +56,7 @@ @Nullable public UUID target; public final float bobOffs; @@ -23,8 +24,12 @@ public EntityItem(EntityTypes entitytypes, World world) { super(entitytypes, world); -@@ -128,9 +137,12 @@ - this.discard(); +@@ -125,12 +135,15 @@ + @Override + public void tick() { + if (this.getItem().isEmpty()) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } else { super.tick(); - if (this.pickupDelay > 0 && this.pickupDelay != 32767) { @@ -39,7 +44,7 @@ this.xo = this.getX(); this.yo = this.getY(); -@@ -180,9 +192,11 @@ +@@ -180,9 +193,11 @@ this.mergeWithNeighbours(); } @@ -51,20 +56,22 @@ this.hasImpulse |= this.updateInWaterStateAndDoFluidPushing(); if (!this.level().isClientSide) { -@@ -194,6 +208,12 @@ +@@ -194,7 +209,13 @@ } if (!this.level().isClientSide && this.age >= 6000) { +- this.discard(); + // CraftBukkit start - fire ItemDespawnEvent + if (CraftEventFactory.callItemDespawnEvent(this).isCancelled()) { + this.age = 0; + return; + } + // CraftBukkit end - this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } -@@ -277,6 +297,11 @@ + } +@@ -277,11 +298,16 @@ } private static void merge(EntityItem entityitem, ItemStack itemstack, EntityItem entityitem1, ItemStack itemstack1) { @@ -76,7 +83,13 @@ merge(entityitem, itemstack, itemstack1); entityitem.pickupDelay = Math.max(entityitem.pickupDelay, entityitem1.pickupDelay); entityitem.age = Math.min(entityitem.age, entityitem1.age); -@@ -302,6 +327,11 @@ + if (itemstack1.isEmpty()) { +- entityitem1.discard(); ++ entityitem1.discard(EntityRemoveEvent.Cause.MERGE); // CraftBukkit - add Bukkit remove cause); + } + + } +@@ -302,12 +328,17 @@ } else if (this.level().isClientSide) { return true; } else { @@ -88,7 +101,23 @@ this.markHurt(); this.health = (int) ((float) this.health - f); this.gameEvent(GameEvent.ENTITY_DAMAGE, damagesource.getEntity()); -@@ -366,6 +396,46 @@ + if (this.health <= 0) { + this.getItem().onDestroyed(this); +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause + } + + return true; +@@ -354,7 +385,7 @@ + + this.setItem(ItemStack.of(nbttagcompound1)); + if (this.getItem().isEmpty()) { +- this.discard(); ++ this.discard(null); // CraftBukkit - add Bukkit remove cause + } + + } +@@ -366,10 +397,50 @@ Item item = itemstack.getItem(); int i = itemstack.getCount(); @@ -135,3 +164,8 @@ if (this.pickupDelay == 0 && (this.target == null || this.target.equals(entityhuman.getUUID())) && entityhuman.getInventory().add(itemstack)) { entityhuman.take(this, i); if (itemstack.isEmpty()) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + itemstack.setCount(i); + } + diff --git a/paper-server/nms-patches/net/minecraft/world/entity/item/EntityTNTPrimed.patch b/paper-server/nms-patches/net/minecraft/world/entity/item/EntityTNTPrimed.patch index 073f462bcf..50e4ac33e1 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/item/EntityTNTPrimed.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/item/EntityTNTPrimed.patch @@ -1,18 +1,19 @@ --- a/net/minecraft/world/entity/item/EntityTNTPrimed.java +++ b/net/minecraft/world/entity/item/EntityTNTPrimed.java -@@ -19,6 +19,11 @@ +@@ -19,6 +19,12 @@ import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.IBlockData; +// CraftBukkit start; +import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.entity.ExplosionPrimeEvent; +// CraftBukkit end + public class EntityTNTPrimed extends Entity implements TraceableEntity { private static final DataWatcherObject DATA_FUSE_ID = DataWatcher.defineId(EntityTNTPrimed.class, DataWatcherRegistry.INT); -@@ -28,6 +33,8 @@ +@@ -28,6 +34,8 @@ public static final String TAG_FUSE = "fuse"; @Nullable public EntityLiving owner; @@ -21,7 +22,7 @@ public EntityTNTPrimed(EntityTypes entitytypes, World world) { super(entitytypes, world); -@@ -79,10 +86,13 @@ +@@ -79,10 +87,13 @@ this.setFuse(i); if (i <= 0) { @@ -31,12 +32,12 @@ if (!this.level().isClientSide) { this.explode(); } -+ this.discard(); ++ this.discard(EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause + // CraftBukkit end } else { this.updateInWaterStateAndDoFluidPushing(); if (this.level().isClientSide) { -@@ -93,9 +103,14 @@ +@@ -93,9 +104,14 @@ } private void explode() { diff --git a/paper-server/nms-patches/net/minecraft/world/entity/monster/EntityCreeper.patch b/paper-server/nms-patches/net/minecraft/world/entity/monster/EntityCreeper.patch index 4a1e9252c6..670b3f2bb2 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/monster/EntityCreeper.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/monster/EntityCreeper.patch @@ -1,19 +1,20 @@ --- a/net/minecraft/world/entity/monster/EntityCreeper.java +++ b/net/minecraft/world/entity/monster/EntityCreeper.java -@@ -43,6 +43,12 @@ +@@ -43,6 +43,13 @@ import net.minecraft.world.level.World; import net.minecraft.world.level.gameevent.GameEvent; +// CraftBukkit start; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.entity.ExplosionPrimeEvent; +// CraftBukkit end + public class EntityCreeper extends EntityMonster implements PowerableMob { private static final DataWatcherObject DATA_SWELL_DIR = DataWatcher.defineId(EntityCreeper.class, DataWatcherRegistry.INT); -@@ -218,9 +224,20 @@ +@@ -218,9 +225,20 @@ @Override public void thunderHit(WorldServer worldserver, EntityLightning entitylightning) { super.thunderHit(worldserver, entitylightning); @@ -34,7 +35,7 @@ @Override protected EnumInteractionResult mobInteract(EntityHuman entityhuman, EnumHand enumhand) { ItemStack itemstack = entityhuman.getItemInHand(enumhand); -@@ -231,7 +248,7 @@ +@@ -231,7 +249,7 @@ this.level().playSound(entityhuman, this.getX(), this.getY(), this.getZ(), soundeffect, this.getSoundSource(), 1.0F, this.random.nextFloat() * 0.4F + 0.8F); if (!this.level().isClientSide) { this.ignite(); @@ -43,7 +44,7 @@ itemstack.shrink(1); } else { itemstack.hurtAndBreak(1, entityhuman, (entityhuman1) -> { -@@ -250,10 +267,19 @@ +@@ -250,10 +268,19 @@ if (!this.level().isClientSide) { float f = this.isPowered() ? 2.0F : 1.0F; @@ -53,8 +54,9 @@ + // CraftBukkit end this.dead = true; - this.level().explode(this, this.getX(), this.getY(), this.getZ(), (float) this.explosionRadius * f, World.a.MOB); +- this.discard(); + this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), World.a.MOB); // CraftBukkit - this.discard(); ++ this.discard(EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause this.spawnLingeringCloud(); + // CraftBukkit start + } else { @@ -64,7 +66,7 @@ } } -@@ -264,6 +290,7 @@ +@@ -264,6 +291,7 @@ if (!collection.isEmpty()) { EntityAreaEffectCloud entityareaeffectcloud = new EntityAreaEffectCloud(this.level(), this.getX(), this.getY(), this.getZ()); @@ -72,7 +74,7 @@ entityareaeffectcloud.setRadius(2.5F); entityareaeffectcloud.setRadiusOnUse(-0.5F); entityareaeffectcloud.setWaitTime(10); -@@ -277,7 +304,7 @@ +@@ -277,7 +305,7 @@ entityareaeffectcloud.addEffect(new MobEffect(mobeffect)); } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/monster/EntityEndermite.patch b/paper-server/nms-patches/net/minecraft/world/entity/monster/EntityEndermite.patch new file mode 100644 index 0000000000..e65dbc1ef4 --- /dev/null +++ b/paper-server/nms-patches/net/minecraft/world/entity/monster/EntityEndermite.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/world/entity/monster/EntityEndermite.java ++++ b/net/minecraft/world/entity/monster/EntityEndermite.java +@@ -29,6 +29,10 @@ + import net.minecraft.world.level.block.state.IBlockData; + import org.joml.Vector3f; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class EntityEndermite extends EntityMonster { + + private static final int MAX_LIFE = 2400; +@@ -122,7 +126,7 @@ + } + + if (this.life >= 2400) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } + } + diff --git a/paper-server/nms-patches/net/minecraft/world/entity/monster/EntityPillager.patch b/paper-server/nms-patches/net/minecraft/world/entity/monster/EntityPillager.patch new file mode 100644 index 0000000000..719f3af548 --- /dev/null +++ b/paper-server/nms-patches/net/minecraft/world/entity/monster/EntityPillager.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/world/entity/monster/EntityPillager.java ++++ b/net/minecraft/world/entity/monster/EntityPillager.java +@@ -51,6 +51,10 @@ + import net.minecraft.world.level.World; + import net.minecraft.world.level.WorldAccess; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class EntityPillager extends EntityIllagerAbstract implements ICrossbow, InventoryCarrier { + + private static final DataWatcherObject IS_CHARGING_CROSSBOW = DataWatcher.defineId(EntityPillager.class, DataWatcherRegistry.BOOLEAN); +@@ -213,7 +217,7 @@ + ItemStack itemstack1 = this.inventory.addItem(itemstack); + + if (itemstack1.isEmpty()) { +- entityitem.discard(); ++ entityitem.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + } else { + itemstack.setCount(itemstack1.getCount()); + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/monster/EntitySilverfish.patch b/paper-server/nms-patches/net/minecraft/world/entity/monster/EntitySilverfish.patch index d7e3c5aabf..8467a5fa91 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/monster/EntitySilverfish.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/monster/EntitySilverfish.patch @@ -1,17 +1,18 @@ --- a/net/minecraft/world/entity/monster/EntitySilverfish.java +++ b/net/minecraft/world/entity/monster/EntitySilverfish.java -@@ -34,6 +34,10 @@ +@@ -34,6 +34,11 @@ import net.minecraft.world.level.block.state.IBlockData; import org.joml.Vector3f; +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityRemoveEvent; +// CraftBukkit end + public class EntitySilverfish extends EntityMonster { @Nullable -@@ -176,6 +180,11 @@ +@@ -176,6 +181,11 @@ Block block = iblockdata.getBlock(); if (block instanceof BlockMonsterEggs) { @@ -23,7 +24,7 @@ if (world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { world.destroyBlock(blockposition1, true, this.silverfish); } else { -@@ -245,6 +254,11 @@ +@@ -245,9 +255,14 @@ IBlockData iblockdata = world.getBlockState(blockposition); if (BlockMonsterEggs.isCompatibleHostBlock(iblockdata)) { @@ -34,4 +35,8 @@ + // CraftBukkit end world.setBlock(blockposition, BlockMonsterEggs.infestedStateByHost(iblockdata), 3); this.mob.spawnAnim(); - this.mob.discard(); +- this.mob.discard(); ++ this.mob.discard(EntityRemoveEvent.Cause.ENTER_BLOCK); // CraftBukkit - add Bukkit remove cause + } + + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/monster/EntitySlime.patch b/paper-server/nms-patches/net/minecraft/world/entity/monster/EntitySlime.patch index 1c26a1f3a3..040b5403eb 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/monster/EntitySlime.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/monster/EntitySlime.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/EntitySlime.java +++ b/net/minecraft/world/entity/monster/EntitySlime.java -@@ -44,6 +44,14 @@ +@@ -44,6 +44,15 @@ import net.minecraft.world.phys.Vec3D; import org.joml.Vector3f; @@ -8,6 +8,7 @@ +import java.util.ArrayList; +import java.util.List; +import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.entity.EntityTransformEvent; +import org.bukkit.event.entity.SlimeSplitEvent; +// CraftBukkit end @@ -15,7 +16,7 @@ public class EntitySlime extends EntityInsentient implements IMonster { private static final DataWatcherObject ID_SIZE = DataWatcher.defineId(EntitySlime.class, DataWatcherRegistry.INT); -@@ -192,7 +200,7 @@ +@@ -192,11 +201,18 @@ @Override public EntityTypes getType() { @@ -24,7 +25,18 @@ } @Override -@@ -206,6 +214,19 @@ + public void remove(Entity.RemovalReason entity_removalreason) { ++ // CraftBukkit start - add Bukkit remove cause ++ this.remove(entity_removalreason, null); ++ } ++ ++ @Override ++ public void remove(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { ++ // CraftBukkit end + int i = this.getSize(); + + if (!this.level().isClientSide && i > 1 && this.isDeadOrDying()) { +@@ -206,6 +222,19 @@ int j = i / 2; int k = 2 + this.random.nextInt(3); @@ -35,7 +47,7 @@ + if (!event.isCancelled() && event.getCount() > 0) { + k = event.getCount(); + } else { -+ super.remove(entity_removalreason); ++ super.remove(entity_removalreason, cause); // CraftBukkit - add Bukkit remove cause + return; + } + List slimes = new ArrayList<>(j); @@ -44,7 +56,7 @@ for (int l = 0; l < k; ++l) { float f1 = ((float) (l % 2) - 0.5F) * f; float f2 = ((float) (l / 2) - 0.5F) * f; -@@ -221,9 +242,18 @@ +@@ -221,12 +250,21 @@ entityslime.setInvulnerable(this.isInvulnerable()); entityslime.setSize(j, true); entityslime.moveTo(this.getX() + (double) f1, this.getY() + 0.5D, this.getZ() + (double) f2, this.random.nextFloat() * 360.0F, 0.0F); @@ -54,7 +66,7 @@ } + // CraftBukkit start + if (CraftEventFactory.callEntityTransformEvent(this, slimes, EntityTransformEvent.TransformReason.SPLIT).isCancelled()) { -+ super.remove(entity_removalreason); ++ super.remove(entity_removalreason, cause); // CraftBukkit - add Bukkit remove cause + return; + } + for (EntityLiving living : slimes) { @@ -63,4 +75,8 @@ + // CraftBukkit end } - super.remove(entity_removalreason); +- super.remove(entity_removalreason); ++ super.remove(entity_removalreason, cause); // CraftBukkit - add Bukkit remove cause + } + + @Override diff --git a/paper-server/nms-patches/net/minecraft/world/entity/monster/piglin/PiglinAI.patch b/paper-server/nms-patches/net/minecraft/world/entity/monster/piglin/PiglinAI.patch index 78bc59e864..941d85899d 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/monster/piglin/PiglinAI.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/monster/piglin/PiglinAI.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/piglin/PiglinAI.java +++ b/net/minecraft/world/entity/monster/piglin/PiglinAI.java -@@ -74,6 +74,13 @@ +@@ -74,6 +74,14 @@ import net.minecraft.world.level.storage.loot.parameters.LootContextParameters; import net.minecraft.world.phys.Vec3D; @@ -8,13 +8,14 @@ +import java.util.stream.Collectors; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.entity.PiglinBarterEvent; +// CraftBukkit end + public class PiglinAI { public static final int REPELLENT_DETECTION_RANGE_HORIZONTAL = 8; -@@ -164,7 +171,8 @@ +@@ -164,7 +172,8 @@ } private static void initRideHoglinActivity(BehaviorController behaviorcontroller) { @@ -24,7 +25,7 @@ return true; }), 1)).build())), BehaviorStopRiding.create(8, PiglinAI::wantsToStopRiding)), MemoryModuleType.RIDE_TARGET); } -@@ -174,7 +182,7 @@ +@@ -174,7 +183,7 @@ } private static BehaviorGateSingle createIdleLookBehaviors() { @@ -33,7 +34,7 @@ } private static BehaviorGateSingle createIdleMovementBehaviors() { -@@ -195,13 +203,13 @@ +@@ -195,13 +204,13 @@ protected static void updateActivity(EntityPiglin entitypiglin) { BehaviorController behaviorcontroller = entitypiglin.getBrain(); @@ -50,7 +51,7 @@ Objects.requireNonNull(entitypiglin); optional.ifPresent(entitypiglin::playSoundEvent); -@@ -233,23 +241,27 @@ +@@ -233,23 +242,27 @@ stopWalking(entitypiglin); ItemStack itemstack; @@ -59,8 +60,9 @@ + if (entityitem.getItem().is(Items.GOLD_NUGGET) && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(entitypiglin, entityitem, 0, false).isCancelled()) { entitypiglin.take(entityitem, entityitem.getItem().getCount()); itemstack = entityitem.getItem(); - entityitem.discard(); +- entityitem.discard(); - } else { ++ entityitem.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + } else if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(entitypiglin, entityitem, entityitem.getItem().getCount() - 1, false).isCancelled()) { entitypiglin.take(entityitem, 1); itemstack = removeOneItemFromItemEntity(entityitem); @@ -82,7 +84,16 @@ if (!flag) { putInInventory(entitypiglin, itemstack); -@@ -285,9 +297,14 @@ +@@ -270,7 +283,7 @@ + ItemStack itemstack1 = itemstack.split(1); + + if (itemstack.isEmpty()) { +- entityitem.discard(); ++ entityitem.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + } else { + entityitem.setItem(itemstack); + } +@@ -285,9 +298,14 @@ boolean flag1; if (entitypiglin.isAdult()) { @@ -99,7 +110,7 @@ } else if (!flag1) { boolean flag2 = !entitypiglin.equipItemIfPossible(itemstack).isEmpty(); -@@ -300,7 +317,7 @@ +@@ -300,7 +318,7 @@ if (!flag1) { ItemStack itemstack1 = entitypiglin.getMainHandItem(); @@ -108,7 +119,7 @@ putInInventory(entitypiglin, itemstack1); } else { throwItems(entitypiglin, Collections.singletonList(itemstack1)); -@@ -377,7 +394,7 @@ +@@ -377,7 +395,7 @@ return false; } else if (isAdmiringDisabled(entitypiglin) && entitypiglin.getBrain().hasMemoryValue(MemoryModuleType.ATTACK_TARGET)) { return false; @@ -117,7 +128,7 @@ return isNotHoldingLovedItemInOffHand(entitypiglin); } else { boolean flag = entitypiglin.canAddToInventory(itemstack); -@@ -386,6 +403,12 @@ +@@ -386,6 +404,12 @@ } } @@ -130,7 +141,7 @@ protected static boolean isLovedItem(ItemStack itemstack) { return itemstack.is(TagsItem.PIGLIN_LOVED); } -@@ -481,7 +504,7 @@ +@@ -481,7 +505,7 @@ } protected static boolean canAdmire(EntityPiglin entitypiglin, ItemStack itemstack) { @@ -139,7 +150,7 @@ } protected static void wasHurtBy(EntityPiglin entitypiglin, EntityLiving entityliving) { -@@ -738,6 +761,12 @@ +@@ -738,6 +762,12 @@ return entitypiglin.getBrain().hasMemoryValue(MemoryModuleType.ADMIRING_ITEM); } @@ -152,7 +163,7 @@ private static boolean isBarterCurrency(ItemStack itemstack) { return itemstack.is(PiglinAI.BARTERING_ITEM); } -@@ -775,7 +804,7 @@ +@@ -775,7 +805,7 @@ } private static boolean isNotHoldingLovedItemInOffHand(EntityPiglin entitypiglin) { diff --git a/paper-server/nms-patches/net/minecraft/world/entity/npc/EntityVillager.patch b/paper-server/nms-patches/net/minecraft/world/entity/npc/EntityVillager.patch index 9e8c71fa85..d5da963e79 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/npc/EntityVillager.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/npc/EntityVillager.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/npc/EntityVillager.java +++ b/net/minecraft/world/entity/npc/EntityVillager.java -@@ -92,6 +92,14 @@ +@@ -92,6 +92,15 @@ import net.minecraft.world.phys.AxisAlignedBB; import org.slf4j.Logger; @@ -8,6 +8,7 @@ +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.entity.Villager; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.entity.EntityTransformEvent; +import org.bukkit.event.entity.VillagerReplenishTradeEvent; +// CraftBukkit end @@ -15,7 +16,7 @@ public class EntityVillager extends EntityVillagerAbstract implements ReputationHandler, VillagerDataHolder { private static final Logger LOGGER = LogUtils.getLogger(); -@@ -150,7 +158,7 @@ +@@ -150,7 +159,7 @@ @Override public BehaviorController getBrain() { @@ -24,7 +25,7 @@ } @Override -@@ -233,7 +241,7 @@ +@@ -233,7 +242,7 @@ this.increaseProfessionLevelOnUpdate = false; } @@ -33,7 +34,7 @@ } } -@@ -361,7 +369,13 @@ +@@ -361,7 +370,13 @@ while (iterator.hasNext()) { MerchantRecipe merchantrecipe = (MerchantRecipe) iterator.next(); @@ -48,7 +49,7 @@ } this.resendOffersToTradingPlayer(); -@@ -430,7 +444,13 @@ +@@ -430,7 +445,13 @@ while (iterator.hasNext()) { MerchantRecipe merchantrecipe = (MerchantRecipe) iterator.next(); @@ -63,7 +64,7 @@ } } -@@ -490,7 +510,7 @@ +@@ -490,7 +511,7 @@ @Override public void addAdditionalSaveData(NBTTagCompound nbttagcompound) { super.addAdditionalSaveData(nbttagcompound); @@ -72,7 +73,7 @@ Logger logger = EntityVillager.LOGGER; Objects.requireNonNull(logger); -@@ -834,7 +854,12 @@ +@@ -834,9 +855,14 @@ } entitywitch.setPersistenceRequired(); @@ -84,9 +85,12 @@ + worldserver.addFreshEntityWithPassengers(entitywitch, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); + // CraftBukkit end this.releaseAllPois(); - this.discard(); +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.TRANSFORMATION); // CraftBukkit - add Bukkit remove cause } else { -@@ -933,7 +958,7 @@ + super.thunderHit(worldserver, entitylightning); + } +@@ -933,7 +959,7 @@ }).limit(5L).collect(Collectors.toList()); if (list1.size() >= j) { @@ -95,7 +99,7 @@ list.forEach(SensorGolemLastSeen::golemDetected); } } -@@ -990,7 +1015,7 @@ +@@ -990,7 +1016,7 @@ @Override public void startSleeping(BlockPosition blockposition) { super.startSleeping(blockposition); @@ -104,7 +108,7 @@ this.brain.eraseMemory(MemoryModuleType.WALK_TARGET); this.brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE); } -@@ -998,7 +1023,7 @@ +@@ -998,7 +1024,7 @@ @Override public void stopSleeping() { super.stopSleeping(); diff --git a/paper-server/nms-patches/net/minecraft/world/entity/npc/EntityVillagerTrader.patch b/paper-server/nms-patches/net/minecraft/world/entity/npc/EntityVillagerTrader.patch index 13fa1f829d..5b5518d48b 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/npc/EntityVillagerTrader.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/npc/EntityVillagerTrader.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/npc/EntityVillagerTrader.java +++ b/net/minecraft/world/entity/npc/EntityVillagerTrader.java -@@ -47,6 +47,13 @@ +@@ -47,6 +47,14 @@ import net.minecraft.world.phys.Vec3D; import org.apache.commons.lang3.tuple.Pair; @@ -8,13 +8,14 @@ +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.inventory.CraftMerchantRecipe; +import org.bukkit.entity.AbstractVillager; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.entity.VillagerAcquireTradeEvent; +// CraftBukkit end + public class EntityVillagerTrader extends EntityVillagerAbstract { private static final int NUMBER_OF_TRADE_OFFERS = 5; -@@ -56,6 +63,7 @@ +@@ -56,6 +64,7 @@ public EntityVillagerTrader(EntityTypes entitytypes, World world) { super(entitytypes, world); @@ -22,7 +23,7 @@ } @Override -@@ -136,7 +144,16 @@ +@@ -136,7 +145,16 @@ MerchantRecipe merchantrecipe = villagertrades_imerchantrecipeoption.getOffer(this, this.random); if (merchantrecipe != null) { @@ -40,3 +41,12 @@ } } +@@ -244,7 +262,7 @@ + + private void maybeDespawn() { + if (this.despawnDelay > 0 && !this.isTrading() && --this.despawnDelay == 0) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } + + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/npc/InventoryCarrier.patch b/paper-server/nms-patches/net/minecraft/world/entity/npc/InventoryCarrier.patch index 977c925820..72b47a1d91 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/npc/InventoryCarrier.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/npc/InventoryCarrier.patch @@ -1,6 +1,17 @@ --- a/net/minecraft/world/entity/npc/InventoryCarrier.java +++ b/net/minecraft/world/entity/npc/InventoryCarrier.java -@@ -23,6 +23,13 @@ +@@ -6,6 +6,10 @@ + import net.minecraft.world.entity.item.EntityItem; + import net.minecraft.world.item.ItemStack; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public interface InventoryCarrier { + + String TAG_INVENTORY = "Inventory"; +@@ -23,13 +27,20 @@ return; } @@ -14,3 +25,11 @@ entityinsentient.onItemPickup(entityitem); int i = itemstack.getCount(); ItemStack itemstack1 = inventorysubcontainer.addItem(itemstack); + + entityinsentient.take(entityitem, i - itemstack1.getCount()); + if (itemstack1.isEmpty()) { +- entityitem.discard(); ++ entityitem.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + } else { + itemstack.setCount(itemstack1.getCount()); + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/player/EntityHuman.patch b/paper-server/nms-patches/net/minecraft/world/entity/player/EntityHuman.patch index 014413a3d7..4c164497b7 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/player/EntityHuman.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/player/EntityHuman.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/player/EntityHuman.java +++ b/net/minecraft/world/entity/player/EntityHuman.java -@@ -112,6 +112,21 @@ +@@ -112,6 +112,22 @@ import net.minecraft.world.scores.ScoreboardTeam; import org.slf4j.Logger; @@ -15,6 +15,7 @@ +import org.bukkit.event.entity.EntityCombustByEntityEvent; +import org.bukkit.event.entity.EntityExhaustionEvent; +import org.bukkit.event.entity.EntityKnockbackEvent; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerVelocityEvent; +// CraftBukkit end @@ -22,7 +23,7 @@ public abstract class EntityHuman extends EntityLiving { private static final Logger LOGGER = LogUtils.getLogger(); -@@ -127,7 +142,8 @@ +@@ -127,7 +143,8 @@ public static final float SWIMMING_BB_HEIGHT = 0.6F; public static final float DEFAULT_EYE_HEIGHT = 1.62F; public static final EntitySize STANDING_DIMENSIONS = EntitySize.scalable(0.6F, 1.8F); @@ -32,7 +33,7 @@ private static final DataWatcherObject DATA_PLAYER_ABSORPTION_ID = DataWatcher.defineId(EntityHuman.class, DataWatcherRegistry.FLOAT); private static final DataWatcherObject DATA_SCORE_ID = DataWatcher.defineId(EntityHuman.class, DataWatcherRegistry.INT); protected static final DataWatcherObject DATA_PLAYER_MODE_CUSTOMISATION = DataWatcher.defineId(EntityHuman.class, DataWatcherRegistry.BYTE); -@@ -136,10 +152,10 @@ +@@ -136,10 +153,10 @@ protected static final DataWatcherObject DATA_SHOULDER_RIGHT = DataWatcher.defineId(EntityHuman.class, DataWatcherRegistry.COMPOUND_TAG); private long timeEntitySatOnShoulder; private final PlayerInventory inventory = new PlayerInventory(this); @@ -45,7 +46,7 @@ protected int jumpTriggerTime; public float oBob; public float bob; -@@ -168,6 +184,16 @@ +@@ -168,6 +185,16 @@ public EntityFishingHook fishing; protected float hurtDir; @@ -62,7 +63,7 @@ public EntityHuman(World world, BlockPosition blockposition, float f, GameProfile gameprofile) { super(EntityTypes.PLAYER, world); this.lastItemInMainHand = ItemStack.EMPTY; -@@ -312,7 +338,7 @@ +@@ -312,7 +339,7 @@ ItemStack itemstack = this.getItemBySlot(EnumItemSlot.HEAD); if (itemstack.is(Items.TURTLE_HELMET) && !this.isEyeInFluid(TagsFluid.WATER)) { @@ -71,7 +72,7 @@ } } -@@ -482,8 +508,14 @@ +@@ -482,8 +509,14 @@ public void rideTick() { if (!this.level().isClientSide && this.wantsToStopRiding() && this.isPassenger()) { this.stopRiding(); @@ -88,7 +89,7 @@ super.rideTick(); this.oBob = this.bob; this.bob = 0.0F; -@@ -505,7 +537,8 @@ +@@ -505,7 +538,8 @@ if (this.level().getDifficulty() == EnumDifficulty.PEACEFUL && this.level().getGameRules().getBoolean(GameRules.RULE_NATURAL_REGENERATION)) { if (this.getHealth() < this.getMaxHealth() && this.tickCount % 20 == 0) { @@ -98,7 +99,7 @@ } if (this.foodData.needsFood() && this.tickCount % 10 == 0) { -@@ -665,6 +698,13 @@ +@@ -665,6 +699,13 @@ @Nullable public EntityItem drop(ItemStack itemstack, boolean flag, boolean flag1) { @@ -112,7 +113,7 @@ if (itemstack.isEmpty()) { return null; } else { -@@ -699,6 +739,33 @@ +@@ -699,6 +740,33 @@ entityitem.setDeltaMovement((double) (-f3 * f2 * 0.3F) + Math.cos((double) f5) * (double) f6, (double) (-f1 * 0.3F + 0.1F + (this.random.nextFloat() - this.random.nextFloat()) * 0.1F), (double) (f4 * f2 * 0.3F) + Math.sin((double) f5) * (double) f6); } @@ -146,7 +147,7 @@ return entityitem; } } -@@ -789,7 +856,7 @@ +@@ -789,7 +857,7 @@ } if (nbttagcompound.contains("LastDeathLocation", 10)) { @@ -155,7 +156,7 @@ Logger logger = EntityHuman.LOGGER; Objects.requireNonNull(logger); -@@ -822,7 +889,7 @@ +@@ -822,7 +890,7 @@ } this.getLastDeathLocation().flatMap((globalpos) -> { @@ -164,7 +165,7 @@ Logger logger = EntityHuman.LOGGER; Objects.requireNonNull(logger); -@@ -849,12 +916,12 @@ +@@ -849,12 +917,12 @@ return false; } else { if (!this.level().isClientSide) { @@ -179,7 +180,7 @@ } if (this.level().getDifficulty() == EnumDifficulty.EASY) { -@@ -866,7 +933,13 @@ +@@ -866,7 +934,13 @@ } } @@ -194,7 +195,7 @@ } } } -@@ -886,10 +959,29 @@ +@@ -886,10 +960,29 @@ } public boolean canHarmPlayer(EntityHuman entityhuman) { @@ -227,7 +228,7 @@ } @Override -@@ -931,8 +1023,13 @@ +@@ -931,8 +1024,13 @@ } } @@ -242,7 +243,7 @@ if (!this.isInvulnerableTo(damagesource)) { f = this.getDamageAfterArmorAbsorb(damagesource, f); f = this.getDamageAfterMagicAbsorb(damagesource, f); -@@ -947,7 +1044,7 @@ +@@ -947,7 +1045,7 @@ } if (f != 0.0F) { @@ -251,7 +252,7 @@ this.getCombatTracker().recordDamage(damagesource, f); this.setHealth(this.getHealth() - f); if (f < 3.4028235E37F) { -@@ -957,6 +1054,7 @@ +@@ -957,6 +1055,7 @@ this.gameEvent(GameEvent.ENTITY_DAMAGE); } } @@ -259,7 +260,7 @@ } @Override -@@ -1121,7 +1219,7 @@ +@@ -1121,7 +1220,7 @@ f *= 0.2F + f2 * f2 * 0.8F; f1 *= f2; @@ -268,7 +269,7 @@ if (f > 0.0F || f1 > 0.0F) { boolean flag = f2 > 0.9F; boolean flag1 = false; -@@ -1160,8 +1258,15 @@ +@@ -1160,8 +1259,15 @@ if (entity instanceof EntityLiving) { f3 = ((EntityLiving) entity).getHealth(); if (j > 0 && !entity.isOnFire()) { @@ -286,7 +287,7 @@ } } -@@ -1171,7 +1276,7 @@ +@@ -1171,7 +1277,7 @@ if (flag5) { if (i > 0) { if (entity instanceof EntityLiving) { @@ -295,7 +296,7 @@ } else { entity.push((double) (-MathHelper.sin(this.getYRot() * 0.017453292F) * (float) i * 0.5F), 0.1D, (double) (MathHelper.cos(this.getYRot() * 0.017453292F) * (float) i * 0.5F)); } -@@ -1189,8 +1294,11 @@ +@@ -1189,8 +1295,11 @@ EntityLiving entityliving = (EntityLiving) iterator.next(); if (entityliving != this && entityliving != entity && !this.isAlliedTo((Entity) entityliving) && (!(entityliving instanceof EntityArmorStand) || !((EntityArmorStand) entityliving).isMarker()) && this.distanceToSqr((Entity) entityliving) < 9.0D) { @@ -309,7 +310,7 @@ } } -@@ -1199,9 +1307,26 @@ +@@ -1199,9 +1308,26 @@ } if (entity instanceof EntityPlayer && entity.hurtMarked) { @@ -336,7 +337,7 @@ } if (flag2) { -@@ -1246,7 +1371,14 @@ +@@ -1246,7 +1372,14 @@ this.awardStat(StatisticList.DAMAGE_DEALT, Math.round(f5 * 10.0F)); if (j > 0) { @@ -352,7 +353,7 @@ } if (this.level() instanceof WorldServer && f5 > 2.0F) { -@@ -1256,12 +1388,17 @@ +@@ -1256,12 +1389,17 @@ } } @@ -371,7 +372,23 @@ } } -@@ -1338,6 +1475,12 @@ +@@ -1307,7 +1445,14 @@ + + @Override + public void remove(Entity.RemovalReason entity_removalreason) { +- super.remove(entity_removalreason); ++ // CraftBukkit start - add Bukkit remove cause ++ this.remove(entity_removalreason, null); ++ } ++ ++ @Override ++ public void remove(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { ++ super.remove(entity_removalreason, cause); ++ // CraftBukkit end + this.inventoryMenu.removed(this); + if (this.containerMenu != null && this.hasContainerOpen()) { + this.doCloseContainer(); +@@ -1338,6 +1483,12 @@ } public Either startSleepInBed(BlockPosition blockposition) { @@ -384,7 +401,7 @@ this.startSleeping(blockposition); this.sleepCounter = 0; return Either.right(Unit.INSTANCE); -@@ -1425,9 +1568,9 @@ +@@ -1425,9 +1576,9 @@ super.jumpFromGround(); this.awardStat(StatisticList.JUMP); if (this.isSprinting()) { @@ -396,7 +413,7 @@ } } -@@ -1454,7 +1597,11 @@ +@@ -1454,7 +1605,11 @@ this.setDeltaMovement(vec3d2.x, d0 * 0.6D, vec3d2.z); this.resetFallDistance(); @@ -409,7 +426,7 @@ } else { super.travel(vec3d); } -@@ -1507,12 +1654,24 @@ +@@ -1507,12 +1662,24 @@ } public void startFallFlying() { @@ -435,7 +452,7 @@ } @Override -@@ -1626,10 +1785,21 @@ +@@ -1626,10 +1793,21 @@ return this.experienceLevel >= 30 ? 112 + (this.experienceLevel - 30) * 9 : (this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2); } @@ -458,7 +475,7 @@ } } -@@ -1715,13 +1885,20 @@ +@@ -1715,13 +1893,20 @@ @Override public void setItemSlot(EnumItemSlot enumitemslot, ItemStack itemstack) { @@ -482,7 +499,7 @@ } } -@@ -1760,26 +1937,31 @@ +@@ -1760,26 +1945,31 @@ protected void removeEntitiesOnShoulder() { if (this.timeEntitySatOnShoulder + 20L < this.level().getGameTime()) { diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityArrow.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityArrow.patch index eef2007b80..af91f84c1d 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityArrow.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityArrow.patch @@ -1,19 +1,20 @@ --- a/net/minecraft/world/entity/projectile/EntityArrow.java +++ b/net/minecraft/world/entity/projectile/EntityArrow.java -@@ -47,6 +47,12 @@ +@@ -47,6 +47,13 @@ import net.minecraft.world.phys.Vec3D; import net.minecraft.world.phys.shapes.VoxelShape; +// CraftBukkit start +import net.minecraft.world.entity.item.EntityItem; +import org.bukkit.event.entity.EntityCombustByEntityEvent; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.player.PlayerPickupArrowEvent; +// CraftBukkit end + public abstract class EntityArrow extends IProjectile { private static final double ARROW_BASE_DAMAGE = 2.0D; -@@ -219,7 +225,7 @@ +@@ -219,7 +226,7 @@ } if (object != null && !flag) { @@ -22,7 +23,25 @@ this.hasImpulse = true; } -@@ -367,7 +373,13 @@ +@@ -304,7 +311,7 @@ + protected void tickDespawn() { + ++this.life; + if (this.life >= 1200) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } + + } +@@ -337,7 +344,7 @@ + } + + if (this.piercingIgnoreEntityIds.size() >= this.getPierceLevel() + 1) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause + return; + } + +@@ -367,7 +374,13 @@ boolean flag1 = entity.getType().is(TagsEntity.DEFLECTS_ARROWS); if (this.isOnFire() && !flag && !flag1) { @@ -37,7 +56,25 @@ } if (entity.hurt(damagesource, (float) i)) { -@@ -545,7 +557,22 @@ +@@ -418,7 +431,7 @@ + + this.playSound(this.soundEvent, 1.0F, 1.2F / (this.random.nextFloat() * 0.2F + 0.9F)); + if (this.getPierceLevel() <= 0) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause + } + } else if (flag1) { + this.deflect(); +@@ -432,7 +445,7 @@ + this.spawnAtLocation(this.getPickupItem(), 0.1F); + } + +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause + } + } + +@@ -545,9 +558,24 @@ @Override public void playerTouch(EntityHuman entityhuman) { if (!this.level().isClientSide && (this.inGround || this.isNoPhysics()) && this.shakeTime <= 0) { @@ -59,5 +96,8 @@ + if ((this.pickup == EntityArrow.PickupStatus.ALLOWED && entityhuman.getInventory().add(itemstack)) || (this.pickup == EntityArrow.PickupStatus.CREATIVE_ONLY && entityhuman.getAbilities().instabuild)) { + // CraftBukkit end entityhuman.take(this, 1); - this.discard(); +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause } + + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityDragonFireball.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityDragonFireball.patch new file mode 100644 index 0000000000..2f9cb64fa2 --- /dev/null +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityDragonFireball.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/world/entity/projectile/EntityDragonFireball.java ++++ b/net/minecraft/world/entity/projectile/EntityDragonFireball.java +@@ -15,6 +15,10 @@ + import net.minecraft.world.phys.MovingObjectPosition; + import net.minecraft.world.phys.MovingObjectPositionEntity; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class EntityDragonFireball extends EntityFireball { + + public static final float SPLASH_RANGE = 4.0F; +@@ -61,7 +65,7 @@ + + this.level().levelEvent(2006, this.blockPosition(), this.isSilent() ? -1 : 1); + this.level().addFreshEntity(entityareaeffectcloud); +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause + } + + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityEgg.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityEgg.patch index ba9188ddf6..c043d13187 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityEgg.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityEgg.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/EntityEgg.java +++ b/net/minecraft/world/entity/projectile/EntityEgg.java -@@ -11,6 +11,15 @@ +@@ -11,6 +11,16 @@ import net.minecraft.world.phys.MovingObjectPosition; import net.minecraft.world.phys.MovingObjectPositionEntity; @@ -10,13 +10,14 @@ +import org.bukkit.entity.Ageable; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.player.PlayerEggThrowEvent; +// CraftBukkit end + public class EntityEgg extends EntityProjectileThrowable { public EntityEgg(EntityTypes entitytypes, World world) { -@@ -47,20 +56,47 @@ +@@ -47,26 +57,53 @@ protected void onHit(MovingObjectPosition movingobjectposition) { super.onHit(movingobjectposition); if (!this.level().isClientSide) { @@ -69,3 +70,10 @@ } } } + + this.level().broadcastEntityEvent(this, (byte) 3); +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause + } + + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityEnderPearl.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityEnderPearl.patch index b417f20a77..2011a8d422 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityEnderPearl.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityEnderPearl.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/EntityEnderPearl.java +++ b/net/minecraft/world/entity/projectile/EntityEnderPearl.java -@@ -18,6 +18,13 @@ +@@ -18,6 +18,14 @@ import net.minecraft.world.phys.MovingObjectPosition; import net.minecraft.world.phys.MovingObjectPositionEntity; @@ -8,13 +8,14 @@ +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.CreatureSpawnEvent; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +// CraftBukkit end + public class EntityEnderPearl extends EntityProjectileThrowable { public EntityEnderPearl(EntityTypes entitytypes, World world) { -@@ -54,23 +61,34 @@ +@@ -54,23 +62,34 @@ EntityPlayer entityplayer = (EntityPlayer) entity; if (entityplayer.connection.isAcceptingMessages() && entityplayer.level() == this.level() && !entityplayer.isSleeping()) { @@ -62,7 +63,25 @@ this.level().playSound((EntityHuman) null, this.getX(), this.getY(), this.getZ(), SoundEffects.PLAYER_TELEPORT, SoundCategory.PLAYERS); } } else if (entity != null) { -@@ -100,7 +118,7 @@ +@@ -78,7 +97,7 @@ + entity.resetFallDistance(); + } + +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause + } + + } +@@ -88,7 +107,7 @@ + Entity entity = this.getOwner(); + + if (entity instanceof EntityPlayer && !entity.isAlive() && this.level().getGameRules().getBoolean(GameRules.RULE_ENDER_PEARLS_VANISH_ON_DEATH)) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } else { + super.tick(); + } +@@ -100,7 +119,7 @@ public Entity changeDimension(WorldServer worldserver) { Entity entity = this.getOwner(); diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityEnderSignal.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityEnderSignal.patch index 63b12f9cc6..33eec682ad 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityEnderSignal.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityEnderSignal.patch @@ -1,6 +1,17 @@ --- a/net/minecraft/world/entity/projectile/EntityEnderSignal.java +++ b/net/minecraft/world/entity/projectile/EntityEnderSignal.java -@@ -35,7 +35,7 @@ +@@ -16,6 +16,10 @@ + import net.minecraft.world.level.World; + import net.minecraft.world.phys.Vec3D; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class EntityEnderSignal extends Entity implements ItemSupplier { + + private static final DataWatcherObject DATA_ITEM_STACK = DataWatcher.defineId(EntityEnderSignal.class, DataWatcherRegistry.ITEM_STACK); +@@ -35,7 +39,7 @@ } public void setItem(ItemStack itemstack) { @@ -9,7 +20,16 @@ this.getEntityData().set(EntityEnderSignal.DATA_ITEM_STACK, itemstack.copyWithCount(1)); } -@@ -177,7 +177,7 @@ +@@ -150,7 +154,7 @@ + ++this.life; + if (this.life > 80 && !this.level().isClientSide) { + this.playSound(SoundEffects.ENDER_EYE_DEATH, 1.0F, 1.0F); +- this.discard(); ++ this.discard(this.surviveAfterDeath ? EntityRemoveEvent.Cause.DROP : EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + if (this.surviveAfterDeath) { + this.level().addFreshEntity(new EntityItem(this.level(), this.getX(), this.getY(), this.getZ(), this.getItem())); + } else { +@@ -177,7 +181,7 @@ public void readAdditionalSaveData(NBTTagCompound nbttagcompound) { ItemStack itemstack = ItemStack.of(nbttagcompound.getCompound("Item")); diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityEvokerFangs.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityEvokerFangs.patch index e0d2efa7a7..78ba4514e7 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityEvokerFangs.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityEvokerFangs.patch @@ -1,6 +1,26 @@ --- a/net/minecraft/world/entity/projectile/EntityEvokerFangs.java +++ b/net/minecraft/world/entity/projectile/EntityEvokerFangs.java -@@ -129,7 +129,7 @@ +@@ -14,6 +14,10 @@ + import net.minecraft.world.entity.TraceableEntity; + import net.minecraft.world.level.World; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class EntityEvokerFangs extends Entity implements TraceableEntity { + + public static final int ATTACK_DURATION = 20; +@@ -118,7 +122,7 @@ + } + + if (--this.lifeTicks < 0) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } + } + +@@ -129,7 +133,7 @@ if (entityliving.isAlive() && !entityliving.isInvulnerable() && entityliving != entityliving1) { if (entityliving1 == null) { diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityFireball.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityFireball.patch index 7642d2b0c7..8e5ab2cb4b 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityFireball.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityFireball.patch @@ -1,10 +1,13 @@ --- a/net/minecraft/world/entity/projectile/EntityFireball.java +++ b/net/minecraft/world/entity/projectile/EntityFireball.java -@@ -17,11 +17,15 @@ +@@ -17,11 +17,18 @@ import net.minecraft.world.phys.MovingObjectPosition; import net.minecraft.world.phys.Vec3D; -+import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end + public abstract class EntityFireball extends IProjectile { @@ -16,7 +19,7 @@ protected EntityFireball(EntityTypes entitytypes, World world) { super(entitytypes, world); -@@ -36,6 +40,12 @@ +@@ -36,6 +43,12 @@ this(entitytypes, world); this.moveTo(d0, d1, d2, this.getYRot(), this.getXRot()); this.reapplyPosition(); @@ -29,7 +32,16 @@ double d6 = Math.sqrt(d3 * d3 + d4 * d4 + d5 * d5); if (d6 != 0.0D) { -@@ -86,7 +96,13 @@ +@@ -76,7 +89,7 @@ + Entity entity = this.getOwner(); + + if (!this.level().isClientSide && (entity != null && entity.isRemoved() || !this.level().hasChunkAt(this.blockPosition()))) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } else { + super.tick(); + if (this.shouldBurn()) { +@@ -86,7 +99,13 @@ MovingObjectPosition movingobjectposition = ProjectileHelper.getHitResultOnMoveVector(this, this::canHitEntity, this.getClipType()); if (movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS) { @@ -44,7 +56,7 @@ } this.checkInsideBlocks(); -@@ -184,6 +200,11 @@ +@@ -184,6 +203,11 @@ if (entity != null) { if (!this.level().isClientSide) { diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityFireworks.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityFireworks.patch index d6e8ec263d..b8ee85381a 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityFireworks.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityFireworks.patch @@ -1,6 +1,17 @@ --- a/net/minecraft/world/entity/projectile/EntityFireworks.java +++ b/net/minecraft/world/entity/projectile/EntityFireworks.java -@@ -143,7 +143,7 @@ +@@ -28,6 +28,10 @@ + import net.minecraft.world.phys.MovingObjectPositionEntity; + import net.minecraft.world.phys.Vec3D; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class EntityFireworks extends IProjectile implements ItemSupplier { + + public static final DataWatcherObject DATA_ID_FIREWORKS_ITEM = DataWatcher.defineId(EntityFireworks.class, DataWatcherRegistry.ITEM_STACK); +@@ -143,7 +147,7 @@ MovingObjectPosition movingobjectposition = ProjectileHelper.getHitResultOnMoveVector(this, this::canHitEntity); if (!this.noPhysics) { @@ -9,7 +20,7 @@ this.hasImpulse = true; } -@@ -158,7 +158,11 @@ +@@ -158,7 +162,11 @@ } if (!this.level().isClientSide && this.life > this.lifetime) { @@ -22,7 +33,15 @@ } } -@@ -174,7 +178,11 @@ +@@ -167,14 +175,18 @@ + this.level().broadcastEntityEvent(this, (byte) 17); + this.gameEvent(GameEvent.EXPLODE, this.getOwner()); + this.dealExplosionDamage(); +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause + } + + @Override protected void onHitEntity(MovingObjectPositionEntity movingobjectpositionentity) { super.onHitEntity(movingobjectpositionentity); if (!this.level().isClientSide) { @@ -35,7 +54,7 @@ } } -@@ -184,7 +192,11 @@ +@@ -184,7 +196,11 @@ this.level().getBlockState(blockposition).entityInside(this.level(), blockposition, this); if (!this.level().isClientSide() && this.hasExplosion()) { diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityFishingHook.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityFishingHook.patch index 93a0601030..82382ba0a3 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityFishingHook.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityFishingHook.patch @@ -1,19 +1,20 @@ --- a/net/minecraft/world/entity/projectile/EntityFishingHook.java +++ b/net/minecraft/world/entity/projectile/EntityFishingHook.java -@@ -46,6 +46,12 @@ +@@ -46,6 +46,13 @@ import net.minecraft.world.phys.Vec3D; import org.slf4j.Logger; +// CraftBukkit start +import org.bukkit.entity.Player; +import org.bukkit.entity.FishHook; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.player.PlayerFishEvent; +// CraftBukkit end + public class EntityFishingHook extends IProjectile { private static final Logger LOGGER = LogUtils.getLogger(); -@@ -67,6 +73,18 @@ +@@ -67,6 +74,18 @@ private final int luck; private final int lureSpeed; @@ -32,7 +33,31 @@ private EntityFishingHook(EntityTypes entitytypes, World world, int i, int j) { super(entitytypes, world); this.syncronizedRandom = RandomSource.create(); -@@ -261,7 +279,7 @@ +@@ -147,12 +166,12 @@ + EntityHuman entityhuman = this.getPlayerOwner(); + + if (entityhuman == null) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } else if (this.level().isClientSide || !this.shouldStopFishing(entityhuman)) { + if (this.onGround()) { + ++this.life; + if (this.life >= 1200) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + return; + } + } else { +@@ -253,7 +272,7 @@ + if (!entityhuman.isRemoved() && entityhuman.isAlive() && (flag || flag1) && this.distanceToSqr((Entity) entityhuman) <= 1024.0D) { + return false; + } else { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + return true; + } + } +@@ -261,7 +280,7 @@ private void checkCollision() { MovingObjectPosition movingobjectposition = ProjectileHelper.getHitResultOnMoveVector(this, this::canHitEntity); @@ -41,7 +66,7 @@ } @Override -@@ -294,11 +312,11 @@ +@@ -294,11 +313,11 @@ int i = 1; BlockPosition blockposition1 = blockposition.above(); @@ -55,7 +80,7 @@ --i; } -@@ -308,6 +326,10 @@ +@@ -308,6 +327,10 @@ this.timeUntilLured = 0; this.timeUntilHooked = 0; this.getEntityData().set(EntityFishingHook.DATA_BITING, false); @@ -66,7 +91,7 @@ } } else { float f; -@@ -341,6 +363,13 @@ +@@ -341,6 +364,13 @@ worldserver.sendParticles(Particles.FISHING, d0, d1, d2, 0, (double) (-f4), 0.01D, (double) f3, 1.0D); } } else { @@ -80,7 +105,7 @@ this.playSound(SoundEffects.FISHING_BOBBER_SPLASH, 0.25F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); double d3 = this.getY() + 0.5D; -@@ -373,12 +402,16 @@ +@@ -373,12 +403,16 @@ } if (this.timeUntilLured <= 0) { @@ -101,7 +126,7 @@ } } -@@ -445,6 +478,14 @@ +@@ -445,6 +479,14 @@ int i = 0; if (this.hookedIn != null) { @@ -116,7 +141,7 @@ this.pullEntity(this.hookedIn); CriterionTriggers.FISHING_ROD_HOOKED.trigger((EntityPlayer) entityhuman, itemstack, this, Collections.emptyList()); this.level().broadcastEntityEvent(this, (byte) 31); -@@ -460,6 +501,15 @@ +@@ -460,6 +502,15 @@ while (iterator.hasNext()) { ItemStack itemstack1 = (ItemStack) iterator.next(); EntityItem entityitem = new EntityItem(this.level(), this.getX(), this.getY(), this.getZ(), itemstack1); @@ -132,7 +157,7 @@ double d0 = entityhuman.getX() - this.getX(); double d1 = entityhuman.getY() - this.getY(); double d2 = entityhuman.getZ() - this.getZ(); -@@ -467,7 +517,11 @@ +@@ -467,7 +518,11 @@ entityitem.setDeltaMovement(d0 * 0.1D, d1 * 0.1D + Math.sqrt(Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2)) * 0.08D, d2 * 0.1D); this.level().addFreshEntity(entityitem); @@ -145,7 +170,7 @@ if (itemstack1.is(TagsItem.FISHES)) { entityhuman.awardStat(StatisticList.FISH_CAUGHT, 1); } -@@ -477,8 +531,25 @@ +@@ -477,10 +532,27 @@ } if (this.onGround()) { @@ -169,5 +194,25 @@ + } + // CraftBukkit end - this.discard(); +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause return i; + } else { + return 0; +@@ -513,8 +585,15 @@ + + @Override + public void remove(Entity.RemovalReason entity_removalreason) { ++ // CraftBukkit start - add Bukkit remove cause ++ this.remove(entity_removalreason, null); ++ } ++ ++ @Override ++ public void remove(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { ++ // CraftBukkit end + this.updateOwnerInfo((EntityFishingHook) null); +- super.remove(entity_removalreason); ++ super.remove(entity_removalreason, cause); // CraftBukkit - add Bukkit remove cause + } + + @Override diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityLargeFireball.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityLargeFireball.patch index 3a8815f46c..897eb439af 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityLargeFireball.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityLargeFireball.patch @@ -1,10 +1,13 @@ --- a/net/minecraft/world/entity/projectile/EntityLargeFireball.java +++ b/net/minecraft/world/entity/projectile/EntityLargeFireball.java -@@ -9,17 +9,21 @@ +@@ -9,17 +9,24 @@ import net.minecraft.world.phys.MovingObjectPosition; import net.minecraft.world.phys.MovingObjectPositionEntity; -+import org.bukkit.event.entity.ExplosionPrimeEvent; // CraftBukkit ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++import org.bukkit.event.entity.ExplosionPrimeEvent; ++// CraftBukkit end + public class EntityLargeFireball extends EntityFireballFireball { @@ -22,11 +25,12 @@ } @Override -@@ -28,7 +32,15 @@ +@@ -28,8 +35,16 @@ if (!this.level().isClientSide) { boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); - this.level().explode(this, this.getX(), this.getY(), this.getZ(), (float) this.explosionPower, flag, World.a.MOB); +- this.discard(); + // CraftBukkit start - fire ExplosionPrimeEvent + ExplosionPrimeEvent event = new ExplosionPrimeEvent((org.bukkit.entity.Explosive) this.getBukkitEntity()); + this.level().getCraftServer().getPluginManager().callEvent(event); @@ -36,10 +40,11 @@ + this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), World.a.MOB); + } + // CraftBukkit end - this.discard(); ++ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause } -@@ -59,7 +71,8 @@ + } +@@ -59,7 +74,8 @@ public void readAdditionalSaveData(NBTTagCompound nbttagcompound) { super.readAdditionalSaveData(nbttagcompound); if (nbttagcompound.contains("ExplosionPower", 99)) { diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityLlamaSpit.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityLlamaSpit.patch index 408aa43d97..95397a3d48 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityLlamaSpit.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityLlamaSpit.patch @@ -1,6 +1,17 @@ --- a/net/minecraft/world/entity/projectile/EntityLlamaSpit.java +++ b/net/minecraft/world/entity/projectile/EntityLlamaSpit.java -@@ -32,7 +32,7 @@ +@@ -14,6 +14,10 @@ + import net.minecraft.world.phys.MovingObjectPositionEntity; + import net.minecraft.world.phys.Vec3D; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class EntityLlamaSpit extends IProjectile { + + public EntityLlamaSpit(EntityTypes entitytypes, World world) { +@@ -32,7 +36,7 @@ Vec3D vec3d = this.getDeltaMovement(); MovingObjectPosition movingobjectposition = ProjectileHelper.getHitResultOnMoveVector(this, this::canHitEntity); @@ -9,3 +20,24 @@ double d0 = this.getX() + vec3d.x; double d1 = this.getY() + vec3d.y; double d2 = this.getZ() + vec3d.z; +@@ -42,9 +46,9 @@ + float f1 = 0.06F; + + if (this.level().getBlockStates(this.getBoundingBox()).noneMatch(BlockBase.BlockData::isAir)) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } else if (this.isInWaterOrBubble()) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } else { + this.setDeltaMovement(vec3d.scale(0.9900000095367432D)); + if (!this.isNoGravity()) { +@@ -72,7 +76,7 @@ + protected void onHitBlock(MovingObjectPositionBlock movingobjectpositionblock) { + super.onHitBlock(movingobjectpositionblock); + if (!this.level().isClientSide) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause + } + + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityPotion.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityPotion.patch index a6087a3bc0..d9357b2373 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityPotion.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityPotion.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/EntityPotion.java +++ b/net/minecraft/world/entity/projectile/EntityPotion.java -@@ -31,6 +31,17 @@ +@@ -31,6 +31,18 @@ import net.minecraft.world.phys.MovingObjectPositionBlock; import net.minecraft.world.phys.MovingObjectPositionEntity; @@ -13,12 +13,13 @@ +import org.bukkit.craftbukkit.entity.CraftLivingEntity; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.entity.LivingEntity; ++import org.bukkit.event.entity.EntityRemoveEvent; +// CraftBukkit end + public class EntityPotion extends EntityProjectileThrowable implements ItemSupplier { public static final double SPLASH_RANGE = 4.0D; -@@ -99,11 +110,11 @@ +@@ -99,18 +111,18 @@ if (flag) { this.applyWater(); @@ -33,7 +34,15 @@ } } -@@ -145,9 +156,10 @@ + int i = potionregistry.hasInstantEffects() ? 2007 : 2002; + + this.level().levelEvent(i, this.blockPosition(), PotionUtil.getColor(itemstack)); +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause + } + } + +@@ -145,9 +157,10 @@ } @@ -45,7 +54,7 @@ if (!list1.isEmpty()) { Entity entity1 = this.getEffectSource(); -@@ -168,24 +180,49 @@ +@@ -168,24 +181,49 @@ d1 = 1.0D - Math.sqrt(d0) / 4.0D; } @@ -110,7 +119,7 @@ } } } -@@ -194,7 +231,7 @@ +@@ -194,7 +232,7 @@ } @@ -119,7 +128,7 @@ EntityAreaEffectCloud entityareaeffectcloud = new EntityAreaEffectCloud(this.level(), this.getX(), this.getY(), this.getZ()); Entity entity = this.getOwner(); -@@ -221,7 +258,14 @@ +@@ -221,7 +259,14 @@ entityareaeffectcloud.setFixedColor(nbttagcompound.getInt("CustomPotionColor")); } @@ -129,13 +138,13 @@ + if (!(event.isCancelled() || entityareaeffectcloud.isRemoved())) { + this.level().addFreshEntity(entityareaeffectcloud); + } else { -+ entityareaeffectcloud.discard(); ++ entityareaeffectcloud.discard(null); // CraftBukkit - add Bukkit remove cause + } + // CraftBukkit end } public boolean isLingering() { -@@ -232,13 +276,25 @@ +@@ -232,13 +277,25 @@ IBlockData iblockdata = this.level().getBlockState(blockposition); if (iblockdata.is(TagsBlock.FIRE)) { diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityShulkerBullet.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityShulkerBullet.patch index cdcf10b224..f96d664a88 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityShulkerBullet.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityShulkerBullet.patch @@ -1,6 +1,17 @@ --- a/net/minecraft/world/entity/projectile/EntityShulkerBullet.java +++ b/net/minecraft/world/entity/projectile/EntityShulkerBullet.java -@@ -60,7 +60,20 @@ +@@ -29,6 +29,10 @@ + import net.minecraft.world.phys.MovingObjectPositionEntity; + import net.minecraft.world.phys.Vec3D; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class EntityShulkerBullet extends IProjectile { + + private static final double SPEED = 0.15D; +@@ -60,8 +64,21 @@ this.finalTarget = entity; this.currentMoveDirection = EnumDirection.UP; this.selectNextMoveDirection(enumdirection_enumaxis); @@ -10,18 +21,28 @@ + // CraftBukkit start + public Entity getTarget() { + return this.finalTarget; -+ } -+ + } + + public void setTarget(Entity e) { + this.finalTarget = e; + this.currentMoveDirection = EnumDirection.UP; + this.selectNextMoveDirection(EnumDirection.EnumAxis.X); - } ++ } + // CraftBukkit end - ++ @Override public SoundCategory getSoundSource() { -@@ -225,7 +238,7 @@ + return SoundCategory.HOSTILE; +@@ -194,7 +211,7 @@ + @Override + public void checkDespawn() { + if (this.level().getDifficulty() == EnumDifficulty.PEACEFUL) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause + } + + } +@@ -225,7 +242,7 @@ MovingObjectPosition movingobjectposition = ProjectileHelper.getHitResultOnMoveVector(this, this::canHitEntity); if (movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.MISS) { @@ -30,7 +51,7 @@ } } -@@ -294,7 +307,7 @@ +@@ -294,7 +311,7 @@ if (entity instanceof EntityLiving) { EntityLiving entityliving1 = (EntityLiving) entity; @@ -39,7 +60,30 @@ } } -@@ -325,6 +338,11 @@ +@@ -308,14 +325,20 @@ + } + + private void destroy() { +- this.discard(); ++ // CraftBukkit start - add Bukkit remove cause ++ this.destroy(null); ++ } ++ ++ private void destroy(EntityRemoveEvent.Cause cause) { ++ this.discard(cause); ++ // CraftBukkit end + this.level().gameEvent(GameEvent.ENTITY_DAMAGE, this.position(), GameEvent.a.of((Entity) this)); + } + + @Override + protected void onHit(MovingObjectPosition movingobjectposition) { + super.onHit(movingobjectposition); +- this.destroy(); ++ this.destroy(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause + } + + @Override +@@ -325,10 +348,15 @@ @Override public boolean hurt(DamageSource damagesource, float f) { @@ -51,3 +95,8 @@ if (!this.level().isClientSide) { this.playSound(SoundEffects.SHULKER_BULLET_HURT, 1.0F, 1.0F); ((WorldServer) this.level()).sendParticles(Particles.CRIT, this.getX(), this.getY(), this.getZ(), 15, 0.2D, 0.2D, 0.2D, 0.0D); +- this.destroy(); ++ this.destroy(EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause + } + + return true; diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntitySmallFireball.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntitySmallFireball.patch index d193a82795..b20b84cf77 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntitySmallFireball.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntitySmallFireball.patch @@ -1,15 +1,18 @@ --- a/net/minecraft/world/entity/projectile/EntitySmallFireball.java +++ b/net/minecraft/world/entity/projectile/EntitySmallFireball.java -@@ -13,6 +13,8 @@ +@@ -13,6 +13,11 @@ import net.minecraft.world.phys.MovingObjectPositionBlock; import net.minecraft.world.phys.MovingObjectPositionEntity; -+import org.bukkit.event.entity.EntityCombustByEntityEvent; // CraftBukkit ++// CraftBukkit start ++import org.bukkit.event.entity.EntityCombustByEntityEvent; ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end + public class EntitySmallFireball extends EntityFireballFireball { public EntitySmallFireball(EntityTypes entitytypes, World world) { -@@ -21,6 +23,11 @@ +@@ -21,6 +26,11 @@ public EntitySmallFireball(World world, EntityLiving entityliving, double d0, double d1, double d2) { super(EntityTypes.SMALL_FIREBALL, entityliving, d0, d1, d2, world); @@ -21,7 +24,7 @@ } public EntitySmallFireball(World world, double d0, double d1, double d2, double d3, double d4, double d5) { -@@ -35,7 +42,14 @@ +@@ -35,7 +45,14 @@ Entity entity1 = this.getOwner(); int i = entity.getRemainingFireTicks(); @@ -37,7 +40,7 @@ if (!entity.hurt(this.damageSources().fireball(this, entity1), 5.0F)) { entity.setRemainingFireTicks(i); } else if (entity1 instanceof EntityLiving) { -@@ -51,10 +65,10 @@ +@@ -51,10 +68,10 @@ if (!this.level().isClientSide) { Entity entity = this.getOwner(); @@ -50,3 +53,12 @@ this.level().setBlockAndUpdate(blockposition, BlockFireAbstract.getState(this.level(), blockposition)); } } +@@ -66,7 +83,7 @@ + protected void onHit(MovingObjectPosition movingobjectposition) { + super.onHit(movingobjectposition); + if (!this.level().isClientSide) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause + } + + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntitySnowball.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntitySnowball.patch new file mode 100644 index 0000000000..e4596932fa --- /dev/null +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntitySnowball.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/world/entity/projectile/EntitySnowball.java ++++ b/net/minecraft/world/entity/projectile/EntitySnowball.java +@@ -14,6 +14,10 @@ + import net.minecraft.world.phys.MovingObjectPosition; + import net.minecraft.world.phys.MovingObjectPositionEntity; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class EntitySnowball extends EntityProjectileThrowable { + + public EntitySnowball(EntityTypes entitytypes, World world) { +@@ -65,7 +69,7 @@ + super.onHit(movingobjectposition); + if (!this.level().isClientSide) { + this.level().broadcastEntityEvent(this, (byte) 3); +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause + } + + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityThrownExpBottle.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityThrownExpBottle.patch index 4d2228fa51..457d72d219 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityThrownExpBottle.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityThrownExpBottle.patch @@ -1,6 +1,17 @@ --- a/net/minecraft/world/entity/projectile/EntityThrownExpBottle.java +++ b/net/minecraft/world/entity/projectile/EntityThrownExpBottle.java -@@ -39,9 +39,18 @@ +@@ -11,6 +11,10 @@ + import net.minecraft.world.level.World; + import net.minecraft.world.phys.MovingObjectPosition; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class EntityThrownExpBottle extends EntityProjectileThrowable { + + public EntityThrownExpBottle(EntityTypes entitytypes, World world) { +@@ -39,11 +43,20 @@ protected void onHit(MovingObjectPosition movingobjectposition) { super.onHit(movingobjectposition); if (this.level() instanceof WorldServer) { @@ -18,5 +29,8 @@ + // CraftBukkit end + EntityExperienceOrb.award((WorldServer) this.level(), this.position(), i); - this.discard(); +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause } + + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityThrownTrident.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityThrownTrident.patch index fac6f2e3ab..3b9dbb04fb 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityThrownTrident.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityThrownTrident.patch @@ -1,6 +1,26 @@ --- a/net/minecraft/world/entity/projectile/EntityThrownTrident.java +++ b/net/minecraft/world/entity/projectile/EntityThrownTrident.java -@@ -153,7 +153,7 @@ +@@ -24,6 +24,10 @@ + import net.minecraft.world.phys.MovingObjectPositionEntity; + import net.minecraft.world.phys.Vec3D; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class EntityThrownTrident extends EntityArrow { + + private static final DataWatcherObject ID_LOYALTY = DataWatcher.defineId(EntityThrownTrident.class, DataWatcherRegistry.BYTE); +@@ -64,7 +68,7 @@ + this.spawnAtLocation(this.getPickupItem(), 0.1F); + } + +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause + } else { + this.setNoPhysics(true); + Vec3D vec3d = entity.getEyePosition().subtract(this.position()); +@@ -153,7 +157,7 @@ if (entitylightning != null) { entitylightning.moveTo(Vec3D.atBottomCenterOf(blockposition)); entitylightning.setCause(entity1 instanceof EntityPlayer ? (EntityPlayer) entity1 : null); diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityWitherSkull.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityWitherSkull.patch index 0554cccc02..83d1ec1953 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityWitherSkull.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/EntityWitherSkull.patch @@ -1,17 +1,18 @@ --- a/net/minecraft/world/entity/projectile/EntityWitherSkull.java +++ b/net/minecraft/world/entity/projectile/EntityWitherSkull.java -@@ -21,6 +21,10 @@ +@@ -21,6 +21,11 @@ import net.minecraft.world.phys.MovingObjectPosition; import net.minecraft.world.phys.MovingObjectPositionEntity; +// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.entity.ExplosionPrimeEvent; +// CraftBukkit end + public class EntityWitherSkull extends EntityFireball { private static final DataWatcherObject DATA_DANGEROUS = DataWatcher.defineId(EntityWitherSkull.class, DataWatcherRegistry.BOOLEAN); -@@ -64,7 +68,7 @@ +@@ -64,7 +69,7 @@ if (entity.isAlive()) { this.doEnchantDamageEffects(entityliving, entity); } else { @@ -20,7 +21,7 @@ } } } else { -@@ -82,7 +86,7 @@ +@@ -82,7 +87,7 @@ } if (b0 > 0) { @@ -29,11 +30,12 @@ } } -@@ -93,7 +97,15 @@ +@@ -93,8 +98,16 @@ protected void onHit(MovingObjectPosition movingobjectposition) { super.onHit(movingobjectposition); if (!this.level().isClientSide) { - this.level().explode(this, this.getX(), this.getY(), this.getZ(), 1.0F, false, World.a.MOB); +- this.discard(); + // CraftBukkit start + // this.level().explode(this, this.getX(), this.getY(), this.getZ(), 1.0F, false, World.a.MOB); + ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 1.0F, false); @@ -43,6 +45,7 @@ + this.level().explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), World.a.MOB); + } + // CraftBukkit end - this.discard(); ++ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause } + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/projectile/WindCharge.patch b/paper-server/nms-patches/net/minecraft/world/entity/projectile/WindCharge.patch index 036fa3fec3..3c90e4702b 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/projectile/WindCharge.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/projectile/WindCharge.patch @@ -1,6 +1,17 @@ --- a/net/minecraft/world/entity/projectile/WindCharge.java +++ b/net/minecraft/world/entity/projectile/WindCharge.java -@@ -81,7 +81,7 @@ +@@ -22,6 +22,10 @@ + import net.minecraft.world.phys.MovingObjectPositionBlock; + import net.minecraft.world.phys.MovingObjectPositionEntity; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class WindCharge extends EntityFireball implements ItemSupplier { + + public static final WindCharge.a EXPLOSION_DAMAGE_CALCULATOR = new WindCharge.a(); +@@ -81,7 +85,7 @@ } } @@ -9,3 +20,20 @@ this.level().explode(this, (DamageSource) null, WindCharge.EXPLOSION_DAMAGE_CALCULATOR, this.getX(), this.getY(), this.getZ(), (float) (3.0D + this.random.nextDouble()), false, World.a.BLOW, Particles.GUST, Particles.GUST_EMITTER, SoundEffects.WIND_BURST); } +@@ -89,14 +93,14 @@ + protected void onHitBlock(MovingObjectPositionBlock movingobjectpositionblock) { + super.onHitBlock(movingobjectpositionblock); + this.explode(); +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause + } + + @Override + protected void onHit(MovingObjectPosition movingobjectposition) { + super.onHit(movingobjectposition); + if (!this.level().isClientSide) { +- this.discard(); ++ this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause + } + + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/raid/EntityRaider.patch b/paper-server/nms-patches/net/minecraft/world/entity/raid/EntityRaider.patch index a54568be33..f297e570a8 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/raid/EntityRaider.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/raid/EntityRaider.patch @@ -1,6 +1,17 @@ --- a/net/minecraft/world/entity/raid/EntityRaider.java +++ b/net/minecraft/world/entity/raid/EntityRaider.java -@@ -165,7 +165,7 @@ +@@ -43,6 +43,10 @@ + import net.minecraft.world.level.WorldAccess; + import net.minecraft.world.phys.Vec3D; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public abstract class EntityRaider extends EntityMonsterPatrolling { + + protected static final DataWatcherObject IS_CELEBRATING = DataWatcher.defineId(EntityRaider.class, DataWatcherRegistry.BOOLEAN); +@@ -165,7 +169,7 @@ MobEffect mobeffect1 = new MobEffect(MobEffects.BAD_OMEN, 120000, i, false, false, true); if (!this.level().getGameRules().getBoolean(GameRules.RULE_DISABLE_RAIDS)) { @@ -9,7 +20,16 @@ } } } -@@ -305,7 +305,7 @@ +@@ -256,7 +260,7 @@ + this.onItemPickup(entityitem); + this.setItemSlot(enumitemslot, itemstack); + this.take(entityitem, itemstack.getCount()); +- entityitem.discard(); ++ entityitem.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + this.getCurrentRaid().setLeader(this.getWave(), this); + this.setPatrolLeader(true); + } else { +@@ -305,7 +309,7 @@ private final T mob; @@ -18,7 +38,7 @@ this.mob = entityraider; this.setFlags(EnumSet.of(PathfinderGoal.Type.MOVE)); } -@@ -521,7 +521,7 @@ +@@ -521,7 +525,7 @@ while (iterator.hasNext()) { EntityRaider entityraider = (EntityRaider) iterator.next(); @@ -27,7 +47,7 @@ } } -@@ -538,7 +538,7 @@ +@@ -538,7 +542,7 @@ while (iterator.hasNext()) { EntityRaider entityraider = (EntityRaider) iterator.next(); diff --git a/paper-server/nms-patches/net/minecraft/world/entity/vehicle/ChestBoat.patch b/paper-server/nms-patches/net/minecraft/world/entity/vehicle/ChestBoat.patch index fa8f1a63b7..37a9d9b1cd 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/vehicle/ChestBoat.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/vehicle/ChestBoat.patch @@ -1,20 +1,42 @@ --- a/net/minecraft/world/entity/vehicle/ChestBoat.java +++ b/net/minecraft/world/entity/vehicle/ChestBoat.java -@@ -23,6 +23,13 @@ - import net.minecraft.world.item.Items; +@@ -24,6 +24,15 @@ import net.minecraft.world.level.World; import net.minecraft.world.level.gameevent.GameEvent; + +// CraftBukkit start +import java.util.List; +import org.bukkit.Location; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.inventory.InventoryHolder; +// CraftBukkit end - ++ public class ChestBoat extends EntityBoat implements HasCustomInventoryScreen, ContainerEntity { -@@ -238,4 +245,51 @@ + private static final int CONTAINER_SIZE = 27; +@@ -76,11 +85,18 @@ + + @Override + public void remove(Entity.RemovalReason entity_removalreason) { ++ // CraftBukkit start - add Bukkit remove cause ++ this.remove(entity_removalreason, null); ++ } ++ ++ @Override ++ public void remove(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { ++ // CraftBukkit end + if (!this.level().isClientSide && entity_removalreason.shouldDestroy()) { + InventoryUtils.dropContents(this.level(), (Entity) this, (IInventory) this); + } + +- super.remove(entity_removalreason); ++ super.remove(entity_removalreason, cause); // CraftBukkit - add Bukkit remove cause + } + + @Override +@@ -238,4 +254,51 @@ public void stopOpen(EntityHuman entityhuman) { this.level().gameEvent(GameEvent.CONTAINER_CLOSE, this.position(), GameEvent.a.of((Entity) entityhuman)); } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/vehicle/EntityMinecartContainer.patch b/paper-server/nms-patches/net/minecraft/world/entity/vehicle/EntityMinecartContainer.patch index b5693bdfa2..df662dadeb 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/vehicle/EntityMinecartContainer.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/vehicle/EntityMinecartContainer.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/vehicle/EntityMinecartContainer.java +++ b/net/minecraft/world/entity/vehicle/EntityMinecartContainer.java -@@ -18,6 +18,14 @@ +@@ -18,6 +18,15 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.World; @@ -9,13 +9,14 @@ +import org.bukkit.Location; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.inventory.InventoryHolder; +// CraftBukkit end + public abstract class EntityMinecartContainer extends EntityMinecartAbstract implements ContainerEntity { private NonNullList itemStacks; -@@ -25,14 +33,55 @@ +@@ -25,14 +34,55 @@ public MinecraftKey lootTable; public long lootTableSeed; @@ -72,4 +73,24 @@ + this.itemStacks = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); // CraftBukkit - SPIGOT-3513 } + @Override +@@ -76,11 +126,18 @@ + + @Override + public void remove(Entity.RemovalReason entity_removalreason) { ++ // CraftBukkit start - add Bukkit remove cause ++ this.remove(entity_removalreason, null); ++ } ++ ++ @Override ++ public void remove(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { ++ // CraftBukkit end + if (!this.level().isClientSide && entity_removalreason.shouldDestroy()) { + InventoryUtils.dropContents(this.level(), (Entity) this, (IInventory) this); + } + +- super.remove(entity_removalreason); ++ super.remove(entity_removalreason, cause); // CraftBukkit - add Bukkit remove cause + } + @Override diff --git a/paper-server/nms-patches/net/minecraft/world/entity/vehicle/EntityMinecartTNT.patch b/paper-server/nms-patches/net/minecraft/world/entity/vehicle/EntityMinecartTNT.patch index 9e12da637f..1161f9689c 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/vehicle/EntityMinecartTNT.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/vehicle/EntityMinecartTNT.patch @@ -1,21 +1,23 @@ --- a/net/minecraft/world/entity/vehicle/EntityMinecartTNT.java +++ b/net/minecraft/world/entity/vehicle/EntityMinecartTNT.java -@@ -23,6 +23,10 @@ +@@ -23,6 +23,11 @@ import net.minecraft.world.level.block.state.IBlockData; import net.minecraft.world.level.material.Fluid; +// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.entity.ExplosionPrimeEvent; +// CraftBukkit end + public class EntityMinecartTNT extends EntityMinecartAbstract { private static final byte EVENT_PRIME = 10; -@@ -115,7 +119,15 @@ +@@ -115,8 +120,16 @@ d1 = 5.0D; } - this.level().explode(this, damagesource, (ExplosionDamageCalculator) null, this.getX(), this.getY(), this.getZ(), (float) (4.0D + this.random.nextDouble() * 1.5D * d1), false, World.a.TNT); +- this.discard(); + // CraftBukkit start + ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), (float) (4.0D + this.random.nextDouble() * 1.5D * d1), false); + this.level().getCraftServer().getPluginManager().callEvent(event); @@ -25,6 +27,7 @@ + } + this.level().explode(this, damagesource, (ExplosionDamageCalculator) null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), World.a.TNT); + // CraftBukkit end - this.discard(); ++ this.discard(EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause } + } diff --git a/paper-server/nms-patches/net/minecraft/world/entity/vehicle/VehicleEntity.patch b/paper-server/nms-patches/net/minecraft/world/entity/vehicle/VehicleEntity.patch index ea7db6b296..f8f4a155d2 100644 --- a/paper-server/nms-patches/net/minecraft/world/entity/vehicle/VehicleEntity.patch +++ b/paper-server/nms-patches/net/minecraft/world/entity/vehicle/VehicleEntity.patch @@ -1,11 +1,12 @@ --- a/net/minecraft/world/entity/vehicle/VehicleEntity.java +++ b/net/minecraft/world/entity/vehicle/VehicleEntity.java -@@ -13,6 +13,12 @@ +@@ -13,6 +13,13 @@ import net.minecraft.world.level.World; import net.minecraft.world.level.gameevent.GameEvent; +// CraftBukkit start +import org.bukkit.entity.Vehicle; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.vehicle.VehicleDamageEvent; +import org.bukkit.event.vehicle.VehicleDestroyEvent; +// CraftBukkit end @@ -13,7 +14,7 @@ public abstract class VehicleEntity extends Entity { protected static final DataWatcherObject DATA_ID_HURT = DataWatcher.defineId(VehicleEntity.class, DataWatcherRegistry.INT); -@@ -29,6 +35,18 @@ +@@ -29,6 +36,18 @@ if (this.isInvulnerableTo(damagesource)) { return false; } else { @@ -32,10 +33,11 @@ this.setHurtDir(-this.getHurtDir()); this.setHurtTime(10); this.markHurt(); -@@ -38,9 +56,27 @@ +@@ -38,9 +57,27 @@ if ((flag || this.getDamage() <= 40.0F) && !this.shouldSourceDestroy(damagesource)) { if (flag) { +- this.discard(); + // CraftBukkit start + VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, attacker); + this.level().getCraftServer().getPluginManager().callEvent(destroyEvent); @@ -45,7 +47,7 @@ + return true; + } + // CraftBukkit end - this.discard(); ++ this.discard(EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause } } else { + // CraftBukkit start diff --git a/paper-server/nms-patches/net/minecraft/world/item/ItemLeash.patch b/paper-server/nms-patches/net/minecraft/world/item/ItemLeash.patch index 53a585f225..1e0a8684eb 100644 --- a/paper-server/nms-patches/net/minecraft/world/item/ItemLeash.patch +++ b/paper-server/nms-patches/net/minecraft/world/item/ItemLeash.patch @@ -41,7 +41,7 @@ + world.getCraftServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { -+ entityleash.discard(); ++ entityleash.discard(null); // CraftBukkit - add Bukkit remove cause + return EnumInteractionResult.PASS; + } + // CraftBukkit end diff --git a/paper-server/nms-patches/net/minecraft/world/level/block/entity/TileEntityBeehive.patch b/paper-server/nms-patches/net/minecraft/world/level/block/entity/TileEntityBeehive.patch index 706e9a6773..abde947a8a 100644 --- a/paper-server/nms-patches/net/minecraft/world/level/block/entity/TileEntityBeehive.patch +++ b/paper-server/nms-patches/net/minecraft/world/level/block/entity/TileEntityBeehive.patch @@ -1,6 +1,17 @@ --- a/net/minecraft/world/level/block/entity/TileEntityBeehive.java +++ b/net/minecraft/world/level/block/entity/TileEntityBeehive.java -@@ -43,6 +43,7 @@ +@@ -27,6 +27,10 @@ + import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.level.gameevent.GameEvent; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public class TileEntityBeehive extends TileEntity { + + public static final String TAG_FLOWER_POS = "FlowerPos"; +@@ -43,6 +47,7 @@ private final List stored = Lists.newArrayList(); @Nullable public BlockPosition savedFlowerPos; @@ -8,7 +19,7 @@ public TileEntityBeehive(BlockPosition blockposition, IBlockData iblockdata) { super(TileEntityTypes.BEEHIVE, blockposition, iblockdata); -@@ -82,7 +83,7 @@ +@@ -82,7 +87,7 @@ } public boolean isFull() { @@ -17,7 +28,7 @@ } public void emptyAllLivingFromHive(@Nullable EntityHuman entityhuman, IBlockData iblockdata, TileEntityBeehive.ReleaseStatus tileentitybeehive_releasestatus) { -@@ -99,7 +100,7 @@ +@@ -99,7 +104,7 @@ if (entityhuman.position().distanceToSqr(entity.position()) <= 16.0D) { if (!this.isSedated()) { @@ -26,7 +37,7 @@ } else { entitybee.setStayOutOfHiveCountdown(400); } -@@ -111,10 +112,16 @@ +@@ -111,10 +116,16 @@ } private List releaseAllOccupants(IBlockData iblockdata, TileEntityBeehive.ReleaseStatus tileentitybeehive_releasestatus) { @@ -44,7 +55,7 @@ }); if (!list.isEmpty()) { super.setChanged(); -@@ -142,7 +149,19 @@ +@@ -142,7 +153,19 @@ } public void addOccupantWithPresetTicks(Entity entity, boolean flag, int i) { @@ -65,7 +76,16 @@ entity.stopRiding(); entity.ejectPassengers(); NBTTagCompound nbttagcompound = new NBTTagCompound(); -@@ -174,7 +193,13 @@ +@@ -164,7 +187,7 @@ + this.level.gameEvent(GameEvent.BLOCK_CHANGE, blockposition, GameEvent.a.of(entity, this.getBlockState())); + } + +- entity.discard(); ++ entity.discard(EntityRemoveEvent.Cause.ENTER_BLOCK); // CraftBukkit - add Bukkit remove cause + super.setChanged(); + } + } +@@ -174,7 +197,13 @@ } private static boolean releaseOccupant(World world, BlockPosition blockposition, IBlockData iblockdata, TileEntityBeehive.HiveBee tileentitybeehive_hivebee, @Nullable List list, TileEntityBeehive.ReleaseStatus tileentitybeehive_releasestatus, @Nullable BlockPosition blockposition1) { @@ -80,7 +100,7 @@ return false; } else { NBTTagCompound nbttagcompound = tileentitybeehive_hivebee.entityData.copy(); -@@ -197,6 +222,18 @@ +@@ -197,6 +226,18 @@ if (!entity.getType().is(TagsEntity.BEEHIVE_INHABITORS)) { return false; } else { @@ -99,7 +119,7 @@ if (entity instanceof EntityBee) { EntityBee entitybee = (EntityBee) entity; -@@ -228,6 +265,7 @@ +@@ -228,6 +269,7 @@ list.add(entitybee); } @@ -107,7 +127,7 @@ float f = entity.getBbWidth(); double d0 = flag ? 0.0D : 0.55D + (double) (f / 2.0F); double d1 = (double) blockposition.getX() + 0.5D + d0 * (double) enumdirection.getStepX(); -@@ -235,11 +273,12 @@ +@@ -235,11 +277,12 @@ double d3 = (double) blockposition.getZ() + 0.5D + d0 * (double) enumdirection.getStepZ(); entity.moveTo(d1, d2, d3, entity.getYRot(), entity.getXRot()); @@ -121,7 +141,7 @@ } } else { return false; -@@ -288,6 +327,10 @@ +@@ -288,6 +331,10 @@ if (releaseOccupant(world, blockposition, iblockdata, tileentitybeehive_hivebee, (List) null, tileentitybeehive_releasestatus, blockposition1)) { flag = true; iterator.remove(); @@ -132,7 +152,7 @@ } } } -@@ -329,6 +372,11 @@ +@@ -329,6 +376,11 @@ this.savedFlowerPos = GameProfileSerializer.readBlockPos(nbttagcompound.getCompound("FlowerPos")); } @@ -144,7 +164,7 @@ } @Override -@@ -338,6 +386,7 @@ +@@ -338,6 +390,7 @@ if (this.hasSavedFlowerPos()) { nbttagcompound.put("FlowerPos", GameProfileSerializer.writeBlockPos(this.savedFlowerPos)); } diff --git a/paper-server/nms-patches/net/minecraft/world/level/block/entity/TileEntityEndGateway.patch b/paper-server/nms-patches/net/minecraft/world/level/block/entity/TileEntityEndGateway.patch index 6020597ac4..5b24ed1a79 100644 --- a/paper-server/nms-patches/net/minecraft/world/level/block/entity/TileEntityEndGateway.patch +++ b/paper-server/nms-patches/net/minecraft/world/level/block/entity/TileEntityEndGateway.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/TileEntityEndGateway.java +++ b/net/minecraft/world/level/block/entity/TileEntityEndGateway.java -@@ -33,6 +33,14 @@ +@@ -33,6 +33,15 @@ import net.minecraft.world.phys.Vec3D; import org.slf4j.Logger; @@ -9,13 +9,14 @@ +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.util.CraftLocation; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +// CraftBukkit end + public class TileEntityEndGateway extends TileEntityEnderPortal { private static final Logger LOGGER = LogUtils.getLogger(); -@@ -169,7 +177,7 @@ +@@ -169,7 +178,7 @@ tileentityendgateway.teleportCooldown = 100; BlockPosition blockposition1; @@ -24,7 +25,16 @@ blockposition1 = findOrCreateValidTeleportPos(worldserver, blockposition); blockposition1 = blockposition1.above(10); TileEntityEndGateway.LOGGER.debug("Creating portal at {}", blockposition1); -@@ -198,8 +206,34 @@ +@@ -190,7 +199,7 @@ + + if (entity2 != null) { + entity1 = entity2; +- entity.discard(); ++ entity.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause + } else { + entity1 = entity; + } +@@ -198,8 +207,34 @@ entity1 = entity.getRootVehicle(); } diff --git a/paper-server/nms-patches/net/minecraft/world/level/block/entity/TileEntityHopper.patch b/paper-server/nms-patches/net/minecraft/world/level/block/entity/TileEntityHopper.patch index 31cee6b138..48985e38c9 100644 --- a/paper-server/nms-patches/net/minecraft/world/level/block/entity/TileEntityHopper.patch +++ b/paper-server/nms-patches/net/minecraft/world/level/block/entity/TileEntityHopper.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/TileEntityHopper.java +++ b/net/minecraft/world/level/block/entity/TileEntityHopper.java -@@ -32,6 +32,21 @@ +@@ -32,6 +32,22 @@ import net.minecraft.world.phys.shapes.OperatorBoolean; import net.minecraft.world.phys.shapes.VoxelShapes; @@ -13,6 +13,7 @@ +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.HumanEntity; ++import org.bukkit.event.entity.EntityRemoveEvent; +import org.bukkit.event.inventory.HopperInventorySearchEvent; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.event.inventory.InventoryPickupItemEvent; @@ -22,7 +23,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper { public static final int MOVE_ITEM_SPEED = 8; -@@ -40,6 +55,36 @@ +@@ -40,6 +56,36 @@ private int cooldownTime; private long tickedGameTime; @@ -59,7 +60,7 @@ public TileEntityHopper(BlockPosition blockposition, IBlockData iblockdata) { super(TileEntityTypes.HOPPER, blockposition, iblockdata); this.items = NonNullList.withSize(5, ItemStack.EMPTY); -@@ -113,7 +158,7 @@ +@@ -113,7 +159,7 @@ boolean flag = false; if (!tileentityhopper.isEmpty()) { @@ -68,7 +69,7 @@ } if (!tileentityhopper.inventoryFull()) { -@@ -147,7 +192,7 @@ +@@ -147,7 +193,7 @@ return false; } @@ -77,7 +78,7 @@ IInventory iinventory1 = getAttachedContainer(world, blockposition, iblockdata); if (iinventory1 == null) { -@@ -161,7 +206,30 @@ +@@ -161,7 +207,30 @@ for (int i = 0; i < iinventory.getContainerSize(); ++i) { if (!iinventory.getItem(i).isEmpty()) { ItemStack itemstack = iinventory.getItem(i).copy(); @@ -109,7 +110,7 @@ if (itemstack1.isEmpty()) { iinventory1.setChanged(); -@@ -226,7 +294,34 @@ +@@ -226,7 +295,34 @@ if (!itemstack.isEmpty() && canTakeItemFromContainer(ihopper, iinventory, itemstack, i, enumdirection)) { ItemStack itemstack1 = itemstack.copy(); @@ -145,7 +146,7 @@ if (itemstack2.isEmpty()) { iinventory.setChanged(); -@@ -241,6 +336,13 @@ +@@ -241,13 +337,20 @@ public static boolean addItem(IInventory iinventory, EntityItem entityitem) { boolean flag = false; @@ -159,7 +160,15 @@ ItemStack itemstack = entityitem.getItem().copy(); ItemStack itemstack1 = addItem((IInventory) null, iinventory, itemstack, (EnumDirection) null); -@@ -367,16 +469,40 @@ + if (itemstack1.isEmpty()) { + flag = true; + entityitem.setItem(ItemStack.EMPTY); +- entityitem.discard(); ++ entityitem.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + } else { + entityitem.setItem(itemstack1); + } +@@ -367,16 +470,40 @@ return itemstack; } diff --git a/paper-server/nms-patches/net/minecraft/world/level/dimension/end/EnderDragonBattle.patch b/paper-server/nms-patches/net/minecraft/world/level/dimension/end/EnderDragonBattle.patch index d8ee4ee0ad..2d099269f3 100644 --- a/paper-server/nms-patches/net/minecraft/world/level/dimension/end/EnderDragonBattle.patch +++ b/paper-server/nms-patches/net/minecraft/world/level/dimension/end/EnderDragonBattle.patch @@ -26,6 +26,15 @@ this.gateways.addAll((Collection) enderdragonbattle_a.gateways.orElseGet(() -> { ObjectArrayList objectarraylist = new ObjectArrayList(ContiguousSet.create(Range.closedOpen(0, 20), DiscreteDomain.integers())); +@@ -207,7 +207,7 @@ + this.dragonKilled = false; + if (!flag) { + EnderDragonBattle.LOGGER.info("But we didn't have a portal, let's remove it."); +- entityenderdragon.discard(); ++ entityenderdragon.discard(null); // CraftBukkit - add Bukkit remove cause + this.dragonUUID = null; + } + } @@ -510,7 +510,7 @@ return this.previouslyKilled; } diff --git a/paper-server/nms-patches/net/minecraft/world/level/dimension/end/EnumDragonRespawn.patch b/paper-server/nms-patches/net/minecraft/world/level/dimension/end/EnumDragonRespawn.patch new file mode 100644 index 0000000000..7ffc939cd1 --- /dev/null +++ b/paper-server/nms-patches/net/minecraft/world/level/dimension/end/EnumDragonRespawn.patch @@ -0,0 +1,58 @@ +--- a/net/minecraft/world/level/dimension/end/EnumDragonRespawn.java ++++ b/net/minecraft/world/level/dimension/end/EnumDragonRespawn.java +@@ -13,6 +13,10 @@ + import net.minecraft.world.level.levelgen.feature.WorldGenerator; + import net.minecraft.world.level.levelgen.feature.configurations.WorldGenFeatureEndSpikeConfiguration; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public enum EnumDragonRespawn { + + START { +@@ -27,7 +31,7 @@ + entityendercrystal.setBeamTarget(blockposition1); + } + +- enderdragonbattle.setRespawnStage(null.PREPARING_TO_SUMMON_PILLARS); ++ enderdragonbattle.setRespawnStage(PREPARING_TO_SUMMON_PILLARS); // CraftBukkit - decompile error + } + }, + PREPARING_TO_SUMMON_PILLARS { +@@ -38,7 +42,7 @@ + worldserver.levelEvent(3001, new BlockPosition(0, 128, 0), 0); + } + } else { +- enderdragonbattle.setRespawnStage(null.SUMMONING_PILLARS); ++ enderdragonbattle.setRespawnStage(SUMMONING_PILLARS); // CraftBukkit - decompile error + } + + } +@@ -81,7 +85,7 @@ + WorldGenerator.END_SPIKE.place(worldgenfeatureendspikeconfiguration, worldserver, worldserver.getChunkSource().getGenerator(), RandomSource.create(), new BlockPosition(worldgenender_spike.getCenterX(), 45, worldgenender_spike.getCenterZ())); + } + } else if (flag1) { +- enderdragonbattle.setRespawnStage(null.SUMMONING_DRAGON); ++ enderdragonbattle.setRespawnStage(SUMMONING_DRAGON); // CraftBukkit - decompile error + } + } + +@@ -94,7 +98,7 @@ + EntityEnderCrystal entityendercrystal; + + if (i >= 100) { +- enderdragonbattle.setRespawnStage(null.END); ++ enderdragonbattle.setRespawnStage(END); // CraftBukkit - decompile error + enderdragonbattle.resetSpikeCrystals(); + iterator = list.iterator(); + +@@ -102,7 +106,7 @@ + entityendercrystal = (EntityEnderCrystal) iterator.next(); + entityendercrystal.setBeamTarget((BlockPosition) null); + worldserver.explode(entityendercrystal, entityendercrystal.getX(), entityendercrystal.getY(), entityendercrystal.getZ(), 6.0F, World.a.NONE); +- entityendercrystal.discard(); ++ entityendercrystal.discard(EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause + } + } else if (i >= 80) { + worldserver.levelEvent(3001, new BlockPosition(0, 128, 0), 0); diff --git a/paper-server/nms-patches/net/minecraft/world/level/entity/EntityAccess.patch b/paper-server/nms-patches/net/minecraft/world/level/entity/EntityAccess.patch new file mode 100644 index 0000000000..55f2fd8d6c --- /dev/null +++ b/paper-server/nms-patches/net/minecraft/world/level/entity/EntityAccess.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/world/level/entity/EntityAccess.java ++++ b/net/minecraft/world/level/entity/EntityAccess.java +@@ -6,6 +6,10 @@ + import net.minecraft.world.entity.Entity; + import net.minecraft.world.phys.AxisAlignedBB; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityRemoveEvent; ++// CraftBukkit end ++ + public interface EntityAccess { + + int getId(); +@@ -24,6 +28,12 @@ + + void setRemoved(Entity.RemovalReason entity_removalreason); + ++ // CraftBukkit start - add Bukkit remove cause ++ default void setRemoved(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { ++ setRemoved(entity_removalreason); ++ } ++ // CraftBukkit end ++ + boolean shouldBeSaved(); + + boolean isAlwaysTicking(); diff --git a/paper-server/nms-patches/net/minecraft/world/level/entity/PersistentEntitySectionManager.patch b/paper-server/nms-patches/net/minecraft/world/level/entity/PersistentEntitySectionManager.patch index 2fb5483db0..79b60adb35 100644 --- a/paper-server/nms-patches/net/minecraft/world/level/entity/PersistentEntitySectionManager.patch +++ b/paper-server/nms-patches/net/minecraft/world/level/entity/PersistentEntitySectionManager.patch @@ -1,18 +1,19 @@ --- a/net/minecraft/world/level/entity/PersistentEntitySectionManager.java +++ b/net/minecraft/world/level/entity/PersistentEntitySectionManager.java -@@ -32,6 +32,11 @@ +@@ -32,6 +32,12 @@ import net.minecraft.world.level.ChunkCoordIntPair; import org.slf4j.Logger; +// CraftBukkit start +import net.minecraft.world.level.chunk.storage.EntityStorage; +import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityRemoveEvent; +// CraftBukkit end + public class PersistentEntitySectionManager implements AutoCloseable { static final Logger LOGGER = LogUtils.getLogger(); -@@ -55,6 +60,16 @@ +@@ -55,6 +61,16 @@ this.entityGetter = new LevelEntityGetterAdapter<>(this.visibleEntityStorage, this.sectionStorage); } @@ -29,7 +30,7 @@ void removeSectionIfEmpty(long i, EntitySection entitysection) { if (entitysection.isEmpty()) { this.sectionStorage.remove(i); -@@ -196,6 +211,12 @@ +@@ -196,6 +212,12 @@ } private boolean storeChunkSections(long i, Consumer consumer) { @@ -42,7 +43,7 @@ PersistentEntitySectionManager.b persistententitysectionmanager_b = (PersistentEntitySectionManager.b) this.chunkLoadStatuses.get(i); if (persistententitysectionmanager_b == PersistentEntitySectionManager.b.PENDING) { -@@ -207,6 +228,7 @@ +@@ -207,6 +229,7 @@ if (list.isEmpty()) { if (persistententitysectionmanager_b == PersistentEntitySectionManager.b.LOADED) { @@ -50,7 +51,7 @@ this.permanentStorage.storeEntities(new ChunkEntities<>(new ChunkCoordIntPair(i), ImmutableList.of())); } -@@ -215,6 +237,7 @@ +@@ -215,6 +238,7 @@ this.requestChunkLoad(i); return false; } else { @@ -58,7 +59,7 @@ this.permanentStorage.storeEntities(new ChunkEntities<>(new ChunkCoordIntPair(i), list)); list.forEach(consumer); return true; -@@ -238,7 +261,7 @@ +@@ -238,7 +262,7 @@ private boolean processChunkUnload(long i) { boolean flag = this.storeChunkSections(i, (entityaccess) -> { entityaccess.getPassengersAndSelf().forEach(this::unloadEntity); @@ -67,7 +68,13 @@ if (!flag) { return false; -@@ -254,19 +277,23 @@ +@@ -249,24 +273,28 @@ + } + + private void unloadEntity(EntityAccess entityaccess) { +- entityaccess.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK); ++ entityaccess.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, EntityRemoveEvent.Cause.UNLOAD); // CraftBukkit - add Bukkit remove cause + entityaccess.setLevelCallback(EntityInLevelCallback.NULL); } private void processUnloads() { @@ -93,7 +100,7 @@ } } -@@ -292,7 +319,7 @@ +@@ -292,7 +320,7 @@ } public void autoSave() { @@ -102,7 +109,7 @@ boolean flag = this.chunkVisibility.get(i) == Visibility.HIDDEN; if (flag) { -@@ -311,7 +338,7 @@ +@@ -311,7 +339,7 @@ while (!longset.isEmpty()) { this.permanentStorage.flush(false); this.processPendingLoads(); @@ -111,7 +118,7 @@ boolean flag = this.chunkVisibility.get(i) == Visibility.HIDDEN; return flag ? this.processChunkUnload(i) : this.storeChunkSections(i, (entityaccess) -> { -@@ -323,7 +350,15 @@ +@@ -323,7 +351,15 @@ } public void close() throws IOException { @@ -128,7 +135,7 @@ this.permanentStorage.close(); } -@@ -350,7 +385,7 @@ +@@ -350,7 +386,7 @@ public void dumpSections(Writer writer) throws IOException { CSVWriter csvwriter = CSVWriter.builder().addColumn("x").addColumn("y").addColumn("z").addColumn("visibility").addColumn("load_status").addColumn("entity_count").build(writer); @@ -137,7 +144,7 @@ PersistentEntitySectionManager.b persistententitysectionmanager_b = (PersistentEntitySectionManager.b) this.chunkLoadStatuses.get(i); this.sectionStorage.getExistingSectionPositionsInChunk(i).forEach((j) -> { -@@ -394,7 +429,7 @@ +@@ -394,7 +430,7 @@ private EntitySection currentSection; a(EntityAccess entityaccess, long i, EntitySection entitysection) { diff --git a/paper-server/nms-patches/net/minecraft/world/level/levelgen/structure/structures/MineshaftPieces.patch b/paper-server/nms-patches/net/minecraft/world/level/levelgen/structure/structures/MineshaftPieces.patch index 2cedb04da6..952c87774d 100644 --- a/paper-server/nms-patches/net/minecraft/world/level/levelgen/structure/structures/MineshaftPieces.patch +++ b/paper-server/nms-patches/net/minecraft/world/level/levelgen/structure/structures/MineshaftPieces.patch @@ -4,7 +4,7 @@ import net.minecraft.world.level.storage.loot.LootTables; import org.slf4j.Logger; -+// CraftBukkit start - imports ++// CraftBukkit start +import net.minecraft.nbt.NBTBase; +// CraftBukkit end + diff --git a/paper-server/pom.xml b/paper-server/pom.xml index a9ffd7fa5e..44aba403a1 100644 --- a/paper-server/pom.xml +++ b/paper-server/pom.xml @@ -281,6 +281,12 @@ 5.5.0 test + + org.ow2.asm + asm-tree + 9.5 + test + diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index 5ad14d4a39..d19210e115 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -45,6 +45,7 @@ import org.bukkit.entity.Player; import org.bukkit.entity.Pose; import org.bukkit.entity.SpawnCategory; import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityRemoveEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.metadata.MetadataValue; import org.bukkit.permissions.PermissibleBase; @@ -291,7 +292,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { @Override public void remove() { entity.pluginRemoved = true; - entity.discard(); + entity.discard(getHandle().generation ? null : EntityRemoveEvent.Cause.PLUGIN); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java index 695c1bf8eb..f583788dce 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java @@ -118,7 +118,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { // during world generation, we don't want to run logic for dropping items and xp if (getHandle().generation && health == 0) { - getHandle().discard(); + getHandle().discard(null); // Add Bukkit remove cause return; } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWindCharge.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWindCharge.java index c878b831cd..fae25769bb 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWindCharge.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWindCharge.java @@ -2,6 +2,7 @@ package org.bukkit.craftbukkit.entity; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.WindCharge; +import org.bukkit.event.entity.EntityRemoveEvent; public class CraftWindCharge extends CraftFireball implements WindCharge { public CraftWindCharge(CraftServer server, net.minecraft.world.entity.projectile.WindCharge entity) { @@ -11,7 +12,7 @@ public class CraftWindCharge extends CraftFireball implements WindCharge { @Override public void explode() { this.getHandle().explode(); - this.getHandle().discard(); // SPIGOT-7577 - explode doesn't discard the entity, this happens only in tick and onHitBlock + this.getHandle().discard(EntityRemoveEvent.Cause.EXPLODE); // SPIGOT-7577 - explode doesn't discard the entity, this happens only in tick and onHitBlock } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index d3becde4f6..c74cd39b7d 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -182,6 +182,7 @@ import org.bukkit.event.entity.EntityKnockbackEvent; import org.bukkit.event.entity.EntityPickupItemEvent; import org.bukkit.event.entity.EntityPlaceEvent; import org.bukkit.event.entity.EntityPotionEffectEvent; +import org.bukkit.event.entity.EntityRemoveEvent; import org.bukkit.event.entity.EntityShootBowEvent; import org.bukkit.event.entity.EntitySpawnEvent; import org.bukkit.event.entity.EntitySpellCastEvent; @@ -659,7 +660,7 @@ public class CraftEventFactory { if (spawnReason != SpawnReason.CUSTOM) { if (isAnimal && !world.getWorld().getAllowAnimals() || isMonster && !world.getWorld().getAllowMonsters() || isNpc && !world.getCraftServer().getServer().areNpcsEnabled()) { - entity.discard(); + entity.discard(null); // Add Bukkit remove cause return false; } } @@ -697,12 +698,12 @@ public class CraftEventFactory { if (event != null && (event.isCancelled() || entity.isRemoved())) { Entity vehicle = entity.getVehicle(); if (vehicle != null) { - vehicle.discard(); + vehicle.discard(null); // Add Bukkit remove cause } for (Entity passenger : entity.getIndirectPassengers()) { - passenger.discard(); + passenger.discard(null); // Add Bukkit remove cause } - entity.discard(); + entity.discard(null); // Add Bukkit remove cause return false; } @@ -1829,4 +1830,20 @@ public class CraftEventFactory { Bukkit.getPluginManager().callEvent(event); return event; } + + public static void callEntityRemoveEvent(Entity entity, EntityRemoveEvent.Cause cause) { + if (entity instanceof EntityPlayer) { + return; // Don't call for player + } + + if (cause == null) { + // Don't call if cause is null + // This can happen when an entity changes dimension, + // the entity gets removed during world gen or + // the entity is removed before it is even spawned (when the spawn event is cancelled for example) + return; + } + + Bukkit.getPluginManager().callEvent(new EntityRemoveEvent(entity.getBukkitEntity(), cause)); + } } diff --git a/paper-server/src/test/java/org/bukkit/event/EntityRemoveEventTest.java b/paper-server/src/test/java/org/bukkit/event/EntityRemoveEventTest.java new file mode 100644 index 0000000000..cb4a6fec06 --- /dev/null +++ b/paper-server/src/test/java/org/bukkit/event/EntityRemoveEventTest.java @@ -0,0 +1,220 @@ +package org.bukkit.event; + +import static org.junit.jupiter.api.Assertions.*; +import com.google.common.base.Joiner; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.jar.JarFile; +import java.util.stream.Stream; +import net.minecraft.WorldVersion; +import net.minecraft.server.Main; +import net.minecraft.world.level.entity.EntityAccess; +import org.bukkit.support.AbstractTestingBase; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.Handle; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.InvokeDynamicInsnNode; +import org.objectweb.asm.tree.LineNumberNode; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; + +public class EntityRemoveEventTest extends AbstractTestingBase { + + // Needs to be a class, which is present in the source, and not a test class + private static final URI CRAFT_BUKKIT_CLASSES; + // Needs to be a class, which is from the minecraft package and not patch by CraftBukkit + private static final URI MINECRAFT_CLASSES; + + static { + try { + CRAFT_BUKKIT_CLASSES = Main.class.getProtectionDomain().getCodeSource().getLocation().toURI(); + MINECRAFT_CLASSES = WorldVersion.class.getProtectionDomain().getCodeSource().getLocation().toURI(); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + + private static JarFile jarFile = null; + private static Stream files = null; + + public static Stream craftBukkitData() { + return files + .map(Path::toFile) + .filter(File::isFile) + .filter(file -> file.getName().endsWith(".class")) + .filter(file -> !file.getName().equals("EntityAccess.class")) + .map(file -> { + try { + return new FileInputStream(file); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + }).map(Arguments::of); + } + + public static Stream minecraftData() { + return jarFile + .stream() + .filter(entry -> entry.getName().endsWith(".class")) + .filter(entry -> !new File(CRAFT_BUKKIT_CLASSES.resolve(entry.getName())).exists()) + .filter(entry -> !entry.getName().startsWith("net/minecraft/gametest/framework")) + .map(entry -> { + try { + return jarFile.getInputStream(entry); + } catch (IOException e) { + throw new RuntimeException(e); + } + }).map(Arguments::arguments); + } + + @BeforeAll + public static void beforeAll() throws IOException { + assertNotEquals(CRAFT_BUKKIT_CLASSES, MINECRAFT_CLASSES, """ + The minecraft and craft bukkit uri point to the same directory / file. + Please make sure the CRAFT_BUKKIT_CLASSES points to the test class directory and MINECRAFT_CLASSES to the minecraft server jar. + """); + + jarFile = new JarFile(new File(MINECRAFT_CLASSES)); + files = Files.walk(Path.of(CRAFT_BUKKIT_CLASSES)); + } + + @ParameterizedTest + @MethodSource("minecraftData") + public void testMinecraftClasses(InputStream inputStream) throws IOException, ClassNotFoundException { + test(inputStream); + } + + @ParameterizedTest + @MethodSource("craftBukkitData") + public void testCraftBukkitModifiedClasses(InputStream inputStream) throws IOException, ClassNotFoundException { + test(inputStream); + } + + private void test(InputStream inputStream) throws IOException, ClassNotFoundException { + List missingReason = new ArrayList<>(); + + try (inputStream) { + ClassReader classReader = new ClassReader(inputStream); + ClassNode classNode = new ClassNode(Opcodes.ASM9); + + classReader.accept(classNode, Opcodes.ASM9); + boolean minecraftCause = false; + boolean bukkitCause = false; + + for (MethodNode methodNode : classNode.methods) { + if (methodNode.name.equals("remove") && methodNode.desc.contains("Lnet/minecraft/world/entity/Entity$RemovalReason;")) { + if (methodNode.desc.contains("Lorg/bukkit/event/entity/EntityRemoveEvent$Cause;")) { + bukkitCause = true; + } else { + minecraftCause = true; + } + } + + LineNumberNode lastLineNumber = null; + for (AbstractInsnNode instruction : methodNode.instructions) { + if (instruction instanceof LineNumberNode lineNumberNode) { + lastLineNumber = lineNumberNode; + continue; + } + + if (instruction instanceof MethodInsnNode methodInsnNode) { + // Check for discard and remove method call + if (check(methodInsnNode.owner, methodInsnNode.name, methodInsnNode.desc)) { + // Add to list + missingReason.add(String.format("Method name: %s, name: %s, line number: %s", methodNode.name, methodInsnNode.name, lastLineNumber.line)); + } + } else if (instruction instanceof InvokeDynamicInsnNode dynamicInsnNode) { + // Check for discard and remove method call + if (!dynamicInsnNode.bsm.getOwner().equals("java/lang/invoke/LambdaMetafactory") + || !dynamicInsnNode.bsm.getName().equals("metafactory") || dynamicInsnNode.bsmArgs.length != 3) { + continue; + } + + Handle handle = (Handle) dynamicInsnNode.bsmArgs[1]; + + if (check(handle.getOwner(), handle.getName(), handle.getDesc())) { + // Add to list + missingReason.add(String.format("[D] Method name: %s, name: %s, line number: %s", methodNode.name, handle.getName(), lastLineNumber.line)); + } + } + } + } + + assertTrue(missingReason.isEmpty(), String.format(""" + The class %s has Entity#discard, Entity#remove and/or Entity#setRemoved method calls, which don't have a bukkit reason. + Please add a bukkit reason to them, if the event should not be called use null as reason. + + Following missing reasons where found: + %s""", classNode.name, Joiner.on('\n').join(missingReason))); + + if (minecraftCause == bukkitCause) { + return; + } + + if (minecraftCause) { + fail(String.format(""" + The class %s has the Entity#remove method override, but there is no bukkit override. + Please add a bukkit method override, which adds the bukkit cause. + """, classNode.name)); + return; // Will never reach ): + } + + fail(String.format(""" + The class %s has the Entity#remove method override, to add a bukkit cause, but there is no normal override. + Please remove the bukkit method override, since it is no longer needed. + """, classNode.name)); + } + } + + private boolean check(String owner, String name, String desc) throws ClassNotFoundException { + if (!name.equals("discard") && !name.equals("remove") && !name.equals("setRemoved")) { + if (!checkExtraMethod(owner, name, desc)) { + return false; + } + } + + if (desc.contains("Lorg/bukkit/event/entity/EntityRemoveEvent$Cause;")) { + return false; + } + + Class ownerClass = Class.forName(owner.replace('/', '.'), false, getClass().getClassLoader()); + + // Found missing discard, remove or setRemoved method call + return EntityAccess.class.isAssignableFrom(ownerClass); + } + + private boolean checkExtraMethod(String owner, String name, String desc) { + if (owner.equals("net/minecraft/world/entity/projectile/EntityShulkerBullet")) { + return name.equals("destroy"); + } + + return false; + } + + @AfterAll + public static void clear() throws IOException { + if (jarFile != null) { + jarFile.close(); + } + + if (files != null) { + files.close(); + } + } +}