Foundational work for Future Memory usage improvements

This commit doesn't do much on its own, but adds a new Java Cleaner API
that lets us hook into Garbage Collector events to reclaim pooled objects and
return them to the pool.

Adds framework for Network Packets to know when a packet has finished dispatching
to get an idea when a packet is done sending to players.

Rewrites PooledObjects impl to properly respect max pool size and remove
almost all risk of contention.

Bumps the Paper Async Task Queue to use 2 threads, and properly shuts it down on shutdown.
This commit is contained in:
Aikar 2020-05-16 21:38:19 -04:00
parent bb4002d82e
commit 897dd2c840
No known key found for this signature in database
GPG key ID: 401ADFC9891FAAFE
30 changed files with 395 additions and 274 deletions

View file

@ -5,7 +5,7 @@ Subject: [PATCH] POM Changes
diff --git a/pom.xml b/pom.xml
index 9fc92e347f24a0210a9190513e93cba3b6772557..6cc18aa360c20448fca59cf5490d69267c8e2521 100644
index 9fc92e347f24a0210a9190513e93cba3b6772557..adf32845001fae7a870f588184c2efaf0ab41504 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,15 +1,14 @@
@ -55,7 +55,20 @@ index 9fc92e347f24a0210a9190513e93cba3b6772557..6cc18aa360c20448fca59cf5490d6926
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
@@ -106,34 +111,22 @@
@@ -50,6 +55,12 @@
<version>7.3.1</version>
<scope>compile</scope>
</dependency>
+ <dependency>
+ <!-- wrapper to use either java 8 sun cleaner or java9+ official cleaner -->
+ <groupId>co.aikar</groupId>
+ <artifactId>cleaner</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
<!-- deprecated API depend -->
<dependency>
<groupId>com.googlecode.json-simple</groupId>
@@ -106,34 +117,22 @@
<!-- This builds a completely 'ready to start' jar with all dependencies inside -->
<build>
@ -101,7 +114,7 @@ index 9fc92e347f24a0210a9190513e93cba3b6772557..6cc18aa360c20448fca59cf5490d6926
</goals>
</execution>
</executions>
@@ -143,6 +136,7 @@
@@ -143,6 +142,7 @@
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
@ -109,7 +122,7 @@ index 9fc92e347f24a0210a9190513e93cba3b6772557..6cc18aa360c20448fca59cf5490d6926
<archive>
<manifest>
<addDefaultEntries>false</addDefaultEntries>
@@ -150,8 +144,9 @@
@@ -150,8 +150,9 @@
<manifestEntries>
<Main-Class>org.bukkit.craftbukkit.Main</Main-Class>
<Implementation-Title>CraftBukkit</Implementation-Title>
@ -121,7 +134,7 @@ index 9fc92e347f24a0210a9190513e93cba3b6772557..6cc18aa360c20448fca59cf5490d6926
<Specification-Title>Bukkit</Specification-Title>
<Specification-Version>${api.version}</Specification-Version>
<Specification-Vendor>Bukkit Team</Specification-Vendor>
@@ -190,6 +185,7 @@
@@ -190,6 +191,7 @@
<goal>shade</goal>
</goals>
<configuration>
@ -129,7 +142,7 @@ index 9fc92e347f24a0210a9190513e93cba3b6772557..6cc18aa360c20448fca59cf5490d6926
<createSourcesJar>${shadeSourcesJar}</createSourcesJar>
<filters>
<filter>
@@ -213,10 +209,11 @@
@@ -213,10 +215,11 @@
<pattern>jline</pattern>
<shadedPattern>org.bukkit.craftbukkit.libs.jline</shadedPattern>
</relocation>
@ -145,7 +158,7 @@ index 9fc92e347f24a0210a9190513e93cba3b6772557..6cc18aa360c20448fca59cf5490d6926
<relocation>
<pattern>org.apache.commons.codec</pattern>
<shadedPattern>org.bukkit.craftbukkit.libs.org.apache.commons.codec</shadedPattern>
@@ -258,10 +255,6 @@
@@ -258,10 +261,6 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>

View file

@ -2077,90 +2077,173 @@ index 0000000000000000000000000000000000000000..e51104e65a07b6ea7bbbcbb6afb066ef
+}
diff --git a/src/main/java/com/destroystokyo/paper/util/pooled/PooledObjects.java b/src/main/java/com/destroystokyo/paper/util/pooled/PooledObjects.java
new file mode 100644
index 0000000000000000000000000000000000000000..e272b512520486cf7d46fe4e1021ca148d4cf74f
index 0000000000000000000000000000000000000000..9841212a60346870535e81b22851261e12380650
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/util/pooled/PooledObjects.java
@@ -0,0 +1,174 @@
+package com.destroystokyo.paper.util.pooled;
+
+import net.minecraft.server.MCUtil;
+import org.apache.commons.lang3.mutable.MutableInt;
+
+import java.util.ArrayDeque;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
+
+/**
+ * Object pooling with thread safe, low contention design. Pooled objects have no additional object overhead
+ * due to usage of ArrayDeque per insertion/removal unless a resizing is needed in the buckets.
+ * Supports up to bucket size (default 8) threads concurrently accessing if all buckets have a value.
+ * Releasing may conditionally have contention if multiple buckets have same current size, but randomization will be used.
+ *
+ * Original interface API by Spottedleaf
+ * Implementation by Aikar <aikar@aikar.co>
+ * @license MIT
+ */
+public final class PooledObjects<E> {
+
+ public static final PooledObjects<MutableInt> POOLED_MUTABLE_INTEGERS = new PooledObjects<>(MutableInt::new, 200, -1);
+ /**
+ * Wrapper for an object that will be have a cleaner registered for it, and may be automatically returned to pool.
+ */
+ public class AutoReleased {
+ private final E object;
+ private final Runnable cleaner;
+
+ public AutoReleased(E object, Runnable cleaner) {
+ this.object = object;
+ this.cleaner = cleaner;
+ }
+
+ public final E getObject() {
+ return object;
+ }
+
+ public final Runnable getCleaner() {
+ return cleaner;
+ }
+ }
+
+ public static final PooledObjects<MutableInt> POOLED_MUTABLE_INTEGERS = new PooledObjects<>(MutableInt::new, 1024, 16);
+
+ private final PooledObjectHandler<E> handler;
+ private final int maxPoolSize;
+ private final int expectingThreads;
+ private final int bucketCount;
+ private final int bucketSize;
+ private final ArrayDeque<E>[] buckets;
+ private final ReentrantLock[] locks;
+ private final AtomicLong bucketIdCounter = new AtomicLong(0);
+
+ private final IsolatedPool<E> mainPool;
+ // use these under contention
+ private final IsolatedPool<E>[] contendedPools;
+
+ public PooledObjects(final PooledObjectHandler<E> handler, final int maxPoolSize, int expectingThreads) {
+ public PooledObjects(final PooledObjectHandler<E> handler, int maxPoolSize) {
+ this(handler, maxPoolSize, 8);
+ }
+ public PooledObjects(final PooledObjectHandler<E> handler, int maxPoolSize, int bucketCount) {
+ if (handler == null) {
+ throw new NullPointerException("Handler must not be null");
+ }
+ if (maxPoolSize <= 0) {
+ throw new IllegalArgumentException("Max pool size must be greater-than 0");
+ }
+ if (expectingThreads <= 0) {
+ expectingThreads = Runtime.getRuntime().availableProcessors();
+ if (bucketCount < 1) {
+ throw new IllegalArgumentException("Bucket count must be greater-than 0");
+ }
+
+ int remainder = maxPoolSize % bucketCount;
+ if (remainder > 0) {
+ // Auto adjust up to the next bucket divisible size
+ maxPoolSize = maxPoolSize - remainder + bucketCount;
+ }
+ //noinspection unchecked
+ this.buckets = new ArrayDeque[bucketCount];
+ this.locks = new ReentrantLock[bucketCount];
+ this.bucketCount = bucketCount;
+ this.handler = handler;
+ this.maxPoolSize = maxPoolSize;
+ this.expectingThreads = expectingThreads;
+ this.mainPool = new IsolatedPool<>(handler, maxPoolSize);
+ final IsolatedPool<E>[] contendedPools = new IsolatedPool[2 * expectingThreads];
+
+ for (int i = 0; i < contendedPools.length; ++i) {
+ contendedPools[i] = new IsolatedPool<>(handler, Math.max(1, maxPoolSize / 2));
+ this.bucketSize = maxPoolSize / bucketCount;
+ for (int i = 0; i < bucketCount; i++) {
+ this.buckets[i] = new ArrayDeque<>(bucketSize / 4);
+ this.locks[i] = new ReentrantLock();
+ }
+ }
+
+ this.contendedPools = contendedPools;
+ public AutoReleased acquireCleaner(Object holder) {
+ return acquireCleaner(holder, this::release);
+ }
+
+ // Taken from
+ // https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
+ // https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/blob/master/2016/06/25/fastrange.c
+ // Original license is public domain
+ public static int fastRandomBounded(final long randomInteger, final long limit) {
+ // randomInteger must be [0, pow(2, 32))
+ // limit must be [0, pow(2, 32))
+ return (int)((randomInteger * limit) >>> 32);
+ public AutoReleased acquireCleaner(Object holder, Consumer<E> releaser) {
+ E resource = acquire();
+ Runnable cleaner = MCUtil.registerCleaner(holder, resource, releaser);
+ return new AutoReleased(resource, cleaner);
+ }
+
+
+ public long size() {
+ long size = 0;
+ for (int i = 0; i < bucketCount; i++) {
+ size += this.buckets[i].size();
+ }
+
+ return size;
+ }
+ public E acquire() {
+ E ret;
+ PooledObjects.IsolatedPool<E> pooled = this.mainPool;
+ int lastIndex = -1;
+ while ((ret = pooled.tryAcquireUncontended()) == null) {
+ int index;
+ while (lastIndex == (index = fastRandomBounded(ThreadLocalRandom.current().nextInt() & 0xFFFFFFFFL, this.contendedPools.length)));
+ lastIndex = index;
+ pooled = this.contendedPools[index];
+ for (int base = (int) (this.bucketIdCounter.getAndIncrement() % bucketCount), i = 0; i < bucketCount; i++ ) {
+ int bucketId = (base + i) % bucketCount;
+ if (this.buckets[bucketId].isEmpty()) continue;
+ // lock will alloc an object if blocked, so spinwait instead since lock duration is super fast
+ lockBucket(bucketId);
+ E value = this.buckets[bucketId].poll();
+ this.locks[bucketId].unlock();
+ if (value != null) {
+ this.handler.onAcquire(value);
+ return value;
+ }
+ }
+ return this.handler.createNew();
+ }
+
+ return ret;
+ private void lockBucket(int bucketId) {
+ // lock will alloc an object if blocked, try to avoid unless 2 failures
+ ReentrantLock lock = this.locks[bucketId];
+ if (!lock.tryLock()) {
+ Thread.yield();
+ } else {
+ return;
+ }
+ if (!lock.tryLock()) {
+ Thread.yield();
+ lock.lock();
+ }
+ }
+
+ public void release(final E value) {
+ PooledObjects.IsolatedPool<E> pooled = this.mainPool;
+ int lastIndex = -1;
+ while (!pooled.tryReleaseUncontended(value)) {
+ int index;
+ while (lastIndex == (index = fastRandomBounded(ThreadLocalRandom.current().nextInt() & 0xFFFFFFFFL, this.contendedPools.length)));
+ lastIndex = index;
+ pooled = this.contendedPools[index];
+ int attempts = 3; // cap on contention
+ do {
+ // find least filled bucket before locking
+ int smallestIdx = -1;
+ int smallest = Integer.MAX_VALUE;
+ for (int i = 0; i < bucketCount; i++ ) {
+ ArrayDeque<E> bucket = this.buckets[i];
+ int size = bucket.size();
+ if (size < this.bucketSize && (smallestIdx == -1 || size < smallest || (size == smallest && ThreadLocalRandom.current().nextBoolean()))) {
+ smallestIdx = i;
+ smallest = size;
+ }
+ }
+ if (smallestIdx == -1) return; // Can not find a bucket to fill
+
+ lockBucket(smallestIdx);
+ ArrayDeque<E> bucket = this.buckets[smallestIdx];
+ if (bucket.size() < this.bucketSize) {
+ this.handler.onRelease(value);
+ bucket.push(value);
+ this.locks[smallestIdx].unlock();
+ return;
+ } else {
+ this.locks[smallestIdx].unlock();
+ }
+ } while (attempts-- > 0);
+ }
+
+ /** This object is restricted from interacting with any pool */
+ public static interface PooledObjectHandler<E> {
+ public interface PooledObjectHandler<E> {
+
+ /**
+ * Must return a non-null object
@ -2171,89 +2254,6 @@ index 0000000000000000000000000000000000000000..e272b512520486cf7d46fe4e1021ca14
+
+ default void onRelease(final E value) {}
+ }
+
+ protected static class IsolatedPool<E> {
+
+ protected final PooledObjectHandler<E> handler;
+
+ // We use arraydeque as it doesn't create garbage per element...
+ protected final ArrayDeque<E> pool;
+ protected final int maxPoolSize;
+
+ protected final ReentrantLock lock = new ReentrantLock();
+
+ public IsolatedPool(final PooledObjectHandler<E> handler, final int maxPoolSize) {
+ this.handler = handler;
+ this.pool = new ArrayDeque<>();
+ this.maxPoolSize = maxPoolSize;
+ }
+
+ protected E acquireOrCreateNoLock() {
+ E ret;
+
+ ret = this.pool.poll();
+
+ if (ret == null) {
+ ret = this.handler.createNew();
+ }
+ this.handler.onAcquire(ret);
+
+ return ret;
+ }
+
+ public E tryAcquireUncontended() {
+ if (!this.lock.tryLock()) {
+ return null;
+ }
+ try {
+ return this.acquireOrCreateNoLock();
+ } finally {
+ this.lock.unlock();
+ }
+ }
+
+ public E acquire() {
+ this.lock.lock();
+ try {
+ return this.acquireOrCreateNoLock();
+ } finally {
+ this.lock.unlock();
+ }
+ }
+
+ protected void releaseNoLock(final E value) {
+ if (this.pool.size() >= this.maxPoolSize) {
+ this.handler.onRelease(value);
+ return; // can't accept, we're at capacity
+ }
+
+ this.pool.add(value);
+ this.handler.onRelease(value);
+ }
+
+ public boolean tryReleaseUncontended(final E value) {
+ if (!this.lock.tryLock()) {
+ return false;
+ }
+
+ try {
+ this.releaseNoLock(value);
+ } finally {
+ this.lock.unlock();
+ }
+
+ return true;
+ }
+
+ public void release(final E value) {
+ this.lock.lock();
+ try {
+ this.releaseNoLock(value);
+ } finally {
+ this.lock.unlock();
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java b/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java
new file mode 100644
@ -3335,10 +3335,10 @@ index 75308712d0642d5ab168de653023349df8aee5ed..aa7501d366b15e7f7f64b7d98a1dccff
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..9fb9a96ccb37f5c7f39403e24e7b3bdb9279fe81
index 0000000000000000000000000000000000000000..7164f46516bdf49ed52062f2d72f33418506bae0
--- /dev/null
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -0,0 +1,414 @@
@@ -0,0 +1,473 @@
+package net.minecraft.server;
+
+import com.destroystokyo.paper.block.TargetBlockInfo;
@ -3355,21 +3355,80 @@ index 0000000000000000000000000000000000000000..9fb9a96ccb37f5c7f39403e24e7b3bdb
+import java.util.Queue;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+public final class MCUtil {
+ private static final Executor asyncExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("Paper Async Task Handler Thread - %1$d").build());
+ public static final ThreadPoolExecutor asyncExecutor = new ThreadPoolExecutor(
+ 0, 2, 60L, TimeUnit.SECONDS,
+ new LinkedBlockingQueue<Runnable>(),
+ new ThreadFactoryBuilder().setNameFormat("Paper Async Task Handler Thread - %1$d").build()
+ );
+ public static final ThreadPoolExecutor cleanerExecutor = new ThreadPoolExecutor(
+ 1, 1, 0L, TimeUnit.SECONDS,
+ new LinkedBlockingQueue<Runnable>(),
+ new ThreadFactoryBuilder().setNameFormat("Paper Object Cleaner").build()
+ );
+
+ public static final long INVALID_CHUNK_KEY = getCoordinateKey(Integer.MAX_VALUE, Integer.MAX_VALUE);
+
+ public static void ensureTickThread(final String reason) {
+ if (MinecraftServer.getServer().serverThread != Thread.currentThread()) {
+ throw new IllegalStateException(reason);
+
+ public static Runnable once(Runnable run) {
+ AtomicBoolean ran = new AtomicBoolean(false);
+ return () -> {
+ if (ran.compareAndSet(false, true)) {
+ run.run();
+ }
+ };
+ }
+
+ private static Runnable makeCleanerCallback(Runnable run) {
+ return once(() -> cleanerExecutor.execute(run));
+ }
+
+ /**
+ * DANGER WILL ROBINSON: Be sure you do not use a lambda that lives in the object being monitored, or leaky leaky!
+ * @param obj
+ * @param run
+ * @return
+ */
+ public static Runnable registerCleaner(Object obj, Runnable run) {
+ // Wrap callback in its own method above or the lambda will leak object
+ Runnable cleaner = makeCleanerCallback(run);
+ co.aikar.cleaner.Cleaner.register(obj, cleaner);
+ return cleaner;
+ }
+
+ /**
+ * DANGER WILL ROBINSON: Be sure you do not use a lambda that lives in the object being monitored, or leaky leaky!
+ * @param obj
+ * @param list
+ * @param cleaner
+ * @param <T>
+ * @return
+ */
+ public static <T> Runnable registerListCleaner(Object obj, List<T> list, Consumer<T> cleaner) {
+ return registerCleaner(obj, () -> {
+ list.forEach(cleaner);
+ list.clear();
+ });
+ }
+
+ /**
+ * DANGER WILL ROBINSON: Be sure you do not use a lambda that lives in the object being monitored, or leaky leaky!
+ * @param obj
+ * @param resource
+ * @param cleaner
+ * @param <T>
+ * @return
+ */
+ public static <T> Runnable registerCleaner(Object obj, T resource, java.util.function.Consumer<T> cleaner) {
+ return registerCleaner(obj, () -> cleaner.accept(resource));
+ }
+
+ public static List<ChunkCoordIntPair> getSpiralOutChunks(BlockPosition blockposition, int radius) {
@ -3753,6 +3812,20 @@ index 0000000000000000000000000000000000000000..9fb9a96ccb37f5c7f39403e24e7b3bdb
+ }
+ }
+}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index b4a0bd79511a3b1185a165991c937375aeecf3d1..786d38438cc1bd5a736b2dfa80aca9b9c6253e65 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -741,6 +741,9 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
}
// Spigot start
+ MCUtil.asyncExecutor.shutdown(); // Paper
+ try { MCUtil.asyncExecutor.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS); // Paper
+ } catch (java.lang.InterruptedException ignored) {} // Paper
if (org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) {
LOGGER.info("Saving usercache.json");
this.getUserCache().c();
diff --git a/src/main/java/net/minecraft/server/NBTTagCompound.java b/src/main/java/net/minecraft/server/NBTTagCompound.java
index e85b24a327fb0a17ed28ed3c90cd039c2bdbed6a..75604dbc69d0a416dc9d56ae3f795ed03e120af8 100644
--- a/src/main/java/net/minecraft/server/NBTTagCompound.java

View file

@ -625,7 +625,7 @@ index 9eed98e3796be6d49dc51af9038a7376c94edeee..d6646d7e61b63c116fa87951b0ef3131
}
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index fc878e28c96bb4a9d4cd84001141935736d23e1f..c75b74d5581e3517d39079eea827a24c471eaa6c 100644
index 0d8262b1d2722e716f95db4c9a8a132c54b613cf..19d68aa4585ccfc156e9db6024b7a99bbeca4de4 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -29,7 +29,8 @@ import org.bukkit.command.CommandSender;
@ -740,7 +740,7 @@ index 3ace8ee854c11abd607dc27b93fe61a0982a73de..690c1ce0f6707b2f5dd787e0fe340af5
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index b4a0bd79511a3b1185a165991c937375aeecf3d1..67bdd577477730f1775f87189c9fcee6f92c7e57 100644
index 786d38438cc1bd5a736b2dfa80aca9b9c6253e65..5429d8eee93980a01cdf008b57e88e1dccc1ef67 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -63,7 +63,7 @@ import org.bukkit.craftbukkit.CraftServer;
@ -771,7 +771,7 @@ index b4a0bd79511a3b1185a165991c937375aeecf3d1..67bdd577477730f1775f87189c9fcee6
// CraftBukkit start
if (this.server != null) {
this.server.disablePlugins();
@@ -881,9 +882,21 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -884,9 +885,21 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
private boolean canSleepForTick() {
// CraftBukkit start
@ -793,7 +793,7 @@ index b4a0bd79511a3b1185a165991c937375aeecf3d1..67bdd577477730f1775f87189c9fcee6
private void executeModerately() {
this.executeAll();
java.util.concurrent.locks.LockSupport.parkNanos("executing tasks", 1000L);
@@ -891,9 +904,9 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -894,9 +907,9 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
// CraftBukkit end
protected void sleepForTick() {
@ -805,7 +805,7 @@ index b4a0bd79511a3b1185a165991c937375aeecf3d1..67bdd577477730f1775f87189c9fcee6
});
}
@@ -976,10 +989,18 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -979,10 +992,18 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
protected void exit() {}
protected void a(BooleanSupplier booleansupplier) {
@ -825,7 +825,7 @@ index b4a0bd79511a3b1185a165991c937375aeecf3d1..67bdd577477730f1775f87189c9fcee6
++this.ticks;
this.b(booleansupplier);
if (i - this.Z >= 5000000000L) {
@@ -997,14 +1018,12 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1000,14 +1021,12 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
}
if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit
@ -840,7 +840,7 @@ index b4a0bd79511a3b1185a165991c937375aeecf3d1..67bdd577477730f1775f87189c9fcee6
}
this.methodProfiler.enter("snooper");
@@ -1017,6 +1036,13 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1020,6 +1039,13 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
}
this.methodProfiler.exit();
@ -854,7 +854,7 @@ index b4a0bd79511a3b1185a165991c937375aeecf3d1..67bdd577477730f1775f87189c9fcee6
this.methodProfiler.enter("tallying");
long l = this.f[this.ticks % 100] = SystemUtils.getMonotonicNanos() - i;
@@ -1027,30 +1053,29 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1030,30 +1056,29 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.methodProfiler.exit();
org.spigotmc.WatchdogThread.tick(); // Spigot
this.slackActivityAccountant.tickEnded(l); // Spigot
@ -893,7 +893,7 @@ index b4a0bd79511a3b1185a165991c937375aeecf3d1..67bdd577477730f1775f87189c9fcee6
// Send time updates to everyone, it will get the right time from the world the player is in.
if (this.ticks % 20 == 0) {
for (int i = 0; i < this.getPlayerList().players.size(); ++i) {
@@ -1058,7 +1083,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1061,7 +1086,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateTime(entityplayer.world.getTime(), entityplayer.getPlayerTime(), entityplayer.world.getGameRules().getBoolean(GameRules.DO_DAYLIGHT_CYCLE))); // Add support for per player time
}
}
@ -902,7 +902,7 @@ index b4a0bd79511a3b1185a165991c937375aeecf3d1..67bdd577477730f1775f87189c9fcee6
while (iterator.hasNext()) {
WorldServer worldserver = (WorldServer) iterator.next();
@@ -1101,24 +1126,24 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1104,24 +1129,24 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
}
this.methodProfiler.exitEnter("connection");
@ -1111,7 +1111,7 @@ index 2c671629a43f42da8335e7216f9fd399bb878729..eb3269e0ea3ce33d08e9eee3bca7cf43
PlayerConnectionUtils.LOGGER.debug("Ignoring packet due to disconnection: " + packet);
}
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index 94ed83baf06646e8edc050fe15aab1d176c98a19..f28be11eee2b6e64e9db84a533dd2fb297611740 100644
index 7e8c50aa92e036b88b1fd725021c31846eb06097..79cfcbce85e779fc8e8589840a27961f59209f3d 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -1,5 +1,6 @@
@ -1260,7 +1260,7 @@ index 2a4fa455ff3065f9b1ad9bcf8d236bbb6f830bc9..f572c5f22712288cc75fffeae65fc2bd
CrashReport crashreport = CrashReport.a(throwable, "Ticking entity");
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being ticked");
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index d5014abc9d13efd801e17ecede37918b7acf7b33..38a71bca2f4c708fea656ce3bddf3842a44c82de 100644
index 545ec5a2de00e9a91b349e358db44ed16aa50e68..4ab77e8dc0f918bd4f069a0f886d04dea473f046 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -1,6 +1,8 @@

View file

@ -19,10 +19,10 @@ index 3f35a28ba15f4d0dfe1cb2b56f621e81b1fb8c99..cf00f35a5b7c2d2f6b6989e0855de8b8
throwable = throwable1;
throw throwable1;
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 67bdd577477730f1775f87189c9fcee6f92c7e57..e71ee0fb3393463044ca3e1d486ab749e55fbc44 100644
index 5429d8eee93980a01cdf008b57e88e1dccc1ef67..b6912f97c2240b0524735e0f8d1937f2e76dba5b 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1345,7 +1345,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1348,7 +1348,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
}
public String getServerModName() {

View file

@ -12,7 +12,7 @@ Previous implementation did not calculate TPS correctly.
Switch to a realistic rolling average and factor in std deviation as an extra reporting variable
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index e71ee0fb3393463044ca3e1d486ab749e55fbc44..53d0a98d00c7f923e4ee87804a214d812a7ef1bb 100644
index b6912f97c2240b0524735e0f8d1937f2e76dba5b..c61037c837e29544e3afeb0b23f422073d3f5166 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -160,7 +160,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@ -33,7 +33,7 @@ index e71ee0fb3393463044ca3e1d486ab749e55fbc44..53d0a98d00c7f923e4ee87804a214d81
public final double[] recentTps = new double[ 3 ];
public final SlackActivityAccountant slackActivityAccountant = new SlackActivityAccountant();
// Spigot end
@@ -778,6 +778,57 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -781,6 +781,57 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
{
return ( avg * exp ) + ( tps * ( 1 - exp ) );
}
@ -91,7 +91,7 @@ index e71ee0fb3393463044ca3e1d486ab749e55fbc44..53d0a98d00c7f923e4ee87804a214d81
// Spigot End
public void run() {
@@ -790,30 +841,38 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -793,30 +844,38 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
// Spigot start
Arrays.fill( recentTps, 20 );

View file

@ -123,10 +123,10 @@ index a063d1bfaa1acd20a5de9701eef028a543235d5e..5583860f152aadcbe74bf7b99e7efd8e
+ // Paper end
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 53d0a98d00c7f923e4ee87804a214d812a7ef1bb..11f81ab364b3bff8b61650a77eb8369c188e6e30 100644
index c61037c837e29544e3afeb0b23f422073d3f5166..a67c31a6021d881b49cfdb75f514404c342eea45 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1181,6 +1181,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1184,6 +1184,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.methodProfiler.exit();
this.methodProfiler.exit();

View file

@ -32,10 +32,10 @@ index 42e86881bd891b176237eeb24492fe8050e36334..6cdce115814690f6e432aea54f69f32d
}
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 11f81ab364b3bff8b61650a77eb8369c188e6e30..773f93edb753b505ba7ceb4cacaab8d4fcb13c68 100644
index a67c31a6021d881b49cfdb75f514404c342eea45..4c7df81217c10d92d05e619ad760bc5d9a6a79cf 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1147,6 +1147,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1150,6 +1150,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
while (iterator.hasNext()) {
WorldServer worldserver = (WorldServer) iterator.next();
@ -66,7 +66,7 @@ index 6b1ff8f64f87e1d5fc98fd9733d6b45d312c1f69..1edd03086535834fc68260f0ee6653d8
this.getServer().getPluginManager().callEvent(event);
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 9f801852ead82e7639175ab9342500c06909c20d..3769f0533dc0cfaf23e2411df982f901d788f80b 100644
index 4b355ecbdaa8471225eb979270f2abc086e27e18..1e74e339de72ac34351e7bda6a2992c582d56f3f 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -75,6 +75,7 @@ public class WorldServer extends World {

View file

@ -6,7 +6,7 @@ Subject: [PATCH] remove null possibility for getServer singleton
to stop IDE complaining about potential NPE
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 36d20d5e3a622bb944f89c37e8b9050ccea2c86d..a5aa6553cc5d44ad9be41a4f35de73a1c5bf3cb8 100644
index bd14edb06f7ce2560b600845df284e6c6860d699..d4434f10b879d9e2119b8adb6757b771e9df04f7 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -68,6 +68,7 @@ import org.spigotmc.SlackActivityAccountant; // Spigot
@ -25,7 +25,7 @@ index 36d20d5e3a622bb944f89c37e8b9050ccea2c86d..a5aa6553cc5d44ad9be41a4f35de73a1
this.resourcePackRepository = new ResourcePackRepository<>(ResourcePackLoader::new);
this.craftingManager = new CraftingManager();
this.tagRegistry = new TagRegistry();
@@ -2186,7 +2188,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -2189,7 +2191,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@Deprecated
public static MinecraftServer getServer() {

View file

@ -10,11 +10,11 @@ Additionally, move Saving of the User cache to be done async, incase
the user never changed the default setting for Spigot's save on stop only.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index a5aa6553cc5d44ad9be41a4f35de73a1c5bf3cb8..35d31a9c36e837fcc361e8ba82c89aaee319b73d 100644
index d4434f10b879d9e2119b8adb6757b771e9df04f7..629304c403c596bf81dd8de919f0fcb5c77bd403 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -760,7 +760,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
// Spigot start
@@ -763,7 +763,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
} catch (java.lang.InterruptedException ignored) {} // Paper
if (org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) {
LOGGER.info("Saving usercache.json");
- this.getUserCache().c();

View file

@ -5,7 +5,7 @@ Subject: [PATCH] String based Action Bar API
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
index 9fb9a96ccb37f5c7f39403e24e7b3bdb9279fe81..48f88eaba40b54cdf24da794ae5dc692c33553c7 100644
index 7164f46516bdf49ed52062f2d72f33418506bae0..87bd51ab1b844e05ecd3d9d2555841554976023c 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -2,6 +2,7 @@ package net.minecraft.server;
@ -16,7 +16,7 @@ index 9fb9a96ccb37f5c7f39403e24e7b3bdb9279fe81..48f88eaba40b54cdf24da794ae5dc692
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.CraftWorld;
@@ -122,6 +123,24 @@ public final class MCUtil {
@@ -181,6 +182,24 @@ public final class MCUtil {
private MCUtil() {}

View file

@ -30,7 +30,7 @@ will have plugins and worlds saving to the disk has a high potential to result
in corruption/dataloss.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 35d31a9c36e837fcc361e8ba82c89aaee319b73d..8d6a0890073adbbb39db202f80d4b83cef2ceca9 100644
index 629304c403c596bf81dd8de919f0fcb5c77bd403..80d8b0b0eac47b8d8e62db60da9daf0da8671fb3 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -88,6 +88,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@ -50,7 +50,7 @@ index 35d31a9c36e837fcc361e8ba82c89aaee319b73d..8d6a0890073adbbb39db202f80d4b83c
try { Thread.sleep(100); } catch (InterruptedException ex) {} // CraftBukkit - SPIGOT-625 - give server at least a chance to send packets
}
@@ -777,8 +778,13 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -780,8 +781,13 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
return this.isRunning;
}
@ -64,7 +64,7 @@ index 35d31a9c36e837fcc361e8ba82c89aaee319b73d..8d6a0890073adbbb39db202f80d4b83c
if (flag) {
try {
this.serverThread.join();
@@ -788,6 +794,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -791,6 +797,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
}
}

View file

@ -19,7 +19,7 @@ Other changes:
configuration
diff --git a/pom.xml b/pom.xml
index 6cc18aa360c20448fca59cf5490d69267c8e2521..01dcaf4f4bbe03a118958e494544d7fc4a92e300 100644
index adf32845001fae7a870f588184c2efaf0ab41504..d07ec94d3011eca8b986e45a63d0c6392691b273 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,10 +44,27 @@
@ -54,7 +54,7 @@ index 6cc18aa360c20448fca59cf5490d69267c8e2521..01dcaf4f4bbe03a118958e494544d7fc
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
@@ -246,10 +263,18 @@
@@ -252,10 +269,18 @@
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/java.sql.Driver</resource>
</transformer>
@ -185,7 +185,7 @@ index 4b1f8c53737f998fa57859146d5ddb999cdc8d41..d34f772fae3543cec6a130831b1f3eaa
System.setOut(new PrintStream(new LoggerOutputStream(logger, Level.INFO), true));
System.setErr(new PrintStream(new LoggerOutputStream(logger, Level.WARN), true));
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 8d6a0890073adbbb39db202f80d4b83cef2ceca9..284793e4bf04cddae3e070a1fa0afdd18001fd2e 100644
index 80d8b0b0eac47b8d8e62db60da9daf0da8671fb3..87595425a358a13c8f2393619d51a981140556cf 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -57,7 +57,7 @@ import org.apache.commons.lang3.Validate;
@ -225,7 +225,7 @@ index 8d6a0890073adbbb39db202f80d4b83cef2ceca9..284793e4bf04cddae3e070a1fa0afdd1
Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this));
}
// CraftBukkit end
@@ -951,7 +955,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -954,7 +958,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
org.spigotmc.WatchdogThread.doStop(); // Spigot
// CraftBukkit start - Restore terminal to original settings
try {
@ -234,7 +234,7 @@ index 8d6a0890073adbbb39db202f80d4b83cef2ceca9..284793e4bf04cddae3e070a1fa0afdd1
} catch (Exception ignored) {
}
// CraftBukkit end
@@ -1475,7 +1479,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1478,7 +1482,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@Override
public void sendMessage(IChatBaseComponent ichatbasecomponent) {
@ -244,7 +244,7 @@ index 8d6a0890073adbbb39db202f80d4b83cef2ceca9..284793e4bf04cddae3e070a1fa0afdd1
public KeyPair getKeyPair() {
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index 56266a77296bc9a84de1d853a6d739337608b995..77f1ddc8a8d6fa816488de5d8c821bfa59f6c729 100644
index 940c3acfa0dee0d454a1cc10dd3ca3862fd7b030..0b403f08bed136916969b927c04078c14697803e 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -76,8 +76,7 @@ public abstract class PlayerList {

View file

@ -403,7 +403,7 @@ index 0000000000000000000000000000000000000000..3aceb0ea8a1a3ed94dd8a9e954c52ecd
+ }
+}
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
index 48f88eaba40b54cdf24da794ae5dc692c33553c7..9d0b0c9fc3c9e5e73506a43d7195b139cbcb30cf 100644
index 87bd51ab1b844e05ecd3d9d2555841554976023c..37b8257552efd0d66a020f0b5007514f2ac890cd 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -1,7 +1,10 @@
@ -417,7 +417,7 @@ index 48f88eaba40b54cdf24da794ae5dc692c33553c7..9d0b0c9fc3c9e5e73506a43d7195b139
import org.apache.commons.lang.exception.ExceptionUtils;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
@@ -256,6 +259,10 @@ public final class MCUtil {
@@ -315,6 +318,10 @@ public final class MCUtil {
return run.get();
}
@ -429,10 +429,10 @@ index 48f88eaba40b54cdf24da794ae5dc692c33553c7..9d0b0c9fc3c9e5e73506a43d7195b139
* Calculates distance between 2 entities
* @param e1
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 284793e4bf04cddae3e070a1fa0afdd18001fd2e..1f2793967045d0bea59e62d9d9d39b03dbdef6c8 100644
index 87595425a358a13c8f2393619d51a981140556cf..4a513aaea587414cf6abc1c136e52420d59688d8 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1301,7 +1301,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1304,7 +1304,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
DispenserRegistry.init();
DispenserRegistry.c();
File s = (File) optionset.valueOf("universe"); // CraftBukkit
@ -441,7 +441,7 @@ index 284793e4bf04cddae3e070a1fa0afdd18001fd2e..1f2793967045d0bea59e62d9d9d39b03
MinecraftSessionService minecraftsessionservice = yggdrasilauthenticationservice.createMinecraftSessionService();
GameProfileRepository gameprofilerepository = yggdrasilauthenticationservice.createProfileRepository();
UserCache usercache = new UserCache(gameprofilerepository, new File(s, MinecraftServer.b.getName()));
@@ -1766,6 +1766,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1769,6 +1769,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.H = i;
}

View file

@ -177,7 +177,7 @@ index 0000000000000000000000000000000000000000..a85466bc7e0a8aa54b9eff14077fe6c9
+
+}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 1f2793967045d0bea59e62d9d9d39b03dbdef6c8..c502aedb8dc4e7a5d7ba9d16a200c20ca3d24cd4 100644
index 4a513aaea587414cf6abc1c136e52420d59688d8..d1667eba3398efecc8913c2778931030a90d6195 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1,6 +1,9 @@
@ -190,7 +190,7 @@ index 1f2793967045d0bea59e62d9d9d39b03dbdef6c8..c502aedb8dc4e7a5d7ba9d16a200c20c
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.JsonElement;
@@ -1092,7 +1095,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1095,7 +1098,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
if (i - this.Z >= 5000000000L) {
this.Z = i;
this.serverPing.setPlayerSample(new ServerPing.ServerPingPlayerSample(this.getMaxPlayers(), this.getPlayerCount()));

View file

@ -36,10 +36,10 @@ index adef07d4d521b4aaa6f3389b04aa27e29bec0229..214b577b326bc794fa3721deb6171228
public static int tabSpamLimit = 500;
private static void tabSpamLimiters() {
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index c502aedb8dc4e7a5d7ba9d16a200c20ca3d24cd4..056cbdeec8a1c17de44d59f16b77a995c82a3abb 100644
index d1667eba3398efecc8913c2778931030a90d6195..b7c83cd82ca1c9b6bdaaf566e800b8d15ad7d966 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -870,6 +870,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -873,6 +873,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.a(this.serverPing);
// Spigot start

View file

@ -39,10 +39,10 @@ index 0f74ec89b3e85c918c95f9d8fef6d68403ed1107..4609e402b419ed21e17ad34d02dca55b
this.setCustomNameVisible(nbttagcompound.getBoolean("CustomNameVisible"));
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
index 9d0b0c9fc3c9e5e73506a43d7195b139cbcb30cf..3342278bcd42a6d5a1793e33bc7fe4356be02451 100644
index 37b8257552efd0d66a020f0b5007514f2ac890cd..be20d770df41a656cf2aabfec87e0bdc639053f4 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -437,4 +437,19 @@ public final class MCUtil {
@@ -496,4 +496,19 @@ public final class MCUtil {
return null;
}
}

View file

@ -8,7 +8,7 @@ our own relocation. Also lets us rewrite NMS calls for when we're
debugging in an IDE pre-relocate.
diff --git a/pom.xml b/pom.xml
index fd417a9eeb7a3371ceabc07b49a7406b38b419a3..bc8438ae1ae939be4d2257d37df9a843a13ac301 100644
index 7be8342c5007487601487794699b0389e8f7d222..60bf6dd28527f6ffcb59779ec9546030245724ca 100644
--- a/pom.xml
+++ b/pom.xml
@@ -87,7 +87,7 @@
@ -19,7 +19,7 @@ index fd417a9eeb7a3371ceabc07b49a7406b38b419a3..bc8438ae1ae939be4d2257d37df9a843
+ <version>8.0.1</version> <!-- Paper -->
<scope>compile</scope>
</dependency>
<!-- deprecated API depend -->
<dependency>
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
index 9b4a0f0678a7e8e347ef062ad15562484a74452b..4ae41fd2557dcc2a8e31d39ed978b2b26093dd06 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java

View file

@ -8,10 +8,10 @@ the updates per world, so that we can re-use the same packet
object for every player unless they have per-player time enabled.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index c97bbe933dd05829d9da7bc71d03d2c0a26a4ad1..3d9cc2ce67b5dc033df397e8d1c31f718792dcc4 100644
index 66097d8cbc916d459ac0ab3b69fbac91a5b57ed3..207dd30539fa3961ba96aafe1e3cfef5020a885c 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1166,12 +1166,24 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1169,12 +1169,24 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
MinecraftTimings.timeUpdateTimer.startTiming(); // Spigot // Paper
// Send time updates to everyone, it will get the right time from the world the player is in.

View file

@ -5,7 +5,6 @@ Subject: [PATCH] Optimize Network Manager and add advanced packet support
Adds ability for 1 packet to bundle other packets to follow it
Adds ability for a packet to delay sending more packets until a state is ready.
Adds ability to clean up a packet when it is finished (not sent, or finished encoding), such as freeing buffers
Removes synchronization from sending packets
Removes processing packet queue off of main thread
@ -24,7 +23,7 @@ This should solve some deadlock risks
Part of this commit was authored by: Spottedleaf
diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java
index b1dededc15cce686ead74a99bee64c89ac1de22c..35085ca3992e7c21139540d0c404e1568f28a275 100644
index b1dededc15cce686ead74a99bee64c89ac1de22c..94c25c542dd18396fa792af944794bdb2436d2fd 100644
--- a/src/main/java/net/minecraft/server/NetworkManager.java
+++ b/src/main/java/net/minecraft/server/NetworkManager.java
@@ -64,6 +64,10 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
@ -46,11 +45,18 @@ index b1dededc15cce686ead74a99bee64c89ac1de22c..35085ca3992e7c21139540d0c404e156
this.channel.attr(NetworkManager.c).set(enumprotocol);
this.channel.config().setAutoRead(true);
NetworkManager.LOGGER.debug("Enabled auto read");
@@ -158,19 +163,75 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
@@ -158,19 +163,82 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
NetworkManager.LOGGER.debug("Set listener of {} to {}", this, packetlistener);
this.packetListener = packetlistener;
}
+ // Paper start
+ private EntityPlayer getPlayer() {
+ if (packetListener instanceof PlayerConnection) {
+ return ((PlayerConnection) packetListener).player;
+ } else {
+ return null;
+ }
+ }
+ private static class InnerUtil { // Attempt to hide these methods from ProtocolLib so it doesn't accidently pick them up.
+ private static java.util.List<Packet> buildExtraPackets(Packet packet) {
+ java.util.List<Packet> extra = packet.getExtraPackets();
@ -95,9 +101,9 @@ index b1dededc15cce686ead74a99bee64c89ac1de22c..35085ca3992e7c21139540d0c404e156
+ // Paper start - handle oversized packets better
+ boolean connected = this.isConnected();
+ if (!connected && !preparing) {
+ packet.onPacketDone();
+ return; // Do nothing
+ }
+ packet.onPacketDispatch(getPlayer());
+ if (connected && (InnerUtil.canSendImmediate(this, packet) || (
+ MCUtil.isMainThread() && packet.isReady() && this.packetQueue.isEmpty() &&
+ (packet.getExtraPackets() == null || packet.getExtraPackets().isEmpty())
@ -113,13 +119,13 @@ index b1dededc15cce686ead74a99bee64c89ac1de22c..35085ca3992e7c21139540d0c404e156
+ } else {
+ java.util.List<NetworkManager.QueuedPacket> packets = new java.util.ArrayList<>(1 + extraPackets.size());
+ packets.add(new NetworkManager.QueuedPacket(packet, null)); // delay the future listener until the end of the extra packets
+
+ for (int i = 0, len = extraPackets.size(); i < len;) {
+ Packet extra = extraPackets.get(i);
+ boolean end = ++i == len;
+ packets.add(new NetworkManager.QueuedPacket(extra, end ? genericfuturelistener : null)); // append listener to the end
+ }
+
+ this.packetQueue.addAll(packets); // atomic
+ }
+ this.sendPacketQueue();
@ -127,7 +133,31 @@ index b1dededc15cce686ead74a99bee64c89ac1de22c..35085ca3992e7c21139540d0c404e156
}
private void dispatchPacket(Packet<?> packet, @Nullable GenericFutureListener<? extends Future<? super Void>> genericFutureListener) { this.b(packet, genericFutureListener); } // Paper - OBFHELPER
@@ -214,21 +275,46 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
@@ -194,6 +262,11 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
if (genericfuturelistener != null) {
channelfuture.addListener(genericfuturelistener);
}
+ // Paper start
+ if (packet.hasFinishListener()) {
+ channelfuture.addListener((ChannelFutureListener) channelFuture -> packet.onPacketDispatchFinish(getPlayer(), channelFuture));
+ }
+ // Paper end
channelfuture.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
} else {
@@ -207,6 +280,11 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
if (genericfuturelistener != null) {
channelfuture1.addListener(genericfuturelistener);
}
+ // Paper start
+ if (packet.hasFinishListener()) {
+ channelfuture1.addListener((ChannelFutureListener) channelFuture -> packet.onPacketDispatchFinish(getPlayer(), channelFuture));
+ }
+ // Paper end
channelfuture1.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
});
@@ -214,21 +292,46 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
}
@ -184,11 +214,21 @@ index b1dededc15cce686ead74a99bee64c89ac1de22c..35085ca3992e7c21139540d0c404e156
public void a() {
this.o();
@@ -257,9 +343,11 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
@@ -257,9 +360,21 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
return this.socketAddress;
}
+ public void clearPacketQueue() { QueuedPacket packet; while ((packet = packetQueue.poll()) != null) packet.getPacket().onPacketDone(); } // Paper
+ // Paper start
+ public void clearPacketQueue() {
+ EntityPlayer player = getPlayer();
+ packetQueue.forEach(queuedPacket -> {
+ Packet<?> packet = queuedPacket.getPacket();
+ if (packet.hasFinishListener()) {
+ packet.onPacketDispatchFinish(player, null);
+ }
+ });
+ packetQueue.clear();
+ } // Paper end
public void close(IChatBaseComponent ichatbasecomponent) {
// Spigot Start
this.preparing = false;
@ -196,7 +236,7 @@ index b1dededc15cce686ead74a99bee64c89ac1de22c..35085ca3992e7c21139540d0c404e156
// Spigot End
if (this.channel.isOpen()) {
this.channel.close(); // We can't wait as this may be called from an event loop.
@@ -335,7 +423,7 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
@@ -335,7 +450,7 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
} else if (this.i() != null) {
this.i().a(new ChatMessage("multiplayer.disconnect.generic", new Object[0]));
}
@ -206,34 +246,32 @@ index b1dededc15cce686ead74a99bee64c89ac1de22c..35085ca3992e7c21139540d0c404e156
final PacketListener packetListener = this.i();
if (packetListener instanceof PlayerConnection) {
diff --git a/src/main/java/net/minecraft/server/Packet.java b/src/main/java/net/minecraft/server/Packet.java
index 2d8e6a2f4a0c3c5d74a647d7164b0028781d3bf5..df1b4877b1560f982a1fcaf98404c8fe73e29973 100644
index 2d8e6a2f4a0c3c5d74a647d7164b0028781d3bf5..ffc9a1f7d58d67611c4ab46462ac13a921042313 100644
--- a/src/main/java/net/minecraft/server/Packet.java
+++ b/src/main/java/net/minecraft/server/Packet.java
@@ -11,6 +11,9 @@ public interface Packet<T extends PacketListener> {
@@ -11,6 +11,20 @@ public interface Packet<T extends PacketListener> {
void a(T t0);
// Paper start
+ default void onPacketDone() {}
+
+ /**
+ * @param player Null if not at PLAY stage yet
+ */
+ default void onPacketDispatch(@javax.annotation.Nullable EntityPlayer player) {}
+
+ /**
+ * @param player Null if not at PLAY stage yet
+ * @param future Can be null if packet was cancelled
+ */
+ default void onPacketDispatchFinish(@javax.annotation.Nullable EntityPlayer player, @javax.annotation.Nullable io.netty.channel.ChannelFuture future) {}
+ default boolean hasFinishListener() { return false; }
+ default boolean isReady() { return true; }
+ default java.util.List<Packet> getExtraPackets() { return null; }
default boolean packetTooLarge(NetworkManager manager) {
return false;
}
diff --git a/src/main/java/net/minecraft/server/PacketEncoder.java b/src/main/java/net/minecraft/server/PacketEncoder.java
index b0cfef52cbb5e23beae528668e4e98cedecf603c..f46d028016a425a29674e768ae9310c825c088f2 100644
--- a/src/main/java/net/minecraft/server/PacketEncoder.java
+++ b/src/main/java/net/minecraft/server/PacketEncoder.java
@@ -48,7 +48,7 @@ public class PacketEncoder extends MessageToByteEncoder<Packet<?>> {
} else {
throw throwable;
}
- }
+ } finally { try { packet.onPacketDone(); } catch (Exception e) { e.printStackTrace(); } ; } // Paper
// Paper start
int packetLength = bytebuf.readableBytes();
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index e148940ab3721cff27cf791c159c11b9b94191e4..e917d37382dab70ed9e6b62decf1557c33b26065 100644
index 5136905b71085445eb6bac00e9200af8cc7fbe27..14c82861158eed8c91336590fb71c69d185d22f8 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -143,6 +143,7 @@ public abstract class PlayerList {

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Server Tick Events
Fires event at start and end of a server tick
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 3d9cc2ce67b5dc033df397e8d1c31f718792dcc4..249eaf56bc0ec9eb99fdf8958d3ebe2b18999819 100644
index 207dd30539fa3961ba96aafe1e3cfef5020a885c..ae4d62d52c0763849d06709fc405018711db6f90 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1089,6 +1089,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1092,6 +1092,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
});
isOversleep = false;MinecraftTimings.serverOversleep.stopTiming();
// Paper end
@ -17,7 +17,7 @@ index 3d9cc2ce67b5dc033df397e8d1c31f718792dcc4..249eaf56bc0ec9eb99fdf8958d3ebe2b
++this.ticks;
this.b(booleansupplier);
@@ -1132,6 +1133,12 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1135,6 +1136,12 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
}
// Paper end

View file

@ -16,10 +16,10 @@ handling that should have been handled synchronously will be handled
synchronously when the server gets shut down.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 249eaf56bc0ec9eb99fdf8958d3ebe2b18999819..45882ee30f52067909d55bca9202df66a9a48677 100644
index ae4d62d52c0763849d06709fc405018711db6f90..4b50158fe12533d0af541be343731d220e772bd9 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -2217,7 +2217,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -2220,7 +2220,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
// CraftBukkit start
@Override
public boolean isMainThread() {

View file

@ -198,7 +198,7 @@ index 8c6550433c20c54cbe390219821ce393c5720da8..e6d08756f76360b29b29f18305e5ec84
public final ChunkGenerator<?> chunkGenerator;
private final WorldServer world;
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
index 3342278bcd42a6d5a1793e33bc7fe4356be02451..2dcecc1bbd00e46b0a9b5e48bc580475fc8b4cb3 100644
index be20d770df41a656cf2aabfec87e0bdc639053f4..de8b8f54cd906c1154a6790b9220d3e0976c74bd 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -4,7 +4,13 @@ import com.destroystokyo.paper.block.TargetBlockInfo;
@ -226,8 +226,8 @@ index 3342278bcd42a6d5a1793e33bc7fe4356be02451..2dcecc1bbd00e46b0a9b5e48bc580475
+import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
@@ -452,4 +461,170 @@ public final class MCUtil {
import java.util.concurrent.LinkedBlockingQueue;
@@ -511,4 +520,170 @@ public final class MCUtil {
return null;
}

View file

@ -62,7 +62,7 @@ index e6d08756f76360b29b29f18305e5ec84d09f2d54..6713b7667ae4fe3f1f555a71321832b4
public void close() throws IOException {
// CraftBukkit start
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 0ee1d8e4869bfd0ccba21a227e115a36ff027984..7ecf781263179d87c943b08e192d8f010cf20d3e 100644
index 8b499c815c77bf5b356d4216ba6cbf2a329c9aca..cfed5f51431ec5aecb538a321327bfb6e8a0bd88 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -168,6 +168,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@ -73,7 +73,7 @@ index 0ee1d8e4869bfd0ccba21a227e115a36ff027984..7ecf781263179d87c943b08e192d8f01
public File bukkitDataPackFolder;
public CommandDispatcher vanillaCommandDispatcher;
private boolean forceTicks;
@@ -1113,14 +1114,28 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1116,14 +1117,28 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.serverPing.b().a(agameprofile);
}
@ -261,7 +261,7 @@ index 34f470779fa5d1cf9638431253024481236c073b..4f5b516144829a7ae11f21a56789ac7a
return PlayerChunk.getChunkState(playerchunk.getTicketLevel());
});
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index b28868766117f0cfdcc5db271b9415d9ae97ad19..46ad4612a1bd5ab005450645f69b0cb9f6f18aa7 100644
index ca0a23be27ee8174204867d463eb89a10931ff84..a0484d8062ecfb817cfd5b996915dc8f9a4eb2bd 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -817,11 +817,44 @@ public class WorldServer extends World {

View file

@ -1489,10 +1489,10 @@ index 0000000000000000000000000000000000000000..ee906b594b306906c170180a29a8b619
+}
diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkLoadTask.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkLoadTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..ac9bc3e2316a9dc28d13f54296ee6fd5e81188a1
index 0000000000000000000000000000000000000000..044c3da825505f9dc002c02296bf2de51ceef01e
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkLoadTask.java
@@ -0,0 +1,149 @@
@@ -0,0 +1,146 @@
+package com.destroystokyo.paper.io.chunk;
+
+import co.aikar.timings.Timing;
@ -1587,11 +1587,8 @@ index 0000000000000000000000000000000000000000..ac9bc3e2316a9dc28d13f54296ee6fd5
+ // apply fixes
+
+ try {
+ if (chunkData.poiData != null) {
+ chunkData.poiData = chunkData.poiData.clone(); // clone data for safety, file IO thread does not clone
+ }
+ chunkData.chunkData = chunkManager.getChunkData(this.world.getWorldProvider().getDimensionManager(),
+ chunkManager.getWorldPersistentDataSupplier(), chunkData.chunkData.clone(), chunkPos, this.world); // clone data for safety, file IO thread does not clone
+ chunkManager.getWorldPersistentDataSupplier(), chunkData.chunkData, chunkPos, this.world); // clone data for safety, file IO thread does not clone
+ } catch (final Throwable ex) {
+ PaperFileIOThread.LOGGER.error("Could not apply datafixers for chunk task: " + this.toString(), ex);
+ this.complete(ChunkLoadTask.createEmptyHolder());
@ -2930,10 +2927,10 @@ index 2f95174fcc467908808ed3f2dc956bdcafdc3558..134c76065bf382912e6c28d15449db3f
+// Paper end
}
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
index 2dcecc1bbd00e46b0a9b5e48bc580475fc8b4cb3..d9941b38ca037a31f520784b3706080f1d322fb4 100644
index de8b8f54cd906c1154a6790b9220d3e0976c74bd..f8a1f0b96f2eb8535e3080db979bb383d5a18a11 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -627,4 +627,9 @@ public final class MCUtil {
@@ -686,4 +686,9 @@ public final class MCUtil {
out.print(fileData);
}
}
@ -2944,10 +2941,10 @@ index 2dcecc1bbd00e46b0a9b5e48bc580475fc8b4cb3..d9941b38ca037a31f520784b3706080f
+ }
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 7ecf781263179d87c943b08e192d8f010cf20d3e..26be34987047370b0a8971f387cf959468031ebd 100644
index cfed5f51431ec5aecb538a321327bfb6e8a0bd88..aadc4635ecef4e5ba19ff56c37ecbdc5a1721ec6 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -777,6 +777,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -780,6 +780,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.getUserCache().c(false); // Paper
}
// Spigot end
@ -3537,7 +3534,7 @@ index 94b0c54d9d4d77b724087be55ffe6ce464a0bbe7..963ce3eeec6f9eea087054ea48b714ee
return this.m;
}
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
index 65c171cec3cc7c7c7433c63b3718fa7e1c16f148..0a06ed36795afad00839174fc1a7e7f7b9e4a8c8 100644
index 1c4a8d95d02dac65e01bb42fb1cc491af07c0cdc..9d001f816d0b8b6d6cf80ee6bce548f1017960b7 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -541,6 +541,13 @@ public class PlayerConnection implements PacketListenerPlayIn {

View file

@ -73,10 +73,10 @@ index d953cdef14a9b62833a35a4fe94a22b5e9b19c2d..d6e43313bf0c678cf78fe77de2f8f4b6
itemstack.d(this.C());
if (this.tag != null) {
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 26be34987047370b0a8971f387cf959468031ebd..63db74993c12671292b6beef45c2e8be577d4a50 100644
index aadc4635ecef4e5ba19ff56c37ecbdc5a1721ec6..e9c3d1507317e38272305e157e889a033c5d2803 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1219,6 +1219,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1222,6 +1222,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
WorldServer worldserver = (WorldServer) iterator.next();
worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper

View file

@ -63,10 +63,10 @@ index fd998e4fb1534690a2ef8c1bca55e0ae9fe855f9..8f849d83d08b39f1cd9184f484a2089a
if (optional.isPresent()) {
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
index d9941b38ca037a31f520784b3706080f1d322fb4..71ab65e00fe31ea4047cf8a5921c6deba13de6b9 100644
index f8a1f0b96f2eb8535e3080db979bb383d5a18a11..88b41b1d0c2045d01449256a5875ae73765c5595 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -529,7 +529,7 @@ public final class MCUtil {
@@ -588,7 +588,7 @@ public final class MCUtil {
WorldServer world = ((org.bukkit.craftbukkit.CraftWorld)bukkitWorld).getHandle();
PlayerChunkMap chunkMap = world.getChunkProvider().playerChunkMap;

View file

@ -135,10 +135,10 @@ index 8f849d83d08b39f1cd9184f484a2089a7a3124ef..5806ca545191e609bab04e522e358948
protected boolean executeNext() {
// CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 77adc64e30cbc1d4542eb8f4a446788c1fdc61be..3c25436f158316d2e09cbf4673365eddb03ecef4 100644
index f9faa30ef914b1dd2dada9b7d89e80b34d2f1d0d..97cca4495a8dab4434e917a5d94192a28581925c 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -907,6 +907,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -910,6 +910,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
// Paper end
tickSection = curTime;
}
@ -146,7 +146,7 @@ index 77adc64e30cbc1d4542eb8f4a446788c1fdc61be..3c25436f158316d2e09cbf4673365edd
// Spigot end
//MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit // Paper - don't overwrite current tick time
@@ -977,7 +978,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -980,7 +981,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
}
@ -155,7 +155,7 @@ index 77adc64e30cbc1d4542eb8f4a446788c1fdc61be..3c25436f158316d2e09cbf4673365edd
// CraftBukkit start
if (isOversleep) return canOversleep();// Paper - because of our changes, this logic is broken
return this.forceTicks || this.isEntered() || SystemUtils.getMonotonicMillis() < (this.ac ? this.ab : this.nextTick);
@@ -1007,6 +1008,23 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1010,6 +1011,23 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
});
}
@ -179,7 +179,7 @@ index 77adc64e30cbc1d4542eb8f4a446788c1fdc61be..3c25436f158316d2e09cbf4673365edd
@Override
protected TickTask postToMainThread(Runnable runnable) {
return new TickTask(this.ticks, runnable);
@@ -1093,6 +1111,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1096,6 +1114,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
// Paper start - move oversleep into full server tick
isOversleep = true;MinecraftTimings.serverOversleep.startTiming();
this.awaitTasks(() -> {
@ -187,7 +187,7 @@ index 77adc64e30cbc1d4542eb8f4a446788c1fdc61be..3c25436f158316d2e09cbf4673365edd
return !this.canOversleep();
});
isOversleep = false;MinecraftTimings.serverOversleep.stopTiming();
@@ -1175,13 +1194,16 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1178,13 +1197,16 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
}
protected void b(BooleanSupplier booleansupplier) {
@ -204,7 +204,7 @@ index 77adc64e30cbc1d4542eb8f4a446788c1fdc61be..3c25436f158316d2e09cbf4673365edd
this.methodProfiler.exitEnter("levels");
Iterator iterator = this.getWorlds().iterator();
@@ -1192,7 +1214,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1195,7 +1217,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
processQueue.remove().run();
}
MinecraftTimings.processQueueTimer.stopTiming(); // Spigot
@ -213,7 +213,7 @@ index 77adc64e30cbc1d4542eb8f4a446788c1fdc61be..3c25436f158316d2e09cbf4673365edd
MinecraftTimings.timeUpdateTimer.startTiming(); // Spigot // Paper
// Send time updates to everyone, it will get the right time from the world the player is in.
// Paper start - optimize time updates
@@ -1235,9 +1257,11 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1238,9 +1260,11 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.methodProfiler.enter("tick");
try {

View file

@ -87,7 +87,7 @@ index 9f1662ece533f5ea744662b718e2d89ace3107fb..e0d7832c3a081b54a0e3a27380015477
version = getInt("config-version", 20);
set("config-version", 20);
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 3c25436f158316d2e09cbf4673365eddb03ecef4..5f57a9e1c8d5f641facdadbd1877637a8fe8daf5 100644
index 97cca4495a8dab4434e917a5d94192a28581925c..10f7283cbf6f7763186ca0dcc9eb6ba8574264a7 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -106,6 +106,11 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@ -102,7 +102,7 @@ index 3c25436f158316d2e09cbf4673365eddb03ecef4..5f57a9e1c8d5f641facdadbd1877637a
@Nullable
private KeyPair I;
@Nullable
@@ -1186,6 +1191,12 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1189,6 +1194,12 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.av = this.av * 0.8F + (float) l / 1000000.0F * 0.19999999F;
long i1 = SystemUtils.getMonotonicNanos();
@ -115,7 +115,7 @@ index 3c25436f158316d2e09cbf4673365eddb03ecef4..5f57a9e1c8d5f641facdadbd1877637a
this.circularTimer.a(i1 - i);
this.methodProfiler.exit();
org.spigotmc.WatchdogThread.tick(); // Spigot
@@ -2272,4 +2283,30 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -2275,4 +2286,30 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
return SERVER; // Paper
}
// CraftBukkit end

View file

@ -87,7 +87,7 @@ index cfe43e882e524b6ab3d9702e81269c97e6b75eba..2632c7c3ec77918be7979f2aa49209e5
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 5f57a9e1c8d5f641facdadbd1877637a8fe8daf5..1a4bc90435d0a56ab7b607c72f28772fb92049bc 100644
index 10f7283cbf6f7763186ca0dcc9eb6ba8574264a7..4e9f331975e9f1f754875db25a6c6f99ed099327 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -144,6 +144,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@ -120,7 +120,7 @@ index 5f57a9e1c8d5f641facdadbd1877637a8fe8daf5..1a4bc90435d0a56ab7b607c72f28772f
}
// CraftBukkit end
MinecraftServer.LOGGER.info("Stopping server");
@@ -782,7 +788,18 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -785,7 +791,18 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.getUserCache().c(false); // Paper
}
// Spigot end
@ -139,7 +139,7 @@ index 5f57a9e1c8d5f641facdadbd1877637a8fe8daf5..1a4bc90435d0a56ab7b607c72f28772f
}
public String getServerIp() {
@@ -875,6 +892,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -878,6 +895,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
public void run() {
try {
@ -147,7 +147,7 @@ index 5f57a9e1c8d5f641facdadbd1877637a8fe8daf5..1a4bc90435d0a56ab7b607c72f28772f
if (this.init()) {
this.nextTick = SystemUtils.getMonotonicMillis();
this.serverPing.setMOTD(new ChatComponentText(this.motd));
@@ -882,6 +900,18 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -885,6 +903,18 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.a(this.serverPing);
// Spigot start
@ -166,7 +166,7 @@ index 5f57a9e1c8d5f641facdadbd1877637a8fe8daf5..1a4bc90435d0a56ab7b607c72f28772f
org.spigotmc.WatchdogThread.hasStarted = true; // Paper
Arrays.fill( recentTps, 20 );
long start = System.nanoTime(), curTime, tickSection = start; // Paper - Further improve server tick loop
@@ -938,6 +968,12 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -941,6 +971,12 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.a((CrashReport) null);
}
} catch (Throwable throwable) {
@ -179,7 +179,7 @@ index 5f57a9e1c8d5f641facdadbd1877637a8fe8daf5..1a4bc90435d0a56ab7b607c72f28772f
MinecraftServer.LOGGER.error("Encountered an unexpected exception", throwable);
// Spigot Start
if ( throwable.getCause() != null )
@@ -969,14 +1005,14 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -972,14 +1008,14 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
} catch (Throwable throwable1) {
MinecraftServer.LOGGER.error("Exception stopping the server", throwable1);
} finally {
@ -197,7 +197,7 @@ index 5f57a9e1c8d5f641facdadbd1877637a8fe8daf5..1a4bc90435d0a56ab7b607c72f28772f
}
}
@@ -1032,6 +1068,12 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@@ -1035,6 +1071,12 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@Override
protected TickTask postToMainThread(Runnable runnable) {
@ -211,7 +211,7 @@ index 5f57a9e1c8d5f641facdadbd1877637a8fe8daf5..1a4bc90435d0a56ab7b607c72f28772f
}
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index 0b5800649abfc2fd6722e4cb5e8e40e51240a032..62891d2dc6f40bb57e92dfefcbcdf72f89ba5c4f 100644
index e089e619a9616128c85b67497f6643262d2aeef9..aed1e9b3d0fc270e77d05dcf590683e38459da7e 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -400,7 +400,7 @@ public abstract class PlayerList {

View file

@ -5,10 +5,10 @@ Subject: [PATCH] Implement Mob Goal API
diff --git a/pom.xml b/pom.xml
index bc8438ae1ae939be4d2257d37df9a843a13ac301..0c0051f7f2a58d63b851e80b442acbb47ca75dfa 100644
index 60bf6dd28527f6ffcb59779ec9546030245724ca..1ae57e8ab2681e674f97ef3220c5cbf9143c6a7e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -122,6 +122,13 @@
@@ -128,6 +128,13 @@
<version>1.3</version>
<scope>test</scope>
</dependency>