From c3d5f253fedf91cb9d1bd9413618ec7730a99a61 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Fri, 13 Dec 2024 20:30:07 +0100 Subject: [PATCH] Moar --- .../util/SimpleBitStorage.java.patch | 37 ++++------ .../net/minecraft/util/SpawnUtil.java.patch | 70 +++++++++++++++++++ .../net/minecraft/util/StringUtil.java.patch | 8 +-- .../minecraft/util/TickThrottler.java.patch | 26 +++---- .../minecraft/util/ZeroBitStorage.java.patch | 2 +- .../DynamicGameEventListener.java.patch | 11 +++ .../level/gameevent/GameEvent.java.patch | 10 +-- .../gameevent/GameEventDispatcher.java.patch | 40 +++++++++++ .../minecraft/util/SortedArraySet.java.patch | 11 --- .../net/minecraft/util/SpawnUtil.java.patch | 60 ---------------- .../DynamicGameEventListener.java.patch | 11 --- .../gameevent/GameEventDispatcher.java.patch | 39 ----------- 12 files changed, 155 insertions(+), 170 deletions(-) rename paper-server/patches/{unapplied => sources}/net/minecraft/util/SimpleBitStorage.java.patch (58%) create mode 100644 paper-server/patches/sources/net/minecraft/util/SpawnUtil.java.patch rename paper-server/patches/{unapplied => sources}/net/minecraft/util/StringUtil.java.patch (75%) rename paper-server/patches/{unapplied => sources}/net/minecraft/util/TickThrottler.java.patch (73%) rename paper-server/patches/{unapplied => sources}/net/minecraft/util/ZeroBitStorage.java.patch (98%) create mode 100644 paper-server/patches/sources/net/minecraft/world/level/gameevent/DynamicGameEventListener.java.patch rename paper-server/patches/{unapplied => sources}/net/minecraft/world/level/gameevent/GameEvent.java.patch (51%) create mode 100644 paper-server/patches/sources/net/minecraft/world/level/gameevent/GameEventDispatcher.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/util/SortedArraySet.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/util/SpawnUtil.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/gameevent/DynamicGameEventListener.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/gameevent/GameEventDispatcher.java.patch diff --git a/paper-server/patches/unapplied/net/minecraft/util/SimpleBitStorage.java.patch b/paper-server/patches/sources/net/minecraft/util/SimpleBitStorage.java.patch similarity index 58% rename from paper-server/patches/unapplied/net/minecraft/util/SimpleBitStorage.java.patch rename to paper-server/patches/sources/net/minecraft/util/SimpleBitStorage.java.patch index d3a669c38d..29822af20e 100644 --- a/paper-server/patches/unapplied/net/minecraft/util/SimpleBitStorage.java.patch +++ b/paper-server/patches/sources/net/minecraft/util/SimpleBitStorage.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/util/SimpleBitStorage.java +++ b/net/minecraft/util/SimpleBitStorage.java -@@ -204,8 +204,8 @@ +@@ -204,8 +_,8 @@ private final long mask; private final int size; private final int valuesPerLong; @@ -10,28 +10,26 @@ + private final int divideAdd; private final long divideAddUnsigned; // Paper - Perf: Optimize SimpleBitStorage private final int divideShift; - public SimpleBitStorage(int elementBits, int size, int[] data) { -@@ -248,8 +248,8 @@ - this.mask = (1L << elementBits) - 1L; - this.valuesPerLong = (char)(64 / elementBits); + public SimpleBitStorage(int bits, int size, int[] data) { +@@ -248,8 +_,8 @@ + this.mask = (1L << bits) - 1L; + this.valuesPerLong = (char)(64 / bits); int i = 3 * (this.valuesPerLong - 1); - this.divideMul = MAGIC[i + 0]; - this.divideAdd = MAGIC[i + 1]; + this.divideMul = MAGIC[i + 0]; this.divideMulUnsigned = Integer.toUnsignedLong(this.divideMul); // Paper - Perf: Optimize SimpleBitStorage + this.divideAdd = MAGIC[i + 1]; this.divideAddUnsigned = Integer.toUnsignedLong(this.divideAdd); // Paper - Perf: Optimize SimpleBitStorage this.divideShift = MAGIC[i + 2]; - int j = (size + this.valuesPerLong - 1) / this.valuesPerLong; + int i1 = (size + this.valuesPerLong - 1) / this.valuesPerLong; if (data != null) { -@@ -264,15 +264,15 @@ +@@ -264,15 +_,11 @@ } private int cellIndex(int index) { - long l = Integer.toUnsignedLong(this.divideMul); -- long m = Integer.toUnsignedLong(this.divideAdd); -- return (int)((long)index * l + m >> 32 >> this.divideShift); -+ //long l = Integer.toUnsignedLong(this.divideMul); // Paper - Perf: Optimize SimpleBitStorage -+ //long m = Integer.toUnsignedLong(this.divideAdd); // Paper - Perf: Optimize SimpleBitStorage -+ return (int) (index * this.divideMulUnsigned + this.divideAddUnsigned >> 32 >> this.divideShift); // Paper - Perf: Optimize SimpleBitStorage +- long l1 = Integer.toUnsignedLong(this.divideAdd); +- return (int)(index * l + l1 >> 32 >> this.divideShift); ++ return (int)(index * this.divideMulUnsigned + this.divideAddUnsigned >> 32 >> this.divideShift); // Paper - Perf: Optimize SimpleBitStorage } @Override @@ -39,12 +37,10 @@ - Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); - Validate.inclusiveBetween(0L, this.mask, (long)value); + public final int getAndSet(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage -+ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage -+ //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper - Perf: Optimize SimpleBitStorage int i = this.cellIndex(index); long l = this.data[i]; - int j = (index - i * this.valuesPerLong) * this.bits; -@@ -282,9 +282,9 @@ + int i1 = (index - i * this.valuesPerLong) * this.bits; +@@ -282,9 +_,7 @@ } @Override @@ -52,19 +48,16 @@ - Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); - Validate.inclusiveBetween(0L, this.mask, (long)value); + public final void set(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage -+ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage -+ //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper - Perf: Optimize SimpleBitStorage int i = this.cellIndex(index); long l = this.data[i]; - int j = (index - i * this.valuesPerLong) * this.bits; -@@ -292,8 +292,8 @@ + int i1 = (index - i * this.valuesPerLong) * this.bits; +@@ -292,8 +_,7 @@ } @Override - public int get(int index) { - Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); + public final int get(int index) { // Paper - Perf: Optimize SimpleBitStorage -+ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper - Perf: Optimize SimpleBitStorage int i = this.cellIndex(index); long l = this.data[i]; - int j = (index - i * this.valuesPerLong) * this.bits; + int i1 = (index - i * this.valuesPerLong) * this.bits; diff --git a/paper-server/patches/sources/net/minecraft/util/SpawnUtil.java.patch b/paper-server/patches/sources/net/minecraft/util/SpawnUtil.java.patch new file mode 100644 index 0000000000..89419f5c21 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/util/SpawnUtil.java.patch @@ -0,0 +1,70 @@ +--- a/net/minecraft/util/SpawnUtil.java ++++ b/net/minecraft/util/SpawnUtil.java +@@ -16,6 +_,7 @@ + import net.minecraft.world.level.block.state.BlockState; + + public class SpawnUtil { ++ + public static Optional trySpawnMob( + EntityType entityType, + EntitySpawnReason spawnReason, +@@ -27,6 +_,24 @@ + SpawnUtil.Strategy strategy, + boolean checkCollision + ) { ++ // CraftBukkit start ++ return trySpawnMob(entityType, spawnReason, level, pos, attempts, range, yOffset, strategy, checkCollision, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT, null); // Paper - pre creature spawn event ++ } ++ ++ public static Optional trySpawnMob( ++ EntityType entityType, ++ EntitySpawnReason spawnReason, ++ ServerLevel level, ++ BlockPos pos, ++ int attempts, ++ int range, ++ int yOffset, ++ SpawnUtil.Strategy strategy, ++ boolean checkCollision, ++ org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason, ++ @javax.annotation.Nullable Runnable onAbort // Paper - pre creature spawn event ++ ) { ++ // CraftBukkit end + BlockPos.MutableBlockPos mutableBlockPos = pos.mutable(); + + for (int i = 0; i < attempts; i++) { +@@ -39,15 +_,32 @@ + !checkCollision + || level.noCollision(entityType.getSpawnAABB(mutableBlockPos.getX() + 0.5, mutableBlockPos.getY(), mutableBlockPos.getZ() + 0.5)) + )) { ++ // Paper start - PreCreatureSpawnEvent ++ final com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent( ++ io.papermc.paper.util.MCUtil.toLocation(level, pos), ++ org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkit(entityType), ++ reason ++ ); ++ if (!event.callEvent()) { ++ if (event.shouldAbortSpawn()) { ++ if (onAbort != null) { ++ onAbort.run(); ++ } ++ return Optional.empty(); ++ } ++ break; ++ } ++ // Paper end - PreCreatureSpawnEvent + T mob = (T)entityType.create(level, null, mutableBlockPos, spawnReason, false, false); + if (mob != null) { + if (mob.checkSpawnRules(level, spawnReason) && mob.checkSpawnObstruction(level)) { +- level.addFreshEntityWithPassengers(mob); ++ level.addFreshEntityWithPassengers(mob, reason); // CraftBukkit ++ if (mob.isRemoved()) return Optional.empty(); // CraftBukkit + mob.playAmbientSound(); + return Optional.of(mob); + } + +- mob.discard(); ++ mob.discard(null); // CraftBukkit - add Bukkit remove cause + } + } + } diff --git a/paper-server/patches/unapplied/net/minecraft/util/StringUtil.java.patch b/paper-server/patches/sources/net/minecraft/util/StringUtil.java.patch similarity index 75% rename from paper-server/patches/unapplied/net/minecraft/util/StringUtil.java.patch rename to paper-server/patches/sources/net/minecraft/util/StringUtil.java.patch index d0f9b93e86..99b6032596 100644 --- a/paper-server/patches/unapplied/net/minecraft/util/StringUtil.java.patch +++ b/paper-server/patches/sources/net/minecraft/util/StringUtil.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/util/StringUtil.java +++ b/net/minecraft/util/StringUtil.java -@@ -67,6 +67,25 @@ - return name.length() <= 16 && name.chars().filter(c -> c <= 32 || c >= 127).findAny().isEmpty(); +@@ -85,6 +_,25 @@ + return stringBuilder.toString(); } + // Paper start - Username validation @@ -23,6 +23,6 @@ + } + // Paper end - Username validation + - public static String filterText(String string) { - return filterText(string, false); + public static boolean isWhitespace(int character) { + return Character.isWhitespace(character) || Character.isSpaceChar(character); } diff --git a/paper-server/patches/unapplied/net/minecraft/util/TickThrottler.java.patch b/paper-server/patches/sources/net/minecraft/util/TickThrottler.java.patch similarity index 73% rename from paper-server/patches/unapplied/net/minecraft/util/TickThrottler.java.patch rename to paper-server/patches/sources/net/minecraft/util/TickThrottler.java.patch index b829a1224e..b50d74a2be 100644 --- a/paper-server/patches/unapplied/net/minecraft/util/TickThrottler.java.patch +++ b/paper-server/patches/sources/net/minecraft/util/TickThrottler.java.patch @@ -1,26 +1,19 @@ --- a/net/minecraft/util/TickThrottler.java +++ b/net/minecraft/util/TickThrottler.java -@@ -1,10 +1,14 @@ - package net.minecraft.util; - -+// CraftBukkit start -+import java.util.concurrent.atomic.AtomicInteger; -+// CraftBukkit end -+ +@@ -3,7 +_,7 @@ public class TickThrottler { - private final int incrementStep; private final int threshold; - private int count; -+ private final AtomicInteger count = new AtomicInteger(); // CraftBukkit - multithreaded field ++ private final java.util.concurrent.atomic.AtomicInteger count = new java.util.concurrent.atomic.AtomicInteger(); // CraftBukkit - multithreaded field - public TickThrottler(int increment, int threshold) { - this.incrementStep = increment; -@@ -12,17 +16,32 @@ + public TickThrottler(int incrementStep, int threshold) { + this.incrementStep = incrementStep; +@@ -11,16 +_,31 @@ } public void increment() { -- this.count += this.incrementStep; +- this.count = this.count + this.incrementStep; + this.count.addAndGet(this.incrementStep); // CraftBukkit - use thread-safe field access instead } @@ -29,18 +22,17 @@ + for (int val; (val = this.count.get()) > 0 && !this.count.compareAndSet(val, val - 1); ) ; + /* Use thread-safe field access instead if (this.count > 0) { - --this.count; + this.count--; } + */ + // CraftBukkit end - } public boolean isUnderThreshold() { - return this.count < this.threshold; + // CraftBukkit start - use thread-safe field access instead + return this.count.get() < this.threshold; - } ++ } + + public boolean isIncrementAndUnderThreshold() { + return this.isIncrementAndUnderThreshold(this.incrementStep, this.threshold); @@ -49,5 +41,5 @@ + public boolean isIncrementAndUnderThreshold(int incrementStep, int threshold) { + return this.count.addAndGet(incrementStep) < threshold; + // CraftBukkit end -+ } + } } diff --git a/paper-server/patches/unapplied/net/minecraft/util/ZeroBitStorage.java.patch b/paper-server/patches/sources/net/minecraft/util/ZeroBitStorage.java.patch similarity index 98% rename from paper-server/patches/unapplied/net/minecraft/util/ZeroBitStorage.java.patch rename to paper-server/patches/sources/net/minecraft/util/ZeroBitStorage.java.patch index a9e7cdc67b..93069aec37 100644 --- a/paper-server/patches/unapplied/net/minecraft/util/ZeroBitStorage.java.patch +++ b/paper-server/patches/sources/net/minecraft/util/ZeroBitStorage.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/util/ZeroBitStorage.java +++ b/net/minecraft/util/ZeroBitStorage.java -@@ -13,21 +13,21 @@ +@@ -13,21 +_,21 @@ } @Override diff --git a/paper-server/patches/sources/net/minecraft/world/level/gameevent/DynamicGameEventListener.java.patch b/paper-server/patches/sources/net/minecraft/world/level/gameevent/DynamicGameEventListener.java.patch new file mode 100644 index 0000000000..c0246df6bb --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/gameevent/DynamicGameEventListener.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/gameevent/DynamicGameEventListener.java ++++ b/net/minecraft/world/level/gameevent/DynamicGameEventListener.java +@@ -41,7 +_,7 @@ + + private static void ifChunkExists(LevelReader level, @Nullable SectionPos sectionPos, Consumer dispatcherConsumer) { + if (sectionPos != null) { +- ChunkAccess chunk = level.getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.FULL, false); ++ ChunkAccess chunk = level.getChunkIfLoadedImmediately(sectionPos.getX(), sectionPos.getZ()); // Paper - Perf: can cause sync loads while completing a chunk, resulting in deadlock + if (chunk != null) { + dispatcherConsumer.accept(chunk.getListenerRegistry(sectionPos.y())); + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/gameevent/GameEvent.java.patch b/paper-server/patches/sources/net/minecraft/world/level/gameevent/GameEvent.java.patch similarity index 51% rename from paper-server/patches/unapplied/net/minecraft/world/level/gameevent/GameEvent.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/gameevent/GameEvent.java.patch index 508ac18f4c..be2290d7c9 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/gameevent/GameEvent.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/gameevent/GameEvent.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/level/gameevent/GameEvent.java +++ b/net/minecraft/world/level/gameevent/GameEvent.java -@@ -85,7 +85,7 @@ +@@ -85,7 +_,7 @@ } - private static Holder.Reference register(String id, int range) { -- return Registry.registerForHolder(BuiltInRegistries.GAME_EVENT, ResourceLocation.withDefaultNamespace(id), new GameEvent(range)); -+ return io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.registerForHolderWithListeners(BuiltInRegistries.GAME_EVENT, ResourceLocation.withDefaultNamespace(id), new GameEvent(range)); // Paper - run with listeners + private static Holder.Reference register(String name, int notificationRadius) { +- return Registry.registerForHolder(BuiltInRegistries.GAME_EVENT, ResourceLocation.withDefaultNamespace(name), new GameEvent(notificationRadius)); ++ return io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.registerForHolderWithListeners(BuiltInRegistries.GAME_EVENT, ResourceLocation.withDefaultNamespace(name), new GameEvent(notificationRadius)); // Paper - run with listeners } - public static record Context(@Nullable Entity sourceEntity, @Nullable BlockState affectedState) { + public record Context(@Nullable Entity sourceEntity, @Nullable BlockState affectedState) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/gameevent/GameEventDispatcher.java.patch b/paper-server/patches/sources/net/minecraft/world/level/gameevent/GameEventDispatcher.java.patch new file mode 100644 index 0000000000..bcefb8669e --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/gameevent/GameEventDispatcher.java.patch @@ -0,0 +1,40 @@ +--- a/net/minecraft/world/level/gameevent/GameEventDispatcher.java ++++ b/net/minecraft/world/level/gameevent/GameEventDispatcher.java +@@ -11,6 +_,13 @@ + import net.minecraft.world.level.chunk.ChunkAccess; + import net.minecraft.world.phys.Vec3; + ++// CraftBukkit start ++import org.bukkit.Bukkit; ++import org.bukkit.craftbukkit.CraftGameEvent; ++import org.bukkit.craftbukkit.util.CraftLocation; ++import org.bukkit.event.world.GenericGameEvent; ++// CraftBukkit end ++ + public class GameEventDispatcher { + private final ServerLevel level; + +@@ -21,6 +_,14 @@ + public void post(Holder gameEvent, Vec3 pos, GameEvent.Context context) { + int notificationRadius = gameEvent.value().notificationRadius(); + BlockPos blockPos = BlockPos.containing(pos); ++ // CraftBukkit start ++ GenericGameEvent apiEvent = new GenericGameEvent(CraftGameEvent.minecraftToBukkit(gameEvent.value()), CraftLocation.toBukkit(blockPos, this.level.getWorld()), (context.sourceEntity() == null) ? null : context.sourceEntity().getBukkitEntity(), notificationRadius, !Bukkit.isPrimaryThread()); ++ this.level.getCraftServer().getPluginManager().callEvent(apiEvent); ++ if (apiEvent.isCancelled()) { ++ return; ++ } ++ notificationRadius = apiEvent.getRadius(); ++ // CraftBukkit end + int sectionPosCoord = SectionPos.blockToSectionCoord(blockPos.getX() - notificationRadius); + int sectionPosCoord1 = SectionPos.blockToSectionCoord(blockPos.getY() - notificationRadius); + int sectionPosCoord2 = SectionPos.blockToSectionCoord(blockPos.getZ() - notificationRadius); +@@ -39,7 +_,7 @@ + + for (int i = sectionPosCoord; i <= sectionPosCoord3; i++) { + for (int i1 = sectionPosCoord2; i1 <= sectionPosCoord5; i1++) { +- ChunkAccess chunkNow = this.level.getChunkSource().getChunkNow(i, i1); ++ ChunkAccess chunkNow = this.level.getChunkIfLoadedImmediately(i, i1); // Paper - Use getChunkIfLoadedImmediately + if (chunkNow != null) { + for (int i2 = sectionPosCoord1; i2 <= sectionPosCoord4; i2++) { + flag |= chunkNow.getListenerRegistry(i2).visitInRangeListeners(gameEvent, pos, context, listenerVisitor); diff --git a/paper-server/patches/unapplied/net/minecraft/util/SortedArraySet.java.patch b/paper-server/patches/unapplied/net/minecraft/util/SortedArraySet.java.patch deleted file mode 100644 index 00af73f775..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/util/SortedArraySet.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/util/SortedArraySet.java -+++ b/net/minecraft/util/SortedArraySet.java -@@ -28,7 +28,7 @@ - } - - public static > SortedArraySet create(int initialCapacity) { -- return new SortedArraySet<>(initialCapacity, Comparator.naturalOrder()); -+ return new SortedArraySet<>(initialCapacity, Comparator.naturalOrder()); // Paper - decompile fix - } - - public static SortedArraySet create(Comparator comparator) { diff --git a/paper-server/patches/unapplied/net/minecraft/util/SpawnUtil.java.patch b/paper-server/patches/unapplied/net/minecraft/util/SpawnUtil.java.patch deleted file mode 100644 index 803fd149f1..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/util/SpawnUtil.java.patch +++ /dev/null @@ -1,60 +0,0 @@ ---- a/net/minecraft/util/SpawnUtil.java -+++ b/net/minecraft/util/SpawnUtil.java -@@ -21,24 +21,47 @@ - public SpawnUtil() {} - - public static Optional trySpawnMob(EntityType entityType, EntitySpawnReason reason, ServerLevel world, BlockPos pos, int tries, int horizontalRange, int verticalRange, SpawnUtil.Strategy requirements, boolean requireEmptySpace) { -- BlockPos.MutableBlockPos blockposition_mutableblockposition = pos.mutable(); -+ // CraftBukkit start -+ return SpawnUtil.trySpawnMob(entityType, reason, world, pos, tries, horizontalRange, verticalRange, requirements, requireEmptySpace, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT, null); // Paper - pre creature spawn event -+ } - -- for (int l = 0; l < tries; ++l) { -- int i1 = Mth.randomBetweenInclusive(world.random, -horizontalRange, horizontalRange); -- int j1 = Mth.randomBetweenInclusive(world.random, -horizontalRange, horizontalRange); -+ public static Optional trySpawnMob(EntityType entitytypes, EntitySpawnReason entityspawnreason, ServerLevel worldserver, BlockPos blockposition, int i, int j, int k, SpawnUtil.Strategy spawnutil_a, boolean flag, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason, @javax.annotation.Nullable Runnable onAbort) { // Paper - pre creature spawn event -+ // CraftBukkit end -+ BlockPos.MutableBlockPos blockposition_mutableblockposition = blockposition.mutable(); - -- blockposition_mutableblockposition.setWithOffset(pos, i1, verticalRange, j1); -- if (world.getWorldBorder().isWithinBounds((BlockPos) blockposition_mutableblockposition) && SpawnUtil.moveToPossibleSpawnPosition(world, verticalRange, blockposition_mutableblockposition, requirements) && (!requireEmptySpace || world.noCollision(entityType.getSpawnAABB((double) blockposition_mutableblockposition.getX() + 0.5D, (double) blockposition_mutableblockposition.getY(), (double) blockposition_mutableblockposition.getZ() + 0.5D)))) { -- T t0 = (Mob) entityType.create(world, (Consumer) null, blockposition_mutableblockposition, reason, false, false); -+ for (int l = 0; l < i; ++l) { -+ int i1 = Mth.randomBetweenInclusive(worldserver.random, -j, j); -+ int j1 = Mth.randomBetweenInclusive(worldserver.random, -j, j); - -+ blockposition_mutableblockposition.setWithOffset(blockposition, i1, k, j1); -+ if (worldserver.getWorldBorder().isWithinBounds((BlockPos) blockposition_mutableblockposition) && SpawnUtil.moveToPossibleSpawnPosition(worldserver, k, blockposition_mutableblockposition, spawnutil_a) && (!flag || worldserver.noCollision(entitytypes.getSpawnAABB((double) blockposition_mutableblockposition.getX() + 0.5D, (double) blockposition_mutableblockposition.getY(), (double) blockposition_mutableblockposition.getZ() + 0.5D)))) { -+ // Paper start - PreCreatureSpawnEvent -+ final com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent( -+ io.papermc.paper.util.MCUtil.toLocation(worldserver, blockposition), -+ org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkit(entitytypes), -+ reason -+ ); -+ if (!event.callEvent()) { -+ if (event.shouldAbortSpawn()) { -+ if (onAbort != null) { -+ onAbort.run(); -+ } -+ return Optional.empty(); -+ } -+ break; -+ } -+ // Paper end - PreCreatureSpawnEvent -+ T t0 = entitytypes.create(worldserver, (Consumer) null, blockposition_mutableblockposition, entityspawnreason, false, false); // CraftBukkit - decompile error -+ - if (t0 != null) { -- if (t0.checkSpawnRules(world, reason) && t0.checkSpawnObstruction(world)) { -- world.addFreshEntityWithPassengers(t0); -+ if (t0.checkSpawnRules(worldserver, entityspawnreason) && t0.checkSpawnObstruction(worldserver)) { -+ worldserver.addFreshEntityWithPassengers(t0, reason); // CraftBukkit -+ if (t0.isRemoved()) return Optional.empty(); // CraftBukkit - t0.playAmbientSound(); - return Optional.of(t0); - } - -- t0.discard(); -+ t0.discard(null); // CraftBukkit - add Bukkit remove cause - } - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/gameevent/DynamicGameEventListener.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/gameevent/DynamicGameEventListener.java.patch deleted file mode 100644 index bcaf4b1a37..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/gameevent/DynamicGameEventListener.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/level/gameevent/DynamicGameEventListener.java -+++ b/net/minecraft/world/level/gameevent/DynamicGameEventListener.java -@@ -41,7 +41,7 @@ - - private static void ifChunkExists(LevelReader world, @Nullable SectionPos sectionPos, Consumer dispatcherConsumer) { - if (sectionPos != null) { -- ChunkAccess chunkAccess = world.getChunk(sectionPos.x(), sectionPos.z(), ChunkStatus.FULL, false); -+ ChunkAccess chunkAccess = world.getChunkIfLoadedImmediately(sectionPos.getX(), sectionPos.getZ()); // Paper - Perf: can cause sync loads while completing a chunk, resulting in deadlock - if (chunkAccess != null) { - dispatcherConsumer.accept(chunkAccess.getListenerRegistry(sectionPos.y())); - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/gameevent/GameEventDispatcher.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/gameevent/GameEventDispatcher.java.patch deleted file mode 100644 index 25f012f615..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/gameevent/GameEventDispatcher.java.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- a/net/minecraft/world/level/gameevent/GameEventDispatcher.java -+++ b/net/minecraft/world/level/gameevent/GameEventDispatcher.java -@@ -11,6 +11,12 @@ - import net.minecraft.server.level.ServerLevel; - import net.minecraft.world.level.chunk.LevelChunk; - import net.minecraft.world.phys.Vec3; -+// CraftBukkit start -+import org.bukkit.Bukkit; -+import org.bukkit.craftbukkit.CraftGameEvent; -+import org.bukkit.craftbukkit.util.CraftLocation; -+import org.bukkit.event.world.GenericGameEvent; -+// CraftBukkit end - - public class GameEventDispatcher { - -@@ -23,6 +29,14 @@ - public void post(Holder event, Vec3 emitterPos, GameEvent.Context emitter) { - int i = ((GameEvent) event.value()).notificationRadius(); - BlockPos blockposition = BlockPos.containing(emitterPos); -+ // CraftBukkit start -+ GenericGameEvent event1 = new GenericGameEvent(CraftGameEvent.minecraftToBukkit(event.value()), CraftLocation.toBukkit(blockposition, this.level.getWorld()), (emitter.sourceEntity() == null) ? null : emitter.sourceEntity().getBukkitEntity(), i, !Bukkit.isPrimaryThread()); -+ this.level.getCraftServer().getPluginManager().callEvent(event1); -+ if (event1.isCancelled()) { -+ return; -+ } -+ i = event1.getRadius(); -+ // CraftBukkit end - int j = SectionPos.blockToSectionCoord(blockposition.getX() - i); - int k = SectionPos.blockToSectionCoord(blockposition.getY() - i); - int l = SectionPos.blockToSectionCoord(blockposition.getZ() - i); -@@ -42,7 +56,7 @@ - - for (int l1 = j; l1 <= i1; ++l1) { - for (int i2 = l; i2 <= k1; ++i2) { -- LevelChunk chunk = this.level.getChunkSource().getChunkNow(l1, i2); -+ LevelChunk chunk = (LevelChunk) this.level.getChunkIfLoadedImmediately(l1, i2); // Paper - Use getChunkIfLoadedImmediately - - if (chunk != null) { - for (int j2 = k; j2 <= j1; ++j2) {