diff --git a/paper-server/patches/sources/net/minecraft/server/commands/SummonCommand.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/SummonCommand.java.patch index 8a1124cf96..5a74f92631 100644 --- a/paper-server/patches/sources/net/minecraft/server/commands/SummonCommand.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/commands/SummonCommand.java.patch @@ -1,6 +1,14 @@ --- a/net/minecraft/server/commands/SummonCommand.java +++ b/net/minecraft/server/commands/SummonCommand.java -@@ -67,7 +67,7 @@ +@@ -57,6 +57,7 @@ + ServerLevel worldserver = source.getLevel(); + Entity entity = EntityType.loadEntityRecursive(nbttagcompound1, worldserver, EntitySpawnReason.COMMAND, (entity1) -> { + entity1.moveTo(pos.x, pos.y, pos.z, entity1.getYRot(), entity1.getXRot()); ++ entity1.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.COMMAND; // Paper - Entity#getEntitySpawnReason + return entity1; + }); + +@@ -67,7 +68,7 @@ ((Mob) entity).finalizeSpawn(source.getLevel(), source.getLevel().getCurrentDifficultyAt(entity.blockPosition()), EntitySpawnReason.COMMAND, (SpawnGroupData) null); } diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch index ca46cf0f32..cf51e45a29 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch @@ -568,7 +568,7 @@ } } -@@ -939,41 +1169,92 @@ +@@ -939,41 +1169,93 @@ this.entityManager.addNewEntity(player); } @@ -582,6 +582,7 @@ + return true; + } + // Paper end - extra debug info ++ if (entity.spawnReason == null) entity.spawnReason = spawnReason; // Paper - Entity#getEntitySpawnReason if (entity.isRemoved()) { - ServerLevel.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityType.getKey(entity.getType())); + // WorldServer.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getKey(entity.getType())); // CraftBukkit @@ -666,7 +667,7 @@ while (iterator.hasNext()) { ServerPlayer entityplayer = (ServerPlayer) iterator.next(); -@@ -982,6 +1263,12 @@ +@@ -982,6 +1264,12 @@ double d1 = (double) pos.getY() - entityplayer.getY(); double d2 = (double) pos.getZ() - entityplayer.getZ(); @@ -679,7 +680,7 @@ if (d0 * d0 + d1 * d1 + d2 * d2 < 1024.0D) { entityplayer.connection.send(new ClientboundBlockDestructionPacket(entityId, pos, progress)); } -@@ -1030,7 +1317,7 @@ +@@ -1030,7 +1318,7 @@ @Override public void levelEvent(@Nullable Player player, int eventId, BlockPos pos, int data) { @@ -688,7 +689,7 @@ } public int getLogicalHeight() { -@@ -1060,7 +1347,18 @@ +@@ -1060,7 +1348,18 @@ Iterator iterator = this.navigatingMobs.iterator(); while (iterator.hasNext()) { @@ -708,7 +709,7 @@ PathNavigation navigationabstract = entityinsentient.getNavigation(); if (navigationabstract.shouldRecomputePath(pos)) { -@@ -1086,11 +1384,13 @@ +@@ -1086,11 +1385,13 @@ @Override public void updateNeighborsAt(BlockPos pos, Block block) { @@ -722,7 +723,7 @@ this.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, (Direction) null, orientation); } -@@ -1126,9 +1426,20 @@ +@@ -1126,9 +1427,20 @@ @Override public void explode(@Nullable Entity entity, @Nullable DamageSource damageSource, @Nullable ExplosionDamageCalculator behavior, double x, double y, double z, float power, boolean createFire, Level.ExplosionInteraction explosionSourceType, ParticleOptions smallParticle, ParticleOptions largeParticle, Holder soundEvent) { @@ -744,15 +745,14 @@ case NONE: explosion_effect = Explosion.BlockInteraction.KEEP; break; -@@ -1143,17 +1454,28 @@ - break; +@@ -1144,16 +1456,27 @@ case TRIGGER: explosion_effect = Explosion.BlockInteraction.TRIGGER_BLOCK; -+ break; + break; + // CraftBukkit start - handle custom explosion type + case STANDARD: + explosion_effect = Explosion.BlockInteraction.DESTROY; - break; ++ break; + // CraftBukkit end default: throw new MatchException((String) null, (Throwable) null); @@ -776,7 +776,7 @@ Iterator iterator = this.players.iterator(); while (iterator.hasNext()) { -@@ -1162,10 +1484,11 @@ +@@ -1162,10 +1485,11 @@ if (entityplayer.distanceToSqr(vec3d) < 4096.0D) { Optional optional = Optional.ofNullable((Vec3) serverexplosion.getHitPlayers().get(entityplayer)); @@ -789,7 +789,7 @@ } private Explosion.BlockInteraction getDestroyType(GameRules.Key decayRule) { -@@ -1226,17 +1549,29 @@ +@@ -1226,17 +1550,29 @@ } public int sendParticles(T parameters, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double speed) { @@ -825,7 +825,7 @@ ++j; } } -@@ -1292,7 +1627,7 @@ +@@ -1292,7 +1628,7 @@ @Nullable public BlockPos findNearestMapStructure(TagKey structureTag, BlockPos pos, int radius, boolean skipReferencedStructures) { @@ -834,7 +834,7 @@ return null; } else { Optional> optional = this.registryAccess().lookupOrThrow(Registries.STRUCTURE).get(structureTag); -@@ -1334,11 +1669,22 @@ +@@ -1334,11 +1670,22 @@ @Nullable @Override public MapItemSavedData getMapData(MapId id) { @@ -858,7 +858,7 @@ this.getServer().overworld().getDataStorage().set(id.key(), state); } -@@ -1649,6 +1995,11 @@ +@@ -1649,6 +1996,11 @@ @Override public void blockUpdated(BlockPos pos, Block block) { if (!this.isDebug()) { @@ -870,7 +870,7 @@ this.updateNeighborsAt(pos, block); } -@@ -1668,12 +2019,12 @@ +@@ -1668,12 +2020,12 @@ } public boolean isFlat() { @@ -885,7 +885,7 @@ } @Nullable -@@ -1696,7 +2047,7 @@ +@@ -1696,7 +2048,7 @@ private static String getTypeCount(Iterable items, Function classifier) { try { Object2IntOpenHashMap object2intopenhashmap = new Object2IntOpenHashMap(); @@ -894,7 +894,7 @@ while (iterator.hasNext()) { T t0 = iterator.next(); -@@ -1705,7 +2056,7 @@ +@@ -1705,7 +2057,7 @@ object2intopenhashmap.addTo(s, 1); } @@ -903,7 +903,7 @@ String s1 = (String) entry.getKey(); return s1 + ":" + entry.getIntValue(); -@@ -1717,6 +2068,7 @@ +@@ -1717,6 +2069,7 @@ @Override public LevelEntityGetter getEntities() { @@ -911,7 +911,7 @@ return this.entityManager.getEntityGetter(); } -@@ -1802,6 +2154,17 @@ +@@ -1802,6 +2155,17 @@ return this.serverLevelData.getGameRules(); } @@ -929,7 +929,7 @@ @Override public CrashReportCategory fillReportDetails(CrashReport report) { CrashReportCategory crashreportsystemdetails = super.fillReportDetails(report); -@@ -1836,6 +2199,7 @@ +@@ -1836,6 +2200,7 @@ } public void onTrackingStart(Entity entity) { @@ -937,7 +937,7 @@ ServerLevel.this.getChunkSource().addEntity(entity); if (entity instanceof ServerPlayer entityplayer) { ServerLevel.this.players.add(entityplayer); -@@ -1864,9 +2228,52 @@ +@@ -1864,9 +2229,52 @@ } entity.updateDynamicGameEventListener(DynamicGameEventListener::add); @@ -990,7 +990,7 @@ ServerLevel.this.getChunkSource().removeEntity(entity); if (entity instanceof ServerPlayer entityplayer) { ServerLevel.this.players.remove(entityplayer); -@@ -1895,6 +2302,15 @@ +@@ -1895,6 +2303,15 @@ } entity.updateDynamicGameEventListener(DynamicGameEventListener::remove); diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch index e21e083614..237e8e9f59 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch @@ -114,7 +114,7 @@ @Nullable private Vec3 startingToFallPosition; @Nullable -@@ -258,6 +293,31 @@ +@@ -258,7 +293,32 @@ private final CommandSource commandSource; private int containerCounter; public boolean wonGame; @@ -124,7 +124,7 @@ + public boolean queueHealthUpdatePacket; + public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket; + // Paper end - cancellable death event -+ + + // CraftBukkit start + public CraftPlayer.TransferCookieConnection transferCookieConnection; + public String displayName; @@ -143,9 +143,10 @@ + // CraftBukkit end + public boolean isRealPlayer; // Paper + public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent - ++ public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) { super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); + this.chatVisibility = ChatVisiblity.FULL; @@ -266,7 +326,7 @@ this.canChatColor = true; this.lastActionTime = Util.getMillis(); @@ -179,8 +180,8 @@ + this.adventure$displayName = net.kyori.adventure.text.Component.text(this.getScoreboardName()); // Paper + this.bukkitPickUpLoot = true; + this.maxHealthCache = this.getMaxHealth(); - } - ++ } ++ + // Use method to resend items in hands in case of client desync, because the item use got cancelled. + // For example, when cancelling the leash event + public void resendItemInHands() { @@ -226,9 +227,9 @@ + } + + return blockposition; -+ } + } + // CraftBukkit end -+ + @Override public BlockPos adjustSpawnLocation(ServerLevel world, BlockPos basePos) { AABB axisalignedbb = this.getDimensions(Pose.STANDING).makeBoundingBox(Vec3.ZERO); @@ -347,6 +348,15 @@ CompoundTag nbttagcompound1 = new CompoundTag(); CompoundTag nbttagcompound2 = new CompoundTag(); +@@ -564,7 +714,7 @@ + ServerLevel worldserver = (ServerLevel) world; + CompoundTag nbttagcompound = ((CompoundTag) nbt.get()).getCompound("RootVehicle"); + Entity entity = EntityType.loadEntityRecursive(nbttagcompound.getCompound("Entity"), worldserver, EntitySpawnReason.LOAD, (entity1) -> { +- return !worldserver.addWithUUID(entity1) ? null : entity1; ++ return !worldserver.addWithUUID(entity1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT) ? null : entity1; // CraftBukkit - decompile error // Paper - Entity#getEntitySpawnReason + }); + + if (entity == null) { @@ -598,12 +748,12 @@ if (!this.isPassenger()) { @@ -461,15 +471,17 @@ if (this.experienceLevel != this.lastRecordedLevel) { this.lastRecordedLevel = this.experienceLevel; this.updateScoreForCriteria(ObjectiveCriteria.LEVEL, Mth.ceil((float) this.lastRecordedLevel)); -@@ -865,6 +1053,20 @@ - CriteriaTriggers.LOCATION.trigger(this); - } +@@ -863,8 +1051,22 @@ + if (this.tickCount % 20 == 0) { + CriteriaTriggers.LOCATION.trigger(this); ++ } ++ + // CraftBukkit start - initialize oldLevel, fire PlayerLevelChangeEvent, and tick client-sided world border + if (this.oldLevel == -1) { + this.oldLevel = this.experienceLevel; -+ } -+ + } + + if (this.oldLevel != this.experienceLevel) { + CraftEventFactory.callPlayerLevelChangeEvent(this.getBukkitEntity(), this.oldLevel, this.experienceLevel); + this.oldLevel = this.experienceLevel; @@ -526,7 +538,7 @@ + // SPIGOT-5071: manually add player loot tables (SPIGOT-5195 - ignores keepInventory rule) + this.dropFromLootTable(this.serverLevel(), damageSource, this.lastHurtByPlayerTime > 0); + this.dropCustomDeathLoot(this.serverLevel(), damageSource, flag); - ++ + loot.addAll(this.drops); + this.drops.clear(); // SPIGOT-5188: make sure to clear + @@ -552,7 +564,7 @@ + } + + net.kyori.adventure.text.Component deathMessage = event.deathMessage() != null ? event.deathMessage() : net.kyori.adventure.text.Component.empty(); // Paper - Adventure -+ + + if (deathMessage != null && deathMessage != net.kyori.adventure.text.Component.empty() && flag) { // Paper - Adventure // TODO: allow plugins to override? + Component ichatbasecomponent = PaperAdventure.asVanilla(deathMessage); // Paper - Adventure + @@ -1498,8 +1510,8 @@ + } else { + // Adds timeOffset to the beginning of this day. + return this.level().getDayTime() - (this.level().getDayTime() % 24000) + this.timeOffset; -+ } -+ } + } + } + + public WeatherType weather = null; + @@ -1514,14 +1526,14 @@ + + if (plugin) { + this.weather = type; - } ++ } + + if (type == WeatherType.DOWNFALL) { + this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.STOP_RAINING, 0)); + } else { + this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.START_RAINING, 0)); + } - } ++ } + + private float pluginRainPosition; + private float pluginRainPositionPrevious; diff --git a/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch b/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch index 89737981a3..c8ee7ab0fe 100644 --- a/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch @@ -134,7 +134,15 @@ ServerLevel worldserver = this.server.getLevel(resourcekey); ServerLevel worldserver1; -@@ -182,10 +226,27 @@ +@@ -179,13 +223,35 @@ + worldserver1 = worldserver; + } + ++ // Paper start - Entity#getEntitySpawnReason ++ if (optional.isEmpty()) { ++ player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login ++ } ++ // Paper end - Entity#getEntitySpawnReason player.setServerLevel(worldserver1); String s1 = connection.getLoggableAddress(this.server.logIPs()); @@ -164,7 +172,7 @@ ServerGamePacketListenerImpl playerconnection = new ServerGamePacketListenerImpl(this.server, connection, player, clientData); connection.setupInboundProtocol(GameProtocols.SERVERBOUND_TEMPLATE.bind(RegistryFriendlyByteBuf.decorator(this.server.registryAccess())), playerconnection); -@@ -194,7 +255,9 @@ +@@ -194,7 +260,9 @@ boolean flag1 = gamerules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO); boolean flag2 = gamerules.getBoolean(GameRules.RULE_LIMITED_CRAFTING); @@ -175,7 +183,7 @@ playerconnection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); playerconnection.send(new ClientboundPlayerAbilitiesPacket(player.getAbilities())); playerconnection.send(new ClientboundSetHeldSlotPacket(player.getInventory().selected)); -@@ -213,8 +276,10 @@ +@@ -213,8 +281,10 @@ } else { ichatmutablecomponent = Component.translatable("multiplayer.player.joined.renamed", player.getDisplayName(), s); } @@ -187,7 +195,7 @@ playerconnection.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot()); ServerStatus serverping = this.server.getStatus(); -@@ -222,17 +287,77 @@ +@@ -222,17 +292,77 @@ player.sendServerStatus(serverping); } @@ -269,7 +277,7 @@ } public void updateEntireScoreboard(ServerScoreboard scoreboard, ServerPlayer player) { -@@ -269,30 +394,31 @@ +@@ -269,30 +399,31 @@ } public void addWorldborderListener(ServerLevel world) { @@ -306,7 +314,7 @@ } @Override -@@ -319,14 +445,15 @@ +@@ -319,14 +450,15 @@ } protected void save(ServerPlayer player) { @@ -324,7 +332,7 @@ if (advancementdataplayer != null) { advancementdataplayer.save(); -@@ -334,95 +461,186 @@ +@@ -334,95 +466,186 @@ } @@ -549,7 +557,7 @@ if (entityplayer1 != null) { set.add(entityplayer1); -@@ -431,30 +649,50 @@ +@@ -431,30 +654,50 @@ Iterator iterator1 = set.iterator(); while (iterator1.hasNext()) { @@ -613,7 +621,7 @@ while (iterator.hasNext()) { String s = (String) iterator.next(); -@@ -462,41 +700,88 @@ +@@ -462,41 +705,88 @@ entityplayer1.addTag(s); } @@ -710,7 +718,7 @@ return entityplayer1; } -@@ -516,15 +801,32 @@ +@@ -516,15 +806,32 @@ } public void sendPlayerPermissionLevel(ServerPlayer player) { @@ -745,7 +753,7 @@ this.sendAllPlayerInfoIn = 0; } -@@ -541,6 +843,25 @@ +@@ -541,6 +848,25 @@ } @@ -771,7 +779,7 @@ public void broadcastAll(Packet packet, ResourceKey dimension) { Iterator iterator = this.players.iterator(); -@@ -554,7 +875,7 @@ +@@ -554,7 +880,7 @@ } @@ -780,7 +788,7 @@ PlayerTeam scoreboardteam = source.getTeam(); if (scoreboardteam != null) { -@@ -573,7 +894,7 @@ +@@ -573,7 +899,7 @@ } } @@ -789,7 +797,7 @@ PlayerTeam scoreboardteam = source.getTeam(); if (scoreboardteam == null) { -@@ -619,7 +940,7 @@ +@@ -619,7 +945,7 @@ } public void deop(GameProfile profile) { @@ -798,7 +806,7 @@ ServerPlayer entityplayer = this.getPlayer(profile.getId()); if (entityplayer != null) { -@@ -643,11 +964,30 @@ +@@ -643,36 +969,51 @@ player.connection.send(new ClientboundEntityEventPacket(player, b0)); } @@ -810,12 +818,12 @@ - return !this.doWhiteList || this.ops.contains(profile) || this.whitelist.contains(profile); + // Paper start - ProfileWhitelistVerifyEvent + return this.isWhiteListed(profile, null); -+ } + } + public boolean isWhiteListed(GameProfile gameprofile, @Nullable org.bukkit.event.player.PlayerLoginEvent loginEvent) { + boolean isOp = this.ops.contains(gameprofile); + boolean isWhitelisted = !this.doWhiteList || isOp || this.whitelist.contains(gameprofile); + final com.destroystokyo.paper.event.profile.ProfileWhitelistVerifyEvent event; -+ + + final net.kyori.adventure.text.Component configuredMessage = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.whitelistMessage); + event = new com.destroystokyo.paper.event.profile.ProfileWhitelistVerifyEvent(com.destroystokyo.paper.profile.CraftPlayerProfile.asBukkitMirror(gameprofile), this.doWhiteList, isWhitelisted, isOp, configuredMessage); + event.callEvent(); @@ -827,10 +835,11 @@ + } + return true; + // Paper end - ProfileWhitelistVerifyEvent - } - ++ } ++ public boolean isOp(GameProfile profile) { -@@ -656,23 +996,19 @@ + return this.ops.contains(profile) || this.server.isSingleplayerOwner(profile) && this.server.getWorldData().isAllowCommands() || this.allowCommandsForAllPlayers; + } @Nullable public ServerPlayer getPlayerByName(String name) { @@ -862,7 +871,7 @@ if (entityplayer != player && entityplayer.level().dimension() == worldKey) { double d4 = x - entityplayer.getX(); double d5 = y - entityplayer.getY(); -@@ -687,10 +1023,12 @@ +@@ -687,10 +1028,12 @@ } public void saveAll() { @@ -875,7 +884,7 @@ } public UserWhiteList getWhiteList() { -@@ -712,15 +1050,19 @@ +@@ -712,15 +1055,19 @@ public void reloadWhiteList() {} public void sendLevelInfo(ServerPlayer player, ServerLevel world) { @@ -899,7 +908,7 @@ } player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0.0F)); -@@ -729,8 +1071,16 @@ +@@ -729,8 +1076,16 @@ public void sendAllPlayerInfo(ServerPlayer player) { player.inventoryMenu.sendAllDataToRemote(); @@ -917,7 +926,7 @@ } public int getPlayerCount() { -@@ -746,6 +1096,7 @@ +@@ -746,6 +1101,7 @@ } public void setUsingWhiteList(boolean whitelistEnabled) { @@ -925,7 +934,7 @@ this.doWhiteList = whitelistEnabled; } -@@ -786,11 +1137,35 @@ +@@ -786,11 +1142,35 @@ } public void removeAll() { @@ -963,7 +972,7 @@ public void broadcastSystemMessage(Component message, boolean overlay) { this.broadcastSystemMessage(message, (entityplayer) -> { -@@ -819,24 +1194,43 @@ +@@ -819,24 +1199,43 @@ } public void broadcastChatMessage(PlayerChatMessage message, ServerPlayer sender, ChatType.Bound params) { @@ -1010,7 +1019,7 @@ } if (flag1 && sender != null) { -@@ -845,20 +1239,27 @@ +@@ -845,20 +1244,27 @@ } @@ -1043,7 +1052,7 @@ Path path = file2.toPath(); if (FileUtil.isPathNormalized(path) && FileUtil.isPathPortable(path) && path.startsWith(file.getPath()) && file2.isFile()) { -@@ -867,7 +1268,7 @@ +@@ -867,7 +1273,7 @@ } serverstatisticmanager = new ServerStatsCounter(this.server, file1); @@ -1052,7 +1061,7 @@ } return serverstatisticmanager; -@@ -875,13 +1276,13 @@ +@@ -875,13 +1281,13 @@ public PlayerAdvancements getPlayerAdvancements(ServerPlayer player) { UUID uuid = player.getUUID(); @@ -1068,7 +1077,7 @@ } advancementdataplayer.setPlayer(player); -@@ -932,15 +1333,28 @@ +@@ -932,15 +1338,28 @@ } public void reloadResources() { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch index feefaa5db1..cc68813c83 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch @@ -18,7 +18,7 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.FenceGateBlock; -@@ -138,9 +138,140 @@ +@@ -138,9 +138,141 @@ import net.minecraft.world.scores.ScoreHolder; import net.minecraft.world.scores.Team; import org.slf4j.Logger; @@ -140,9 +140,10 @@ + } + } + // Paper end - Share random for entities to make them more random - -+ private CraftEntity bukkitEntity; ++ public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason + ++ private CraftEntity bukkitEntity; + + public CraftEntity getBukkitEntity() { + if (this.bukkitEntity == null) { + this.bukkitEntity = CraftEntity.getEntity(this.level.getCraftServer(), this); @@ -159,7 +160,7 @@ private static final Logger LOGGER = LogUtils.getLogger(); public static final String ID_TAG = "id"; public static final String PASSENGERS_TAG = "Passengers"; -@@ -224,7 +355,7 @@ +@@ -224,7 +356,7 @@ private static final EntityDataAccessor DATA_CUSTOM_NAME_VISIBLE = SynchedEntityData.defineId(Entity.class, EntityDataSerializers.BOOLEAN); private static final EntityDataAccessor DATA_SILENT = SynchedEntityData.defineId(Entity.class, EntityDataSerializers.BOOLEAN); private static final EntityDataAccessor DATA_NO_GRAVITY = SynchedEntityData.defineId(Entity.class, EntityDataSerializers.BOOLEAN); @@ -168,7 +169,7 @@ private static final EntityDataAccessor DATA_TICKS_FROZEN = SynchedEntityData.defineId(Entity.class, EntityDataSerializers.INT); private EntityInLevelCallback levelCallback; private final VecDeltaCodec packetPositionCodec; -@@ -253,7 +384,64 @@ +@@ -253,7 +385,64 @@ private final List movementThisTick; private final Set blocksInside; private final LongSet visitedBlocks; @@ -233,7 +234,7 @@ public Entity(EntityType type, Level world) { this.id = Entity.ENTITY_COUNTER.incrementAndGet(); this.passengers = ImmutableList.of(); -@@ -261,7 +449,7 @@ +@@ -261,7 +450,7 @@ this.bb = Entity.INITIAL_AABB; this.stuckSpeedMultiplier = Vec3.ZERO; this.nextStep = 1.0F; @@ -242,7 +243,7 @@ this.remainingFireTicks = -this.getFireImmuneTicks(); this.fluidHeight = new Object2DoubleArrayMap(2); this.fluidOnEyes = new HashSet(); -@@ -284,6 +472,13 @@ +@@ -284,6 +473,13 @@ this.position = Vec3.ZERO; this.blockPosition = BlockPos.ZERO; this.chunkPosition = ChunkPos.ZERO; @@ -256,7 +257,7 @@ SynchedEntityData.Builder datawatcher_a = new SynchedEntityData.Builder(this); datawatcher_a.define(Entity.DATA_SHARED_FLAGS_ID, (byte) 0); -@@ -292,7 +487,7 @@ +@@ -292,7 +488,7 @@ datawatcher_a.define(Entity.DATA_CUSTOM_NAME, Optional.empty()); datawatcher_a.define(Entity.DATA_SILENT, false); datawatcher_a.define(Entity.DATA_NO_GRAVITY, false); @@ -265,7 +266,7 @@ datawatcher_a.define(Entity.DATA_TICKS_FROZEN, 0); this.defineSynchedData(datawatcher_a); this.entityData = datawatcher_a.build(); -@@ -362,20 +557,36 @@ +@@ -362,20 +558,36 @@ } public void kill(ServerLevel world) { @@ -304,7 +305,7 @@ public boolean equals(Object object) { return object instanceof Entity ? ((Entity) object).id == this.id : false; } -@@ -385,22 +596,34 @@ +@@ -385,22 +597,34 @@ } public void remove(Entity.RemovalReason reason) { @@ -344,7 +345,7 @@ return this.getPose() == pose; } -@@ -417,6 +640,33 @@ +@@ -417,6 +641,33 @@ } public void setRot(float yaw, float pitch) { @@ -378,7 +379,7 @@ this.setYRot(yaw % 360.0F); this.setXRot(pitch % 360.0F); } -@@ -462,6 +712,15 @@ +@@ -462,6 +713,15 @@ this.baseTick(); } @@ -394,7 +395,7 @@ public void baseTick() { ProfilerFiller gameprofilerfiller = Profiler.get(); -@@ -475,7 +734,7 @@ +@@ -475,7 +735,7 @@ --this.boardingCooldown; } @@ -403,7 +404,7 @@ if (this.canSpawnSprintParticle()) { this.spawnSprintParticle(); } -@@ -514,6 +773,10 @@ +@@ -514,6 +774,10 @@ if (this.isInLava()) { this.lavaHurt(); this.fallDistance *= 0.5F; @@ -414,7 +415,7 @@ } this.checkBelowWorld(); -@@ -525,7 +788,7 @@ +@@ -525,7 +789,7 @@ world = this.level(); if (world instanceof ServerLevel worldserver) { if (this instanceof Leashable) { @@ -423,7 +424,7 @@ } } -@@ -537,7 +800,11 @@ +@@ -537,7 +801,11 @@ } public void checkBelowWorld() { @@ -436,7 +437,7 @@ this.onBelowWorld(); } -@@ -568,15 +835,32 @@ +@@ -568,15 +836,32 @@ public void lavaHurt() { if (!this.fireImmune()) { @@ -471,7 +472,7 @@ } } -@@ -587,9 +871,25 @@ +@@ -587,9 +872,25 @@ } public final void igniteForSeconds(float seconds) { @@ -498,7 +499,7 @@ public void igniteForTicks(int ticks) { if (this.remainingFireTicks < ticks) { this.setRemainingFireTicks(ticks); -@@ -610,7 +910,7 @@ +@@ -610,7 +911,7 @@ } protected void onBelowWorld() { @@ -507,13 +508,10 @@ } public boolean isFree(double offsetX, double offsetY, double offsetZ) { -@@ -747,8 +1047,30 @@ +@@ -750,6 +1051,28 @@ + } + } - if (movement.y != vec3d1.y) { - block.updateEntityMovementAfterFallOn(this.level(), this); -+ } -+ } -+ + // CraftBukkit start + if (this.horizontalCollision && this.getBukkitEntity() instanceof Vehicle) { + Vehicle vehicle = (Vehicle) this.getBukkitEntity(); @@ -527,18 +525,19 @@ + bl = bl.getRelative(BlockFace.SOUTH); + } else if (movement.z < vec3d1.z) { + bl = bl.getRelative(BlockFace.NORTH); - } ++ } + + if (!bl.getType().isAir()) { + VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, bl); + this.level.getCraftServer().getPluginManager().callEvent(event); + } - } ++ } + // CraftBukkit end - ++ if (!this.level().isClientSide() || this.isControlledByLocalInstance()) { Entity.MovementEmission entity_movementemission = this.getMovementEmission(); -@@ -1133,6 +1455,20 @@ + +@@ -1133,6 +1456,20 @@ return SoundEvents.GENERIC_SPLASH; } @@ -559,7 +558,7 @@ public void recordMovementThroughBlocks(Vec3 oldPos, Vec3 newPos) { this.movementThisTick.add(new Entity.Movement(oldPos, newPos)); } -@@ -1609,6 +1945,7 @@ +@@ -1609,6 +1946,7 @@ this.yo = y; this.zo = d4; this.setPos(d3, y, d4); @@ -567,7 +566,7 @@ } public void moveTo(Vec3 pos) { -@@ -1737,7 +2074,21 @@ +@@ -1737,7 +2075,21 @@ } public void push(double deltaX, double deltaY, double deltaZ) { @@ -590,7 +589,7 @@ this.hasImpulse = true; } -@@ -1861,6 +2212,12 @@ +@@ -1861,6 +2213,12 @@ return false; } @@ -603,7 +602,7 @@ public void awardKillScore(Entity entityKilled, DamageSource damageSource) { if (entityKilled instanceof ServerPlayer) { CriteriaTriggers.ENTITY_KILLED_PLAYER.trigger((ServerPlayer) entityKilled, this, damageSource); -@@ -1889,16 +2246,22 @@ +@@ -1889,16 +2247,22 @@ } public boolean saveAsPassenger(CompoundTag nbt) { @@ -629,21 +628,22 @@ return true; } } -@@ -1909,54 +2272,98 @@ +@@ -1909,54 +2273,98 @@ } public CompoundTag saveWithoutId(CompoundTag nbt) { +- try { +- if (this.vehicle != null) { +- nbt.put("Pos", this.newDoubleList(this.vehicle.getX(), this.getY(), this.vehicle.getZ())); +- } else { +- nbt.put("Pos", this.newDoubleList(this.getX(), this.getY(), this.getZ())); + // CraftBukkit start - allow excluding certain data when saving + return this.saveWithoutId(nbt, true); + } + + public CompoundTag saveWithoutId(CompoundTag nbttagcompound, boolean includeAll) { + // CraftBukkit end - try { -- if (this.vehicle != null) { -- nbt.put("Pos", this.newDoubleList(this.vehicle.getX(), this.getY(), this.vehicle.getZ())); -- } else { -- nbt.put("Pos", this.newDoubleList(this.getX(), this.getY(), this.getZ())); ++ try { + // CraftBukkit start - selectively save position + if (includeAll) { + if (this.vehicle != null) { @@ -748,7 +748,7 @@ } ListTag nbttaglist; -@@ -1972,10 +2379,10 @@ +@@ -1972,10 +2380,10 @@ nbttaglist.add(StringTag.valueOf(s)); } @@ -761,7 +761,7 @@ if (this.isVehicle()) { nbttaglist = new ListTag(); iterator = this.getPassengers().iterator(); -@@ -1984,17 +2391,35 @@ +@@ -1984,17 +2392,38 @@ Entity entity = (Entity) iterator.next(); CompoundTag nbttagcompound1 = new CompoundTag(); @@ -791,6 +791,9 @@ + } + nbttagcompound.put("Paper.Origin", this.newDoubleList(origin.getX(), origin.getY(), origin.getZ())); + } ++ if (spawnReason != null) { ++ nbttagcompound.putString("Paper.SpawnReason", spawnReason.name()); ++ } + // Save entity's from mob spawner status + if (spawnedViaMobSpawner) { + nbttagcompound.putBoolean("Paper.FromMobSpawner", true); @@ -800,10 +803,11 @@ } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT"); CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being saved"); -@@ -2080,6 +2505,66 @@ +@@ -2079,7 +2508,87 @@ + } } else { throw new IllegalStateException("Entity has invalid position"); - } ++ } + + // CraftBukkit start + // Spigot start @@ -862,12 +866,32 @@ + } + + spawnedViaMobSpawner = nbt.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status ++ if (nbt.contains("Paper.SpawnReason")) { ++ String spawnReasonName = nbt.getString("Paper.SpawnReason"); ++ try { ++ spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.valueOf(spawnReasonName); ++ } catch (Exception ignored) { ++ LOGGER.error("Unknown SpawnReason " + spawnReasonName + " for " + this); ++ } ++ } ++ if (spawnReason == null) { ++ if (spawnedViaMobSpawner) { ++ spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; ++ } else if (this instanceof Mob && (this instanceof net.minecraft.world.entity.animal.Animal || this instanceof net.minecraft.world.entity.animal.AbstractFish) && !((Mob) this).removeWhenFarAway(0.0)) { ++ if (!nbt.getBoolean("PersistenceRequired")) { ++ spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL; ++ } ++ } + } ++ if (spawnReason == null) { ++ spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; ++ } + // Paper end + } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT"); CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being loaded"); -@@ -2101,6 +2586,12 @@ +@@ -2101,6 +2610,12 @@ return entitytypes.canSerialize() && minecraftkey != null ? minecraftkey.toString() : null; } @@ -880,7 +904,7 @@ protected abstract void readAdditionalSaveData(CompoundTag nbt); protected abstract void addAdditionalSaveData(CompoundTag nbt); -@@ -2153,9 +2644,22 @@ +@@ -2153,9 +2668,22 @@ if (stack.isEmpty()) { return null; } else { @@ -903,7 +927,7 @@ world.addFreshEntity(entityitem); return entityitem; } -@@ -2184,6 +2688,12 @@ +@@ -2184,6 +2712,12 @@ if (this.isAlive() && this instanceof Leashable leashable) { if (leashable.getLeashHolder() == player) { if (!this.level().isClientSide()) { @@ -916,7 +940,7 @@ if (player.hasInfiniteMaterials()) { leashable.removeLeash(); } else { -@@ -2200,6 +2710,13 @@ +@@ -2200,6 +2734,13 @@ if (itemstack.is(Items.LEAD) && leashable.canHaveALeashAttachedToIt()) { if (!this.level().isClientSide()) { @@ -930,7 +954,7 @@ leashable.setLeashedTo(player, true); } -@@ -2265,7 +2782,7 @@ +@@ -2265,7 +2806,7 @@ } public boolean showVehicleHealth() { @@ -939,7 +963,7 @@ } public boolean startRiding(Entity entity, boolean force) { -@@ -2273,7 +2790,7 @@ +@@ -2273,7 +2814,7 @@ return false; } else if (!entity.couldAcceptPassenger()) { return false; @@ -948,7 +972,7 @@ return false; } else { for (Entity entity1 = entity; entity1.vehicle != null; entity1 = entity1.vehicle) { -@@ -2285,11 +2802,32 @@ +@@ -2285,11 +2826,32 @@ if (!force && (!this.canRide(entity) || !entity.canAddPassenger(this))) { return false; } else { @@ -982,7 +1006,7 @@ this.vehicle = entity; this.vehicle.addPassenger(this); entity.getIndirectPassengersStream().filter((entity2) -> { -@@ -2314,19 +2852,30 @@ +@@ -2314,19 +2876,30 @@ } public void removeVehicle() { @@ -1015,7 +1039,7 @@ protected void addPassenger(Entity passenger) { if (passenger.getVehicle() != this) { throw new IllegalStateException("Use x.startRiding(y), not y.addPassenger(x)"); -@@ -2349,21 +2898,53 @@ +@@ -2349,21 +2922,53 @@ } } @@ -1075,7 +1099,7 @@ } protected boolean canAddPassenger(Entity passenger) { -@@ -2464,7 +3045,7 @@ +@@ -2464,7 +3069,7 @@ if (teleporttransition != null) { ServerLevel worldserver1 = teleporttransition.newLevel(); @@ -1084,7 +1108,7 @@ this.teleport(teleporttransition); } } -@@ -2547,7 +3128,7 @@ +@@ -2547,7 +3152,7 @@ } public boolean isCrouching() { @@ -1093,7 +1117,7 @@ } public boolean isSprinting() { -@@ -2563,7 +3144,7 @@ +@@ -2563,7 +3168,7 @@ } public boolean isVisuallySwimming() { @@ -1102,7 +1126,7 @@ } public boolean isVisuallyCrawling() { -@@ -2571,6 +3152,13 @@ +@@ -2571,6 +3176,13 @@ } public void setSwimming(boolean swimming) { @@ -1116,7 +1140,7 @@ this.setSharedFlag(4, swimming); } -@@ -2609,6 +3197,7 @@ +@@ -2609,6 +3221,7 @@ @Nullable public PlayerTeam getTeam() { @@ -1124,7 +1148,7 @@ return this.level().getScoreboard().getPlayersTeam(this.getScoreboardName()); } -@@ -2624,8 +3213,12 @@ +@@ -2624,8 +3237,12 @@ return this.getTeam() != null ? this.getTeam().isAlliedTo(team) : false; } @@ -1138,7 +1162,7 @@ } public boolean getSharedFlag(int index) { -@@ -2644,7 +3237,7 @@ +@@ -2644,7 +3261,7 @@ } public int getMaxAirSupply() { @@ -1147,7 +1171,7 @@ } public int getAirSupply() { -@@ -2652,7 +3245,18 @@ +@@ -2652,7 +3269,18 @@ } public void setAirSupply(int air) { @@ -1167,7 +1191,7 @@ } public int getTicksFrozen() { -@@ -2679,11 +3283,40 @@ +@@ -2679,11 +3307,40 @@ public void thunderHit(ServerLevel world, LightningBolt lightning) { this.setRemainingFireTicks(this.remainingFireTicks + 1); @@ -1210,7 +1234,7 @@ } public void onAboveBubbleCol(boolean drag) { -@@ -2713,7 +3346,7 @@ +@@ -2713,7 +3370,7 @@ this.resetFallDistance(); } @@ -1219,7 +1243,7 @@ return true; } -@@ -2818,7 +3451,7 @@ +@@ -2818,7 +3475,7 @@ public String toString() { String s = this.level() == null ? "~NULL~" : this.level().toString(); @@ -1228,7 +1252,7 @@ } public final boolean isInvulnerableToBase(DamageSource damageSource) { -@@ -2852,6 +3485,26 @@ +@@ -2852,6 +3509,26 @@ if (world instanceof ServerLevel worldserver) { if (!this.isRemoved()) { @@ -1255,7 +1279,7 @@ ServerLevel worldserver1 = teleportTarget.newLevel(); boolean flag = worldserver1.dimension() != worldserver.dimension(); -@@ -2920,8 +3573,12 @@ +@@ -2920,8 +3597,12 @@ } else { entity.restoreFrom(this); this.removeAfterChangingDimensions(); @@ -1269,7 +1293,7 @@ Iterator iterator1 = list1.iterator(); while (iterator1.hasNext()) { -@@ -2947,7 +3604,7 @@ +@@ -2947,7 +3628,7 @@ } private void sendTeleportTransitionToRidingPlayers(TeleportTransition teleportTarget) { @@ -1278,7 +1302,7 @@ Iterator iterator = this.getIndirectPassengers().iterator(); while (iterator.hasNext()) { -@@ -2995,8 +3652,9 @@ +@@ -2995,8 +3676,9 @@ } protected void removeAfterChangingDimensions() { @@ -1289,7 +1313,7 @@ leashable.removeLeash(); } -@@ -3004,7 +3662,21 @@ +@@ -3004,7 +3686,21 @@ public Vec3 getRelativePortalPosition(Direction.Axis portalAxis, BlockUtil.FoundRectangle portalRect) { return PortalShape.getRelativePosition(portalRect, portalAxis, this.position(), this.getDimensions(this.getPose())); @@ -1311,7 +1335,7 @@ public boolean canUsePortal(boolean allowVehicles) { return (allowVehicles || !this.isPassenger()) && this.isAlive(); -@@ -3134,10 +3806,16 @@ +@@ -3134,10 +3830,16 @@ return (Boolean) this.entityData.get(Entity.DATA_CUSTOM_NAME_VISIBLE); } @@ -1331,7 +1355,7 @@ return entity != null; } -@@ -3187,7 +3865,7 @@ +@@ -3187,7 +3889,7 @@ /** @deprecated */ @Deprecated protected void fixupDimensions() { @@ -1340,7 +1364,7 @@ EntityDimensions entitysize = this.getDimensions(entitypose); this.dimensions = entitysize; -@@ -3196,7 +3874,7 @@ +@@ -3196,7 +3898,7 @@ public void refreshDimensions() { EntityDimensions entitysize = this.dimensions; @@ -1349,7 +1373,7 @@ EntityDimensions entitysize1 = this.getDimensions(entitypose); this.dimensions = entitysize1; -@@ -3258,10 +3936,29 @@ +@@ -3258,10 +3960,29 @@ } public final void setBoundingBox(AABB boundingBox) { @@ -1381,7 +1405,7 @@ return this.getDimensions(pose).eyeHeight(); } -@@ -3335,7 +4032,7 @@ +@@ -3335,7 +4056,7 @@ } @Nullable @@ -1390,7 +1414,7 @@ return null; } -@@ -3435,7 +4132,7 @@ +@@ -3435,7 +4156,7 @@ } public boolean isControlledByLocalInstance() { @@ -1399,7 +1423,7 @@ if (entityliving instanceof Player entityhuman) { return entityhuman.isLocalPlayer(); -@@ -3445,7 +4142,7 @@ +@@ -3445,7 +4166,7 @@ } public boolean isControlledByClient() { @@ -1408,7 +1432,7 @@ return entityliving != null && entityliving.isControlledByClient(); } -@@ -3463,7 +4160,7 @@ +@@ -3463,7 +4184,7 @@ return new Vec3((double) f1 * d2 / (double) f3, 0.0D, (double) f2 * d2 / (double) f3); } @@ -1417,7 +1441,7 @@ return new Vec3(this.getX(), this.getBoundingBox().maxY, this.getZ()); } -@@ -3488,9 +4185,38 @@ +@@ -3488,9 +4209,38 @@ public int getFireImmuneTicks() { return 1; } @@ -1457,7 +1481,7 @@ } public void lookAt(EntityAnchorArgument.Anchor anchorPoint, Vec3 target) { -@@ -3551,6 +4277,11 @@ +@@ -3551,6 +4301,11 @@ vec3d = vec3d.add(vec3d1); ++k1; } @@ -1469,7 +1493,7 @@ } } } -@@ -3613,7 +4344,7 @@ +@@ -3613,7 +4368,7 @@ return new ClientboundAddEntityPacket(this, entityTrackerEntry); } @@ -1478,7 +1502,7 @@ return this.type.getDimensions(); } -@@ -3818,8 +4549,16 @@ +@@ -3818,8 +4573,16 @@ @Override public final void setRemoved(Entity.RemovalReason reason) { @@ -1496,7 +1520,7 @@ } if (this.removalReason.shouldDestroy()) { -@@ -3827,8 +4566,8 @@ +@@ -3827,8 +4590,8 @@ } this.getPassengers().forEach(Entity::stopRiding); @@ -1507,7 +1531,7 @@ } public void unsetRemoved() { -@@ -3887,7 +4626,7 @@ +@@ -3887,7 +4650,7 @@ } public Vec3 getKnownMovement() { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/EntityType.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/EntityType.java.patch index 96cfe9b1a7..b8a966fe0f 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/EntityType.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/EntityType.java.patch @@ -32,7 +32,7 @@ public T spawn(ServerLevel world, @Nullable ItemStack stack, @Nullable Player player, BlockPos pos, EntitySpawnReason spawnReason, boolean alignPosition, boolean invertY) { - Consumer consumer; + // CraftBukkit start -+ return this.spawn(world, stack, player, pos, spawnReason, alignPosition, invertY, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); ++ return this.spawn(world, stack, player, pos, spawnReason, alignPosition, invertY, spawnReason == EntitySpawnReason.DISPENSER ? org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DISPENSE_EGG : org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); // Paper - use correct spawn reason for dispenser spawn eggs + } - if (stack != null) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/OminousItemSpawner.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/OminousItemSpawner.java.patch new file mode 100644 index 0000000000..c390374ad2 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/OminousItemSpawner.java.patch @@ -0,0 +1,29 @@ +--- a/net/minecraft/world/entity/OminousItemSpawner.java ++++ b/net/minecraft/world/entity/OminousItemSpawner.java +@@ -76,7 +76,7 @@ + entity = this.spawnProjectile(serverLevel, projectileItem, itemStack); + } else { + entity = new ItemEntity(serverLevel, this.getX(), this.getY(), this.getZ(), itemStack); +- serverLevel.addFreshEntity(entity); ++ serverLevel.addFreshEntity(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.OMINOUS_ITEM_SPAWNER); // Paper - fixes and addition to spawn reason API + } + + serverLevel.levelEvent(3021, this.blockPosition(), 1); +@@ -90,7 +90,7 @@ + ProjectileItem.DispenseConfig dispenseConfig = item.createDispenseConfig(); + dispenseConfig.overrideDispenseEvent().ifPresent(dispenseEvent -> world.levelEvent(dispenseEvent, this.blockPosition(), 0)); + Direction direction = Direction.DOWN; +- Projectile projectile = Projectile.spawnProjectileUsingShoot( ++ Projectile projectile = Projectile.spawnProjectileUsingShootDelayed( // Paper - fixes and addition to spawn reason API + item.asProjectile(world, this.position(), stack, direction), + world, + stack, +@@ -99,7 +99,7 @@ + (double)direction.getStepZ(), + dispenseConfig.power(), + dispenseConfig.uncertainty() +- ); ++ ).spawn(org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.OMINOUS_ITEM_SPAWNER); // Paper - fixes and addition to spawn reason API + projectile.setOwner(this); + return projectile; + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/DragonFireball.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/DragonFireball.java.patch index b26136aad2..6278d9b3bb 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/DragonFireball.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/DragonFireball.java.patch @@ -16,8 +16,9 @@ + if (new com.destroystokyo.paper.event.entity.EnderDragonFireballHitEvent((org.bukkit.entity.DragonFireball) this.getBukkitEntity(), list.stream().map(LivingEntity::getBukkitLivingEntity).collect(java.util.stream.Collectors.toList()), (org.bukkit.entity.AreaEffectCloud) entityareaeffectcloud.getBukkitEntity()).callEvent()) { // Paper - EnderDragon Events this.level().levelEvent(2006, this.blockPosition(), this.isSilent() ? -1 : 1); - this.level().addFreshEntity(entityareaeffectcloud); +- this.level().addFreshEntity(entityareaeffectcloud); - this.discard(); ++ this.level().addFreshEntity(entityareaeffectcloud, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EXPLOSION); // Paper - use correct spawn reason + } else entityareaeffectcloud.discard(null); // Paper - EnderDragon Events + this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/Projectile.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/Projectile.java.patch index fa8233aaf8..1af8ae076b 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/Projectile.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/Projectile.java.patch @@ -43,7 +43,21 @@ iprojectile.shootFromRotation(shooter, shooter.getXRot(), shooter.getYRot(), roll, power, divergence); }); } -@@ -211,11 +224,34 @@ +@@ -201,7 +214,12 @@ + } + + public static T spawnProjectileUsingShoot(T projectile, ServerLevel world, ItemStack projectileStack, double velocityX, double velocityY, double velocityZ, float power, float divergence) { +- return Projectile.spawnProjectile(projectile, world, projectileStack, (iprojectile) -> { ++ // Paper start - fixes and addition to spawn reason API ++ return spawnProjectileUsingShootDelayed(projectile, world, projectileStack, velocityX, velocityY, velocityZ, power, divergence).spawn(); ++ } ++ public static Delayed spawnProjectileUsingShootDelayed(T projectile, ServerLevel world, ItemStack projectileStack, double velocityX, double velocityY, double velocityZ, float power, float divergence) { ++ return Projectile.spawnProjectileDelayed(projectile, world, projectileStack, (iprojectile) -> { ++ // Paper end - fixes and addition to spawn reason API + projectile.shoot(velocityX, velocityY, velocityZ, power, divergence); + }); + } +@@ -211,11 +229,45 @@ }); } @@ -64,6 +78,17 @@ + this.attemptSpawn(); + return projectile(); + } ++ ++ public boolean attemptSpawn(final org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { ++ if (!world.addFreshEntity(projectile, reason)) return false; ++ projectile.applyOnProjectileSpawned(this.world, this.projectileStack); ++ return true; ++ } ++ ++ public T spawn(final org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { ++ this.attemptSpawn(reason); ++ return projectile(); ++ } + } + // Paper end - delayed projectile spawning + @@ -81,7 +106,7 @@ } public void applyOnProjectileSpawned(ServerLevel world, ItemStack projectileStack) { -@@ -232,6 +268,17 @@ +@@ -232,6 +284,17 @@ } @@ -99,7 +124,7 @@ protected ProjectileDeflection hitTargetOrDeflectSelf(HitResult hitResult) { if (hitResult.getType() == HitResult.Type.ENTITY) { EntityHitResult movingobjectpositionentity = (EntityHitResult) hitResult; -@@ -309,6 +356,11 @@ +@@ -309,6 +372,11 @@ protected void onHitEntity(EntityHitResult entityHitResult) {} protected void onHitBlock(BlockHitResult blockHitResult) { @@ -111,7 +136,7 @@ BlockState iblockdata = this.level().getBlockState(blockHitResult.getBlockPos()); iblockdata.onProjectileHit(this.level(), iblockdata, blockHitResult, this); -@@ -320,6 +372,15 @@ +@@ -320,6 +388,15 @@ } else { Entity entity1 = this.getOwner(); diff --git a/paper-server/patches/sources/net/minecraft/world/level/BaseSpawner.java.patch b/paper-server/patches/sources/net/minecraft/world/level/BaseSpawner.java.patch index 027b08f4af..6b80790cb6 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/BaseSpawner.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/BaseSpawner.java.patch @@ -40,12 +40,10 @@ } else { boolean flag = false; RandomSource randomsource = world.getRandom(); -@@ -123,8 +130,22 @@ - continue; - } +@@ -125,6 +132,20 @@ } else if (!SpawnPlacements.checkSpawnRules((EntityType) optional.get(), world, EntitySpawnReason.SPAWNER, blockposition1, world.getRandom())) { -+ continue; -+ } + continue; + } + // Paper start - PreCreatureSpawnEvent + com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent event = new com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent( + io.papermc.paper.util.MCUtil.toLocation(world, d0, d1, d2), @@ -57,13 +55,13 @@ + if (event.shouldAbortSpawn()) { + break; + } - continue; - } ++ continue; ++ } + // Paper end - PreCreatureSpawnEvent Entity entity = EntityType.loadEntityRecursive(nbttagcompound, world, EntitySpawnReason.SPAWNER, (entity1) -> { entity1.moveTo(d0, d1, d2, entity1.getYRot(), entity1.getXRot()); -@@ -157,13 +178,26 @@ +@@ -157,13 +178,27 @@ ((Mob) entity).finalizeSpawn(world, world.getCurrentDifficultyAt(entity.blockPosition()), EntitySpawnReason.SPAWNER, (SpawnGroupData) null); } @@ -82,6 +80,7 @@ - if (!world.tryAddFreshEntityWithPassengers(entity)) { + entity.spawnedViaMobSpawner = true; // Paper ++ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; // Paper - Entity#getEntitySpawnReason + flag = true; // Paper + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) { @@ -92,7 +91,7 @@ this.delay(world, pos); return; } -@@ -174,7 +208,7 @@ +@@ -174,7 +209,7 @@ ((Mob) entity).spawnAnim(); } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/FrogspawnBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/FrogspawnBlock.java.patch new file mode 100644 index 0000000000..949818c5df --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/FrogspawnBlock.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/block/FrogspawnBlock.java ++++ b/net/minecraft/world/level/block/FrogspawnBlock.java +@@ -121,7 +121,7 @@ + int k = random.nextInt(1, 361); + tadpole.moveTo(d, (double)pos.getY() - 0.5, e, (float)k, 0.0F); + tadpole.setPersistenceRequired(); +- world.addFreshEntity(tadpole); ++ world.addFreshEntity(tadpole, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); // Paper - use correct spawn reason + } + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SnifferEggBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SnifferEggBlock.java.patch new file mode 100644 index 0000000000..5d27c22c8f --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SnifferEggBlock.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/block/SnifferEggBlock.java ++++ b/net/minecraft/world/level/block/SnifferEggBlock.java +@@ -74,7 +74,7 @@ + Vec3 vec3 = pos.getCenter(); + sniffer.setBaby(true); + sniffer.moveTo(vec3.x(), vec3.y(), vec3.z(), Mth.wrapDegrees(world.random.nextFloat() * 360.0F), 0.0F); +- world.addFreshEntity(sniffer); ++ world.addFreshEntity(sniffer, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); // Paper - use correct spawn reason + } + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java.patch new file mode 100644 index 0000000000..8e55cbe475 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java ++++ b/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java +@@ -190,7 +190,7 @@ + private boolean trySummonWarden(ServerLevel world) { + return this.warningLevel >= 4 + && SpawnUtil.trySpawnMob( +- EntityType.WARDEN, EntitySpawnReason.TRIGGERED, world, this.getBlockPos(), 20, 5, 6, SpawnUtil.Strategy.ON_TOP_OF_COLLIDER, false ++ EntityType.WARDEN, EntitySpawnReason.TRIGGERED, world, this.getBlockPos(), 20, 5, 6, SpawnUtil.Strategy.ON_TOP_OF_COLLIDER, false, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL, null // Paper - Entity#getEntitySpawnReason + ) + .isPresent(); + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch index e0a9930eed..9bcacf4e23 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch @@ -12,7 +12,7 @@ public final class TrialSpawner { -@@ -219,13 +224,19 @@ +@@ -219,14 +224,21 @@ } entityinsentient.setPersistenceRequired(); @@ -25,16 +25,18 @@ - if (!world.tryAddFreshEntityWithPassengers(entity)) { + entity.spawnedViaMobSpawner = true; // Paper ++ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER; // Paper - Entity#getEntitySpawnReason + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callTrialSpawnerSpawnEvent(entity, pos).isCancelled()) { -+ return Optional.empty(); + return Optional.empty(); + } + if (!world.tryAddFreshEntityWithPassengers(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER)) { + // CraftBukkit end - return Optional.empty(); ++ return Optional.empty(); } else { TrialSpawner.FlameParticle trialspawner_a = this.isOminous ? TrialSpawner.FlameParticle.OMINOUS : TrialSpawner.FlameParticle.NORMAL; -@@ -248,6 +259,15 @@ + +@@ -248,6 +260,15 @@ ObjectArrayList objectarraylist = loottable.getRandomItems(lootparams); if (!objectarraylist.isEmpty()) { 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 d6241e2db3..73788d702a 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 @@ -1014,4 +1014,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return this.getHandle().spawnedViaMobSpawner; } // Paper end - Entity#fromMobSpawner + + // Paper start - entity spawn reason API + @Override + public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason getEntitySpawnReason() { + return getHandle().spawnReason; + } + // Paper end - entity spawn reason API }