mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-28 23:38:25 +01:00
Moar
This commit is contained in:
parent
4091c6ac4d
commit
c3d5f253fe
12 changed files with 155 additions and 170 deletions
|
@ -1,6 +1,6 @@
|
||||||
--- a/net/minecraft/util/SimpleBitStorage.java
|
--- a/net/minecraft/util/SimpleBitStorage.java
|
||||||
+++ b/net/minecraft/util/SimpleBitStorage.java
|
+++ b/net/minecraft/util/SimpleBitStorage.java
|
||||||
@@ -204,8 +204,8 @@
|
@@ -204,8 +_,8 @@
|
||||||
private final long mask;
|
private final long mask;
|
||||||
private final int size;
|
private final int size;
|
||||||
private final int valuesPerLong;
|
private final int valuesPerLong;
|
||||||
|
@ -10,27 +10,25 @@
|
||||||
+ private final int divideAdd; private final long divideAddUnsigned; // Paper - Perf: Optimize SimpleBitStorage
|
+ private final int divideAdd; private final long divideAddUnsigned; // Paper - Perf: Optimize SimpleBitStorage
|
||||||
private final int divideShift;
|
private final int divideShift;
|
||||||
|
|
||||||
public SimpleBitStorage(int elementBits, int size, int[] data) {
|
public SimpleBitStorage(int bits, int size, int[] data) {
|
||||||
@@ -248,8 +248,8 @@
|
@@ -248,8 +_,8 @@
|
||||||
this.mask = (1L << elementBits) - 1L;
|
this.mask = (1L << bits) - 1L;
|
||||||
this.valuesPerLong = (char)(64 / elementBits);
|
this.valuesPerLong = (char)(64 / bits);
|
||||||
int i = 3 * (this.valuesPerLong - 1);
|
int i = 3 * (this.valuesPerLong - 1);
|
||||||
- this.divideMul = MAGIC[i + 0];
|
- this.divideMul = MAGIC[i + 0];
|
||||||
- this.divideAdd = MAGIC[i + 1];
|
- this.divideAdd = MAGIC[i + 1];
|
||||||
+ this.divideMul = MAGIC[i + 0]; this.divideMulUnsigned = Integer.toUnsignedLong(this.divideMul); // Paper - Perf: Optimize SimpleBitStorage
|
+ 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.divideAdd = MAGIC[i + 1]; this.divideAddUnsigned = Integer.toUnsignedLong(this.divideAdd); // Paper - Perf: Optimize SimpleBitStorage
|
||||||
this.divideShift = MAGIC[i + 2];
|
this.divideShift = MAGIC[i + 2];
|
||||||
int j = (size + this.valuesPerLong - 1) / this.valuesPerLong;
|
int i1 = (size + this.valuesPerLong - 1) / this.valuesPerLong;
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
@@ -264,15 +264,15 @@
|
@@ -264,15 +_,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
private int cellIndex(int index) {
|
private int cellIndex(int index) {
|
||||||
- long l = Integer.toUnsignedLong(this.divideMul);
|
- long l = Integer.toUnsignedLong(this.divideMul);
|
||||||
- long m = Integer.toUnsignedLong(this.divideAdd);
|
- long l1 = Integer.toUnsignedLong(this.divideAdd);
|
||||||
- return (int)((long)index * l + m >> 32 >> this.divideShift);
|
- return (int)(index * l + l1 >> 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
|
+ return (int)(index * this.divideMulUnsigned + this.divideAddUnsigned >> 32 >> this.divideShift); // Paper - Perf: Optimize SimpleBitStorage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,12 +37,10 @@
|
||||||
- Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index);
|
- Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index);
|
||||||
- Validate.inclusiveBetween(0L, this.mask, (long)value);
|
- Validate.inclusiveBetween(0L, this.mask, (long)value);
|
||||||
+ public final int getAndSet(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage
|
+ 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);
|
int i = this.cellIndex(index);
|
||||||
long l = this.data[i];
|
long l = this.data[i];
|
||||||
int j = (index - i * this.valuesPerLong) * this.bits;
|
int i1 = (index - i * this.valuesPerLong) * this.bits;
|
||||||
@@ -282,9 +282,9 @@
|
@@ -282,9 +_,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -52,19 +48,16 @@
|
||||||
- Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index);
|
- Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index);
|
||||||
- Validate.inclusiveBetween(0L, this.mask, (long)value);
|
- Validate.inclusiveBetween(0L, this.mask, (long)value);
|
||||||
+ public final void set(int index, int value) { // Paper - Perf: Optimize SimpleBitStorage
|
+ 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);
|
int i = this.cellIndex(index);
|
||||||
long l = this.data[i];
|
long l = this.data[i];
|
||||||
int j = (index - i * this.valuesPerLong) * this.bits;
|
int i1 = (index - i * this.valuesPerLong) * this.bits;
|
||||||
@@ -292,8 +292,8 @@
|
@@ -292,8 +_,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
- public int get(int index) {
|
- public int get(int index) {
|
||||||
- Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index);
|
- Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index);
|
||||||
+ public final int get(int index) { // Paper - Perf: Optimize SimpleBitStorage
|
+ 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);
|
int i = this.cellIndex(index);
|
||||||
long l = this.data[i];
|
long l = this.data[i];
|
||||||
int j = (index - i * this.valuesPerLong) * this.bits;
|
int i1 = (index - i * this.valuesPerLong) * this.bits;
|
|
@ -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 <T extends Mob> Optional<T> trySpawnMob(
|
||||||
|
EntityType<T> 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 <T extends Mob> Optional<T> trySpawnMob(
|
||||||
|
+ EntityType<T> 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
--- a/net/minecraft/util/StringUtil.java
|
--- a/net/minecraft/util/StringUtil.java
|
||||||
+++ b/net/minecraft/util/StringUtil.java
|
+++ b/net/minecraft/util/StringUtil.java
|
||||||
@@ -67,6 +67,25 @@
|
@@ -85,6 +_,25 @@
|
||||||
return name.length() <= 16 && name.chars().filter(c -> c <= 32 || c >= 127).findAny().isEmpty();
|
return stringBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
+ // Paper start - Username validation
|
+ // Paper start - Username validation
|
||||||
|
@ -23,6 +23,6 @@
|
||||||
+ }
|
+ }
|
||||||
+ // Paper end - Username validation
|
+ // Paper end - Username validation
|
||||||
+
|
+
|
||||||
public static String filterText(String string) {
|
public static boolean isWhitespace(int character) {
|
||||||
return filterText(string, false);
|
return Character.isWhitespace(character) || Character.isSpaceChar(character);
|
||||||
}
|
}
|
|
@ -1,26 +1,19 @@
|
||||||
--- a/net/minecraft/util/TickThrottler.java
|
--- a/net/minecraft/util/TickThrottler.java
|
||||||
+++ b/net/minecraft/util/TickThrottler.java
|
+++ b/net/minecraft/util/TickThrottler.java
|
||||||
@@ -1,10 +1,14 @@
|
@@ -3,7 +_,7 @@
|
||||||
package net.minecraft.util;
|
|
||||||
|
|
||||||
+// CraftBukkit start
|
|
||||||
+import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
+// CraftBukkit end
|
|
||||||
+
|
|
||||||
public class TickThrottler {
|
public class TickThrottler {
|
||||||
|
|
||||||
private final int incrementStep;
|
private final int incrementStep;
|
||||||
private final int threshold;
|
private final int threshold;
|
||||||
- private int count;
|
- 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) {
|
public TickThrottler(int incrementStep, int threshold) {
|
||||||
this.incrementStep = increment;
|
this.incrementStep = incrementStep;
|
||||||
@@ -12,17 +16,32 @@
|
@@ -11,16 +_,31 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void increment() {
|
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
|
+ 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); ) ;
|
+ for (int val; (val = this.count.get()) > 0 && !this.count.compareAndSet(val, val - 1); ) ;
|
||||||
+ /* Use thread-safe field access instead
|
+ /* Use thread-safe field access instead
|
||||||
if (this.count > 0) {
|
if (this.count > 0) {
|
||||||
--this.count;
|
this.count--;
|
||||||
}
|
}
|
||||||
+ */
|
+ */
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUnderThreshold() {
|
public boolean isUnderThreshold() {
|
||||||
- return this.count < this.threshold;
|
- return this.count < this.threshold;
|
||||||
+ // CraftBukkit start - use thread-safe field access instead
|
+ // CraftBukkit start - use thread-safe field access instead
|
||||||
+ return this.count.get() < this.threshold;
|
+ return this.count.get() < this.threshold;
|
||||||
}
|
+ }
|
||||||
+
|
+
|
||||||
+ public boolean isIncrementAndUnderThreshold() {
|
+ public boolean isIncrementAndUnderThreshold() {
|
||||||
+ return this.isIncrementAndUnderThreshold(this.incrementStep, this.threshold);
|
+ return this.isIncrementAndUnderThreshold(this.incrementStep, this.threshold);
|
||||||
|
@ -49,5 +41,5 @@
|
||||||
+ public boolean isIncrementAndUnderThreshold(int incrementStep, int threshold) {
|
+ public boolean isIncrementAndUnderThreshold(int incrementStep, int threshold) {
|
||||||
+ return this.count.addAndGet(incrementStep) < threshold;
|
+ return this.count.addAndGet(incrementStep) < threshold;
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
+ }
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
--- a/net/minecraft/util/ZeroBitStorage.java
|
--- a/net/minecraft/util/ZeroBitStorage.java
|
||||||
+++ b/net/minecraft/util/ZeroBitStorage.java
|
+++ b/net/minecraft/util/ZeroBitStorage.java
|
||||||
@@ -13,21 +13,21 @@
|
@@ -13,21 +_,21 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -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<GameEventListenerRegistry> 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()));
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
--- a/net/minecraft/world/level/gameevent/GameEvent.java
|
--- a/net/minecraft/world/level/gameevent/GameEvent.java
|
||||||
+++ b/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<GameEvent> register(String id, int range) {
|
private static Holder.Reference<GameEvent> register(String name, int notificationRadius) {
|
||||||
- return Registry.registerForHolder(BuiltInRegistries.GAME_EVENT, ResourceLocation.withDefaultNamespace(id), new GameEvent(range));
|
- 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(id), new GameEvent(range)); // Paper - run with listeners
|
+ 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) {
|
|
@ -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> 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);
|
|
@ -1,11 +0,0 @@
|
||||||
--- a/net/minecraft/util/SortedArraySet.java
|
|
||||||
+++ b/net/minecraft/util/SortedArraySet.java
|
|
||||||
@@ -28,7 +28,7 @@
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T extends Comparable<T>> SortedArraySet<T> create(int initialCapacity) {
|
|
||||||
- return new SortedArraySet<>(initialCapacity, Comparator.naturalOrder());
|
|
||||||
+ return new SortedArraySet<>(initialCapacity, Comparator.<T>naturalOrder()); // Paper - decompile fix
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> SortedArraySet<T> create(Comparator<T> comparator) {
|
|
|
@ -1,60 +0,0 @@
|
||||||
--- a/net/minecraft/util/SpawnUtil.java
|
|
||||||
+++ b/net/minecraft/util/SpawnUtil.java
|
|
||||||
@@ -21,24 +21,47 @@
|
|
||||||
public SpawnUtil() {}
|
|
||||||
|
|
||||||
public static <T extends Mob> Optional<T> trySpawnMob(EntityType<T> 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 <T extends Mob> Optional<T> trySpawnMob(EntityType<T> 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<T>) 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<GameEventListenerRegistry> 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()));
|
|
||||||
}
|
|
|
@ -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<GameEvent> 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) {
|
|
Loading…
Reference in a new issue