EVEN MOOOOOAAAAAAARRRRRRR patches :) (#5820)

This commit is contained in:
Jake Potrebic 2021-06-13 18:06:38 -07:00
parent 9a87139683
commit ddb72c221d
52 changed files with 426 additions and 981 deletions

View File

@ -0,0 +1,26 @@
plugins {
`java-library`
checkstyle
}
java {
withSourcesJar()
withJavadocJar()
}
repositories {
mavenCentral()
maven("https://libraries.minecraft.net")
}
dependencies {
implementation(project(":Paper-API"))
api("com.mojang:brigadier:1.0.18")
compileOnly("it.unimi.dsi:fastutil")
compileOnly("org.jetbrains:annotations:18.0.0")
testImplementation("junit:junit:4.13.1")
testImplementation("org.hamcrest:hamcrest-library:1.3")
testImplementation("org.ow2.asm:asm-tree:7.3.1")
}

View File

@ -67,18 +67,10 @@ diff --git a/src/main/java/org/bukkit/block/Block.java b/src/main/java/org/bukki
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/block/Block.java --- a/src/main/java/org/bukkit/block/Block.java
+++ b/src/main/java/org/bukkit/block/Block.java +++ b/src/main/java/org/bukkit/block/Block.java
@@ -0,0 +0,0 @@
package org.bukkit.block;
import java.util.Collection;
+
import org.bukkit.Chunk;
import org.bukkit.FluidCollisionMode;
import org.bukkit.Location;
@@ -0,0 +0,0 @@ public interface Block extends Metadatable { @@ -0,0 +0,0 @@ public interface Block extends Metadatable {
*/ */
@NotNull @NotNull
BoundingBox getBoundingBox(); VoxelShape getCollisionShape();
+ +
+ // Paper start + // Paper start
+ /** + /**

View File

@ -126,19 +126,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/bukkit/entity/Skeleton.java --- a/src/main/java/org/bukkit/entity/Skeleton.java
+++ b/src/main/java/org/bukkit/entity/Skeleton.java +++ b/src/main/java/org/bukkit/entity/Skeleton.java
@@ -0,0 +0,0 @@ package org.bukkit.entity; @@ -0,0 +0,0 @@ package org.bukkit.entity;
* Other skeleton-like entities, such as the {@link WitherSkeleton} or the
import org.jetbrains.annotations.Contract; * {@link Stray} are not related to this type.
import org.jetbrains.annotations.NotNull;
+import com.destroystokyo.paper.entity.RangedEntity;
/**
* Represents a Skeleton.
*/ */
-public interface Skeleton extends Monster { -public interface Skeleton extends AbstractSkeleton {
+public interface Skeleton extends Monster, RangedEntity { // Paper +public interface Skeleton extends AbstractSkeleton, com.destroystokyo.paper.entity.RangedEntity { // Paper
/** /**
* Gets the current type of this skeleton. * Computes whether or not this skeleton is currently in the process of
diff --git a/src/main/java/org/bukkit/entity/Snowman.java b/src/main/java/org/bukkit/entity/Snowman.java diff --git a/src/main/java/org/bukkit/entity/Snowman.java b/src/main/java/org/bukkit/entity/Snowman.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/entity/Snowman.java --- a/src/main/java/org/bukkit/entity/Snowman.java

View File

@ -1,45 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sat, 11 Apr 2020 21:23:42 -0400
Subject: [PATCH] Delay unsafe actions until after entity ticking is done
This will help prevent many cases of unregistering entities during entity ticking
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
public final List<ServerPlayer> players = Lists.newArrayList(); // Paper - private -> public
public final ServerChunkCache chunkSource; // Paper - public
boolean tickingEntities;
+ // Paper start
+ List<java.lang.Runnable> afterEntityTickingTasks = Lists.newArrayList();
+ public void doIfNotEntityTicking(java.lang.Runnable run) {
+ if (tickingEntities) {
+ afterEntityTickingTasks.add(run);
+ } else {
+ run.run();
+ }
+ }
+ // Paper end
private final MinecraftServer server;
public final PrimaryLevelData worldDataServer; // CraftBukkit - type
public boolean noSave;
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
timings.entityTick.stopTiming(); // Spigot
this.tickingEntities = false;
+ // Paper start
+ for (java.lang.Runnable run : this.afterEntityTickingTasks) {
+ try {
+ run.run();
+ } catch (Exception e) {
+ LOGGER.error("Error in After Entity Ticking Task", e);
+ }
+ }
+ this.afterEntityTickingTasks.clear();
+ // Paper end
this.getServer().midTickLoadChunks(); // Paper
Entity entity2;

View File

@ -1,59 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Thu, 16 Apr 2020 16:13:59 -0700
Subject: [PATCH] Optimize ChunkProviderServer's chunk level checking helper
methods
These can be hot functions (i.e entity ticking and block ticking),
so inline where possible, and avoid the abstraction of the
Either class.
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -0,0 +0,0 @@ import net.minecraft.network.protocol.Packet;
import net.minecraft.server.MCUtil;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.progress.ChunkProgressListener;
-import net.minecraft.util.Mth;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.util.thread.BlockableEventLoop;
import net.minecraft.world.entity.Entity;
@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
public final boolean isInEntityTickingChunk(Entity entity) { return this.isEntityTickingChunk(entity); } // Paper - OBFHELPER
@Override public boolean isEntityTickingChunk(Entity entity) {
- long i = ChunkPos.asLong(Mth.floor(entity.getX()) >> 4, Mth.floor(entity.getZ()) >> 4);
-
- return this.checkChunkFuture(i, (Function<ChunkHolder, CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>>>) ChunkHolder::getEntityTickingChunkFuture); // CraftBukkit - decompile error
+ // Paper start - optimize is ticking ready type functions
+ // entity ticking
+ ChunkHolder playerChunk = this.getVisibleChunkIfPresent(MCUtil.getCoordinateKey(entity));
+ return playerChunk != null && playerChunk.isEntityTickingReady();
+ // Paper end - optimize is ticking ready type functions
}
public final boolean isEntityTickingChunk(ChunkPos chunkcoordintpair) { return this.isEntityTickingChunk(chunkcoordintpair); } // Paper - OBFHELPER
@Override public boolean isEntityTickingChunk(ChunkPos pos) {
- return this.checkChunkFuture(pos.toLong(), (Function<ChunkHolder, CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>>>) ChunkHolder::getEntityTickingChunkFuture); // CraftBukkit - decompile error
+ // Paper start - optimize is ticking ready type functions
+ // is entity ticking ready
+ ChunkHolder playerChunk = this.getVisibleChunkIfPresent(MCUtil.getCoordinateKey(pos));
+ return playerChunk != null && playerChunk.isEntityTickingReady();
+ // Paper end - optimize is ticking ready type functions
}
@Override
public boolean isTickingChunk(BlockPos pos) {
- long i = ChunkPos.asLong(pos.getX() >> 4, pos.getZ() >> 4);
-
- return this.checkChunkFuture(i, (Function<ChunkHolder, CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>>>) ChunkHolder::getTickingChunkFuture); // CraftBukkit - decompile error
+ // Paper start - optimize is ticking ready type functions
+ // is ticking ready
+ ChunkHolder playerChunk = this.getVisibleChunkIfPresent(MCUtil.getCoordinateKey(pos));
+ return playerChunk != null && playerChunk.isTickingReady();
+ // Paper end - optimize is ticking ready type functions
}
private boolean checkChunkFuture(long pos, Function<ChunkHolder, CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>>> futureFunction) {

View File

@ -1,175 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 3 May 2020 22:35:09 -0400
Subject: [PATCH] Optimize Voxel Shape Merging
This method shows up as super hot in profiler, and also a high "self" time.
Upon analyzing, it appears most usages of this method fall down to the final
else statement of the nasty ternary.
Upon even further analyzation, it appears then the majority of those have a
consistent list 1.... One with Infinity head and Tails.
First optimization is to detect these infinite states and immediately return that
VoxelShapeMergerList so we can avoid testing the rest for most cases.
Break the method into 2 to help the JVM promote inlining of this fast path.
Then it was also noticed that VoxelShapeMergerList constructor is also a hotspot
with a high self time...
Well, knowing that in most cases our list 1 is actualy the same value, it allows
us to know that with an infinite list1, the result on the merger is essentially
list2 as the final values.
This let us analyze the 2 potential states (Infinite with 2 sources or 4 sources)
and compute a deterministic result for the MergerList values.
Additionally, this lets us avoid even allocating new objects for this too, further
reducing memory usage.
diff --git a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java
@@ -0,0 +0,0 @@ import it.unimi.dsi.fastutil.ints.IntArrayList;
public final class IndirectMerger implements IndexMerger {
- private final DoubleArrayList result;
+ private final DoubleList a; // Paper
private final IntArrayList firstIndices;
private final IntArrayList secondIndices;
+ // Paper start
+ private static final IntArrayList INFINITE_B_1 = new IntArrayList(new int[]{1, 1});
+ private static final IntArrayList INFINITE_B_0 = new IntArrayList(new int[]{0, 0});
+ private static final IntArrayList INFINITE_C = new IntArrayList(new int[]{0, 1});
+ // Paper end
+
protected IndirectMerger(DoubleList first, DoubleList second, boolean includeFirstOnly, boolean includeSecondOnly) {
int i = 0;
int j = 0;
@@ -0,0 +0,0 @@ public final class IndirectMerger implements IndexMerger {
int l = second.size();
int i1 = k + l;
- this.result = new DoubleArrayList(i1);
+ // Paper start - optimize common path of infinity doublelist
+ int size = first.size();
+ double tail = first.getDouble(size - 1);
+ double head = first.getDouble(0);
+ if (head == Double.NEGATIVE_INFINITY && tail == Double.POSITIVE_INFINITY && !includeFirstOnly && !includeSecondOnly && (size == 2 || size == 4)) {
+ this.a = second;
+ if (size == 2) {
+ this.firstIndices = INFINITE_B_0;
+ } else {
+ this.firstIndices = INFINITE_B_1;
+ }
+ this.secondIndices = INFINITE_C;
+ return;
+ }
+ // Paper end
+
+ this.a = new DoubleArrayList(i1);
this.firstIndices = new IntArrayList(i1);
this.secondIndices = new IntArrayList(i1);
@@ -0,0 +0,0 @@ public final class IndirectMerger implements IndexMerger {
boolean flag3 = j < l;
if (!flag2 && !flag3) {
- if (this.result.isEmpty()) {
- this.result.add(Math.min(first.getDouble(k - 1), second.getDouble(l - 1)));
+ if (this.a.isEmpty()) {
+ this.a.add(Math.min(first.getDouble(k - 1), second.getDouble(l - 1)));
}
return;
@@ -0,0 +0,0 @@ public final class IndirectMerger implements IndexMerger {
if (!(d0 >= d1 - 1.0E-7D)) { // Paper - decompile error - welcome to hell
this.firstIndices.add(i - 1);
this.secondIndices.add(j - 1);
- this.result.add(d1);
+ this.a.add(d1);
d0 = d1;
- } else if (!this.result.isEmpty()) {
+ } else if (!this.a.isEmpty()) {
this.firstIndices.set(this.firstIndices.size() - 1, i - 1);
this.secondIndices.set(this.secondIndices.size() - 1, j - 1);
}
@@ -0,0 +0,0 @@ public final class IndirectMerger implements IndexMerger {
@Override
public boolean forMergedIndexes(IndexMerger.IndexConsumer predicate) {
- for (int i = 0; i < this.result.size() - 1; ++i) {
+ for (int i = 0; i < this.a.size() - 1; ++i) {
if (!predicate.merge(this.firstIndices.getInt(i), this.secondIndices.getInt(i), i)) {
return false;
}
@@ -0,0 +0,0 @@ public final class IndirectMerger implements IndexMerger {
@Override
public DoubleList getList() {
- return this.result;
+ return this.a;
}
}
diff --git a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
@@ -0,0 +0,0 @@ public final class Shapes {
}
@VisibleForTesting
- protected static IndexMerger createIndexMerger(int size, DoubleList first, DoubleList second, boolean includeFirst, boolean includeSecond) {
- int j = first.size() - 1;
- int k = second.size() - 1;
+ private static IndexMerger createIndexMerger(int size, DoubleList first, DoubleList second, boolean includeFirst, boolean includeSecond) { // Paper - private
+ // Paper start - fast track the most common scenario
+ // doublelist is usually a DoubleArrayList with Infinite head/tails that falls to the final else clause
+ // This is actually the most common path, so jump to it straight away
+ if (first.getDouble(0) == Double.NEGATIVE_INFINITY && first.getDouble(first.size() - 1) == Double.POSITIVE_INFINITY) {
+ return new IndirectMerger(first, second, includeFirst, includeSecond);
+ }
+ // Split out rest to hopefully inline the above
+ return lessCommonMerge(size, first, second, includeFirst, includeSecond);
+ }
+
+ private static IndexMerger lessCommonMerge(int i, DoubleList doublelist, DoubleList doublelist1, boolean flag, boolean flag1) {
+ int j = doublelist.size() - 1;
+ int k = doublelist1.size() - 1;
+ // Paper note - Rewrite below as optimized order if instead of nasty ternary
- if (first instanceof CubePointRange && second instanceof CubePointRange) {
+ if (doublelist instanceof CubePointRange && doublelist1 instanceof CubePointRange) {
long l = lcm(j, k);
- if ((long) size * l <= 256L) {
+ if ((long) i * l <= 256L) {
return new DiscreteCubeMerger(j, k);
}
}
- return (IndexMerger) (first.getDouble(j) < second.getDouble(0) - 1.0E-7D ? new NonOverlappingMerger(first, second, false) : (second.getDouble(k) < first.getDouble(0) - 1.0E-7D ? new NonOverlappingMerger(second, first, true) : (j == k && Objects.equals(first, second) ? (first instanceof IdenticalMerger ? (IndexMerger) first : (second instanceof IdenticalMerger ? (IndexMerger) second : new IdenticalMerger(first))) : new IndirectMerger(first, second, includeFirst, includeSecond))));
+ // Identical happens more often than Disjoint
+ if (j == k && Objects.equals(doublelist, doublelist1)) {
+ if (doublelist instanceof IdenticalMerger) {
+ return (IndexMerger) doublelist;
+ } else if (doublelist1 instanceof IdenticalMerger) {
+ return (IndexMerger) doublelist1;
+ }
+ return new IdenticalMerger(doublelist);
+ } else if (doublelist.getDouble(j) < doublelist1.getDouble(0) - 1.0E-07) {
+ return new NonOverlappingMerger(doublelist, doublelist1, false);
+ } else if (doublelist1.getDouble(k) < doublelist.getDouble(0) - 1.0E-07) {
+ return new NonOverlappingMerger(doublelist1, doublelist, true);
+ } else {
+ return new IndirectMerger(doublelist, doublelist1, flag, flag1);
+ }
+ // Paper end
}
public interface DoubleLineConsumer {

View File

@ -5,50 +5,6 @@ Subject: [PATCH] Add Raw Byte ItemStack Serialization
Serializes using NBT which is safer for server data migrations than bukkits format. Serializes using NBT which is safer for server data migrations than bukkits format.
diff --git a/src/main/java/net/minecraft/nbt/NbtIo.java b/src/main/java/net/minecraft/nbt/NbtIo.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/nbt/NbtIo.java
+++ b/src/main/java/net/minecraft/nbt/NbtIo.java
@@ -0,0 +0,0 @@ public class NbtIo {
return nbttagcompound;
}
+ public static CompoundTag readNBT(InputStream inputstream) throws IOException { return readCompressed(inputstream); } // Paper - OBFHELPER
public static CompoundTag readCompressed(InputStream stream) throws IOException {
DataInputStream datainputstream = new DataInputStream(new BufferedInputStream(new GZIPInputStream(stream)));
Throwable throwable = null;
@@ -0,0 +0,0 @@ public class NbtIo {
}
+ public static void writeNBT(CompoundTag nbttagcompound, OutputStream outputstream) throws IOException { writeCompressed(nbttagcompound, outputstream); } // Paper - OBFHELPER
public static void writeCompressed(CompoundTag tag, OutputStream stream) throws IOException {
DataOutputStream dataoutputstream = new DataOutputStream(new BufferedOutputStream(new GZIPOutputStream(stream)));
Throwable throwable = null;
diff --git a/src/main/java/net/minecraft/util/datafix/DataFixers.java b/src/main/java/net/minecraft/util/datafix/DataFixers.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/util/datafix/DataFixers.java
+++ b/src/main/java/net/minecraft/util/datafix/DataFixers.java
@@ -0,0 +0,0 @@ public class DataFixers {
return datafixerbuilder.build(Util.bootstrapExecutor());
}
+ public static DataFixer getDataFixer() { return getDataFixer(); } // Paper - OBFHELPER
public static DataFixer getDataFixer() {
return DataFixers.DATA_FIXER;
}
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -0,0 +0,0 @@ public final class ItemStack {
this.updateEmptyCacheFlag();
}
+ public static ItemStack fromCompound(CompoundTag nbttagcompound) { return of(nbttagcompound); } // Paper - OBFHELPER
public static ItemStack of(CompoundTag tag) {
try {
return new ItemStack(tag);
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@ -67,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ CompoundTag compound = (item instanceof CraftItemStack ? ((CraftItemStack) item).getHandle() : CraftItemStack.asNMSCopy(item)).save(new CompoundTag()); + CompoundTag compound = (item instanceof CraftItemStack ? ((CraftItemStack) item).getHandle() : CraftItemStack.asNMSCopy(item)).save(new CompoundTag());
+ compound.putInt("DataVersion", getDataVersion()); + compound.putInt("DataVersion", getDataVersion());
+ try { + try {
+ net.minecraft.nbt.NbtIo.writeNBT( + net.minecraft.nbt.NbtIo.writeCompressed(
+ compound, + compound,
+ outputStream + outputStream
+ ); + );
@ -84,14 +40,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ Preconditions.checkArgument(data.length > 0, "cannot deserialize nothing"); + Preconditions.checkArgument(data.length > 0, "cannot deserialize nothing");
+ +
+ try { + try {
+ CompoundTag compound = net.minecraft.nbt.NbtIo.readNBT( + CompoundTag compound = net.minecraft.nbt.NbtIo.readCompressed(
+ new java.io.ByteArrayInputStream(data) + new java.io.ByteArrayInputStream(data)
+ ); + );
+ int dataVersion = compound.getInt("DataVersion"); + int dataVersion = compound.getInt("DataVersion");
+ +
+ Preconditions.checkArgument(dataVersion <= getDataVersion(), "Newer version! Server downgrades are not supported!"); + Preconditions.checkArgument(dataVersion <= getDataVersion(), "Newer version! Server downgrades are not supported!");
+ Dynamic<Tag> converted = DataFixers.getDataFixer().update(References.ITEM_STACK, new Dynamic<Tag>(NbtOps.INSTANCE, compound), dataVersion, getDataVersion()); + Dynamic<Tag> converted = DataFixers.getDataFixer().update(References.ITEM_STACK, new Dynamic<Tag>(NbtOps.INSTANCE, compound), dataVersion, getDataVersion());
+ return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.fromCompound((CompoundTag) converted.getValue())); + return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.of((CompoundTag) converted.getValue()));
+ } catch (IOException ex) { + } catch (IOException ex) {
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(ex); + com.destroystokyo.paper.util.SneakyThrow.sneaky(ex);
+ throw new RuntimeException(); + throw new RuntimeException();

View File

@ -9,44 +9,31 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig { @@ -0,0 +0,0 @@ public class PaperWorldConfig {
private void lightQueueSize() {
lightQueueSize = getInt("light-queue-size", lightQueueSize); lightQueueSize = getInt("light-queue-size", lightQueueSize);
} }
+
+ public boolean phantomIgnoreCreative = true; + public boolean phantomIgnoreCreative = true;
+ public boolean phantomOnlyAttackInsomniacs = true; + public boolean phantomOnlyAttackInsomniacs = true;
+ private void phantomSettings() { + private void phantomSettings() {
+ phantomIgnoreCreative = getBoolean("phantoms-do-not-spawn-on-creative-players", phantomIgnoreCreative); + phantomIgnoreCreative = getBoolean("phantoms-do-not-spawn-on-creative-players", phantomIgnoreCreative);
+ phantomOnlyAttackInsomniacs = getBoolean("phantoms-only-attack-insomniacs", phantomOnlyAttackInsomniacs); + phantomOnlyAttackInsomniacs = getBoolean("phantoms-only-attack-insomniacs", phantomOnlyAttackInsomniacs);
+ } + }
} +
public int noTickViewDistance;
private void viewDistance() {
this.noTickViewDistance = this.getInt("viewdistances.no-tick-view-distance", -1);
diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/EntitySelector.java --- a/src/main/java/net/minecraft/world/entity/EntitySelector.java
+++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java +++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java
@@ -0,0 +0,0 @@ package net.minecraft.world.entity;
import com.google.common.base.Predicates;
import java.util.function.Predicate;
import javax.annotation.Nullable;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.stats.Stats;
+import net.minecraft.util.Mth;
import net.minecraft.world.Container;
import net.minecraft.world.Difficulty;
import net.minecraft.world.entity.player.Player;
@@ -0,0 +0,0 @@ public final class EntitySelector { @@ -0,0 +0,0 @@ public final class EntitySelector {
public static final Predicate<Entity> NO_SPECTATORS = (entity) -> { public static final Predicate<Entity> NO_SPECTATORS = (entity) -> {
return !entity.isSpectator(); return !entity.isSpectator();
}; };
+ public static Predicate<Player> isInsomniac = (player) -> Mth.clamp(((ServerPlayer) player).getStats().getValue(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper + public static Predicate<Player> isInsomniac = (player) -> net.minecraft.util.Mth.clamp(((net.minecraft.server.level.ServerPlayer) player).getStats().getValue(net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper
private EntitySelector() {}
// Paper start // Paper start
public static final Predicate<Entity> affectsSpawning = (entity) -> {
- return !entity.isSpectator() && entity.isAlive() && (entity instanceof EntityPlayer) && ((EntityPlayer) entity).affectsSpawning;
+ return !entity.isSpectator() && entity.isAlive() && (entity instanceof ServerPlayer) && ((ServerPlayer) entity).affectsSpawning;
};
// Paper end
diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java --- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java

View File

@ -91,9 +91,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/MinecraftServer.java --- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
private int maxBuildHeight; private String motd;
private int playerIdleTimeout; private int playerIdleTimeout;
public final long[] tickTimes; public long[] getTickTimes() { return tickTimes; } // Paper - OBFHELPER public final long[] tickTimes;
+ // Paper start + // Paper start
+ public final TickTimes tickTimes5s = new TickTimes(100); + public final TickTimes tickTimes5s = new TickTimes(100);
+ public final TickTimes tickTimes10s = new TickTimes(200); + public final TickTimes tickTimes10s = new TickTimes(200);
@ -116,10 +116,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.profiler.pop(); this.profiler.pop();
org.spigotmc.WatchdogThread.tick(); // Spigot org.spigotmc.WatchdogThread.tick(); // Spigot
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public TextFilter createTextFilterForPlayer(ServerPlayer player) { };
return null; }
} }
+
+ // Paper start + // Paper start
+ public static class TickTimes { + public static class TickTimes {
+ private final long[] times; + private final long[] times;

View File

@ -21,38 +21,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public final CallbackExecutor callbackExecutor = new CallbackExecutor(); public final CallbackExecutor callbackExecutor = new CallbackExecutor();
public static final class CallbackExecutor implements java.util.concurrent.Executor, Runnable { public static final class CallbackExecutor implements java.util.concurrent.Executor, Runnable {
- private Runnable queued; - private final java.util.Queue<Runnable> queue = new java.util.ArrayDeque<>();
+ // Paper start - replace impl with recursive safe multi entry queue + // Paper start - replace impl with recursive safe multi entry queue
+ // it's possible to schedule multiple tasks currently, so it's vital we change this impl + // it's possible to schedule multiple tasks currently, so it's vital we change this impl
+ // If we recurse into the executor again, we will append to another queue, ensuring task order consistency + // If we recurse into the executor again, we will append to another queue, ensuring task order consistency
+ private java.util.ArrayDeque<Runnable> queued = new java.util.ArrayDeque<>(); + private java.util.Queue<Runnable> queue = new java.util.ArrayDeque<>(); // Paper - remove final
@Override @Override
public void execute(Runnable runnable) { public void execute(Runnable runnable) {
- if (queued != null) { + if (this.queue == null) {
- throw new IllegalStateException("Already queued"); + this.queue = new java.util.ArrayDeque<>();
+ if (queued == null) { + }
+ queued = new java.util.ArrayDeque<>(); this.queue.add(runnable);
}
- queued = runnable;
+ queued.add(runnable);
} }
@Override @Override
public void run() { public void run() {
- Runnable task = queued; + if (this.queue == null) {
+ if (queued == null) {
+ return; + return;
+ } + }
+ java.util.ArrayDeque<Runnable> queue = queued; + java.util.Queue<Runnable> queue = this.queue;
queued = null; + this.queue = null;
- if (task != null) { + // Paper end
+ Runnable task; Runnable task;
+ while ((task = queue.pollFirst()) != null) { while ((task = this.queue.poll()) != null) {
task.run(); task.run();
}
}
+ // Paper end
};
// CraftBukkit end

View File

@ -12,9 +12,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure
joinMessage = PaperAdventure.asVanilla(jm); // Paper - Adventure joinMessage = PaperAdventure.asVanilla(jm); // Paper - Adventure
- server.getPlayerList().broadcastAll(new ClientboundChatPacket(joinMessage, ChatType.SYSTEM, Util.NIL_UUID)); // Paper - Adventure - this.server.getPlayerList().broadcastAll(new ClientboundChatPacket(joinMessage, ChatType.SYSTEM, Util.NIL_UUID)); // Paper - Adventure
+ // Paper start - Removed sendAll for loop and broadcasted to console also + // Paper start - Removed sendAll for loop and broadcasted to console also
+ server.getPlayerList().sendMessage(joinMessage); // Paper - Adventure + this.server.getPlayerList().broadcastMessage(joinMessage, ChatType.SYSTEM, Util.NIL_UUID); // Paper - Adventure
+ // Paper end + // Paper end
} }
// CraftBukkit end // CraftBukkit end

View File

@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java
@@ -0,0 +0,0 @@ public class FireBlock extends BaseFireBlock { @@ -0,0 +0,0 @@ public class FireBlock extends BaseFireBlock {
@Override @Override
public BlockState updateShape(BlockState state, Direction direction, BlockState newState, LevelAccessor world, BlockPos pos, BlockPos posFrom) { public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
// CraftBukkit start // CraftBukkit start
+ if (!(world instanceof ServerLevel)) return this.canSurvive(state, world, pos) ? (BlockState) this.getStateWithAge(world, pos, (Integer) state.getValue(FireBlock.AGE)) : Blocks.AIR.defaultBlockState(); // Paper - don't fire events in world generation + if (!(world instanceof ServerLevel)) return this.canSurvive(state, world, pos) ? (BlockState) this.getStateWithAge(world, pos, (Integer) state.getValue(FireBlock.AGE)) : Blocks.AIR.defaultBlockState(); // Paper - don't fire events in world generation
if (!this.canSurvive(state, world, pos)) { if (!this.canSurvive(state, world, pos)) {

View File

@ -14,12 +14,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
protected void serverAiStep() {} protected void serverAiStep() {}
protected void pushEntities() { protected void pushEntities() {
+ // Paper - start don't run getEntities if we're not going to use its result + // Paper start - don't run getEntities if we're not going to use its result
+ int i = this.level.getGameRules().getInt(GameRules.RULE_MAX_ENTITY_CRAMMING); + int i = this.level.getGameRules().getInt(GameRules.RULE_MAX_ENTITY_CRAMMING);
+ if (i <= 0 && level.paperConfig.maxCollisionsPerEntity <= 0) { + if (i <= 0 && level.paperConfig.maxCollisionsPerEntity <= 0) {
+ return; + return;
+ } + }
+ // Paper - end don't run getEntities if we're not going to use its result + // Paper end - don't run getEntities if we're not going to use its result
List<Entity> list = this.level.getEntities(this, this.getBoundingBox(), EntitySelector.pushableBy(this)); List<Entity> list = this.level.getEntities(this, this.getBoundingBox(), EntitySelector.pushableBy(this));
if (!list.isEmpty()) { if (!list.isEmpty()) {

View File

@ -9,7 +9,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -0,0 +0,0 @@ public final class CraftServer implements Server { @@ -0,0 +0,0 @@ public final class CraftServer implements Server {
return bukkitVersion; return this.bukkitVersion;
} }
+ // Paper start - expose game version + // Paper start - expose game version

View File

@ -33,10 +33,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit end // CraftBukkit end
+ final CallbackExecutor chunkLoadConversionCallbackExecutor = new CallbackExecutor(); // Paper + final CallbackExecutor chunkLoadConversionCallbackExecutor = new CallbackExecutor(); // Paper
+
// Paper start - distance maps // Paper start - distance maps
private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<ServerPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>(); private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<ServerPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>();
// Paper start - no-tick view distance
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return Either.left(chunk); return Either.left(chunk);
}); });

View File

@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}); // Paper end - per player view distance
} }
- protected void addEntity(Entity entity) { - protected void addEntity(Entity entity) {
@ -52,7 +52,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener { @@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
public double maxHealthCache; public double maxHealthCache;
public boolean joining = true; public boolean joining = true;
public boolean sentListPacket = false; public boolean sentListPacket = false;
@ -75,8 +75,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ mountSavedVehicle(player, worldserver1, nbttagcompound); + mountSavedVehicle(player, worldserver1, nbttagcompound);
+ // Paper end + // Paper end
// CraftBukkit start // CraftBukkit start
PlayerJoinEvent playerJoinEvent = new org.bukkit.event.player.PlayerJoinEvent(cserver.getPlayer(player), PaperAdventure.asAdventure(chatmessage)); // Paper - Adventure PlayerJoinEvent playerJoinEvent = new org.bukkit.event.player.PlayerJoinEvent(this.cserver.getPlayer(player), PaperAdventure.asAdventure(chatmessage)); // Paper - Adventure
cserver.getPluginManager().callEvent(playerJoinEvent); this.cserver.getPluginManager().callEvent(playerJoinEvent);
@@ -0,0 +0,0 @@ public abstract class PlayerList { @@ -0,0 +0,0 @@ public abstract class PlayerList {
player.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, new ServerPlayer[] { entityplayer1})); player.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, new ServerPlayer[] { entityplayer1}));
} }
@ -93,57 +93,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper start - move vehicle into method so it can be called above - short circuit around that code + // Paper start - move vehicle into method so it can be called above - short circuit around that code
+ onPlayerJoinFinish(player, worldserver1, s1); + onPlayerJoinFinish(player, worldserver1, s1);
+ } + }
+ private void mountSavedVehicle(ServerPlayer entityplayer, ServerLevel worldserver1, CompoundTag nbttagcompound) { + private void mountSavedVehicle(ServerPlayer player, ServerLevel worldserver1, CompoundTag nbttagcompound) {
+ // Paper end + // Paper end
if (nbttagcompound != null && nbttagcompound.contains("RootVehicle", 10)) { if (nbttagcompound != null && nbttagcompound.contains("RootVehicle", 10)) {
CompoundTag nbttagcompound1 = nbttagcompound.getCompound("RootVehicle"); CompoundTag nbttagcompound1 = nbttagcompound.getCompound("RootVehicle");
// CraftBukkit start // CraftBukkit start
@@ -0,0 +0,0 @@ public abstract class PlayerList {
Entity entity1;
if (entity.getUUID().equals(uuid)) {
- player.startRiding(entity, true);
+ entityplayer.startRiding(entity, true);
} else {
iterator1 = entity.getIndirectPassengers().iterator();
while (iterator1.hasNext()) {
entity1 = (Entity) iterator1.next();
if (entity1.getUUID().equals(uuid)) {
- player.startRiding(entity1, true);
+ entityplayer.startRiding(entity1, true);
break;
}
}
}
- if (!player.isPassenger()) {
+ if (!entityplayer.isPassenger()) {
PlayerList.LOGGER.warn("Couldn't reattach entity to player");
worldserver1.despawn(entity);
iterator1 = entity.getIndirectPassengers().iterator();
@@ -0,0 +0,0 @@ public abstract class PlayerList { @@ -0,0 +0,0 @@ public abstract class PlayerList {
} }
} }
- player.initMenu();
+ // Paper start + // Paper start
+ } + }
+ public void onPlayerJoinFinish(ServerPlayer entityplayer, ServerLevel worldserver1, String s1) { + public void onPlayerJoinFinish(ServerPlayer player, ServerLevel worldserver1, String s1) {
+ // Paper end + // Paper end
+ entityplayer.initMenu(); player.initInventoryMenu();
// CraftBukkit - Moved from above, added world
// Paper start - Add to collideRule team if needed // Paper start - Add to collideRule team if needed
final Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard(); @@ -0,0 +0,0 @@ public abstract class PlayerList {
final PlayerTeam collideRuleTeam = scoreboard.getTeam(collideRuleTeamName); scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam);
- if (this.collideRuleTeamName != null && collideRuleTeam != null && player.getTeam() == null) {
- scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam);
+ if (this.collideRuleTeamName != null && collideRuleTeam != null && entityplayer.getTeam() == null) {
+ scoreboard.addPlayerToTeam(entityplayer.getScoreboardName(), collideRuleTeam);
} }
// Paper end // Paper end
// CraftBukkit - Moved from above, added world + // CraftBukkit - Moved from above, added world
- PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.worldDataServer.getLevelName(), player.getX(), player.getY(), player.getZ()); PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ());
+ PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", entityplayer.getName().getString(), s1, entityplayer.getId(), worldserver1.worldDataServer.getLevelName(), entityplayer.getX(), entityplayer.getY(), entityplayer.getZ());
} }
public void updateEntireScoreboard(ServerScoreboard scoreboard, ServerPlayer player) {

View File

@ -19,7 +19,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/jav
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java --- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
} else { } else {
// CraftBukkit start - Capture drops for death event // CraftBukkit start - Capture drops for death event
if (this instanceof net.minecraft.world.entity.LivingEntity && !((net.minecraft.world.entity.LivingEntity) this).forceDrops) { if (this instanceof net.minecraft.world.entity.LivingEntity && !((net.minecraft.world.entity.LivingEntity) this).forceDrops) {
@ -34,7 +34,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
entityitem.setDefaultPickUpDelay(); entityitem.setDefaultPickUpDelay();
// CraftBukkit start // CraftBukkit start
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
@Nullable @Nullable
public Entity teleportTo(ServerLevel worldserver, BlockPos location) { public Entity teleportTo(ServerLevel worldserver, BlockPos location) {
// CraftBukkit end // CraftBukkit end
@ -44,10 +44,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return null; + return null;
+ } + }
+ // Paper end + // Paper end
if (this.level instanceof ServerLevel && !this.removed) { if (this.level instanceof ServerLevel && !this.isRemoved()) {
this.level.getProfiler().push("changeDimension"); this.level.getProfiler().push("changeDimension");
// CraftBukkit start // CraftBukkit start
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
// CraftBukkit end // CraftBukkit end
this.level.getProfiler().popPush("reloading"); this.level.getProfiler().popPush("reloading");
@ -59,7 +59,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
Entity entity = this.getType().create((Level) worldserver); Entity entity = this.getType().create((Level) worldserver);
if (entity != null) { if (entity != null) {
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
// CraftBukkit start - Forward the CraftEntity to the new entity // CraftBukkit start - Forward the CraftEntity to the new entity
this.getBukkitEntity().setHandle(entity); this.getBukkitEntity().setHandle(entity);
entity.bukkitEntity = this.getBukkitEntity(); entity.bukkitEntity = this.getBukkitEntity();
@ -70,7 +70,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit end // CraftBukkit end
} }
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
} }
public boolean canChangeDimensions() { public boolean canChangeDimensions() {

View File

@ -9,6 +9,18 @@ Adds AsyncPlayerSendCommandsEvent
Adds CommandRegisteredEvent Adds CommandRegisteredEvent
- Allows manipulating the CommandNode to add more children/metadata for the client - Allows manipulating the CommandNode to add more children/metadata for the client
diff --git a/build.gradle.kts b/build.gradle.kts
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -0,0 +0,0 @@ repositories {
dependencies {
implementation(project(":Paper-API"))
+ implementation(project(":Paper-MojangAPI"))
// Paper start
implementation("org.jline:jline-terminal-jansi:3.12.1")
implementation("net.minecrell:terminalconsoleappender:1.2.0")
diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/commands/CommandSourceStack.java --- a/src/main/java/net/minecraft/commands/CommandSourceStack.java
@ -72,14 +84,14 @@ diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListener
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
ParseResults<CommandSourceStack> parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack()); ParseResults<CommandSourceStack> parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack());
this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> {
- if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [<args>] from showing for plugins with nothing more to offer - if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [<args>] from showing for plugins with nothing more to offer
- this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestions)); - this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestions));
+ // Paper start + // Paper start
+ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getPlayer(), suggestions, buffer); + com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getCraftPlayer(), suggestions, buffer);
+ suggestEvent.setCancelled(suggestions.isEmpty()); + suggestEvent.setCancelled(suggestions.isEmpty());
+ if (!suggestEvent.callEvent()) return; + if (!suggestEvent.callEvent()) return;
+ this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), (com.mojang.brigadier.suggestion.Suggestions) suggestEvent.getSuggestions())); // CraftBukkit - decompile error // Paper + this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), (com.mojang.brigadier.suggestion.Suggestions) suggestEvent.getSuggestions())); // CraftBukkit - decompile error // Paper
@ -87,13 +99,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}); });
}); });
} }
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
builder = builder.createOffset(builder.getInput().lastIndexOf(' ') + 1); builder = builder.createOffset(builder.getInput().lastIndexOf(' ') + 1);
completions.forEach(builder::suggest); completions.forEach(builder::suggest);
- player.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), builder.buildFuture().join())); - player.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), builder.buildFuture().join()));
+ com.mojang.brigadier.suggestion.Suggestions suggestions = builder.buildFuture().join(); + com.mojang.brigadier.suggestion.Suggestions suggestions = builder.buildFuture().join();
+ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getPlayer(), suggestions, buffer); + com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getCraftPlayer(), suggestions, buffer);
+ suggestEvent.setCancelled(suggestions.isEmpty()); + suggestEvent.setCancelled(suggestions.isEmpty());
+ if (!suggestEvent.callEvent()) return; + if (!suggestEvent.callEvent()) return;
+ this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestEvent.getSuggestions())); + this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestEvent.getSuggestions()));

View File

@ -53,10 +53,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -0,0 +0,0 @@ public class CraftBlock implements Block { @@ -0,0 +0,0 @@ public class CraftBlock implements Block {
AABB aabb = shape.bounds(); VoxelShape shape = this.getNMS().getCollisionShape(world, position);
return new BoundingBox(this.getX() + aabb.minX, this.getY() + aabb.minY, this.getZ() + aabb.minZ, this.getX() + aabb.maxX, this.getY() + aabb.maxY, this.getZ() + aabb.maxZ); return new CraftVoxelShape(shape);
} }
+
+ // Paper start + // Paper start
+ @Override + @Override
+ public com.destroystokyo.paper.block.BlockSoundGroup getSoundGroup() { + public com.destroystokyo.paper.block.BlockSoundGroup getSoundGroup() {

View File

@ -84,67 +84,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ .toString(); + .toString();
+ } + }
+} +}
diff --git a/src/main/java/net/minecraft/network/protocol/game/ServerboundClientInformationPacket.java b/src/main/java/net/minecraft/network/protocol/game/ServerboundClientInformationPacket.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ServerboundClientInformationPacket.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ServerboundClientInformationPacket.java
@@ -0,0 +0,0 @@ public class ServerboundClientInformationPacket implements Packet<ServerGamePack
listener.handleClientInformation(this);
}
+ public ChatVisiblity getChatVisibility() { return getChatVisibility(); } // Paper - OBFHELPER
public ChatVisiblity getChatVisibility() {
return this.chatVisibility;
}
+ public boolean hasChatColorsEnabled() { return getChatColors(); } // Paper - OBFHELPER
public boolean getChatColors() {
return this.chatColors;
}
+ public int getSkinParts() { return getModelCustomisation(); } // Paper - OBFHELPER
public int getModelCustomisation() {
return this.modelCustomisation;
}
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -0,0 +0,0 @@ package net.minecraft.server.level; @@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
import com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent;
import com.google.common.collect.Lists;
+import com.destroystokyo.paper.event.player.PlayerClientOptionsChangeEvent; // Paper
import com.mojang.authlib.GameProfile;
import com.mojang.datafixers.util.Either;
import com.mojang.serialization.DataResult;
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener {
public int lastSentExp = -99999999;
public int spawnInvulnerableTime = 60;
private ChatVisiblity chatVisibility;
- private boolean canChatColor = true;
+ private boolean canChatColor = true; public boolean hasChatColorsEnabled() { return this.canChatColor; } // Paper - OBFHELPER
private long lastActionTime = Util.getMillis();
private Entity camera;
public boolean isChangingDimension;
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener {
public String locale = null; // CraftBukkit - add, lowercase // Paper - default to null public String locale = null; // CraftBukkit - add, lowercase // Paper - default to null
public java.util.Locale adventure$locale = java.util.Locale.US; // Paper public java.util.Locale adventure$locale = java.util.Locale.US; // Paper
public void updateOptions(ServerboundClientInformationPacket packet) { public void updateOptions(ServerboundClientInformationPacket packet) {
+ new PlayerClientOptionsChangeEvent(getBukkitEntity(), packet.language, packet.viewDistance, com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(packet.getChatVisibility().name()), packet.hasChatColorsEnabled(), new com.destroystokyo.paper.PaperSkinParts(packet.getSkinParts()), packet.getMainHand() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT).callEvent(); // Paper - settings event + new com.destroystokyo.paper.event.player.PlayerClientOptionsChangeEvent(getBukkitEntity(), packet.language, packet.viewDistance, com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(packet.getChatVisibility().name()), packet.getChatColors(), new com.destroystokyo.paper.PaperSkinParts(packet.getModelCustomisation()), packet.getMainHand() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT).callEvent(); // Paper - settings event
// CraftBukkit start // CraftBukkit start
if (getMainArm() != packet.getMainHand()) { if (getMainArm() != packet.getMainHand()) {
PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(getBukkitEntity(), getMainArm() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT); PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(this.getBukkitEntity(), getMainArm() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT);
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java --- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity { @@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
private static final Map<Pose, EntityDimensions> POSES = ImmutableMap.<Pose, EntityDimensions>builder().put(Pose.STANDING, Player.STANDING_DIMENSIONS).put(Pose.SLEEPING, Player.SLEEPING_DIMENSIONS).put(Pose.FALL_FLYING, EntityDimensions.scalable(0.6F, 0.6F)).put(Pose.SWIMMING, EntityDimensions.scalable(0.6F, 0.6F)).put(Pose.SPIN_ATTACK, EntityDimensions.scalable(0.6F, 0.6F)).put(Pose.CROUCHING, EntityDimensions.scalable(0.6F, 1.5F)).put(Pose.DYING, EntityDimensions.fixed(0.2F, 0.2F)).build(); private static final int FLY_ACHIEVEMENT_SPEED = 25;
private static final EntityDataAccessor<Float> DATA_PLAYER_ABSORPTION_ID = SynchedEntityData.defineId(Player.class, EntityDataSerializers.FLOAT); private static final EntityDataAccessor<Float> DATA_PLAYER_ABSORPTION_ID = SynchedEntityData.defineId(Player.class, EntityDataSerializers.FLOAT);
private static final EntityDataAccessor<Integer> DATA_SCORE_ID = SynchedEntityData.defineId(Player.class, EntityDataSerializers.INT); private static final EntityDataAccessor<Integer> DATA_SCORE_ID = SynchedEntityData.defineId(Player.class, EntityDataSerializers.INT);
- protected static final EntityDataAccessor<Byte> DATA_PLAYER_MODE_CUSTOMISATION = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE); - protected static final EntityDataAccessor<Byte> DATA_PLAYER_MODE_CUSTOMISATION = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE);
+ protected static final EntityDataAccessor<Byte> DATA_PLAYER_MODE_CUSTOMISATION = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE); public static EntityDataAccessor<Byte> getSkinPartsWatcher() { return DATA_PLAYER_MODE_CUSTOMISATION; } // Paper - OBFHELPER + public static final EntityDataAccessor<Byte> DATA_PLAYER_MODE_CUSTOMISATION = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE); // Paper - protected -> public
protected static final EntityDataAccessor<Byte> DATA_PLAYER_MAIN_HAND = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE); protected static final EntityDataAccessor<Byte> DATA_PLAYER_MAIN_HAND = SynchedEntityData.defineId(Player.class, EntityDataSerializers.BYTE);
protected static final EntityDataAccessor<CompoundTag> DATA_SHOULDER_LEFT = SynchedEntityData.defineId(Player.class, EntityDataSerializers.COMPOUND_TAG); protected static final EntityDataAccessor<CompoundTag> DATA_SHOULDER_LEFT = SynchedEntityData.defineId(Player.class, EntityDataSerializers.COMPOUND_TAG);
protected static final EntityDataAccessor<CompoundTag> DATA_SHOULDER_RIGHT = SynchedEntityData.defineId(Player.class, EntityDataSerializers.COMPOUND_TAG); protected static final EntityDataAccessor<CompoundTag> DATA_SHOULDER_RIGHT = SynchedEntityData.defineId(Player.class, EntityDataSerializers.COMPOUND_TAG);
@ -152,37 +113,28 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -0,0 +0,0 @@
package org.bukkit.craftbukkit.entity;
+import com.destroystokyo.paper.ClientOption.ChatVisibility;
+import com.destroystokyo.paper.PaperSkinParts;
+import com.destroystokyo.paper.ClientOption;
import com.destroystokyo.paper.Title;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
public void setViewDistance(int viewDistance) { public void setViewDistance(int viewDistance) {
throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement (There are per world view distances though!)"); // TODO throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement (There are per world view distances though!)"); // TODO
} }
+ +
+ @Override + @Override
+ public <T> T getClientOption(ClientOption<T> type) { + public <T> T getClientOption(com.destroystokyo.paper.ClientOption<T> type) {
+ if(ClientOption.SKIN_PARTS.equals(type)) { + if(com.destroystokyo.paper.ClientOption.SKIN_PARTS.equals(type)) {
+ return type.getType().cast(new PaperSkinParts(getHandle().getEntityData().get(net.minecraft.world.entity.player.Player.getSkinPartsWatcher()))); + return type.getType().cast(new com.destroystokyo.paper.PaperSkinParts(getHandle().getEntityData().get(net.minecraft.world.entity.player.Player.DATA_PLAYER_MODE_CUSTOMISATION)));
+ } else if(ClientOption.CHAT_COLORS_ENABLED.equals(type)) { + } else if(com.destroystokyo.paper.ClientOption.CHAT_COLORS_ENABLED.equals(type)) {
+ return type.getType().cast(getHandle().hasChatColorsEnabled()); + return type.getType().cast(getHandle().canChatInColor());
+ } else if(ClientOption.CHAT_VISIBILITY.equals(type)) { + } else if(com.destroystokyo.paper.ClientOption.CHAT_VISIBILITY.equals(type)) {
+ return type.getType().cast(getHandle().getChatVisibility() == null ? ChatVisibility.UNKNOWN : ChatVisibility.valueOf(getHandle().getChatVisibility().name())); + return type.getType().cast(getHandle().getChatVisibility() == null ? com.destroystokyo.paper.ClientOption.ChatVisibility.UNKNOWN : com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(getHandle().getChatVisibility().name()));
+ } else if(ClientOption.LOCALE.equals(type)) { + } else if(com.destroystokyo.paper.ClientOption.LOCALE.equals(type)) {
+ return type.getType().cast(getLocale()); + return type.getType().cast(getLocale());
+ } else if(ClientOption.MAIN_HAND.equals(type)) { + } else if(com.destroystokyo.paper.ClientOption.MAIN_HAND.equals(type)) {
+ return type.getType().cast(getMainHand()); + return type.getType().cast(getMainHand());
+ } else if(ClientOption.VIEW_DISTANCE.equals(type)) { + } else if(com.destroystokyo.paper.ClientOption.VIEW_DISTANCE.equals(type)) {
+ return type.getType().cast(getClientViewDistance()); + return type.getType().cast(getClientViewDistance());
+ } + }
+ throw new RuntimeException("Unknown settings type"); + throw new RuntimeException("Unknown settings type");
+ } + }
// Paper end // Paper end
// Spigot start @Override

View File

@ -70,25 +70,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
while (cause instanceof CompletionException && cause.getCause() != null) { while (cause instanceof CompletionException && cause.getCause() != null) {
cause = cause.getCause(); cause = cause.getCause();
} }
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/Util.java
+++ b/src/main/java/net/minecraft/Util.java
@@ -0,0 +0,0 @@ public class Util {
return Util.IO_POOL;
}
+ public static void shutdownServerThreadPool() { shutdownExecutors(); } // Paper - OBFHELPER
public static void shutdownExecutors() {
shutdownExecutor(Util.BACKGROUND_EXECUTOR);
shutdownExecutor(Util.IO_POOL);
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java --- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
public int autosavePeriod; public int autosavePeriod;
public boolean serverAutoSave = false; // Paper
public Commands vanillaCommandDispatcher; public Commands vanillaCommandDispatcher;
- private boolean forceTicks; - private boolean forceTicks;
+ public boolean forceTicks; // Paper + public boolean forceTicks; // Paper
@ -112,10 +100,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public volatile boolean hasFullyShutdown = false; // Paper + public volatile boolean hasFullyShutdown = false; // Paper
private final Object stopLock = new Object(); private final Object stopLock = new Object();
public final boolean hasStopped() { public final boolean hasStopped() {
synchronized (stopLock) { synchronized (this.stopLock) {
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
if (hasStopped) return; if (this.hasStopped) return;
hasStopped = true; this.hasStopped = true;
} }
+ // Paper start - kill main thread, and kill it hard + // Paper start - kill main thread, and kill it hard
+ shutdownThread = Thread.currentThread(); + shutdownThread = Thread.currentThread();
@ -128,24 +116,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ Thread.sleep(1); + Thread.sleep(1);
+ } catch (InterruptedException e) {} + } catch (InterruptedException e) {}
+ } + }
+ // We've just obliterated the main thread, this will prevent stop from dying when removing players
+ MinecraftServer.getServer().getAllLevels().forEach(world -> {
+ world.tickingEntities = false;
+ });
+ } + }
+ // Paper end + // Paper end
// CraftBukkit end // CraftBukkit end
MinecraftServer.LOGGER.info("Stopping server"); MinecraftServer.LOGGER.info("Stopping server");
MinecraftTimings.stopServer(); // Paper MinecraftTimings.stopServer(); // Paper
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.getProfileCache().b(false); // Paper this.getProfileCache().save(false); // Paper
} }
// Spigot end // Spigot end
+ // Paper start - move final shutdown items here + // Paper start - move final shutdown items here
+ LOGGER.info("Flushing Chunk IO"); + LOGGER.info("Flushing Chunk IO");
com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.close(true, true); // Paper com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.close(true, true); // Paper
+ LOGGER.info("Closing Thread Pool"); + LOGGER.info("Closing Thread Pool");
+ Util.shutdownServerThreadPool(); // Paper + Util.shutdownExecutors(); // Paper
+ LOGGER.info("Closing Server"); + LOGGER.info("Closing Server");
+ try { + try {
+ net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Use TerminalConsoleAppender + net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Use TerminalConsoleAppender
@ -237,7 +221,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Spigot End // Spigot End
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.packRepository.setSelected(datapacks); this.packRepository.setSelected(datapacks);
this.worldData.setDataPackConfig(getSelectedPacks(this.packRepository)); this.worldData.setDataPackConfig(MinecraftServer.getSelectedPacks(this.packRepository));
datapackresources.updateGlobals(); datapackresources.updateGlobals();
- this.getPlayerList().saveAll(); - this.getPlayerList().saveAll();
+ if (Thread.currentThread() != this.serverThread) return; // Paper + if (Thread.currentThread() != this.serverThread) return; // Paper
@ -289,25 +273,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
mutableboolean.setFalse(); mutableboolean.setFalse();
list.stream().map((playerchunk) -> { list.stream().map((playerchunk) -> {
CompletableFuture completablefuture; CompletableFuture completablefuture;
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
private final Queue<Entity> toAddAfterTick = Queues.newArrayDeque();
public final List<ServerPlayer> players = Lists.newArrayList(); // Paper - private -> public
public final ServerChunkCache chunkSource; // Paper - public
- boolean tickingEntities;
+ public boolean tickingEntities; // Paper - expose for watchdog
// Paper start
List<java.lang.Runnable> afterEntityTickingTasks = Lists.newArrayList();
public void doIfNotEntityTicking(java.lang.Runnable run) {
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java --- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -0,0 +0,0 @@ public abstract class PlayerList { @@ -0,0 +0,0 @@ public abstract class PlayerList {
cserver.getPluginManager().callEvent(playerQuitEvent); this.cserver.getPluginManager().callEvent(playerQuitEvent);
entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage()); entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());
- entityplayer.doTick(); // SPIGOT-924 - entityplayer.doTick(); // SPIGOT-924
@ -319,26 +290,18 @@ diff --git a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java b/s
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java --- a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java
+++ b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java +++ b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java
@@ -0,0 +0,0 @@ public abstract class BlockableEventLoop<R extends Runnable> implements Processo @@ -0,0 +0,0 @@ public abstract class BlockableEventLoop<R extends Runnable> implements Profiler
try { try {
task.run(); task.run();
} catch (Exception exception) { } catch (Exception var3) {
+ if (exception.getCause() instanceof ThreadDeath) throw exception; // Paper + if (var3.getCause() instanceof ThreadDeath) throw var3; // Paper
BlockableEventLoop.LOGGER.fatal("Error executing task on {}", this.name(), exception); LOGGER.fatal("Error executing task on {}", this.name(), var3);
} }
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/Level.java --- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
gameprofilerfiller.pop();
} catch (Throwable throwable) {
+ if (throwable instanceof ThreadDeath) throw throwable; // Paper
// Paper start - Prevent tile entity and entity crashes
String msg = "TileEntity threw exception at " + tileentity.getLevel().getWorld().getName() + ":" + tileentity.getBlockPos().getX() + "," + tileentity.getBlockPos().getY() + "," + tileentity.getBlockPos().getZ();
System.err.println(msg);
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable { @@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
try { try {
tickConsumer.accept(entity); tickConsumer.accept(entity);
@ -347,6 +310,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Paper start - Prevent tile entity and entity crashes // Paper start - Prevent tile entity and entity crashes
String msg = "Entity threw exception at " + entity.level.getWorld().getName() + ":" + entity.getX() + "," + entity.getY() + "," + entity.getZ(); String msg = "Entity threw exception at " + entity.level.getWorld().getName() + ":" + entity.getX() + "," + entity.getY() + "," + entity.getZ();
System.err.println(msg); System.err.println(msg);
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
gameprofilerfiller.pop();
} catch (Throwable throwable) {
+ if (throwable instanceof ThreadDeath) throw throwable; // Paper
// Paper start - Prevent tile entity and entity crashes
String msg = "TileEntity threw exception at " + LevelChunk.this.getLevel().getWorld().getName() + ":" + this.getPos().getX() + "," + this.getPos().getY() + "," + this.getPos().getZ();
System.err.println(msg);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@ -496,7 +471,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
org.spigotmc.AsyncCatcher.enabled = false; // Spigot org.spigotmc.AsyncCatcher.enabled = false; // Spigot
org.spigotmc.AsyncCatcher.shuttingDown = true; // Paper org.spigotmc.AsyncCatcher.shuttingDown = true; // Paper
+ server.forceTicks = true; + server.forceTicks = true;
server.close(); this.server.close();
+ while (!server.hasFullyShutdown) Thread.sleep(1000); + while (!server.hasFullyShutdown) Thread.sleep(1000);
+ } catch (InterruptedException e) { + } catch (InterruptedException e) {
+ e.printStackTrace(); + e.printStackTrace();
@ -535,19 +510,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private boolean restart; private boolean restart;
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread @@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
{ {
if ( instance == null ) if ( WatchdogThread.instance == null )
{ {
+ if (timeoutTime <= 0) timeoutTime = 300; // Paper + if (timeoutTime <= 0) timeoutTime = 300; // Paper
instance = new WatchdogThread( timeoutTime * 1000L, restart ); WatchdogThread.instance = new WatchdogThread( timeoutTime * 1000L, restart );
instance.start(); WatchdogThread.instance.start();
} else } else
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread @@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
// Paper start // Paper start
Logger log = Bukkit.getServer().getLogger(); Logger log = Bukkit.getServer().getLogger();
long currentTime = monotonicMillis(); long currentTime = WatchdogThread.monotonicMillis();
- if ( lastTick != 0 && timeoutTime > 0 && currentTime > lastTick + earlyWarningEvery && !Boolean.getBoolean("disable.watchdog") ) - if ( this.lastTick != 0 && this.timeoutTime > 0 && currentTime > this.lastTick + this.earlyWarningEvery && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable
+ MinecraftServer server = MinecraftServer.getServer(); + MinecraftServer server = MinecraftServer.getServer();
+ if (lastTick != 0 && timeoutTime > 0 && hasStarted && (!server.isRunning() || (currentTime > lastTick + earlyWarningEvery && !DISABLE_WATCHDOG) )) + if ( this.lastTick != 0 && this.timeoutTime > 0 && WatchdogThread.hasStarted && (!server.isRunning() || (currentTime > this.lastTick + this.earlyWarningEvery && !DISABLE_WATCHDOG) )) // Paper - add property to disable
{ {
- boolean isLongTimeout = currentTime > lastTick + timeoutTime; - boolean isLongTimeout = currentTime > lastTick + timeoutTime;
+ boolean isLongTimeout = currentTime > lastTick + timeoutTime || (!server.isRunning() && !server.hasStopped() && currentTime > lastTick + 1000); + boolean isLongTimeout = currentTime > lastTick + timeoutTime || (!server.isRunning() && !server.hasStopped() && currentTime > lastTick + 1000);
@ -561,9 +536,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread @@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
log.log( Level.SEVERE, "------------------------------" ); log.log( Level.SEVERE, "------------------------------" );
log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
ChunkTaskManager.dumpAllChunkLoadInfo(); // Paper com.destroystokyo.paper.io.chunk.ChunkTaskManager.dumpAllChunkLoadInfo(); // Paper
- dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log ); - WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
+ dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( server.serverThread.getId(), Integer.MAX_VALUE ), log ); + WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( server.serverThread.getId(), Integer.MAX_VALUE ), log );
log.log( Level.SEVERE, "------------------------------" ); log.log( Level.SEVERE, "------------------------------" );
// //
// Paper start - Only print full dump on long timeouts // Paper start - Only print full dump on long timeouts
@ -571,7 +546,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if ( isLongTimeout ) if ( isLongTimeout )
{ {
- if ( restart && !MinecraftServer.getServer().hasStopped() ) - if ( this.restart && !MinecraftServer.getServer().hasStopped() )
+ if ( !server.hasStopped() ) + if ( !server.hasStopped() )
{ {
- RestartCommand.restart(); - RestartCommand.restart();

View File

@ -4,19 +4,6 @@ Date: Sun, 19 Apr 2020 04:28:29 -0400
Subject: [PATCH] Load Chunks for Login Asynchronously Subject: [PATCH] Load Chunks for Login Asynchronously
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
private final ProcessorHandle<ChunkTaskPriorityQueueSorter.Message<Runnable>> worldgenMailbox;
private final ProcessorHandle<ChunkTaskPriorityQueueSorter.Message<Runnable>> mainThreadMailbox;
public final ChunkProgressListener progressListener;
- public final ChunkMap.ChunkDistanceManager distanceManager;
+ public final ChunkMap.ChunkDistanceManager distanceManager; public final DistanceManager getChunkDistanceManager() { return this.distanceManager; } // Paper - OBFHELPER
private final AtomicInteger tickingGenerated;
public final StructureManager structureManager; // Paper - private -> public
private final File storageFolder;
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@ -25,8 +12,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return this.mainThreadProcessor.pollTask(); return this.mainThreadProcessor.pollTask();
} }
- private boolean runDistanceManagerUpdates() { - boolean runDistanceManagerUpdates() {
+ public boolean runDistanceManagerUpdates() { // Paper - private -> public + public boolean runDistanceManagerUpdates() { // Paper - packate-private -> public
boolean flag = this.distanceManager.runAllUpdates(this.chunkMap); boolean flag = this.distanceManager.runAllUpdates(this.chunkMap);
boolean flag1 = this.chunkMap.promoteChunkMap(); boolean flag1 = this.chunkMap.promoteChunkMap();
@ -34,23 +21,15 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -0,0 +0,0 @@ import net.minecraft.core.Vec3i; @@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
import net.minecraft.nbt.CompoundTag; private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32;
import net.minecraft.nbt.NbtOps; private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
import net.minecraft.nbt.Tag;
+import net.minecraft.network.Connection;
import net.minecraft.network.chat.ChatType;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.HoverEvent;
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener {
private static final Logger LOGGER = LogManager.getLogger();
public ServerGamePacketListenerImpl connection; public ServerGamePacketListenerImpl connection;
+ public Connection networkManager; // Paper + public net.minecraft.network.Connection networkManager; // Paper
public final MinecraftServer server; public final MinecraftServer server;
public final ServerPlayerGameMode gameMode; public final ServerPlayerGameMode gameMode;
public final Deque<Integer> removeQueue = new ArrayDeque<>(); // Paper private final PlayerAdvancements advancements;
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener { @@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
public boolean joining = true; public boolean joining = true;
public boolean sentListPacket = false; public boolean sentListPacket = false;
public boolean supressTrackerForLogin = false; // Paper public boolean supressTrackerForLogin = false; // Paper
@ -63,26 +42,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/level/TicketType.java --- a/src/main/java/net/minecraft/server/level/TicketType.java
+++ b/src/main/java/net/minecraft/server/level/TicketType.java +++ b/src/main/java/net/minecraft/server/level/TicketType.java
@@ -0,0 +0,0 @@ public class TicketType<T> { @@ -0,0 +0,0 @@ public class TicketType<T> {
public static final TicketType<ChunkPos> FORCED = create("forced", Comparator.comparingLong(ChunkPos::toLong)); public static final TicketType<ChunkPos> FORCED = TicketType.create("forced", Comparator.comparingLong(ChunkPos::toLong));
public static final TicketType<ChunkPos> LIGHT = create("light", Comparator.comparingLong(ChunkPos::toLong)); public static final TicketType<ChunkPos> LIGHT = TicketType.create("light", Comparator.comparingLong(ChunkPos::toLong));
public static final TicketType<BlockPos> PORTAL = create("portal", Vec3i::compareTo, 300); public static final TicketType<BlockPos> PORTAL = TicketType.create("portal", Vec3i::compareTo, 300);
+ public static final TicketType<Long> LOGIN = create("login", Long::compareTo, 100); // Paper + public static final TicketType<Long> LOGIN = create("login", Long::compareTo, 100); // Paper
public static final TicketType<Integer> POST_TELEPORT = create("post_teleport", Integer::compareTo, 5); public static final TicketType<Integer> POST_TELEPORT = TicketType.create("post_teleport", Integer::compareTo, 5);
public static final TicketType<ChunkPos> UNKNOWN = create("unknown", Comparator.comparingLong(ChunkPos::toLong), 1); public static final TicketType<ChunkPos> UNKNOWN = TicketType.create("unknown", Comparator.comparingLong(ChunkPos::toLong), 1);
public static final TicketType<Unit> PLUGIN = create("plugin", (a, b) -> 0); // CraftBukkit public static final TicketType<Unit> PLUGIN = TicketType.create("plugin", (a, b) -> 0); // CraftBukkit
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
private static final Logger LOGGER = LogManager.getLogger(); private static final int LATENCY_CHECK_INTERVAL = 15000;
public final Connection connection; public final Connection connection;
private final MinecraftServer server; private final MinecraftServer server;
+ public Runnable playerJoinReady; // Paper + public Runnable playerJoinReady; // Paper
public ServerPlayer player; public ServerPlayer player;
private int tickCount; private int tickCount;
private long keepAliveTime = Util.getMillis(); private void setLastPing(long lastPing) { this.keepAliveTime = lastPing;}; private long getLastPing() { return this.keepAliveTime;}; // Paper - OBFHELPER private long keepAliveTime = Util.getMillis();
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
// CraftBukkit end // CraftBukkit end
public void tick() { public void tick() {
@ -98,7 +77,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.resetPosition(); this.resetPosition();
this.player.xo = this.player.getX(); this.player.xo = this.player.getX();
this.player.yo = this.player.getY(); this.player.yo = this.player.getY();
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
this.lastVehicle = null; this.lastVehicle = null;
this.clientVehicleIsFloating = false; this.clientVehicleIsFloating = false;
this.aboveGroundVehicleTickCount = 0; this.aboveGroundVehicleTickCount = 0;
@ -127,8 +106,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- ServerPlayer entityplayer = this.server.getPlayerList().getPlayer(this.gameProfile.getId()); - ServerPlayer entityplayer = this.server.getPlayerList().getPlayer(this.gameProfile.getId());
+ ServerPlayer entityplayer = this.server.getPlayerList().getActivePlayer(this.gameProfile.getId()); // Paper + ServerPlayer entityplayer = this.server.getPlayerList().getActivePlayer(this.gameProfile.getId()); // Paper
if (entityplayer != null) { try {
this.state = ServerLoginPacketListenerImpl.State.DELAY_ACCEPT; ServerPlayer entityplayer1 = this.server.getPlayerList().processLogin(this.gameProfile, s); // CraftBukkit - add player reference
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java --- a/src/main/java/net/minecraft/server/players/PlayerList.java
@ -140,16 +119,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import net.minecraft.network.protocol.game.ClientboundDisconnectPacket; +import net.minecraft.network.protocol.game.ClientboundDisconnectPacket;
import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
import net.minecraft.network.protocol.game.ClientboundGameEventPacket; import net.minecraft.network.protocol.game.ClientboundGameEventPacket;
import net.minecraft.network.protocol.game.ClientboundLoginPacket; import net.minecraft.network.protocol.game.ClientboundInitializeBorderPacket;
@@ -0,0 +0,0 @@ import net.minecraft.server.MCUtil;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.PlayerAdvancements;
import net.minecraft.server.ServerScoreboard;
+import net.minecraft.server.level.ChunkHolder;
+import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.level.ServerPlayerGameMode;
@@ -0,0 +0,0 @@ public abstract class PlayerList { @@ -0,0 +0,0 @@ public abstract class PlayerList {
private static final SimpleDateFormat BAN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z"); private static final SimpleDateFormat BAN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");
private final MinecraftServer server; private final MinecraftServer server;
@ -193,12 +163,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ ServerLevel finalWorldserver = worldserver1; + ServerLevel finalWorldserver = worldserver1;
+ int chunkX = loc.getBlockX() >> 4; + int chunkX = loc.getBlockX() >> 4;
+ int chunkZ = loc.getBlockZ() >> 4; + int chunkZ = loc.getBlockZ() >> 4;
+ final ChunkPos pos = new ChunkPos(chunkX, chunkZ); + final net.minecraft.world.level.ChunkPos pos = new net.minecraft.world.level.ChunkPos(chunkX, chunkZ);
+ ChunkMap playerChunkMap = worldserver1.getChunkSource().chunkMap; + net.minecraft.server.level.ChunkMap playerChunkMap = worldserver1.getChunkSource().chunkMap;
+ playerChunkMap.getChunkDistanceManager().addTicketAtLevel(TicketType.LOGIN, pos, 31, pos.toLong()); + net.minecraft.server.level.DistanceManager distanceManager = playerChunkMap.distanceManager;
+ distanceManager.addTicketAtLevel(net.minecraft.server.level.TicketType.LOGIN, pos, 31, pos.toLong());
+ worldserver1.getChunkSource().runDistanceManagerUpdates(); + worldserver1.getChunkSource().runDistanceManagerUpdates();
+ worldserver1.getChunkSource().getChunkAtAsynchronously(chunkX, chunkZ, true, true).thenApply(chunk -> { + worldserver1.getChunkSource().getChunkAtAsynchronously(chunkX, chunkZ, true, true).thenApply(chunk -> {
+ ChunkHolder updatingChunk = playerChunkMap.getUpdatingChunkIfPresent(pos.toLong()); + net.minecraft.server.level.ChunkHolder updatingChunk = playerChunkMap.getUpdatingChunkIfPresent(pos.toLong());
+ if (updatingChunk != null) { + if (updatingChunk != null) {
+ return updatingChunk.getEntityTickingFuture(); + return updatingChunk.getEntityTickingFuture();
+ } else { + } else {
@ -227,126 +198,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }); + });
+ } + }
+ +
+ private void postChunkLoadJoin(ServerPlayer entityplayer, ServerLevel worldserver1, Connection networkmanager, ServerGamePacketListenerImpl playerconnection, CompoundTag nbttagcompound, String s1, String s) { + private void postChunkLoadJoin(ServerPlayer player, ServerLevel worldserver1, Connection networkmanager, ServerGamePacketListenerImpl playerconnection, CompoundTag nbttagcompound, String s1, String s) {
+ pendingPlayers.remove(entityplayer.getUUID(), entityplayer); + pendingPlayers.remove(player.getUUID(), player);
+ if (!networkmanager.isConnected()) { + if (!networkmanager.isConnected()) {
+ return; + return;
+ } + }
+ entityplayer.didPlayerJoinEvent = true; + player.didPlayerJoinEvent = true;
+ // Paper end + // Paper end
TranslatableComponent chatmessage; TranslatableComponent chatmessage;
- if (player.getGameProfile().getName().equalsIgnoreCase(s)) { if (player.getGameProfile().getName().equalsIgnoreCase(s)) {
- chatmessage = new TranslatableComponent("multiplayer.player.joined", new Object[]{player.getDisplayName()});
+ if (entityplayer.getGameProfile().getName().equalsIgnoreCase(s)) {
+ chatmessage = new TranslatableComponent("multiplayer.player.joined", new Object[]{entityplayer.getDisplayName()});
} else {
- chatmessage = new TranslatableComponent("multiplayer.player.joined.renamed", new Object[]{player.getDisplayName(), s});
+ chatmessage = new TranslatableComponent("multiplayer.player.joined.renamed", new Object[]{entityplayer.getDisplayName(), s});
}
// CraftBukkit start
chatmessage.withStyle(ChatFormatting.YELLOW);
Component joinMessage = chatmessage; // Paper - Adventure
- playerconnection.teleport(player.getX(), player.getY(), player.getZ(), player.yRot, player.xRot);
- this.players.add(player);
- this.playersByName.put(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT), player); // Spigot
- this.playersByUUID.put(player.getUUID(), player);
+ playerconnection.teleport(entityplayer.getX(), entityplayer.getY(), entityplayer.getZ(), entityplayer.yRot, entityplayer.xRot);
+ this.players.add(entityplayer);
+ this.playersByName.put(entityplayer.getScoreboardName().toLowerCase(java.util.Locale.ROOT), entityplayer); // Spigot
+ this.playersByUUID.put(entityplayer.getUUID(), entityplayer);
// this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, new EntityPlayer[]{entityplayer})); // CraftBukkit - replaced with loop below
// Paper start - correctly register player BEFORE PlayerJoinEvent, so the entity is valid and doesn't require tick delay hacks
- player.supressTrackerForLogin = true;
- worldserver1.addNewPlayer(player);
- this.server.getCustomBossEvents().onPlayerConnect(player); // see commented out section below worldserver.addPlayerJoin(entityplayer);
- mountSavedVehicle(player, worldserver1, nbttagcompound);
+ entityplayer.supressTrackerForLogin = true;
+ worldserver1.addNewPlayer(entityplayer);
+ this.server.getCustomBossEvents().onPlayerConnect(entityplayer); // see commented out section below worldserver.addPlayerJoin(entityplayer);
+ mountSavedVehicle(entityplayer, worldserver1, nbttagcompound);
// Paper end
// CraftBukkit start
- PlayerJoinEvent playerJoinEvent = new org.bukkit.event.player.PlayerJoinEvent(cserver.getPlayer(player), PaperAdventure.asAdventure(chatmessage)); // Paper - Adventure
+ PlayerJoinEvent playerJoinEvent = new org.bukkit.event.player.PlayerJoinEvent(cserver.getPlayer(entityplayer), PaperAdventure.asAdventure(chatmessage)); // Paper - Adventure
cserver.getPluginManager().callEvent(playerJoinEvent);
- if (!player.connection.connection.isConnected()) {
+ if (!entityplayer.connection.connection.isConnected()) {
return;
}
@@ -0,0 +0,0 @@ public abstract class PlayerList {
// CraftBukkit end
// CraftBukkit start - sendAll above replaced with this loop
- ClientboundPlayerInfoPacket packet = new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, player);
+ ClientboundPlayerInfoPacket packet = new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, entityplayer);
for (int i = 0; i < this.players.size(); ++i) {
ServerPlayer entityplayer1 = (ServerPlayer) this.players.get(i);
- if (entityplayer1.getBukkitEntity().canSee(player.getBukkitEntity())) {
+ if (entityplayer1.getBukkitEntity().canSee(entityplayer.getBukkitEntity())) {
entityplayer1.connection.send(packet);
}
- if (!player.getBukkitEntity().canSee(entityplayer1.getBukkitEntity())) {
+ if (!entityplayer.getBukkitEntity().canSee(entityplayer1.getBukkitEntity())) {
continue;
}
- player.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, new ServerPlayer[] { entityplayer1}));
+ entityplayer.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, new ServerPlayer[] { entityplayer1}));
}
- player.sentListPacket = true;
- player.supressTrackerForLogin = false; // Paper
- ((ServerLevel)player.level).getChunkSource().chunkMap.addEntity(player); // Paper - track entity now
+ entityplayer.sentListPacket = true;
+ entityplayer.supressTrackerForLogin = false; // Paper
+ ((ServerLevel)entityplayer.level).getChunkSource().chunkMap.addEntity(entityplayer); // Paper - track entity now
// CraftBukkit end
- player.connection.send(new ClientboundSetEntityDataPacket(player.getId(), player.getEntityData(), true)); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn
+ entityplayer.connection.send(new ClientboundSetEntityDataPacket(entityplayer.getId(), entityplayer.getEntityData(), true)); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn
// CraftBukkit start - Only add if the player wasn't moved in the event
- if (player.level == worldserver1 && !worldserver1.players().contains(player)) {
- worldserver1.addNewPlayer(player);
- this.server.getCustomBossEvents().onPlayerConnect(player);
+ if (entityplayer.level == worldserver1 && !worldserver1.players().contains(entityplayer)) {
+ worldserver1.addNewPlayer(entityplayer);
+ this.server.getCustomBossEvents().onPlayerConnect(entityplayer);
}
- worldserver1 = player.getLevel(); // CraftBukkit - Update in case join event changed it
+ worldserver1 = entityplayer.getLevel(); // CraftBukkit - Update in case join event changed it
// CraftBukkit end
- this.sendLevelInfo(player, worldserver1);
+ this.sendLevelInfo(entityplayer, worldserver1);
if (!this.server.getResourcePack().isEmpty()) {
- player.sendTexturePack(this.server.getResourcePack(), this.server.getResourcePackHash());
+ entityplayer.sendTexturePack(this.server.getResourcePack(), this.server.getResourcePackHash());
}
- Iterator iterator = player.getActiveEffects().iterator();
+ Iterator iterator = entityplayer.getActiveEffects().iterator();
while (iterator.hasNext()) {
MobEffectInstance mobeffect = (MobEffectInstance) iterator.next();
- playerconnection.send(new ClientboundUpdateMobEffectPacket(player.getId(), mobeffect));
+ playerconnection.send(new ClientboundUpdateMobEffectPacket(entityplayer.getId(), mobeffect));
}
// Paper start - move vehicle into method so it can be called above - short circuit around that code
- onPlayerJoinFinish(player, worldserver1, s1);
+ onPlayerJoinFinish(entityplayer, worldserver1, s1);
}
private void mountSavedVehicle(ServerPlayer entityplayer, ServerLevel worldserver1, CompoundTag nbttagcompound) {
// Paper end
@@ -0,0 +0,0 @@ public abstract class PlayerList { @@ -0,0 +0,0 @@ public abstract class PlayerList {
protected void save(ServerPlayer player) { protected void save(ServerPlayer player) {
@ -358,9 +219,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class PlayerList { @@ -0,0 +0,0 @@ public abstract class PlayerList {
} }
PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(cserver.getPlayer(entityplayer), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, com.destroystokyo.paper.PaperConfig.useDisplayNameInQuit ? entityplayer.getBukkitEntity().displayName() : net.kyori.adventure.text.Component.text(entityplayer.getScoreboardName()))); PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(this.cserver.getPlayer(entityplayer), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, com.destroystokyo.paper.PaperConfig.useDisplayNameInQuit ? entityplayer.getBukkitEntity().displayName() : net.kyori.adventure.text.Component.text(entityplayer.getScoreboardName())));
- cserver.getPluginManager().callEvent(playerQuitEvent); - this.cserver.getPluginManager().callEvent(playerQuitEvent);
+ if (entityplayer.didPlayerJoinEvent) cserver.getPluginManager().callEvent(playerQuitEvent); // Paper - if we disconnected before join ever fired, don't fire quit + if (entityplayer.didPlayerJoinEvent) this.cserver.getPluginManager().callEvent(playerQuitEvent); // Paper - if we disconnected before join ever fired, don't fire quit
entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage()); entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());
if (server.isSameThread()) entityplayer.doTick(); // SPIGOT-924 // Paper - don't tick during emergency shutdowns (Watchdog) if (server.isSameThread()) entityplayer.doTick(); // SPIGOT-924 // Paper - don't tick during emergency shutdowns (Watchdog)
@ -379,7 +240,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit start // CraftBukkit start
// this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[]{entityplayer})); // this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[]{entityplayer}));
@@ -0,0 +0,0 @@ public abstract class PlayerList { @@ -0,0 +0,0 @@ public abstract class PlayerList {
cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity()); this.cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity());
// CraftBukkit end // CraftBukkit end
- return playerQuitEvent.quitMessage(); // Paper - Adventure - return playerQuitEvent.quitMessage(); // Paper - Adventure
@ -405,12 +266,12 @@ diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/jav
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java --- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
this.yo = y; this.yo = y;
this.zo = d4; this.zo = d4;
this.setPos(d3, y, d4); this.setPos(d3, y, d4);
- level.getChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4); // CraftBukkit - this.level.getChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4); // CraftBukkit
+ if (valid) level.getChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4); // CraftBukkit // Paper + if (valid) this.level.getChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4); // CraftBukkit // Paper
} }
public void moveTo(Vec3 vec3d) { public void moveTo(Vec3 pos) {

View File

@ -10,7 +10,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/jav
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java --- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
bworld = server.getWorld(worldName); bworld = server.getWorld(worldName);
} }
@ -23,5 +23,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+// } +// }
+ // Paper end - Move player to spawn point if spawn in unloaded world + // Paper end - Move player to spawn point if spawn in unloaded world
setLevel(bworld == null ? null : ((CraftWorld) bworld).getHandle()); ((ServerPlayer) this).setLevel(bworld == null ? null : ((CraftWorld) bworld).getHandle());
} }

View File

@ -9,27 +9,16 @@ diff --git a/src/main/java/net/minecraft/util/SortedArraySet.java b/src/main/jav
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/util/SortedArraySet.java --- a/src/main/java/net/minecraft/util/SortedArraySet.java
+++ b/src/main/java/net/minecraft/util/SortedArraySet.java +++ b/src/main/java/net/minecraft/util/SortedArraySet.java
@@ -0,0 +0,0 @@ import java.util.NoSuchElementException;
public class SortedArraySet<T> extends AbstractSet<T> {
private final Comparator<T> comparator;
- private T[] contents;
- private int size;
+ private T[] contents; private final T[] getBackingArray() { return this.contents; } // Paper - OBFHELPER
+ private int size; private final int getSize() { return this.size; } private final void setSize(int value) { this.size = value; } // Paper - OBFHELPER
private SortedArraySet(int initialCapacity, Comparator<T> comparator) {
this.comparator = comparator;
@@ -0,0 +0,0 @@ public class SortedArraySet<T> extends AbstractSet<T> { @@ -0,0 +0,0 @@ public class SortedArraySet<T> extends AbstractSet<T> {
this.contents = (T[])castRawArray(new Object[initialCapacity]);
} }
} }
+ // Paper start - optimise removeIf + // Paper start - optimise removeIf
+ @Override + @Override
+ public boolean removeIf(java.util.function.Predicate<? super T> filter) { + public boolean removeIf(java.util.function.Predicate<? super T> filter) {
+ // prev. impl used an iterator, which could be n^2 and creates garbage + // prev. impl used an iterator, which could be n^2 and creates garbage
+ int i = 0, len = this.getSize(); + int i = 0, len = this.size;
+ T[] backingArray = this.getBackingArray(); + T[] backingArray = this.contents;
+ +
+ for (;;) { + for (;;) {
+ if (i >= len) { + if (i >= len) {
@ -55,11 +44,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ // cleanup end + // cleanup end
+ Arrays.fill(backingArray, lastIndex, len, null); + Arrays.fill(backingArray, lastIndex, len, null);
+ this.setSize(lastIndex); + this.size = lastIndex;
+ return true; + return true;
+ } + }
+ // Paper end - optimise removeIf + // Paper end - optimise removeIf
+
public static <T extends Comparable<T>> SortedArraySet<T> create(int initialCapacity) { public static <T extends Comparable<T>> SortedArraySet<T> create() {
return new SortedArraySet<>(initialCapacity, (Comparator)Comparator.naturalOrder()); // Paper - decompile fix return create(10);
}

View File

@ -10,23 +10,6 @@ diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigati
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java --- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
+++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
@@ -0,0 +0,0 @@ import net.minecraft.core.Position;
import net.minecraft.core.Vec3i;
import net.minecraft.network.protocol.game.DebugPackets;
import net.minecraft.server.MCUtil;
+import net.minecraft.server.MinecraftServer;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Mob;
@@ -0,0 +0,0 @@ public abstract class PathNavigation {
protected final Mob mob; public Entity getEntity() { return mob; } // Paper - OBFHELPER
protected final Level level;
@Nullable
- protected Path path;
+ protected Path path; protected final Path getCurrentPath() { return this.path; } // Paper - OBFHELPER
protected double speedModifier;
protected int tick;
protected int lastStuckCheck;
@@ -0,0 +0,0 @@ public abstract class PathNavigation { @@ -0,0 +0,0 @@ public abstract class PathNavigation {
return this.moveTo(this.createPath(x, y, z, 1), speed); return this.moveTo(this.createPath(x, y, z, 1), speed);
} }
@ -38,21 +21,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
public boolean moveTo(Entity entity, double speed) { public boolean moveTo(Entity entity, double speed) {
+ // Paper start - Pathfinding optimizations + // Paper start - Pathfinding optimizations
+ if (this.pathfindFailures > 10 && this.getCurrentPath() == null && MinecraftServer.currentTick < this.lastFailure + 40) { + if (this.pathfindFailures > 10 && this.path == null && net.minecraft.server.MinecraftServer.currentTick < this.lastFailure + 40) {
+ return false; + return false;
+ } + }
+ // Paper end + // Paper end
Path pathentity = this.createPath(entity, 1); Path path = this.createPath(entity, 1);
- return path != null && this.moveTo(path, speed);
- return pathentity != null && this.moveTo(pathentity, speed);
+ // Paper start - Pathfinding optimizations + // Paper start - Pathfinding optimizations
+ if (pathentity != null && this.moveTo(pathentity, speed)) { + if (path != null && this.moveTo(path, speed)) {
+ this.lastFailure = 0; + this.lastFailure = 0;
+ this.pathfindFailures = 0; + this.pathfindFailures = 0;
+ return true; + return true;
+ } else { + } else {
+ this.pathfindFailures++; + this.pathfindFailures++;
+ this.lastFailure = MinecraftServer.currentTick; + this.lastFailure = net.minecraft.server.MinecraftServer.currentTick;
+ return false; + return false;
+ } + }
+ // Paper end + // Paper end

View File

@ -0,0 +1,121 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 3 May 2020 22:35:09 -0400
Subject: [PATCH] Optimize Voxel Shape Merging
This method shows up as super hot in profiler, and also a high "self" time.
Upon analyzing, it appears most usages of this method fall down to the final
else statement of the nasty ternary.
Upon even further analyzation, it appears then the majority of those have a
consistent list 1.... One with Infinity head and Tails.
First optimization is to detect these infinite states and immediately return that
VoxelShapeMergerList so we can avoid testing the rest for most cases.
Break the method into 2 to help the JVM promote inlining of this fast path.
Then it was also noticed that VoxelShapeMergerList constructor is also a hotspot
with a high self time...
Well, knowing that in most cases our list 1 is actualy the same value, it allows
us to know that with an infinite list1, the result on the merger is essentially
list2 as the final values.
This let us analyze the 2 potential states (Infinite with 2 sources or 4 sources)
and compute a deterministic result for the MergerList values.
Additionally, this lets us avoid even allocating new objects for this too, further
reducing memory usage.
diff --git a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java
@@ -0,0 +0,0 @@ public class IndirectMerger implements IndexMerger {
private final int[] firstIndices;
private final int[] secondIndices;
private final int resultLength;
+ // Paper start
+ private static final int[] INFINITE_B_1 = new int[]{1, 1};
+ private static final int[] INFINITE_B_0 = new int[]{0, 0};
+ private static final int[] INFINITE_C = new int[]{0, 1};
+ // Paper end
public IndirectMerger(DoubleList first, DoubleList second, boolean includeFirstOnly, boolean includeSecondOnly) {
double d = Double.NaN;
int i = first.size();
int j = second.size();
int k = i + j;
+ // Paper start - optimize common path of infinity doublelist
+ int size = first.size();
+ double tail = first.getDouble(size - 1);
+ double head = first.getDouble(0);
+ if (head == Double.NEGATIVE_INFINITY && tail == Double.POSITIVE_INFINITY && !includeFirstOnly && !includeSecondOnly && (size == 2 || size == 4)) {
+ this.result = second.toDoubleArray();
+ this.resultLength = second.size();
+ if (size == 2) {
+ this.firstIndices = INFINITE_B_0;
+ } else {
+ this.firstIndices = INFINITE_B_1;
+ }
+ this.secondIndices = INFINITE_C;
+ return;
+ }
+ // Paper end
this.result = new double[k];
this.firstIndices = new int[k];
this.secondIndices = new int[k];
diff --git a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
@@ -0,0 +0,0 @@ public final class Shapes {
}
@VisibleForTesting
- protected static IndexMerger createIndexMerger(int size, DoubleList first, DoubleList second, boolean includeFirst, boolean includeSecond) {
+ private static IndexMerger createIndexMerger(int size, DoubleList first, DoubleList second, boolean includeFirst, boolean includeSecond) { // Paper - private
+ // Paper start - fast track the most common scenario
+ // doublelist is usually a DoubleArrayList with Infinite head/tails that falls to the final else clause
+ // This is actually the most common path, so jump to it straight away
+ if (first.getDouble(0) == Double.NEGATIVE_INFINITY && first.getDouble(first.size() - 1) == Double.POSITIVE_INFINITY) {
+ return new IndirectMerger(first, second, includeFirst, includeSecond);
+ }
+ // Split out rest to hopefully inline the above
+ return lessCommonMerge(size, first, second, includeFirst, includeSecond);
+ }
+
+ private static IndexMerger lessCommonMerge(int size, DoubleList first, DoubleList second, boolean includeFirst, boolean includeSecond) {
int i = first.size() - 1;
int j = second.size() - 1;
+ // Paper note - Rewrite below as optimized order if instead of nasty ternary
if (first instanceof CubePointRange && second instanceof CubePointRange) {
long l = lcm(i, j);
if ((long)size * l <= 256L) {
@@ -0,0 +0,0 @@ public final class Shapes {
}
}
- if (first.getDouble(i) < second.getDouble(0) - 1.0E-7D) {
+ // Paper start - Identical happens more often than Disjoint
+ if (i == j && Objects.equals(first, second)) {
+ if (first instanceof IdenticalMerger) {
+ return (IndexMerger) first;
+ } else if (second instanceof IdenticalMerger) {
+ return (IndexMerger) second;
+ }
+ return new IdenticalMerger(first);
+ } else if (first.getDouble(i) < second.getDouble(0) - 1.0E-7D) {
return new NonOverlappingMerger(first, second, false);
} else if (second.getDouble(j) < first.getDouble(0) - 1.0E-7D) {
return new NonOverlappingMerger(second, first, true);
} else {
- return (IndexMerger)(i == j && Objects.equals(first, second) ? new IdenticalMerger(first) : new IndirectMerger(first, second, includeFirst, includeSecond));
+ return new IndirectMerger(first, second, includeFirst, includeSecond);
}
+ // Paper end
}
public interface DoubleLineConsumer {

View File

@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener { @@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
containerUpdateDelay = level.paperConfig.containerUpdateTickRate; containerUpdateDelay = level.paperConfig.containerUpdateTickRate;
} }
// Paper end // Paper end
@ -17,24 +17,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper
this.containerMenu = this.inventoryMenu; this.containerMenu = this.inventoryMenu;
} }
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener { @@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
} else { } else {
// CraftBukkit start // CraftBukkit start
this.containerMenu = container; this.containerMenu = container;
- this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), container.getTitle())); - this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), container.getTitle()));
+ if (!isImmobile()) this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), container.getTitle())); // Paper + if (!isImmobile()) this.connection.send(new ClientboundOpenScreenPacket(container.containerId, container.getType(), container.getTitle())); // Paper
// CraftBukkit end // CraftBukkit end
container.addSlotListener(this); this.initMenu(container);
return OptionalInt.of(this.containerCounter); return OptionalInt.of(this.containerCounter);
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener {
}
@Override
- protected boolean isImmobile() {
+ public boolean isImmobile() { // Paper - protected > public
return super.isImmobile() || (this.connection != null && this.connection.isDisconnected()); // Paper
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
@ -45,8 +36,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
//player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0])); // Paper // Paper - comment //player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0])); // Paper // Paper - comment
- player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper - player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper
+ if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper + if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper
getHandle().containerMenu = container; player.containerMenu = container;
getHandle().containerMenu.addSlotListener(player); player.initMenu(container);
} }
@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
net.kyori.adventure.text.Component adventure$title = inventory.title(); // Paper net.kyori.adventure.text.Component adventure$title = inventory.title(); // Paper
@ -55,5 +46,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper - player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper
+ if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper + if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper
player.containerMenu = container; player.containerMenu = container;
player.containerMenu.addSlotListener(player); player.initMenu(container);
} }

View File

@ -114,14 +114,14 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java b/sr
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java
@@ -0,0 +0,0 @@ import org.bukkit.entity.EntityType; @@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Skeleton; import org.bukkit.entity.Skeleton;
import org.bukkit.entity.Skeleton.SkeletonType;
-public class CraftSkeleton extends CraftMonster implements Skeleton { -public class CraftSkeleton extends CraftAbstractSkeleton implements Skeleton {
+public class CraftSkeleton extends CraftMonster implements Skeleton, com.destroystokyo.paper.entity.CraftRangedEntity<AbstractSkeleton> { // Paper +public class CraftSkeleton extends CraftAbstractSkeleton implements Skeleton, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.AbstractSkeleton> { // Paper
public CraftSkeleton(CraftServer server, AbstractSkeleton entity) { public CraftSkeleton(CraftServer server, net.minecraft.world.entity.monster.Skeleton entity) {
super(server, entity); super(server, entity);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View File

@ -11,29 +11,21 @@ diff --git a/src/main/java/net/minecraft/nbt/CompoundTag.java b/src/main/java/ne
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/nbt/CompoundTag.java --- a/src/main/java/net/minecraft/nbt/CompoundTag.java
+++ b/src/main/java/net/minecraft/nbt/CompoundTag.java +++ b/src/main/java/net/minecraft/nbt/CompoundTag.java
@@ -0,0 +0,0 @@ import net.minecraft.ReportedException;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.TextComponent;
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; // Paper
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -0,0 +0,0 @@ public class CompoundTag implements Tag { @@ -0,0 +0,0 @@ public class CompoundTag implements Tag {
if (i > 512) { if (i > 512) {
throw new RuntimeException("Tried to read NBT tag with too high complexity, depth > 512"); throw new RuntimeException("Tried to read NBT tag with too high complexity, depth > 512");
} else { } else {
- HashMap hashmap = Maps.newHashMap(); - Map<String, Tag> map = Maps.newHashMap();
+ Object2ObjectOpenHashMap<String, Tag> hashmap = new Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - reduce memory footprint of NBTTagCompound + it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, Tag> map = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - reduce memory footprint of NBTTagCompound
byte b0;
byte b;
while((b = CompoundTag.readNamedTagType(dataInput, nbtAccounter)) != 0) {
@@ -0,0 +0,0 @@ public class CompoundTag implements Tag { @@ -0,0 +0,0 @@ public class CompoundTag implements Tag {
} }
public CompoundTag() { public CompoundTag() {
- this(Maps.newHashMap()); - this(Maps.newHashMap());
+ this(new Object2ObjectOpenHashMap<>(8, 0.8f)); // Paper - reduce memory footprint of NBTTagCompound + this(new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f)); // Paper - reduce memory footprint of NBTTagCompound
} }
@Override @Override
@ -42,11 +34,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override @Override
public CompoundTag copy() { public CompoundTag copy() {
- Map<String, Tag> map = Maps.newHashMap(Maps.transformValues(this.tags, Tag::copy)); - Map<String, Tag> map = Maps.newHashMap(Maps.transformValues(this.tags, Tag::copy));
+ // Paper start - reduce memory footprint of NBTTagCompound
+ Object2ObjectOpenHashMap<String, Tag> ret = new Object2ObjectOpenHashMap<>(this.tags.size(), 0.8f);
- return new CompoundTag(map); - return new CompoundTag(map);
+ Iterator<Map.Entry<String, Tag>> iterator = (this.tags instanceof Object2ObjectOpenHashMap) ? ((Object2ObjectOpenHashMap)this.tags).object2ObjectEntrySet().fastIterator() : this.tags.entrySet().iterator(); + // Paper start - reduce memory footprint of NBTTagCompound
+ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, Tag> ret = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(this.tags.size(), 0.8f);
+ java.util.Iterator<java.util.Map.Entry<String, Tag>> iterator = (this.tags instanceof it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap) ? ((it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap)this.tags).object2ObjectEntrySet().fastIterator() : this.tags.entrySet().iterator();
+ while (iterator.hasNext()) { + while (iterator.hasNext()) {
+ Map.Entry<String, Tag> entry = iterator.next(); + Map.Entry<String, Tag> entry = iterator.next();
+ ret.put(entry.getKey(), entry.getValue().copy()); + ret.put(entry.getKey(), entry.getValue().copy());
@ -56,4 +47,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - reduce memory footprint of NBTTagCompound + // Paper end - reduce memory footprint of NBTTagCompound
} }
public boolean equals(Object object) { @Override

View File

@ -13,22 +13,18 @@ diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java b/src/ma
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java --- a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@ package net.minecraft.world.entity.ai.goal;
package net.minecraft.world.entity.ai.goal;
+import com.destroystokyo.paper.util.set.OptimizedSmallEnumSet; // Paper - remove streams from pathfindergoalselector
import java.util.EnumSet; import java.util.EnumSet;
public abstract class Goal { public abstract class Goal {
- private final EnumSet<Goal.Flag> flags = EnumSet.noneOf(Goal.Flag.class); - private final EnumSet<Goal.Flag> flags = EnumSet.noneOf(Goal.Flag.class);
+ private final EnumSet<Goal.Flag> flags = EnumSet.noneOf(Goal.Flag.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be. + private final EnumSet<Goal.Flag> flags = EnumSet.noneOf(Goal.Flag.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be.
+ private final OptimizedSmallEnumSet<Flag> goalTypes = new OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector + private final com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<net.minecraft.world.entity.ai.goal.Goal.Flag> goalTypes = new com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector
public Goal() {} public abstract boolean canUse();
@@ -0,0 +0,0 @@ public abstract class Goal { @@ -0,0 +0,0 @@ public abstract class Goal {
public void tick() {} }
public void setFlags(EnumSet<Goal.Flag> controls) { public void setFlags(EnumSet<Goal.Flag> controls) {
- this.flags.clear(); - this.flags.clear();
@ -39,7 +35,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - remove streams from pathfindergoalselector + // Paper end - remove streams from pathfindergoalselector
} }
public String toString() { @Override
@@ -0,0 +0,0 @@ public abstract class Goal {
return this.getClass().getSimpleName(); return this.getClass().getSimpleName();
} }
@ -56,39 +53,32 @@ diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java --- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
@@ -0,0 +0,0 @@
package net.minecraft.world.entity.ai.goal;
+import com.destroystokyo.paper.util.set.OptimizedSmallEnumSet; // Paper - remove streams from pathfindergoalselector
import com.google.common.collect.Sets;
import java.util.EnumMap;
import java.util.EnumSet;
+import java.util.Iterator; // Paper - remove streams from pathfindergoalselector
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
@@ -0,0 +0,0 @@ public class GoalSelector { @@ -0,0 +0,0 @@ public class GoalSelector {
private final Map<Goal.Flag, WrappedGoal> lockedFlags = new EnumMap(Goal.Flag.class); private final Map<Goal.Flag, WrappedGoal> lockedFlags = new EnumMap<>(Goal.Flag.class);
private final Set<WrappedGoal> availableGoals = Sets.newLinkedHashSet(); private Set<WrappedGoal> getTasks() { return availableGoals; }// Paper - OBFHELPER private final Set<WrappedGoal> availableGoals = Sets.newLinkedHashSet();
private final Supplier<ProfilerFiller> profiler; private final Supplier<ProfilerFiller> profiler;
- private final EnumSet<Goal.Flag> disabledFlags = EnumSet.noneOf(Goal.Flag.class); - private final EnumSet<Goal.Flag> disabledFlags = EnumSet.noneOf(Goal.Flag.class);
+ private final EnumSet<Goal.Flag> disabledFlags = EnumSet.noneOf(Goal.Flag.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be. + private final EnumSet<Goal.Flag> disabledFlags = EnumSet.noneOf(Goal.Flag.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be.
+ private final OptimizedSmallEnumSet<Goal.Flag> goalTypes = new OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector + private final com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<net.minecraft.world.entity.ai.goal.Goal.Flag> goalTypes = new com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector
private int newGoalRate = 3;private int getTickRate() { return newGoalRate; } // Paper - OBFHELPER private int tickCount;
private int curRate;private int getCurRate() { return curRate; } private void incRate() { this.curRate++; } // Paper TODO private int newGoalRate = 3;
private int curRate;
+ private static final Goal.Flag[] PATHFINDER_GOAL_TYPES = Goal.Flag.values(); // Paper - remove streams from pathfindergoalselector
public GoalSelector(Supplier<ProfilerFiller> profiler) {
this.profiler = profiler;
@@ -0,0 +0,0 @@ public class GoalSelector { @@ -0,0 +0,0 @@ public class GoalSelector {
}
// Paper end // Paper end
public void removeGoal(Goal goal) { public void removeGoal(Goal goal) {
- this.availableGoals.stream().filter((pathfindergoalwrapped) -> { - this.availableGoals.stream().filter((wrappedGoal) -> {
- return pathfindergoalwrapped.getGoal() == goal; - return wrappedGoal.getGoal() == goal;
- }).filter(WrappedGoal::isRunning).forEach(WrappedGoal::stop); - }).filter(WrappedGoal::isRunning).forEach(WrappedGoal::stop);
- this.availableGoals.removeIf((pathfindergoalwrapped) -> { - this.availableGoals.removeIf((wrappedGoal) -> {
- return pathfindergoalwrapped.getGoal() == goal; - return wrappedGoal.getGoal() == goal;
- }); - });
+ // Paper start - remove streams from pathfindergoalselector + // Paper start - remove streams from pathfindergoalselector
+ for (Iterator<WrappedGoal> iterator = this.availableGoals.iterator(); iterator.hasNext();) { + for (java.util.Iterator<WrappedGoal> iterator = this.availableGoals.iterator(); iterator.hasNext();) {
+ WrappedGoal goalWrapped = iterator.next(); + WrappedGoal goalWrapped = iterator.next();
+ if (goalWrapped.getGoal() != goal) { + if (goalWrapped.getGoal() != goal) {
+ continue; + continue;
@ -101,76 +91,57 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - remove streams from pathfindergoalselector + // Paper end - remove streams from pathfindergoalselector
} }
+ private static final Goal.Flag[] PATHFINDER_GOAL_TYPES = Goal.Flag.values(); // Paper - remove streams from pathfindergoalselector
+
public void tick() { public void tick() {
ProfilerFiller gameprofilerfiller = (ProfilerFiller) this.profiler.get(); ProfilerFiller profilerFiller = this.profiler.get();
profilerFiller.push("goalCleanup");
gameprofilerfiller.push("goalCleanup"); - this.getRunningGoals().filter((wrappedGoal) -> {
- this.getRunningGoals().filter((pathfindergoalwrapped) -> { - return !wrappedGoal.isRunning() || wrappedGoal.getFlags().stream().anyMatch(this.disabledFlags::contains) || !wrappedGoal.canContinueToUse();
- boolean flag;
-
- if (pathfindergoalwrapped.isRunning()) {
- Stream stream = pathfindergoalwrapped.getFlags().stream();
- EnumSet enumset = this.disabledFlags;
-
- this.disabledFlags.getClass();
- if (!stream.anyMatch(enumset::contains) && pathfindergoalwrapped.canContinueToUse()) {
- flag = false;
- return flag;
- }
+ // Paper start - remove streams from pathfindergoalselector
+ for (Iterator<WrappedGoal> iterator = this.availableGoals.iterator(); iterator.hasNext();) {
+ WrappedGoal wrappedGoal = iterator.next();
+ if (!wrappedGoal.isRunning()) {
+ continue;
}
-
- flag = true;
- return flag;
- }).forEach(Goal::stop); - }).forEach(Goal::stop);
- this.lockedFlags.forEach((flag, wrappedGoal) -> {
+ // Paper start - remove streams from pathfindergoalselector
+ for (java.util.Iterator<WrappedGoal> iterator = this.availableGoals.iterator(); iterator.hasNext();) {
+ WrappedGoal wrappedGoal = iterator.next();
if (!wrappedGoal.isRunning()) {
- this.lockedFlags.remove(flag);
+ continue;
+ }
+ if (!this.goalTypes.hasCommonElements(wrappedGoal.getGoalTypes()) && wrappedGoal.canContinueToUse()) { + if (!this.goalTypes.hasCommonElements(wrappedGoal.getGoalTypes()) && wrappedGoal.canContinueToUse()) {
+ continue; + continue;
+ } + }
+ wrappedGoal.stop(); + wrappedGoal.stop();
+ } + }
+ // Paper end - remove streams from pathfindergoalselector + // Paper end - remove streams from pathfindergoalselector
this.lockedFlags.forEach((pathfindergoal_type, pathfindergoalwrapped) -> { + this.lockedFlags.forEach((pathfindergoal_type, pathfindergoalwrapped) -> {
if (!pathfindergoalwrapped.isRunning()) { + if (!pathfindergoalwrapped.isRunning()) {
this.lockedFlags.remove(pathfindergoal_type); + this.lockedFlags.remove(pathfindergoal_type);
@@ -0,0 +0,0 @@ public class GoalSelector { }
}); });
gameprofilerfiller.pop(); profilerFiller.pop();
gameprofilerfiller.push("goalUpdate"); profilerFiller.push("goalUpdate");
- this.availableGoals.stream().filter((pathfindergoalwrapped) -> { - this.availableGoals.stream().filter((wrappedGoal) -> {
- return !pathfindergoalwrapped.isRunning(); - return !wrappedGoal.isRunning();
- }).filter((pathfindergoalwrapped) -> { - }).filter((wrappedGoal) -> {
- Stream stream = pathfindergoalwrapped.getFlags().stream(); - return wrappedGoal.getFlags().stream().noneMatch(this.disabledFlags::contains);
- EnumSet enumset = this.disabledFlags; - }).filter((wrappedGoal) -> {
- - return wrappedGoal.getFlags().stream().allMatch((flag) -> {
- this.disabledFlags.getClass(); - return this.lockedFlags.getOrDefault(flag, NO_GOAL).canBeReplacedBy(wrappedGoal);
- return stream.noneMatch(enumset::contains);
- }).filter((pathfindergoalwrapped) -> {
- return pathfindergoalwrapped.getFlags().stream().allMatch((pathfindergoal_type) -> {
- return ((WrappedGoal) this.lockedFlags.getOrDefault(pathfindergoal_type, GoalSelector.NO_GOAL)).canBeReplacedBy(pathfindergoalwrapped);
- }); - });
- }).filter(WrappedGoal::canUse).forEach((pathfindergoalwrapped) -> { - }).filter(WrappedGoal::canUse).forEach((wrappedGoal) -> {
- pathfindergoalwrapped.getFlags().forEach((pathfindergoal_type) -> { - wrappedGoal.getFlags().forEach((flag) -> {
- WrappedGoal pathfindergoalwrapped1 = (WrappedGoal) this.lockedFlags.getOrDefault(pathfindergoal_type, GoalSelector.NO_GOAL); - WrappedGoal wrappedGoal2 = this.lockedFlags.getOrDefault(flag, NO_GOAL);
- - wrappedGoal2.stop();
- pathfindergoalwrapped1.stop(); - this.lockedFlags.put(flag, wrappedGoal);
- this.lockedFlags.put(pathfindergoal_type, pathfindergoalwrapped);
- }); - });
- pathfindergoalwrapped.start(); +
- });
+ // Paper start - remove streams from pathfindergoalselector + // Paper start - remove streams from pathfindergoalselector
+ goal_update_loop: for (Iterator<WrappedGoal> iterator = this.availableGoals.iterator(); iterator.hasNext();) { + goal_update_loop: for (java.util.Iterator<WrappedGoal> iterator = this.availableGoals.iterator(); iterator.hasNext();) {
+ WrappedGoal wrappedGoal = iterator.next(); + WrappedGoal wrappedGoal = iterator.next();
+ if (wrappedGoal.isRunning()) { + if (wrappedGoal.isRunning()) {
+ continue; + continue;
+ } + }
+ +
+ OptimizedSmallEnumSet<Goal.Flag> wrappedGoalSet = wrappedGoal.getGoalTypes(); + com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<net.minecraft.world.entity.ai.goal.Goal.Flag> wrappedGoalSet = wrappedGoal.getGoalTypes();
+ +
+ if (this.goalTypes.hasCommonElements(wrappedGoalSet)) { + if (this.goalTypes.hasCommonElements(wrappedGoalSet)) {
+ continue; + continue;
@ -201,22 +172,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ wrapped.stop(); + wrapped.stop();
+ this.lockedFlags.put(type, wrappedGoal); + this.lockedFlags.put(type, wrappedGoal);
+ } + }
+ wrappedGoal.start();
+ wrappedGoal.start(); - });
+ } + }
+ // Paper end - remove streams from pathfindergoalselector + // Paper end - remove streams from pathfindergoalselector
gameprofilerfiller.pop(); profilerFiller.pop();
gameprofilerfiller.push("goalTick"); profilerFiller.push("goalTick");
- this.getRunningGoals().forEach(WrappedGoal::tick); - this.getRunningGoals().forEach(WrappedGoal::tick);
+ // Paper start - remove streams from pathfindergoalselector + // Paper start - remove streams from pathfindergoalselector
+ for (Iterator<WrappedGoal> iterator = this.availableGoals.iterator(); iterator.hasNext();) { + for (java.util.Iterator<WrappedGoal> iterator = this.availableGoals.iterator(); iterator.hasNext();) {
+ WrappedGoal wrappedGoal = iterator.next(); + WrappedGoal wrappedGoal = iterator.next();
+ if (wrappedGoal.isRunning()) { + if (wrappedGoal.isRunning()) {
+ wrappedGoal.tick(); + wrappedGoal.tick();
+ } + }
+ } + }
+ // Paper end - remove streams from pathfindergoalselector + // Paper end - remove streams from pathfindergoalselector
gameprofilerfiller.pop(); profilerFiller.pop();
} }
@@ -0,0 +0,0 @@ public class GoalSelector { @@ -0,0 +0,0 @@ public class GoalSelector {
@ -250,4 +221,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - remove streams from pathfindergoalselector + // Paper end - remove streams from pathfindergoalselector
} }
public boolean isRunning() { return this.isRunning(); } // Paper - OBFHELPER public boolean isRunning() {

View File

@ -11,54 +11,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/util/thread/StrictQueue.java --- a/src/main/java/net/minecraft/util/thread/StrictQueue.java
+++ b/src/main/java/net/minecraft/util/thread/StrictQueue.java +++ b/src/main/java/net/minecraft/util/thread/StrictQueue.java
@@ -0,0 +0,0 @@ public interface StrictQueue<T, F> { @@ -0,0 +0,0 @@ public interface StrictQueue<T, F> {
private final List<Queue<Runnable>> queueList;
public static final class FixedPriorityQueue implements StrictQueue<StrictQueue.IntRunnable, Runnable> {
- private final List<Queue<Runnable>> queueList;
+ private final List<Queue<Runnable>> queueList; private final List<Queue<Runnable>> getQueues() { return this.queueList; } // Paper - OBFHELPER
public FixedPriorityQueue(int priorityCount) { public FixedPriorityQueue(int priorityCount) {
- this.queueList = (List) IntStream.range(0, priorityCount).mapToObj((j) -> { - this.queueList = IntStream.range(0, priorityCount).mapToObj((i) -> {
- return Queues.newConcurrentLinkedQueue(); - return Queues.newConcurrentLinkedQueue();
- }).collect(Collectors.toList()); - }).collect(Collectors.toList());
+ // Paper start - remove streams + // Paper start - remove streams
+ this.queueList = new java.util.ArrayList<>(priorityCount); // queues + this.queueList = new java.util.ArrayList<>(priorityCount); // queues
+ for (int j = 0; j < priorityCount; ++j) { + for (int j = 0; j < priorityCount; ++j) {
+ this.getQueues().add(Queues.newConcurrentLinkedQueue()); + this.queueList.add(Queues.newConcurrentLinkedQueue());
+ } + }
+ // Paper end - remove streams + // Paper end - remove streams
} }
@Nullable @Nullable
@Override
public Runnable pop() {
- Iterator iterator = this.queueList.iterator();
-
- Runnable runnable;
-
- do {
- if (!iterator.hasNext()) {
- return null;
+ // Paper start - remove iterator creation
+ for (int i = 0, len = this.getQueues().size(); i < len; ++i) {
+ Queue<Runnable> queue = this.getQueues().get(i);
+ Runnable ret = queue.poll();
+ if (ret != null) {
+ return ret;
}
-
- Queue<Runnable> queue = (Queue) iterator.next();
-
- runnable = (Runnable) queue.poll();
- } while (runnable == null);
-
- return runnable;
+ }
+ return null;
+ // Paper end - remove iterator creation
}
public boolean push(StrictQueue.IntRunnable message) {
@@ -0,0 +0,0 @@ public interface StrictQueue<T, F> { @@ -0,0 +0,0 @@ public interface StrictQueue<T, F> {
@Override @Override
@ -66,8 +33,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- return this.queueList.stream().allMatch(Collection::isEmpty); - return this.queueList.stream().allMatch(Collection::isEmpty);
+ // Paper start - remove streams + // Paper start - remove streams
+ // why are we doing streams every time we might want to execute a task? + // why are we doing streams every time we might want to execute a task?
+ for (int i = 0, len = this.getQueues().size(); i < len; ++i) { + for (int i = 0, len = this.queueList.size(); i < len; ++i) {
+ Queue<Runnable> queue = this.getQueues().get(i); + Queue<Runnable> queue = this.queueList.get(i);
+ if (!queue.isEmpty()) { + if (!queue.isEmpty()) {
+ return false; + return false;
+ } + }
@ -75,5 +42,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return true; + return true;
+ // Paper end - remove streams + // Paper end - remove streams
} }
}
@Override

View File

@ -8,19 +8,19 @@ diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListener
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
@Override @Override
public void handlePickItem(ServerboundPickItemPacket packet) { public void handlePickItem(ServerboundPickItemPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel()); PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel());
- this.player.inventory.pickSlot(packet.getSlot()); - this.player.getInventory().pickSlot(packet.getSlot());
+ // Paper start - validate pick item position + // Paper start - validate pick item position
+ if (!(packet.getSlot() >= 0 && packet.getSlot() < this.player.inventory.items.size())) { + if (!(packet.getSlot() >= 0 && packet.getSlot() < this.player.getInventory().items.size())) {
+ ServerGamePacketListenerImpl.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString()); + ServerGamePacketListenerImpl.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString());
+ this.disconnect("Invalid hotbar selection (Hacking?)"); + this.disconnect("Invalid hotbar selection (Hacking?)");
+ return; + return;
+ } + }
+ this.player.inventory.pickSlot(packet.getSlot()); // Paper - Diff above if changed + this.player.getInventory().pickSlot(packet.getSlot()); // Paper - Diff above if changed
+ // Paper end + // Paper end
this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, this.player.inventory.selected, this.player.inventory.getItem(this.player.inventory.selected))); this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, this.player.getInventory().selected, this.player.getInventory().getItem(this.player.getInventory().selected)));
this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, packet.getSlot(), this.player.inventory.getItem(packet.getSlot()))); this.player.connection.send(new ClientboundContainerSetSlotPacket(-2, packet.getSlot(), this.player.getInventory().getItem(packet.getSlot())));
this.player.connection.send(new ClientboundSetCarriedItemPacket(this.player.inventory.selected)); this.player.connection.send(new ClientboundSetCarriedItemPacket(this.player.getInventory().selected));

View File

@ -16,13 +16,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ private int numberOfRestocksToday; public int getRestocksToday(){ return this.numberOfRestocksToday; } public void setRestocksToday(int restocksToday){ this.numberOfRestocksToday = restocksToday; } // Paper OBFHELPER + private int numberOfRestocksToday; public int getRestocksToday(){ return this.numberOfRestocksToday; } public void setRestocksToday(int restocksToday){ this.numberOfRestocksToday = restocksToday; } // Paper OBFHELPER
private long lastRestockCheckDayTime; private long lastRestockCheckDayTime;
private boolean assignProfessionWhenSpawned; private boolean assignProfessionWhenSpawned;
private static final ImmutableList<MemoryModuleType<?>> MEMORY_TYPES = ImmutableList.of(MemoryModuleType.HOME, MemoryModuleType.JOB_SITE, MemoryModuleType.POTENTIAL_JOB_SITE, MemoryModuleType.MEETING_POINT, MemoryModuleType.MOBS, MemoryModuleType.VISIBLE_MOBS, MemoryModuleType.VISIBLE_VILLAGER_BABIES, MemoryModuleType.NEAREST_PLAYERS, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_TARGETABLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, MemoryModuleType.WALK_TARGET, new MemoryModuleType[]{MemoryModuleType.LOOK_TARGET, MemoryModuleType.INTERACTION_TARGET, MemoryModuleType.BREED_TARGET, MemoryModuleType.PATH, MemoryModuleType.DOORS_TO_CLOSE, MemoryModuleType.NEAREST_BED, MemoryModuleType.HURT_BY, MemoryModuleType.HURT_BY_ENTITY, MemoryModuleType.NEAREST_HOSTILE, MemoryModuleType.SECONDARY_JOB_SITE, MemoryModuleType.HIDING_PLACE, MemoryModuleType.HEARD_BELL_TIME, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.LAST_SLEPT, MemoryModuleType.LAST_WOKEN, MemoryModuleType.LAST_WORKED_AT_POI, MemoryModuleType.GOLEM_DETECTED_RECENTLY}); private static final ImmutableList<MemoryModuleType<?>> MEMORY_TYPES = ImmutableList.of(MemoryModuleType.HOME, MemoryModuleType.JOB_SITE, MemoryModuleType.POTENTIAL_JOB_SITE, MemoryModuleType.MEETING_POINT, MemoryModuleType.NEAREST_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.VISIBLE_VILLAGER_BABIES, MemoryModuleType.NEAREST_PLAYERS, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, MemoryModuleType.WALK_TARGET, new MemoryModuleType[]{MemoryModuleType.LOOK_TARGET, MemoryModuleType.INTERACTION_TARGET, MemoryModuleType.BREED_TARGET, MemoryModuleType.PATH, MemoryModuleType.DOORS_TO_CLOSE, MemoryModuleType.NEAREST_BED, MemoryModuleType.HURT_BY, MemoryModuleType.HURT_BY_ENTITY, MemoryModuleType.NEAREST_HOSTILE, MemoryModuleType.SECONDARY_JOB_SITE, MemoryModuleType.HIDING_PLACE, MemoryModuleType.HEARD_BELL_TIME, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.LAST_SLEPT, MemoryModuleType.LAST_WOKEN, MemoryModuleType.LAST_WORKED_AT_POI, MemoryModuleType.GOLEM_DETECTED_RECENTLY});
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
@@ -0,0 +0,0 @@ public class CraftVillager extends CraftAbstractVillager implements Villager { @@ -0,0 +0,0 @@ public class CraftVillager extends CraftAbstractVillager implements Villager {
getHandle().setVillagerXp(experience); this.getHandle().setVillagerXp(experience);
} }
+ // Paper start + // Paper start

View File

@ -7,4 +7,4 @@ pluginManagement {
rootProject.name = "Paper" rootProject.name = "Paper"
include("Paper-API", "Paper-Server") include("Paper-API", "Paper-Server", "Paper-MojangAPI")

@ -1 +1 @@
Subproject commit 8503c3c9e3dca76b2ae10796d8c288b3f3101737 Subproject commit a791f93de242bf89d116fed843b889e38433e094

@ -1 +1 @@
Subproject commit 40caacc846a6349cd555d9d89cf9cf729c0b75b7 Subproject commit 85b8c1fda69f6f80e45ddd19590846c249e5b6bc