EVEN MOOOOOAAAAAAARRRRRRR patches :) (#5820)

This commit is contained in:
Jake Potrebic 2021-06-13 18:06:38 -07:00 committed by GitHub
parent 9085da6e60
commit 2a46c72164
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
82 changed files with 971 additions and 1418 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

@ -9,10 +9,10 @@ on the real tile entity.
This is useful for where performance is needed
diff --git a/src/main/java/org/bukkit/block/Block.java b/src/main/java/org/bukkit/block/Block.java
index d4c69573f250309adc442c7cf67ea6fc2f2e3ace..969a6cf404d99c186e73321659240195b8650ffc 100644
index da0964b1b6555ad50cb2ee47f13a7b9dfb1ab6aa..3ca05a6e86a5329cf452041eac476e3636eec34a 100644
--- a/src/main/java/org/bukkit/block/Block.java
+++ b/src/main/java/org/bukkit/block/Block.java
@@ -269,6 +269,16 @@ public interface Block extends Metadatable {
@@ -271,6 +271,16 @@ public interface Block extends Metadatable {
@NotNull
BlockState getState();

View File

@ -122,23 +122,18 @@ index 9a2252fef56be1ed3ae2169aea46cb567e965c6c..11f38187fca830d974be01fea2966a31
-public interface Pillager extends Illager, InventoryHolder { }
+public interface Pillager extends Illager, InventoryHolder, RangedEntity { } // Paper
diff --git a/src/main/java/org/bukkit/entity/Skeleton.java b/src/main/java/org/bukkit/entity/Skeleton.java
index 16b1293887cee2bc5267f3da771fb5a6ece1b4e9..1c367f78eadf24850061a84ce63b950b79d3c435 100644
index 01d838a60d056bf4b4a8ef9d0ac18c6f91f412e6..b7e424ea8a282f45fb8b91c919e4e4526c00be8b 100644
--- a/src/main/java/org/bukkit/entity/Skeleton.java
+++ b/src/main/java/org/bukkit/entity/Skeleton.java
@@ -2,11 +2,12 @@ package org.bukkit.entity;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
+import com.destroystokyo.paper.entity.RangedEntity;
/**
* Represents a Skeleton.
@@ -7,7 +7,7 @@ package org.bukkit.entity;
* Other skeleton-like entities, such as the {@link WitherSkeleton} or the
* {@link Stray} are not related to this type.
*/
-public interface Skeleton extends Monster {
+public interface Skeleton extends Monster, RangedEntity { // Paper
-public interface Skeleton extends AbstractSkeleton {
+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
index 818efe2a4d1ac0c4d8dca6c757850d99cdc2cb4b..10f8f6d45ae9280651c3ebddd1f90acbd7d6ff29 100644
--- a/src/main/java/org/bukkit/entity/Snowman.java

View File

@ -91,10 +91,10 @@ index f45bea24a350c3700bdbf4c44aeb1c0562e57d9e..a653a09968123724f9ec5501760257b3
* Gets the highest non-empty (impassable) coordinate at the given
* coordinates.
diff --git a/src/main/java/org/bukkit/block/Block.java b/src/main/java/org/bukkit/block/Block.java
index 969a6cf404d99c186e73321659240195b8650ffc..b090938f883c486e703cb7c036c47925f3016704 100644
index 3ca05a6e86a5329cf452041eac476e3636eec34a..18ab5cca036522df2d245f755d6c67904e6398e8 100644
--- a/src/main/java/org/bukkit/block/Block.java
+++ b/src/main/java/org/bukkit/block/Block.java
@@ -153,6 +153,72 @@ public interface Block extends Metadatable {
@@ -155,6 +155,72 @@ public interface Block extends Metadatable {
*/
int getZ();

View File

@ -64,21 +64,13 @@ index 0000000000000000000000000000000000000000..8cf87d228a7006658d52ce0da16c2d74
+ Sound getFallSound();
+}
diff --git a/src/main/java/org/bukkit/block/Block.java b/src/main/java/org/bukkit/block/Block.java
index b090938f883c486e703cb7c036c47925f3016704..5e2aa4fb8cf8130df21d3172dd94e857317f7653 100644
index 18ab5cca036522df2d245f755d6c67904e6398e8..5ac36e0f90d0889853736390877aa92ec0ca181b 100644
--- a/src/main/java/org/bukkit/block/Block.java
+++ b/src/main/java/org/bukkit/block/Block.java
@@ -1,6 +1,7 @@
package org.bukkit.block;
import java.util.Collection;
+
import org.bukkit.Chunk;
import org.bukkit.FluidCollisionMode;
import org.bukkit.Location;
@@ -560,4 +561,16 @@ public interface Block extends Metadatable {
@@ -587,4 +587,16 @@ public interface Block extends Metadatable {
*/
@NotNull
BoundingBox getBoundingBox();
VoxelShape getCollisionShape();
+
+ // Paper start
+ /**

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Add effect to block break naturally
diff --git a/src/main/java/org/bukkit/block/Block.java b/src/main/java/org/bukkit/block/Block.java
index 5e2aa4fb8cf8130df21d3172dd94e857317f7653..e1cc36fbe808973227c0e8ca7166453235c90279 100644
index 5ac36e0f90d0889853736390877aa92ec0ca181b..786b8011e98b2fe93cc2418d624f6350ede62d90 100644
--- a/src/main/java/org/bukkit/block/Block.java
+++ b/src/main/java/org/bukkit/block/Block.java
@@ -469,6 +469,18 @@ public interface Block extends Metadatable {
@@ -470,6 +470,18 @@ public interface Block extends Metadatable {
*/
boolean breakNaturally(@Nullable ItemStack tool);

View File

@ -5,7 +5,7 @@ Subject: [PATCH] Add tick times API
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index 49bf621a2c0e5e9641b334a42b2769944c991d5d..4bae8a4387b86c868149f06b490ef6dfced2ff41 100644
index 02f91b446697b1c637fda3b65b48ec8cf38de66d..1eeb1257888ef2e2d92598e2b1a80286a087dfa5 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -1590,6 +1590,25 @@ public final class Bukkit {
@ -35,7 +35,7 @@ index 49bf621a2c0e5e9641b334a42b2769944c991d5d..4bae8a4387b86c868149f06b490ef6df
/**
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index e448ae78304974f7664b7ef18568a547833ece9f..bea7ffdb00e6de1391e9143901c62f0aceaaf727 100644
index b038a82ffc298abb5129b6ec20538df5d0b6f595..3c9890ce33231070836ee471206b20cec74e00b4 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -1345,6 +1345,21 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi

View File

@ -6,7 +6,7 @@ Subject: [PATCH] Expose MinecraftServer#isRunning
This allows for plugins to detect if the server is actually turning off in onDisable rather than just plugins reloading.
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index 4bae8a4387b86c868149f06b490ef6dfced2ff41..4dadea432c8d79b15fa126b4f0c810e9a72b4029 100644
index 1eeb1257888ef2e2d92598e2b1a80286a087dfa5..847ba5143660d5c56ff8f2cae2169a51b8927757 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -1858,6 +1858,15 @@ public final class Bukkit {
@ -26,7 +26,7 @@ index 4bae8a4387b86c868149f06b490ef6dfced2ff41..4dadea432c8d79b15fa126b4f0c810e9
@NotNull
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index bea7ffdb00e6de1391e9143901c62f0aceaaf727..b92261e09790e89788560bf7c9784c8399504810 100644
index 3c9890ce33231070836ee471206b20cec74e00b4..e6b62ba32e089e2fd8563ec8430b72196f6680e0 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -1631,5 +1631,12 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi

View File

@ -20,7 +20,7 @@ index d6897f43a0692e031bed8a212d9a637ef548cc60..e348034288c74ab80360086d71f0b7f6
// Paper end
}
diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java
index bf39989dbe08c93120d75bed6281ae75c460afca..15b48ad1ba5bcf7394fb3f52ce2cc6baa6632f66 100644
index 290c3f0fd6e8c3407d421b697e0ee01584f4cebd..9a878e4fde31c015e2f3fdf365d5d16c30198685 100644
--- a/src/main/java/org/bukkit/inventory/ItemStack.java
+++ b/src/main/java/org/bukkit/inventory/ItemStack.java
@@ -628,6 +628,30 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, net.kyor

View File

@ -11,7 +11,7 @@ errors.
This isn't an issue on Spigot
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
index a1a805004941d67abb0b9aa1721e0370c45b5289..26685f59b235ea5b4c4fb7ae21acb5149edaa2b3 100644
index b83637f872be5fc73500b10c917d71802976b340..49e5d49eb09bb966e47d6a03ac08a527c963b43d 100644
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
@@ -591,7 +591,7 @@ public final class SimplePluginManager implements PluginManager {

View File

@ -176,7 +176,7 @@ index 0000000000000000000000000000000000000000..f7f171c4ee0b8339b2f8fbe82442d65f
+ }
+}
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index ec87c78d0f9379511467b6d13b9cdfa4c19d15ca..2530c811f52f51d6338900221b4681c952c1c752 100644
index 685975e7bb8938ce0b2d80855c4c5549f50b262d..e53f641e11dc74c99e656e985caa7c5943fb53a4 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -2,6 +2,7 @@ package org.bukkit.entity;
@ -187,7 +187,7 @@ index ec87c78d0f9379511467b6d13b9cdfa4c19d15ca..2530c811f52f51d6338900221b4681c9
import com.destroystokyo.paper.Title; // Paper
import net.kyori.adventure.text.Component;
import com.destroystokyo.paper.profile.PlayerProfile; // Paper
@@ -1909,6 +1910,12 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
@@ -1936,6 +1937,12 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* Reset the cooldown counter to 0, effectively starting the cooldown period.
*/
void resetCooldown();

View File

@ -5,7 +5,7 @@ Subject: [PATCH] Expose game version
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index 86ac6702b3aeab1126b2b2879b87ef3883793d44..12214ce2af7363d40cf44652e46f05c5c1f2fe5a 100644
index 847ba5143660d5c56ff8f2cae2169a51b8927757..2c9d2739e78d5c422574f5ddda078ca395c0fa6d 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -118,6 +118,18 @@ public final class Bukkit {
@ -28,7 +28,7 @@ index 86ac6702b3aeab1126b2b2879b87ef3883793d44..12214ce2af7363d40cf44652e46f05c5
* Gets a view of all currently logged in players. This {@linkplain
* Collections#unmodifiableCollection(Collection) view} is a reused
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index 16a74b834c4d4b907f9b11ccf9ef9804514df224..360decea2eb6de4c567fa4cceea8f19bceff6823 100644
index e6b62ba32e089e2fd8563ec8430b72196f6680e0..46d1086bd7d7f91b4337c8463974d4b9d501cbf0 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -97,6 +97,16 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi

View File

@ -5,6 +5,8 @@ Subject: [PATCH] Delay unsafe actions until after entity ticking is done
This will help prevent many cases of unregistering entities during entity ticking
1.17: Not used anywhere in 1.16.5 server, and no more tickingEntities bool on ServerLevel
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 4e75cc5e52a5295e32ccadb371702a405bb518bb..b9978d296b83e73d3395b8254c0e8ccd9b36d0fa 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java

View File

@ -8,6 +8,8 @@ These can be hot functions (i.e entity ticking and block ticking),
so inline where possible, and avoid the abstraction of the
Either class.
1.17: needs to be looked at again
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 3744cce8611ac01b1b6c76cd3c4890795c1f06a2..531fe1259a1d60ff69321c3fefbf97f7141e6475 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java

View File

@ -1,102 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Thu, 30 Apr 2020 16:56:54 +0200
Subject: [PATCH] Add Raw Byte ItemStack Serialization
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 b3838e709c1581c25da7738c9a03a827761845b1..05ace1d046e32a261e67bff5afc18c2d32e1a8aa 100644
--- a/src/main/java/net/minecraft/nbt/NbtIo.java
+++ b/src/main/java/net/minecraft/nbt/NbtIo.java
@@ -51,6 +51,7 @@ 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;
@@ -106,6 +107,7 @@ 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 950a4b67f9091af551ec1036ebeb943e3b335e91..dc4e2fc26e1bc2c545f955d30c052bb86e3ef614 100644
--- a/src/main/java/net/minecraft/util/datafix/DataFixers.java
+++ b/src/main/java/net/minecraft/util/datafix/DataFixers.java
@@ -78,6 +78,7 @@ 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 ac996d581925c8f92832009945c766962e5b51c5..458cdfbeac9d757c9721acd4557a548affa0ede1 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -196,6 +196,7 @@ 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
index 86b319337fc41a09dd45df466df60cadaed1343f..a5a5038a84434e69fda8f6b41d2f00b4989e25ae 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -378,6 +378,46 @@ public final class CraftMagicNumbers implements UnsafeValues {
public boolean isSupportedApiVersion(String apiVersion) {
return apiVersion != null && SUPPORTED_API.contains(apiVersion);
}
+
+ @Override
+ public byte[] serializeItem(ItemStack item) {
+ Preconditions.checkNotNull(item, "null cannot be serialized");
+ Preconditions.checkArgument(item.getType() != Material.AIR, "air cannot be serialized");
+
+ java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream();
+ CompoundTag compound = (item instanceof CraftItemStack ? ((CraftItemStack) item).getHandle() : CraftItemStack.asNMSCopy(item)).save(new CompoundTag());
+ compound.putInt("DataVersion", getDataVersion());
+ try {
+ net.minecraft.nbt.NbtIo.writeNBT(
+ compound,
+ outputStream
+ );
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ return outputStream.toByteArray();
+ }
+
+ @Override
+ public ItemStack deserializeItem(byte[] data) {
+ Preconditions.checkNotNull(data, "null cannot be deserialized");
+ Preconditions.checkArgument(data.length > 0, "cannot deserialize nothing");
+
+ try {
+ CompoundTag compound = net.minecraft.nbt.NbtIo.readNBT(
+ new java.io.ByteArrayInputStream(data)
+ );
+ int dataVersion = compound.getInt("DataVersion");
+
+ 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());
+ return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.fromCompound((CompoundTag) converted.getValue()));
+ } catch (IOException ex) {
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(ex);
+ throw new RuntimeException();
+ }
+ }
// Paper end
/**

View File

@ -1,79 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <spottedleaf@spottedleaf.dev>
Date: Mon, 6 Apr 2020 18:10:43 -0700
Subject: [PATCH] Remove streams from PairedQueue
We shouldn't be doing stream calls just to see if the queue is
empty. This creates loads of garbage thanks to how often it's called.
diff --git a/src/main/java/net/minecraft/util/thread/StrictQueue.java b/src/main/java/net/minecraft/util/thread/StrictQueue.java
index cdc572b0261034248960fa13b8412e874fd20db5..07938519b699a31a280f3f419b34fb7cf6cf6883 100644
--- a/src/main/java/net/minecraft/util/thread/StrictQueue.java
+++ b/src/main/java/net/minecraft/util/thread/StrictQueue.java
@@ -20,32 +20,30 @@ public interface StrictQueue<T, F> {
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) {
- this.queueList = (List) IntStream.range(0, priorityCount).mapToObj((j) -> {
- return Queues.newConcurrentLinkedQueue();
- }).collect(Collectors.toList());
+ // Paper start - remove streams
+ this.queueList = new java.util.ArrayList<>(priorityCount); // queues
+ for (int j = 0; j < priorityCount; ++j) {
+ this.getQueues().add(Queues.newConcurrentLinkedQueue());
+ }
+ // Paper end - remove streams
}
@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) {
@@ -57,7 +55,16 @@ public interface StrictQueue<T, F> {
@Override
public boolean isEmpty() {
- return this.queueList.stream().allMatch(Collection::isEmpty);
+ // Paper start - remove streams
+ // 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) {
+ Queue<Runnable> queue = this.getQueues().get(i);
+ if (!queue.isEmpty()) {
+ return false;
+ }
+ }
+ return true;
+ // Paper end - remove streams
}
}

View File

@ -1,416 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 19 Apr 2020 04:28:29 -0400
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 b3ca4300b280a24f3ed2acaffdd6ae2cdffd140d..97a582614ad28f9fa864ae9be4860658e5979214 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -145,7 +145,7 @@ 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
index b45fe750c8ca838e1beebff4077e5819eec2836c..79fb63c40dd0543a6f629e78f390f23f34992ba1 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -629,7 +629,7 @@ public class ServerChunkCache extends ChunkSource {
return this.mainThreadProcessor.pollTask();
}
- private boolean runDistanceManagerUpdates() {
+ public boolean runDistanceManagerUpdates() { // Paper - private -> public
boolean flag = this.distanceManager.runAllUpdates(this.chunkMap);
boolean flag1 = this.chunkMap.promoteChunkMap();
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 75a095e0c2177dc1b46b080597ff8f12f1480acc..24c508ade61a6ad90b0ef73cdc995f531ef18263 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -32,6 +32,7 @@ import net.minecraft.core.Vec3i;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps;
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;
@@ -172,6 +173,7 @@ public class ServerPlayer extends Player implements ContainerListener {
private static final Logger LOGGER = LogManager.getLogger();
public ServerGamePacketListenerImpl connection;
+ public Connection networkManager; // Paper
public final MinecraftServer server;
public final ServerPlayerGameMode gameMode;
public final Deque<Integer> removeQueue = new ArrayDeque<>(); // Paper
@@ -238,6 +240,7 @@ public class ServerPlayer extends Player implements ContainerListener {
public boolean joining = true;
public boolean sentListPacket = false;
public boolean supressTrackerForLogin = false; // Paper
+ public boolean didPlayerJoinEvent = false; // Paper
public Integer clientViewDistance;
// CraftBukkit end
public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper
diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java
index d09e4857b6c40410d134fa81b48e95919a7373bd..583587457790df826a8a3239a4bd1d0f1dcab1da 100644
--- a/src/main/java/net/minecraft/server/level/TicketType.java
+++ b/src/main/java/net/minecraft/server/level/TicketType.java
@@ -21,6 +21,7 @@ public class TicketType<T> {
public static final TicketType<ChunkPos> FORCED = create("forced", Comparator.comparingLong(ChunkPos::toLong));
public static final TicketType<ChunkPos> LIGHT = create("light", Comparator.comparingLong(ChunkPos::toLong));
public static final TicketType<BlockPos> PORTAL = create("portal", Vec3i::compareTo, 300);
+ 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<ChunkPos> UNKNOWN = create("unknown", Comparator.comparingLong(ChunkPos::toLong), 1);
public static final TicketType<Unit> PLUGIN = 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
index 09a663cc53cdf8ae45352b280200c8170dbbcdfc..1bed6e69bf3cc1ab9b0c1259de4f643bf58371aa 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -220,6 +220,7 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
private static final Logger LOGGER = LogManager.getLogger();
public final Connection connection;
private final MinecraftServer server;
+ public Runnable playerJoinReady; // Paper
public ServerPlayer player;
private int tickCount;
private long keepAliveTime = Util.getMillis(); private void setLastPing(long lastPing) { this.keepAliveTime = lastPing;}; private long getLastPing() { return this.keepAliveTime;}; // Paper - OBFHELPER
@@ -298,6 +299,15 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
// CraftBukkit end
public void tick() {
+ // Paper start - login async
+ Runnable playerJoinReady = this.playerJoinReady;
+ if (playerJoinReady != null) {
+ this.playerJoinReady = null;
+ playerJoinReady.run();
+ }
+ // Don't tick if not valid (dead), otherwise we load chunks below
+ if (this.player.valid) {
+ // Paper end
this.resetPosition();
this.player.xo = this.player.getX();
this.player.yo = this.player.getY();
@@ -339,7 +349,7 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
this.lastVehicle = null;
this.clientVehicleIsFloating = false;
this.aboveGroundVehicleTickCount = 0;
- }
+ }} // Paper - end if (valid)
this.server.getProfiler().push("keepAlive");
// Paper Start - give clients a longer time to respond to pings as per pre 1.12.2 timings
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
index 9631fa93b821c7f6bc6dc707c2c82cce2ae8291e..e229c7735ba88be3d8721440104958408a2a075e 100644
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
@@ -86,7 +86,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener
}
// Paper end
} else if (this.state == ServerLoginPacketListenerImpl.State.DELAY_ACCEPT) {
- ServerPlayer entityplayer = this.server.getPlayerList().getPlayer(this.gameProfile.getId());
+ ServerPlayer entityplayer = this.server.getPlayerList().getActivePlayer(this.gameProfile.getId()); // Paper
if (entityplayer == null) {
this.state = ServerLoginPacketListenerImpl.State.READY_TO_ACCEPT;
@@ -186,7 +186,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener
}
this.connection.send(new ClientboundGameProfilePacket(this.gameProfile));
- ServerPlayer entityplayer = this.server.getPlayerList().getPlayer(this.gameProfile.getId());
+ ServerPlayer entityplayer = this.server.getPlayerList().getActivePlayer(this.gameProfile.getId()); // Paper
if (entityplayer != null) {
this.state = ServerLoginPacketListenerImpl.State.DELAY_ACCEPT;
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 454d60566743e02e7e55868c7bb45e30583dfa8f..ffc8c9ee8b1768dd809189858ee45658fb9bf1c5 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -36,6 +36,7 @@ import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket;
import net.minecraft.network.protocol.game.ClientboundChatPacket;
import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket;
+import net.minecraft.network.protocol.game.ClientboundDisconnectPacket;
import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
import net.minecraft.network.protocol.game.ClientboundGameEventPacket;
import net.minecraft.network.protocol.game.ClientboundLoginPacket;
@@ -59,6 +60,8 @@ 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;
@@ -124,11 +127,12 @@ public abstract class PlayerList {
private static final SimpleDateFormat BAN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");
private final MinecraftServer server;
public final List<ServerPlayer> players = new java.util.concurrent.CopyOnWriteArrayList(); // CraftBukkit - ArrayList -> CopyOnWriteArrayList: Iterator safety
- private final Map<UUID, ServerPlayer> playersByUUID = Maps.newHashMap();
+ private final Map<UUID, ServerPlayer> playersByUUID = Maps.newHashMap();Map<UUID, ServerPlayer> getUUIDMap() { return playersByUUID; } // Paper - OBFHELPER
private final UserBanList bans;
private final IpBanList ipBans;
private final ServerOpList ops;
private final UserWhiteList whitelist;
+ private final Map<UUID, ServerPlayer> pendingPlayers = Maps.newHashMap(); // Paper
// CraftBukkit start
// private final Map<UUID, ServerStatisticManager> o;
// private final Map<UUID, AdvancementDataPlayer> p;
@@ -167,6 +171,11 @@ public abstract class PlayerList {
}
public void placeNewPlayer(Connection connection, ServerPlayer player) {
+ ServerPlayer prev = pendingPlayers.put(player.getUUID(), player);// Paper
+ if (prev != null) {
+ disconnectPendingPlayer(prev);
+ }
+ player.networkManager = connection; // Paper
player.loginTime = System.currentTimeMillis(); // Paper
GameProfile gameprofile = player.getGameProfile();
GameProfileCache usercache = this.server.getProfileCache();
@@ -180,7 +189,7 @@ public abstract class PlayerList {
if (nbttagcompound != null && nbttagcompound.contains("bukkit")) {
CompoundTag bukkit = nbttagcompound.getCompound("bukkit");
s = bukkit.contains("lastKnownName", 8) ? bukkit.getString("lastKnownName") : s;
- }
+ }String lastKnownName = s; // Paper
// CraftBukkit end
if (nbttagcompound != null) {
@@ -255,34 +264,79 @@ public abstract class PlayerList {
player.getRecipeBook().sendInitialRecipeBook(player);
this.updateEntireScoreboard(worldserver1.getScoreboard(), player);
this.server.invalidateStatus();
+ // Paper start - async load spawn in chunk
+ ServerLevel finalWorldserver = worldserver1;
+ int chunkX = loc.getBlockX() >> 4;
+ int chunkZ = loc.getBlockZ() >> 4;
+ final ChunkPos pos = new ChunkPos(chunkX, chunkZ);
+ ChunkMap playerChunkMap = worldserver1.getChunkSource().chunkMap;
+ playerChunkMap.getChunkDistanceManager().addTicketAtLevel(TicketType.LOGIN, pos, 31, pos.toLong());
+ worldserver1.getChunkSource().runDistanceManagerUpdates();
+ worldserver1.getChunkSource().getChunkAtAsynchronously(chunkX, chunkZ, true, true).thenApply(chunk -> {
+ ChunkHolder updatingChunk = playerChunkMap.getUpdatingChunkIfPresent(pos.toLong());
+ if (updatingChunk != null) {
+ return updatingChunk.getEntityTickingFuture();
+ } else {
+ return java.util.concurrent.CompletableFuture.completedFuture(chunk);
+ }
+ }).thenAccept(chunk -> {
+ playerconnection.playerJoinReady = () -> {
+ postChunkLoadJoin(
+ player, finalWorldserver, connection, playerconnection,
+ nbttagcompound, connection.getRemoteAddress().toString(), lastKnownName
+ );
+ };
+ });
+ }
+
+ public ServerPlayer getActivePlayer(UUID uuid) {
+ ServerPlayer player = this.getUUIDMap().get(uuid);
+ return player != null ? player : pendingPlayers.get(uuid);
+ }
+
+ void disconnectPendingPlayer(ServerPlayer entityplayer) {
+ TranslatableComponent msg = new TranslatableComponent("multiplayer.disconnect.duplicate_login", new Object[0]);
+ entityplayer.networkManager.send(new ClientboundDisconnectPacket(msg), (future) -> {
+ entityplayer.networkManager.disconnect(msg);
+ entityplayer.networkManager = null;
+ });
+ }
+
+ private void postChunkLoadJoin(ServerPlayer entityplayer, ServerLevel worldserver1, Connection networkmanager, ServerGamePacketListenerImpl playerconnection, CompoundTag nbttagcompound, String s1, String s) {
+ pendingPlayers.remove(entityplayer.getUUID(), entityplayer);
+ if (!networkmanager.isConnected()) {
+ return;
+ }
+ entityplayer.didPlayerJoinEvent = true;
+ // Paper end
TranslatableComponent chatmessage;
- 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;
}
@@ -297,51 +351,51 @@ 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
@@ -492,6 +546,7 @@ public abstract class PlayerList {
protected void save(ServerPlayer player) {
if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit
+ if (!player.didPlayerJoinEvent) return; // Paper - If we never fired PJE, we disconnected during login. Data has not changed, and additionally, our saved vehicle is not loaded! If we save now, we will lose our vehicle (CraftBukkit bug)
this.playerIo.save(player);
ServerStatsCounter serverstatisticmanager = (ServerStatsCounter) player.getStats(); // CraftBukkit
@@ -519,7 +574,7 @@ 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())));
- cserver.getPluginManager().callEvent(playerQuitEvent);
+ if (entityplayer.didPlayerJoinEvent) cserver.getPluginManager().callEvent(playerQuitEvent); // Paper - if we disconnected before join ever fired, don't fire quit
entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());
if (server.isSameThread()) entityplayer.doTick(); // SPIGOT-924 // Paper - don't tick during emergency shutdowns (Watchdog)
@@ -572,6 +627,13 @@ public abstract class PlayerList {
// this.p.remove(uuid);
// CraftBukkit end
}
+ // Paper start
+ entityplayer1 = pendingPlayers.get(uuid);
+ if (entityplayer1 == entityplayer) {
+ pendingPlayers.remove(uuid);
+ }
+ entityplayer.networkManager = null;
+ // Paper end
// CraftBukkit start
// this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[]{entityplayer}));
@@ -589,7 +651,7 @@ public abstract class PlayerList {
cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity());
// CraftBukkit end
- return playerQuitEvent.quitMessage(); // Paper - Adventure
+ return entityplayer.didPlayerJoinEvent ? playerQuitEvent.quitMessage() : null; // CraftBukkit // Paper - Adventure // Paper - don't print quit if we never printed join
}
// CraftBukkit start - Whole method, SocketAddress to LoginListener, added hostname to signature, return EntityPlayer
@@ -608,6 +670,13 @@ public abstract class PlayerList {
list.add(entityplayer);
}
}
+ // Paper start - check pending players too
+ entityplayer = pendingPlayers.get(uuid);
+ if (entityplayer != null) {
+ this.pendingPlayers.remove(uuid);
+ disconnectPendingPlayer(entityplayer);
+ }
+ // Paper end
Iterator iterator = list.iterator();
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index b8dcc91a191f25ca578e0858abf6c1b874fee15d..9f0371282f5829d26dc9618c3d466bccaa4cd3af 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -1371,7 +1371,7 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
this.yo = y;
this.zo = d4;
this.setPos(d3, y, d4);
- 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
}
public void moveTo(Vec3 vec3d) {

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 f0e74daa5bb9e88c028225e7c71deb04c481a7ac..abbe05b07831423eccf8779e854251dec5fbc2ae 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java
@@ -6,10 +6,16 @@ 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;
@@ -18,7 +24,23 @@ 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);
@@ -27,8 +49,8 @@ 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;
@@ -41,9 +63,9 @@ 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);
}
@@ -53,7 +75,7 @@ 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;
}
@@ -64,6 +86,6 @@ 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 c14d5ebe16a693834ed218af8f737714065b2e17..1603eb3f7d90a4b3a028b20776566db77d09c123 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
@@ -329,19 +329,46 @@ 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

@ -1956,10 +1956,10 @@ index cf69a45f038c2b8336010f5fe277313fd0513b5b..a7966aa0846637efdc43df1ca97cbc5d
public net.minecraft.world.item.enchantment.Enchantment getHandle() {
return this.target;
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 98407b26cb94088fd931c445d4ed65eae5b7ecce..408e5a68986a91183d08ce06d385867b947ac04e 100644
index 78d1621c1b5f1870829d92720e2151e9f9d9a8b5..6722d97d498fb2951b7dd8af3b68dd771ce8f5c1 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -807,6 +807,19 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@@ -808,6 +808,19 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
return this.getHandle().getVehicle().getBukkitEntity();
}

View File

@ -114,10 +114,10 @@ index 394164f50256ad9a167e15531a9202875abb6cb6..abc62c560816d945642d830a020deb28
@Nullable
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 408e5a68986a91183d08ce06d385867b947ac04e..e5549f33a472133a8ce8533b5b827560a550f7ae 100644
index 6722d97d498fb2951b7dd8af3b68dd771ce8f5c1..417357f6a187747a5e27fa60a57cee3fb91f3d2e 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1097,4 +1097,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@@ -1098,4 +1098,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
return this.spigot;
}
// Spigot end

View File

@ -17,10 +17,10 @@ index 4b6e6f120edc0e2c3dd3f81c5b9fb96980e41a33..6dab7f65401d5f01e094454b392042cc
static {
ConfigurationSerialization.registerClass(CraftOfflinePlayer.class);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index e5549f33a472133a8ce8533b5b827560a550f7ae..380cd00e55bbdc8851483a5f469e01a5ba48e955 100644
index 417357f6a187747a5e27fa60a57cee3fb91f3d2e..808169e6d78b9e3647763239bbd05fcfba6449a6 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -432,10 +432,40 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@@ -433,10 +433,40 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
public void setVelocity(Vector velocity) {
Preconditions.checkArgument(velocity != null, "velocity");
velocity.checkFinite();

View File

@ -20,10 +20,10 @@ index 52d80086deff664fcfd8952b7cabbfa1f48ad131..a86b5272c0ac4dd64f796f7fd025c7a3
private boolean tickingBlockEntities;
public final Thread thread;
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 26f89f747eba69caaee3cbca71a1d48f2378b4cc..c9f11030ff928d3dca5cfbe48af057eb0480f898 100644
index 1de08dd42366c9988fdcde265b92823e25e48b99..7b1f853913a3d858718a6067b3927946c7e50114 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -271,6 +271,57 @@ public class CraftWorld implements World {
@@ -272,6 +272,57 @@ public class CraftWorld implements World {
private int waterAmbientSpawn = -1;
private int ambientSpawn = -1;

View File

@ -314,10 +314,10 @@ index 11ed01b3ebe4c71e3d3c767887a5dca6033fdf3c..52b2b27f8f8b542a930d649ed6904b4b
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index c9f11030ff928d3dca5cfbe48af057eb0480f898..9925d1f68c35a29156a152a8cc4b653ba280374b 100644
index 7b1f853913a3d858718a6067b3927946c7e50114..efff3e9590e3fd66d9ab56173c986f5b51bbe559 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1837,7 +1837,7 @@ public class CraftWorld implements World {
@@ -1838,7 +1838,7 @@ public class CraftWorld implements World {
} else if (TNTPrimed.class.isAssignableFrom(clazz)) {
entity = new PrimedTnt(this.world, x, y, z, null);
} else if (ExperienceOrb.class.isAssignableFrom(clazz)) {

View File

@ -49,10 +49,10 @@ index 037dafb59e54047d1d54474c44897d35b8f46c98..e310c1eb1108780bcff4d7ba9d49cefa
if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) {
Entity vehicle = entity.getVehicle();
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 380cd00e55bbdc8851483a5f469e01a5ba48e955..af8552f21f598f99151e59fe44df40f13caa3ead 100644
index 808169e6d78b9e3647763239bbd05fcfba6449a6..a2a7b6a62ea1292fce37581863bee931d1497223 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1134,5 +1134,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@@ -1135,5 +1135,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
Location origin = getHandle().origin;
return origin == null ? null : origin.clone();
}

View File

@ -58,10 +58,10 @@ index 77645019c88d61dde28b7598d8a29b7d0c23c209..8a079ee3ed243fd19b1dd7eed2de1dd3
return null;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 6128eb5a793365822d9b00a86629ad4d86c61da9..ca03ed4b1581df2b7db272d6f330174a9d277153 100644
index 923948e7fc63a778ca126c99e1189357bb490dee..bf12cb6a1f991372206e462e46f2686decff11a6 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -313,7 +313,21 @@ public class CraftBlock implements Block {
@@ -316,7 +316,21 @@ public class CraftBlock implements Block {
@Override
public BlockState getState() {

View File

@ -34,10 +34,10 @@ index 18ab943ea2a959f012c3f75957fcb05dbe4ee6ff..c7ac5b323c731e5a7929f87d59e62796
if (this.sendParticles(entityplayer, force, d0, d1, d2, packetplayoutworldparticles)) { // CraftBukkit
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 9925d1f68c35a29156a152a8cc4b653ba280374b..fbc82598a2f7ea439bb371ecf074b486ae09c355 100644
index efff3e9590e3fd66d9ab56173c986f5b51bbe559..8574cca2582d5eaf3720df1c42fda38957d18230 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -2357,11 +2357,17 @@ public class CraftWorld implements World {
@@ -2358,11 +2358,17 @@ public class CraftWorld implements World {
@Override
public <T> void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) {

View File

@ -8,10 +8,10 @@ This API has more capabilities than .dropItem with the Consumer function
Item can be set inside of the Consumer pre spawn function.
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index fbc82598a2f7ea439bb371ecf074b486ae09c355..e744a793062acce339c4914eb2eff2a8c2ff6f1b 100644
index 8574cca2582d5eaf3720df1c42fda38957d18230..082ca9db7e925dfb36998135bea7be298a691b86 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1506,6 +1506,10 @@ public class CraftWorld implements World {
@@ -1507,6 +1507,10 @@ public class CraftWorld implements World {
if (Boat.class.isAssignableFrom(clazz)) {
entity = new net.minecraft.world.entity.vehicle.Boat(this.world, x, y, z);
entity.moveTo(x, y, z, yaw, pitch);

View File

@ -21,10 +21,10 @@ check is essentially the same as this.getHandle() == other.getHandle()
However, replaced it too to make it clearer of intent.
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index af8552f21f598f99151e59fe44df40f13caa3ead..b9089ba658d38397cf07245e31e6d40b3a2a5f2b 100644
index a2a7b6a62ea1292fce37581863bee931d1497223..e57fef24ee5159142ec4f05a9e76a34c6e153386 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -783,14 +783,15 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@@ -784,14 +784,15 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
return false;
}
final CraftEntity other = (CraftEntity) obj;

View File

@ -6,10 +6,10 @@ Subject: [PATCH] Expand Explosions API
Add Entity as a Source capability, and add more API choices, and on Location.
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index e744a793062acce339c4914eb2eff2a8c2ff6f1b..c3a57510cd17203c65c15de0544d5656eb7a0b7b 100644
index 082ca9db7e925dfb36998135bea7be298a691b86..20269c9084dd2a4f941e98e25c40bd3f3af43bcc 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -890,6 +890,12 @@ public class CraftWorld implements World {
@@ -891,6 +891,12 @@ public class CraftWorld implements World {
public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks, Entity source) {
return !this.world.explode(source == null ? null : ((CraftEntity) source).getHandle(), x, y, z, power, setFire, breakBlocks ? Explosion.BlockInteraction.BREAK : Explosion.BlockInteraction.NONE).wasCanceled;
}

View File

@ -111,17 +111,17 @@ index 06786fba1fef36e8fc3d0f5650160123f728a6d1..beea227855f0b978e655efc298024120
public CraftPillager(CraftServer server, net.minecraft.world.entity.monster.Pillager entity) {
super(server, entity);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java
index 4cd3dfd3466f384aab06dacd388e8053b045b046..b2d3244cca4d9d108159f3537d8a9aace3f8e77f 100644
index 7a73ada3d8b8085591308275ece4a9ce617314d3..3b19cd5a232f38d373359072925be12f6c075d4a 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java
@@ -6,7 +6,7 @@ import org.bukkit.entity.EntityType;
@@ -5,7 +5,7 @@ import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Skeleton;
import org.bukkit.entity.Skeleton.SkeletonType;
-public class CraftSkeleton extends CraftMonster implements Skeleton {
+public class CraftSkeleton extends CraftMonster implements Skeleton, com.destroystokyo.paper.entity.CraftRangedEntity<AbstractSkeleton> { // Paper
-public class CraftSkeleton extends CraftAbstractSkeleton implements Skeleton {
+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);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
index 6a82d567d96a42bfea0e38afb4e8de13eb3ad5a2..659e2959c5330e4764ea1edc7f8de9f464f9ff52 100644

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Implement World.getEntity(UUID) API
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index c3a57510cd17203c65c15de0544d5656eb7a0b7b..e819031a4176a54a06c5a09ee29eda4db4f6cc08 100644
index 20269c9084dd2a4f941e98e25c40bd3f3af43bcc..951445d5dba92ada70ce239098c702dd7b8ce0f1 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1296,6 +1296,15 @@ public class CraftWorld implements World {
@@ -1297,6 +1297,15 @@ public class CraftWorld implements World {
return list;
}

View File

@ -6,10 +6,10 @@ Subject: [PATCH] Make CraftWorld#loadChunk(int, int, false) load unconverted
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index e819031a4176a54a06c5a09ee29eda4db4f6cc08..43e47c345a0d2e00f13f0112d26d93b004009ac9 100644
index 951445d5dba92ada70ce239098c702dd7b8ce0f1..ad9a4d4a9363741cc47f142c24fa6f4858dd947f 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -506,7 +506,7 @@ public class CraftWorld implements World {
@@ -507,7 +507,7 @@ public class CraftWorld implements World {
@Override
public boolean loadChunk(int x, int z, boolean generate) {
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot

View File

@ -3678,10 +3678,10 @@ index 844d65612d9c4c19d02a2b0a5b90cd44de9f17c9..cfd4c38ca99b183f23716f82c972c14b
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 43e47c345a0d2e00f13f0112d26d93b004009ac9..b8565aa86b478adb6fca6d433637ddb342ce6dcb 100644
index ad9a4d4a9363741cc47f142c24fa6f4858dd947f..a19de8405de8ee29afc112556e4684b042c6f4ab 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -2424,6 +2424,34 @@ public class CraftWorld implements World {
@@ -2425,6 +2425,34 @@ public class CraftWorld implements World {
public DragonBattle getEnderDragonBattle() {
return (this.getHandle().dragonFight() == null) ? null : new CraftDragonBattle(this.getHandle().dragonFight());
}
@ -3717,7 +3717,7 @@ index 43e47c345a0d2e00f13f0112d26d93b004009ac9..b8565aa86b478adb6fca6d433637ddb3
// Spigot start
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index b9089ba658d38397cf07245e31e6d40b3a2a5f2b..c381ea321b0fb3498e3f101ee059ac7d42aa029a 100644
index e57fef24ee5159142ec4f05a9e76a34c6e153386..d0774636b151e8dbd778f2e2f2e3de154ff18494 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -13,6 +13,7 @@ import net.minecraft.nbt.CompoundTag;
@ -3728,7 +3728,7 @@ index b9089ba658d38397cf07245e31e6d40b3a2a5f2b..c381ea321b0fb3498e3f101ee059ac7d
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.AreaEffectCloud;
import net.minecraft.world.entity.Entity;
@@ -515,6 +516,28 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@@ -516,6 +517,28 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
this.entity.setYHeadRot(yaw);
}

View File

@ -18,10 +18,10 @@ index 8451baff82cb7ec7615ab50a409724897ccf4d95..32e8ae0d2a0f78af671a632c4d1be58a
float f = this.getBrightness();
BlockPos blockposition = new BlockPos(this.getX(), this.getEyeY(), this.getZ());
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index b8565aa86b478adb6fca6d433637ddb342ce6dcb..fda8858375a08e0aac15ca00751df5a34ed6a0f2 100644
index a19de8405de8ee29afc112556e4684b042c6f4ab..be4c05259f176e9ef5c25db2b1745df5ea4d5789 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -866,6 +866,13 @@ public class CraftWorld implements World {
@@ -867,6 +867,13 @@ public class CraftWorld implements World {
}
}

View File

@ -105,10 +105,10 @@ index 12a78685848b7fd945a472902d8200ea1d50b9ec..3aadcb472ab808ee981065ddfa86be6c
// Spigot Start
if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index c381ea321b0fb3498e3f101ee059ac7d42aa029a..33bc56eba4229d844e3af6ff4662d96450e929af 100644
index d0774636b151e8dbd778f2e2f2e3de154ff18494..98d3818d38f487fc7e1302ee4af9e4898efec809 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1163,5 +1163,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@@ -1164,5 +1164,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
public boolean fromMobSpawner() {
return getHandle().spawnedViaMobSpawner;
}

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Add Heightmap API
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index fda8858375a08e0aac15ca00751df5a34ed6a0f2..5f93589106bcf29eabd4544951fa3ad36e00c5a6 100644
index be4c05259f176e9ef5c25db2b1745df5ea4d5789..ea587597bfb205531c03eb0c0c9bde31ea6ab53b 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -341,6 +341,29 @@ public class CraftWorld implements World {
@@ -342,6 +342,29 @@ public class CraftWorld implements World {
return this.getHighestBlockYAt(x, z, org.bukkit.HeightMap.MOTION_BLOCKING);
}

View File

@ -9,10 +9,10 @@ waiting for the execution queue to get to our request; We can just query
the chunk status and get a response now, vs having to wait
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 5f93589106bcf29eabd4544951fa3ad36e00c5a6..a7eb8f69b49bb0229de9e5a4400a4424555ac1dd 100644
index ea587597bfb205531c03eb0c0c9bde31ea6ab53b..a112daf93daeab6d34416bc7c8a69acfc207c98b 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -412,13 +412,13 @@ public class CraftWorld implements World {
@@ -413,13 +413,13 @@ public class CraftWorld implements World {
@Override
public boolean isChunkLoaded(int x, int z) {

View File

@ -225,10 +225,10 @@ index 4185e6bcf9b2bb65b2a0fa5fcbeb5684615169a7..dbc29442f2b2ad3ea451910f4944e901
this.maxCount = i * i;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index a7eb8f69b49bb0229de9e5a4400a4424555ac1dd..30305736b7dc023ad5eb3a177914560b3fec64ee 100644
index a112daf93daeab6d34416bc7c8a69acfc207c98b..98b2d054b6436e3fdb8fadd03369a65cf4156843 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1974,15 +1974,21 @@ public class CraftWorld implements World {
@@ -1975,15 +1975,21 @@ public class CraftWorld implements World {
@Override
public void setKeepSpawnInMemory(boolean keepLoaded) {

View File

@ -49,14 +49,13 @@ index 0000000000000000000000000000000000000000..9a516520d975f52169e346adc4ec6d9d
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index ca03ed4b1581df2b7db272d6f330174a9d277153..0a9ed9992a2fc97472a06591a5d129a767ce21af 100644
index bf12cb6a1f991372206e462e46f2686decff11a6..75dd8cbadae9a2d18931dd49f49f8f1e14b50da5 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -749,4 +749,11 @@ public class CraftBlock implements Block {
AABB aabb = shape.bounds();
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);
@@ -764,4 +764,10 @@ public class CraftBlock implements Block {
VoxelShape shape = this.getNMS().getCollisionShape(world, position);
return new CraftVoxelShape(shape);
}
+
+ // Paper start
+ @Override
+ public com.destroystokyo.paper.block.BlockSoundGroup getSoundGroup() {

View File

@ -272,7 +272,7 @@ index 211ab6cffe78c61fcff12ef7ffba904c4cae57b2..1bee455235ece8aa299a2baeede027d2
}
+
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 30305736b7dc023ad5eb3a177914560b3fec64ee..4841591539fdd5a01f9ded0ee510991602c266a4 100644
index 98b2d054b6436e3fdb8fadd03369a65cf4156843..f9c58de7fa8b3c2ab5ac78cf0b366df69e0b40df 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -20,6 +20,7 @@ import java.util.Objects;
@ -283,7 +283,7 @@ index 30305736b7dc023ad5eb3a177914560b3fec64ee..4841591539fdd5a01f9ded0ee5109916
import java.util.function.Predicate;
import java.util.stream.Collectors;
import net.minecraft.core.BlockPos;
@@ -417,8 +418,22 @@ public class CraftWorld implements World {
@@ -418,8 +419,22 @@ public class CraftWorld implements World {
@Override
public boolean isChunkGenerated(int x, int z) {
@ -307,7 +307,7 @@ index 30305736b7dc023ad5eb3a177914560b3fec64ee..4841591539fdd5a01f9ded0ee5109916
} catch (IOException ex) {
throw new RuntimeException(ex);
}
@@ -529,20 +544,48 @@ public class CraftWorld implements World {
@@ -530,20 +545,48 @@ public class CraftWorld implements World {
@Override
public boolean loadChunk(int x, int z, boolean generate) {
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot

View File

@ -6,10 +6,10 @@ Subject: [PATCH] Fix spawning of hanging entities that are not ItemFrames and
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 4841591539fdd5a01f9ded0ee510991602c266a4..f1cbcdb1e409f8544125dde5f24bff5b07cb5082 100644
index f9c58de7fa8b3c2ab5ac78cf0b366df69e0b40df..053878ce00b77367b403a8c52f0d81f485022c59 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1881,7 +1881,12 @@ public class CraftWorld implements World {
@@ -1882,7 +1882,12 @@ public class CraftWorld implements World {
height = 9;
}

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Add effect to block break naturally
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 0a9ed9992a2fc97472a06591a5d129a767ce21af..ca95a6b1b156b37f839c6479733e5184691af66c 100644
index 75dd8cbadae9a2d18931dd49f49f8f1e14b50da5..64c304cab8c7c4c9c29f73465f99c11f224a72bd 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -632,6 +632,13 @@ public class CraftBlock implements Block {
@@ -635,6 +635,13 @@ public class CraftBlock implements Block {
@Override
public boolean breakNaturally(ItemStack item) {
@ -22,7 +22,7 @@ index 0a9ed9992a2fc97472a06591a5d129a767ce21af..ca95a6b1b156b37f839c6479733e5184
// Order matters here, need to drop before setting to air so skulls can get their data
net.minecraft.world.level.block.state.BlockState iblockdata = this.getNMS();
net.minecraft.world.level.block.Block block = iblockdata.getBlock();
@@ -641,6 +648,7 @@ public class CraftBlock implements Block {
@@ -644,6 +651,7 @@ public class CraftBlock implements Block {
// Modelled off EntityHuman#hasBlock
if (block != Blocks.AIR && (item == null || !iblockdata.requiresCorrectToolForDrops() || nmsItem.isCorrectToolForDrops(iblockdata))) {
net.minecraft.world.level.block.Block.dropResources(iblockdata, this.world.getMinecraftWorld(), position, this.world.getBlockEntity(position), null, nmsItem);

View File

@ -651,10 +651,10 @@ index 521f199e495f3bec232cc9ca36e51e0392afe737..922026da8c234427e0322443004d3c32
this.postProcessing[i].clear();
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index f1cbcdb1e409f8544125dde5f24bff5b07cb5082..1d22119b962840dff789a0619fd2188958f924d0 100644
index 053878ce00b77367b403a8c52f0d81f485022c59..b6134895d1b04d3ea7340e77f70efa23cff8b568 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -2540,10 +2540,39 @@ public class CraftWorld implements World {
@@ -2541,10 +2541,39 @@ public class CraftWorld implements World {
// Spigot start
@Override
public int getViewDistance() {

View File

@ -246,10 +246,10 @@ index 382a68c76e8946840de62f05483870689de80278..8523fbd66ed42cd5b959d57cab515fa4
if (optional.isPresent()) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 1d22119b962840dff789a0619fd2188958f924d0..1023a0d5d1699b28d380e017b386a9b3986f1250 100644
index b6134895d1b04d3ea7340e77f70efa23cff8b568..72c9ad9f75c20d6c1a6d54e2913e2f9918c11ffd 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -286,6 +286,7 @@ public class CraftWorld implements World {
@@ -287,6 +287,7 @@ public class CraftWorld implements World {
@Override
public int getTileEntityCount() {
@ -257,7 +257,7 @@ index 1d22119b962840dff789a0619fd2188958f924d0..1023a0d5d1699b28d380e017b386a9b3
// We don't use the full world tile entity list, so we must iterate chunks
Long2ObjectLinkedOpenHashMap<ChunkHolder> chunks = world.getChunkSource().chunkMap.visibleChunkMap;
int size = 0;
@@ -297,6 +298,7 @@ public class CraftWorld implements World {
@@ -298,6 +299,7 @@ public class CraftWorld implements World {
size += chunk.blockEntities.size();
}
return size;
@ -265,7 +265,7 @@ index 1d22119b962840dff789a0619fd2188958f924d0..1023a0d5d1699b28d380e017b386a9b3
}
@Override
@@ -306,6 +308,7 @@ public class CraftWorld implements World {
@@ -307,6 +309,7 @@ public class CraftWorld implements World {
@Override
public int getChunkCount() {
@ -273,7 +273,7 @@ index 1d22119b962840dff789a0619fd2188958f924d0..1023a0d5d1699b28d380e017b386a9b3
int ret = 0;
for (ChunkHolder chunkHolder : world.getChunkSource().chunkMap.visibleChunkMap.values()) {
@@ -314,7 +317,7 @@ public class CraftWorld implements World {
@@ -315,7 +318,7 @@ public class CraftWorld implements World {
}
}
@ -282,7 +282,7 @@ index 1d22119b962840dff789a0619fd2188958f924d0..1023a0d5d1699b28d380e017b386a9b3
}
@Override
@@ -441,6 +444,14 @@ public class CraftWorld implements World {
@@ -442,6 +445,14 @@ public class CraftWorld implements World {
@Override
public Chunk[] getLoadedChunks() {

View File

@ -87,13 +87,13 @@ index ddbc8cb712c50038922eded75dd6ca85fe851078..78271b400c79578d043b20a5389a37b1
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 087f31ac0cc7816b1cbeffc45be6927b174dee62..99ee9de92264381a064066bc22bb66b4b2852a2e 100644
index fa3a9d763f7072c68b126ce95fee191aab576e43..91ae80ee1020dc017faef7c8be8487132c547fe4 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -217,6 +217,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
private int maxBuildHeight;
@@ -249,6 +249,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
private String motd;
private int playerIdleTimeout;
public final long[] tickTimes; public long[] getTickTimes() { return tickTimes; } // Paper - OBFHELPER
public final long[] tickTimes;
+ // Paper start
+ public final TickTimes tickTimes5s = new TickTimes(100);
+ public final TickTimes tickTimes10s = new TickTimes(200);
@ -102,7 +102,7 @@ index 087f31ac0cc7816b1cbeffc45be6927b174dee62..99ee9de92264381a064066bc22bb66b4
@Nullable
private KeyPair keyPair;
@Nullable
@@ -1329,6 +1334,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1390,6 +1395,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.averageTickTime = this.averageTickTime * 0.8F + (float) l / 1000000.0F * 0.19999999F;
long i1 = Util.getNanos();
@ -115,11 +115,10 @@ index 087f31ac0cc7816b1cbeffc45be6927b174dee62..99ee9de92264381a064066bc22bb66b4
this.frameTimer.logFrameDuration(i1 - i);
this.profiler.pop();
org.spigotmc.WatchdogThread.tick(); // Spigot
@@ -2301,4 +2312,30 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public TextFilter createTextFilterForPlayer(ServerPlayer player) {
return null;
@@ -2461,4 +2472,29 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
};
}
}
+
+ // Paper start
+ public static class TickTimes {
+ private final long[] times;
@ -147,10 +146,10 @@ index 087f31ac0cc7816b1cbeffc45be6927b174dee62..99ee9de92264381a064066bc22bb66b4
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 3c0ba80bbba19f3725013e118cecdbac5612deec..4fa49b6bb26456d485f7f9193af560cb379e36f0 100644
index 9730c701b734eb3491bc1fa5d9bb81ddfefc910a..6eebbe2d7948a164f9562801b727768d199fa228 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2201,6 +2201,16 @@ public final class CraftServer implements Server {
@@ -2202,6 +2202,16 @@ public final class CraftServer implements Server {
net.minecraft.server.MinecraftServer.getServer().tps15.getAverage()
};
}

View File

@ -6,10 +6,10 @@ Subject: [PATCH] Expose MinecraftServer#isRunning
This allows for plugins to detect if the server is actually turning off in onDisable rather than just plugins reloading.
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 4fa49b6bb26456d485f7f9193af560cb379e36f0..3f35e93b42efd03ff1002f09962fe3da51fb4c3f 100644
index 6eebbe2d7948a164f9562801b727768d199fa228..3423de396e0fadfa29714f5fcac4b579a8ff0967 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2378,5 +2378,10 @@ public final class CraftServer implements Server {
@@ -2379,5 +2379,10 @@ public final class CraftServer implements Server {
public int getCurrentTick() {
return net.minecraft.server.MinecraftServer.currentTick;
}

View File

@ -0,0 +1,58 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Thu, 30 Apr 2020 16:56:54 +0200
Subject: [PATCH] Add Raw Byte ItemStack Serialization
Serializes using NBT which is safer for server data migrations than bukkits format.
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
index ad8d6a84e1a66e03ae15269e36bc787148f12396..88d5c7a0d7de2e896433d85fbd5425351f51b64d 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -378,6 +378,46 @@ public final class CraftMagicNumbers implements UnsafeValues {
public boolean isSupportedApiVersion(String apiVersion) {
return apiVersion != null && SUPPORTED_API.contains(apiVersion);
}
+
+ @Override
+ public byte[] serializeItem(ItemStack item) {
+ Preconditions.checkNotNull(item, "null cannot be serialized");
+ Preconditions.checkArgument(item.getType() != Material.AIR, "air cannot be serialized");
+
+ java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream();
+ CompoundTag compound = (item instanceof CraftItemStack ? ((CraftItemStack) item).getHandle() : CraftItemStack.asNMSCopy(item)).save(new CompoundTag());
+ compound.putInt("DataVersion", getDataVersion());
+ try {
+ net.minecraft.nbt.NbtIo.writeCompressed(
+ compound,
+ outputStream
+ );
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ return outputStream.toByteArray();
+ }
+
+ @Override
+ public ItemStack deserializeItem(byte[] data) {
+ Preconditions.checkNotNull(data, "null cannot be deserialized");
+ Preconditions.checkArgument(data.length > 0, "cannot deserialize nothing");
+
+ try {
+ CompoundTag compound = net.minecraft.nbt.NbtIo.readCompressed(
+ new java.io.ByteArrayInputStream(data)
+ );
+ int dataVersion = compound.getInt("DataVersion");
+
+ 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());
+ return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.of((CompoundTag) converted.getValue()));
+ } catch (IOException ex) {
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(ex);
+ throw new RuntimeException();
+ }
+ }
// Paper end
/**

View File

@ -10,25 +10,21 @@ Also optimise the stream.anyMatch statement to move to a bitset
where we can replace the call with a single bitwise operation.
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java
index 558dd72c47930f6993952467f83b5a54ead95d92..acc6306d659cd65a043d12cd42dcbaf55aaf5250 100644
index d92ddc8a4c0f5249b7ff4f97af1ea3db413b2983..8c2ec30a35e86f2b30863045b586a67e485c624b 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java
@@ -1,10 +1,12 @@
package net.minecraft.world.entity.ai.goal;
+import com.destroystokyo.paper.util.set.OptimizedSmallEnumSet; // Paper - remove streams from pathfindergoalselector
@@ -3,7 +3,8 @@ package net.minecraft.world.entity.ai.goal;
import java.util.EnumSet;
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); // 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();
@@ -28,16 +30,20 @@ public abstract class Goal {
public void tick() {}
@@ -25,8 +26,10 @@ public abstract class Goal {
}
public void setFlags(EnumSet<Goal.Flag> controls) {
- this.flags.clear();
@ -39,7 +35,8 @@ index 558dd72c47930f6993952467f83b5a54ead95d92..acc6306d659cd65a043d12cd42dcbaf5
+ // Paper end - remove streams from pathfindergoalselector
}
public String toString() {
@Override
@@ -34,8 +37,10 @@ public abstract class Goal {
return this.getClass().getSimpleName();
}
@ -53,42 +50,35 @@ index 558dd72c47930f6993952467f83b5a54ead95d92..acc6306d659cd65a043d12cd42dcbaf5
public static enum Flag {
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
index 9bd2ee05a0de6678ad8933a8ffbe0ae66bd073b4..5da2d780c17522e07c733a5e23b17ec760c7b342 100644
index f29ace7b6a27a602102d37d43a6dd0571f218dfe..bcb2c5480872eef6f21746003380f71b8d44f5c8 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
@@ -1,8 +1,10 @@
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;
@@ -28,7 +30,8 @@ public class GoalSelector {
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
@@ -28,10 +28,12 @@ public class GoalSelector {
private final Map<Goal.Flag, WrappedGoal> lockedFlags = new EnumMap<>(Goal.Flag.class);
private final Set<WrappedGoal> availableGoals = Sets.newLinkedHashSet();
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); // 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 int newGoalRate = 3;private int getTickRate() { return newGoalRate; } // Paper - OBFHELPER
private int curRate;private int getCurRate() { return curRate; } private void incRate() { this.curRate++; } // Paper TODO
+ 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 tickCount;
private int newGoalRate = 3;
private int curRate;
+ private static final Goal.Flag[] PATHFINDER_GOAL_TYPES = Goal.Flag.values(); // Paper - remove streams from pathfindergoalselector
@@ -56,35 +59,38 @@ public class GoalSelector {
public GoalSelector(Supplier<ProfilerFiller> profiler) {
this.profiler = profiler;
@@ -61,47 +63,95 @@ public class GoalSelector {
}
// Paper end
public void removeGoal(Goal goal) {
- this.availableGoals.stream().filter((pathfindergoalwrapped) -> {
- return pathfindergoalwrapped.getGoal() == goal;
- this.availableGoals.stream().filter((wrappedGoal) -> {
- return wrappedGoal.getGoal() == goal;
- }).filter(WrappedGoal::isRunning).forEach(WrappedGoal::stop);
- this.availableGoals.removeIf((pathfindergoalwrapped) -> {
- return pathfindergoalwrapped.getGoal() == goal;
- this.availableGoals.removeIf((wrappedGoal) -> {
- return wrappedGoal.getGoal() == goal;
- });
+ // 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();
+ if (goalWrapped.getGoal() != goal) {
+ continue;
@ -101,76 +91,57 @@ index 9bd2ee05a0de6678ad8933a8ffbe0ae66bd073b4..5da2d780c17522e07c733a5e23b17ec7
+ // 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() {
ProfilerFiller gameprofilerfiller = (ProfilerFiller) this.profiler.get();
gameprofilerfiller.push("goalCleanup");
- this.getRunningGoals().filter((pathfindergoalwrapped) -> {
- 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;
ProfilerFiller profilerFiller = this.profiler.get();
profilerFiller.push("goalCleanup");
- this.getRunningGoals().filter((wrappedGoal) -> {
- return !wrappedGoal.isRunning() || wrappedGoal.getFlags().stream().anyMatch(this.disabledFlags::contains) || !wrappedGoal.canContinueToUse();
- }).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()) {
+ continue;
+ }
+ wrappedGoal.stop();
+ }
+ // Paper end - remove streams from pathfindergoalselector
this.lockedFlags.forEach((pathfindergoal_type, pathfindergoalwrapped) -> {
if (!pathfindergoalwrapped.isRunning()) {
this.lockedFlags.remove(pathfindergoal_type);
@@ -93,30 +99,58 @@ public class GoalSelector {
+ this.lockedFlags.forEach((pathfindergoal_type, pathfindergoalwrapped) -> {
+ if (!pathfindergoalwrapped.isRunning()) {
+ this.lockedFlags.remove(pathfindergoal_type);
}
});
gameprofilerfiller.pop();
gameprofilerfiller.push("goalUpdate");
- this.availableGoals.stream().filter((pathfindergoalwrapped) -> {
- return !pathfindergoalwrapped.isRunning();
- }).filter((pathfindergoalwrapped) -> {
- Stream stream = pathfindergoalwrapped.getFlags().stream();
- EnumSet enumset = this.disabledFlags;
-
- this.disabledFlags.getClass();
- 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);
profilerFiller.pop();
profilerFiller.push("goalUpdate");
- this.availableGoals.stream().filter((wrappedGoal) -> {
- return !wrappedGoal.isRunning();
- }).filter((wrappedGoal) -> {
- return wrappedGoal.getFlags().stream().noneMatch(this.disabledFlags::contains);
- }).filter((wrappedGoal) -> {
- return wrappedGoal.getFlags().stream().allMatch((flag) -> {
- return this.lockedFlags.getOrDefault(flag, NO_GOAL).canBeReplacedBy(wrappedGoal);
- });
- }).filter(WrappedGoal::canUse).forEach((pathfindergoalwrapped) -> {
- pathfindergoalwrapped.getFlags().forEach((pathfindergoal_type) -> {
- WrappedGoal pathfindergoalwrapped1 = (WrappedGoal) this.lockedFlags.getOrDefault(pathfindergoal_type, GoalSelector.NO_GOAL);
-
- pathfindergoalwrapped1.stop();
- this.lockedFlags.put(pathfindergoal_type, pathfindergoalwrapped);
- }).filter(WrappedGoal::canUse).forEach((wrappedGoal) -> {
- wrappedGoal.getFlags().forEach((flag) -> {
- WrappedGoal wrappedGoal2 = this.lockedFlags.getOrDefault(flag, NO_GOAL);
- wrappedGoal2.stop();
- this.lockedFlags.put(flag, wrappedGoal);
- });
- pathfindergoalwrapped.start();
- });
+
+ // 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();
+ if (wrappedGoal.isRunning()) {
+ 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)) {
+ continue;
@ -201,25 +172,25 @@ index 9bd2ee05a0de6678ad8933a8ffbe0ae66bd073b4..5da2d780c17522e07c733a5e23b17ec7
+ wrapped.stop();
+ this.lockedFlags.put(type, wrappedGoal);
+ }
+
+ wrappedGoal.start();
wrappedGoal.start();
- });
+ }
+ // Paper end - remove streams from pathfindergoalselector
gameprofilerfiller.pop();
gameprofilerfiller.push("goalTick");
profilerFiller.pop();
profilerFiller.push("goalTick");
- this.getRunningGoals().forEach(WrappedGoal::tick);
+ // 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();
+ if (wrappedGoal.isRunning()) {
+ wrappedGoal.tick();
+ }
+ }
+ // Paper end - remove streams from pathfindergoalselector
gameprofilerfiller.pop();
profilerFiller.pop();
}
@@ -125,11 +159,11 @@ public class GoalSelector {
@@ -118,11 +168,11 @@ public class GoalSelector {
}
public void disableControlFlag(Goal.Flag control) {
@ -234,10 +205,10 @@ index 9bd2ee05a0de6678ad8933a8ffbe0ae66bd073b4..5da2d780c17522e07c733a5e23b17ec7
public void setControlFlag(Goal.Flag control, boolean enabled) {
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java
index 81b4618a7979ee8dd25e1749c084de9262318ef4..984146b2b6eb3e498433b1c4971397848166d9c9 100644
index 1e915b999f4261fb27846a0e559ea22e4b09b4db..037cc5d2b41161e040fc9b264a0dd04827c29681 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/WrappedGoal.java
@@ -59,9 +59,10 @@ public class WrappedGoal extends Goal {
@@ -58,9 +58,10 @@ public class WrappedGoal extends Goal {
this.goal.setFlags(controls);
}
@ -250,4 +221,4 @@ index 81b4618a7979ee8dd25e1749c084de9262318ef4..984146b2b6eb3e498433b1c497139784
+ // Paper end - remove streams from pathfindergoalselector
}
public boolean isRunning() { return this.isRunning(); } // Paper - OBFHELPER
public boolean isRunning() {

View File

@ -5,7 +5,7 @@ Subject: [PATCH] Async command map building
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index 44f2e8a3741afc0e3c3bca3b0864e37ecf83e5d4..8154d9327c5411bbfea3bfa4d99d57feab764664 100644
index 7ca6a1a3f10cb19d759f6d4dc9d5458ac0fc05d3..13e358e0eac3bfd426d924b6f745e001df76c64a 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -29,6 +29,7 @@ import net.minecraft.network.chat.MutableComponent;
@ -16,7 +16,7 @@ index 44f2e8a3741afc0e3c3bca3b0864e37ecf83e5d4..8154d9327c5411bbfea3bfa4d99d57fe
import net.minecraft.server.commands.AdvancementCommands;
import net.minecraft.server.commands.AttributeCommand;
import net.minecraft.server.commands.BanIpCommands;
@@ -328,25 +329,40 @@ public class Commands {
@@ -335,25 +336,40 @@ public class Commands {
if ( org.spigotmc.SpigotConfig.tabComplete < 0 ) return; // Spigot
// CraftBukkit start
// Register Vanilla commands into builtRoot as before
@ -61,7 +61,7 @@ index 44f2e8a3741afc0e3c3bca3b0864e37ecf83e5d4..8154d9327c5411bbfea3bfa4d99d57fe
event.getPlayer().getServer().getPluginManager().callEvent(event);
// Remove labels that were removed during the event
@@ -356,7 +372,7 @@ public class Commands {
@@ -363,7 +379,7 @@ public class Commands {
}
}
// CraftBukkit end

View File

@ -41,7 +41,7 @@ This also moves all plugins who register "delayed init" tasks to occur just befo
are properly accounted for and wont trip watchdog on init.
diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java
index 0b9e689d57705965721b5c55bc45d36657f360e4..dee00aac05f1acf050f05d4db557a08dd0f301c8 100644
index e3b74dbdf8e14219a56fab939f3174e0c2f66de6..218f5bafeed8551b55b91c7fccaf6935c8b631ca 100644
--- a/src/main/java/com/destroystokyo/paper/Metrics.java
+++ b/src/main/java/com/destroystokyo/paper/Metrics.java
@@ -92,7 +92,12 @@ public class Metrics {
@ -59,10 +59,10 @@ index 0b9e689d57705965721b5c55bc45d36657f360e4..dee00aac05f1acf050f05d4db557a08d
// Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution of requests on the
// bStats backend. To circumvent this problem, we introduce some randomness into the initial and second delay.
diff --git a/src/main/java/net/minecraft/CrashReport.java b/src/main/java/net/minecraft/CrashReport.java
index 4008fbe506e74f2c463dc7b12f5dd0f3b6fc342d..766ab2fe536a2acccaec28e922ccf8993b0790dc 100644
index bda7137b3435c9b7610be258cefb6b4ac2c1d47a..09f56e49383d3f5413ad4c28f3a7664e4d9570bd 100644
--- a/src/main/java/net/minecraft/CrashReport.java
+++ b/src/main/java/net/minecraft/CrashReport.java
@@ -257,6 +257,7 @@ public class CrashReport {
@@ -231,6 +231,7 @@ public class CrashReport {
}
public static CrashReport forThrowable(Throwable cause, String title) {
@ -70,32 +70,20 @@ index 4008fbe506e74f2c463dc7b12f5dd0f3b6fc342d..766ab2fe536a2acccaec28e922ccf899
while (cause instanceof CompletionException && cause.getCause() != null) {
cause = cause.getCause();
}
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
index c2f747226f10479c826849af898538610a2dd659..83f9f97586f8c0e9d228923e4fec6f121a6702e2 100644
--- a/src/main/java/net/minecraft/Util.java
+++ b/src/main/java/net/minecraft/Util.java
@@ -129,6 +129,7 @@ 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
index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a98beafad 100644
index 91ae80ee1020dc017faef7c8be8487132c547fe4..11fd6d24ed0612e4df1a0493907178fb9c455d1c 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -269,7 +269,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -301,7 +301,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
public int autosavePeriod;
public boolean serverAutoSave = false; // Paper
public Commands vanillaCommandDispatcher;
- private boolean forceTicks;
+ public boolean forceTicks; // Paper
// CraftBukkit end
// Spigot start
public static final int TPS = 20;
@@ -279,6 +279,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -311,6 +311,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public final SlackActivityAccountant slackActivityAccountant = new SlackActivityAccountant();
// Spigot end
@ -105,17 +93,17 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
public static <S extends MinecraftServer> S spin(Function<Thread, S> serverFactory) {
AtomicReference<S> atomicreference = new AtomicReference();
Thread thread = new Thread(() -> {
@@ -851,6 +854,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -908,6 +911,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// CraftBukkit start
private boolean hasStopped = false;
+ public volatile boolean hasFullyShutdown = false; // Paper
private final Object stopLock = new Object();
public final boolean hasStopped() {
synchronized (stopLock) {
@@ -865,6 +869,23 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
if (hasStopped) return;
hasStopped = true;
synchronized (this.stopLock) {
@@ -922,6 +926,19 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
if (this.hasStopped) return;
this.hasStopped = true;
}
+ // Paper start - kill main thread, and kill it hard
+ shutdownThread = Thread.currentThread();
@ -128,24 +116,20 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
+ Thread.sleep(1);
+ } 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
// CraftBukkit end
MinecraftServer.LOGGER.info("Stopping server");
MinecraftTimings.stopServer(); // Paper
@@ -930,7 +951,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.getProfileCache().b(false); // Paper
@@ -987,7 +1004,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.getProfileCache().save(false); // Paper
}
// Spigot end
+ // Paper start - move final shutdown items here
+ LOGGER.info("Flushing Chunk IO");
com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.close(true, true); // Paper
+ LOGGER.info("Closing Thread Pool");
+ Util.shutdownServerThreadPool(); // Paper
+ Util.shutdownExecutors(); // Paper
+ LOGGER.info("Closing Server");
+ try {
+ net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Use TerminalConsoleAppender
@ -156,7 +140,7 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
}
public String getLocalIp() {
@@ -1023,6 +1055,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1080,6 +1108,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
protected void runServer() {
try {
@ -164,7 +148,7 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
if (this.initServer()) {
this.nextTickTime = Util.getMillis();
this.status.setDescription(new TextComponent(this.motd));
@@ -1030,6 +1063,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1087,6 +1116,18 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.updateStatusIcon(this.status);
// Spigot start
@ -183,7 +167,7 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
org.spigotmc.WatchdogThread.hasStarted = true; // Paper
Arrays.fill( recentTps, 20 );
long start = System.nanoTime(), curTime, tickSection = start; // Paper - Further improve server tick loop
@@ -1085,6 +1130,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1143,6 +1184,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.onServerCrash((CrashReport) null);
}
} catch (Throwable throwable) {
@ -196,7 +180,7 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
MinecraftServer.LOGGER.error("Encountered an unexpected exception", throwable);
// Spigot Start
if ( throwable.getCause() != null )
@@ -1116,14 +1167,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1178,14 +1225,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
} catch (Throwable throwable1) {
MinecraftServer.LOGGER.error("Exception stopping the server", throwable1);
} finally {
@ -214,7 +198,7 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
}
}
@@ -1179,6 +1230,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1241,6 +1288,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@Override
public TickTask wrapRunnable(Runnable runnable) {
@ -227,7 +211,7 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
return new TickTask(this.tickCount, runnable);
}
@@ -1421,6 +1478,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1482,6 +1535,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
try {
crashreport = CrashReport.forThrowable(throwable, "Exception ticking world");
} catch (Throwable t) {
@ -235,9 +219,9 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
throw new RuntimeException("Error generating crash report", t);
}
// Spigot End
@@ -1878,7 +1936,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1959,7 +2013,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.packRepository.setSelected(datapacks);
this.worldData.setDataPackConfig(getSelectedPacks(this.packRepository));
this.worldData.setDataPackConfig(MinecraftServer.getSelectedPacks(this.packRepository));
datapackresources.updateGlobals();
- this.getPlayerList().saveAll();
+ if (Thread.currentThread() != this.serverThread) return; // Paper
@ -246,10 +230,10 @@ index 99ee9de92264381a064066bc22bb66b4b2852a2e..e5ad635a480d32e7a10ee92c65cfc18a
this.functionManager.replaceLibrary(this.resources.getFunctionLibrary());
this.structureManager.onResourceManagerReload(this.resources.getResourceManager());
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index f8ddc0aa98874c7879a51e76d1a629cbdaf58812..6477ba1f31d977f8199fb4c7532938920b385ae7 100644
index 0511f1921193b78cbf4d8426136bf1f79746f955..e5f7f043cbdb28d85b8aa0eea7cbaeb584e5fb85 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -276,7 +276,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -283,7 +283,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
long j = Util.getNanos() - i;
String s = String.format(Locale.ROOT, "%.3fs", (double) j / 1.0E9D);
@ -258,7 +242,7 @@ index f8ddc0aa98874c7879a51e76d1a629cbdaf58812..6477ba1f31d977f8199fb4c753293892
if (dedicatedserverproperties.announcePlayerAchievements != null) {
((GameRules.BooleanValue) this.getGameRules().getRule(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)).set(dedicatedserverproperties.announcePlayerAchievements, (MinecraftServer) this);
}
@@ -404,7 +404,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -446,7 +446,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
//this.remoteStatusListener.b(); // Paper - don't wait for remote connections
}
@ -268,7 +252,7 @@ index f8ddc0aa98874c7879a51e76d1a629cbdaf58812..6477ba1f31d977f8199fb4c753293892
}
@Override
@@ -737,7 +738,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -779,7 +780,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@Override
public void stopServer() {
super.stopServer();
@ -278,10 +262,10 @@ index f8ddc0aa98874c7879a51e76d1a629cbdaf58812..6477ba1f31d977f8199fb4c753293892
@Override
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 99eee56d6e66b79dd48ecbd1eeebc08174003f4a..49728aab7512ea8486d277d34e80d3c6a4727aac 100644
index c304c57a572b7e154362b39065ab8cb30a7e112e..c82345c74e0e6246f304283c2e06e2d1fcfe53ca 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -534,6 +534,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -585,6 +585,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
MutableBoolean mutableboolean = new MutableBoolean();
do {
@ -289,25 +273,12 @@ index 99eee56d6e66b79dd48ecbd1eeebc08174003f4a..49728aab7512ea8486d277d34e80d3c6
mutableboolean.setFalse();
list.stream().map((playerchunk) -> {
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 b9978d296b83e73d3395b8254c0e8ccd9b36d0fa..bf4e50cd1d561456c033cda2d5c5487c5e3fe1eb 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -171,7 +171,7 @@ 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
index 30666fca36b683158ff60302684b5093f5536e24..984ac19dcab446531c816e365c7c149e2c49d567 100644
index 18485689bcbf7818c3ca5b82086acef51888603b..3431d28fd69c634ee0a941796308b88bb51bdaac 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -503,7 +503,7 @@ public abstract class PlayerList {
cserver.getPluginManager().callEvent(playerQuitEvent);
@@ -505,7 +505,7 @@ public abstract class PlayerList {
this.cserver.getPluginManager().callEvent(playerQuitEvent);
entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());
- entityplayer.doTick(); // SPIGOT-924
@ -316,30 +287,22 @@ index 30666fca36b683158ff60302684b5093f5536e24..984ac19dcab446531c816e365c7c149e
// Paper start - Remove from collideRule team if needed
diff --git a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java
index a5ce61be7d6e85ac289730d9671e66a7190529f9..add18ba4833686ff51fbb280b0a5759f142b3f91 100644
index 0ef3c4982df88a7991a56d983ac733daa8adc507..cdd797c6fc7507a0e6376f7d9c521be8f1d6decc 100644
--- a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java
+++ b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java
@@ -135,6 +135,7 @@ public abstract class BlockableEventLoop<R extends Runnable> implements Processo
@@ -148,6 +148,7 @@ public abstract class BlockableEventLoop<R extends Runnable> implements Profiler
try {
task.run();
} catch (Exception exception) {
+ if (exception.getCause() instanceof ThreadDeath) throw exception; // Paper
BlockableEventLoop.LOGGER.fatal("Error executing task on {}", this.name(), exception);
} catch (Exception var3) {
+ if (var3.getCause() instanceof ThreadDeath) throw var3; // Paper
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
index 632f32405053fbcff2fd26fa99f98c6add9f9dc7..5860e7866724abd35bde2a5710d9c92799e5de67 100644
index 5fccec12c0325dd9873905c5c3559128c3b4d9ad..03271675b4997588bd8f6774856aef25cdd4fa05 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -858,6 +858,7 @@ 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);
@@ -932,6 +933,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
@@ -836,6 +836,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
try {
tickConsumer.accept(entity);
} catch (Throwable throwable) {
@ -347,11 +310,23 @@ index 632f32405053fbcff2fd26fa99f98c6add9f9dc7..5860e7866724abd35bde2a5710d9c927
// Paper start - Prevent tile entity and entity crashes
String msg = "Entity threw exception at " + entity.level.getWorld().getName() + ":" + entity.getX() + "," + entity.getY() + "," + entity.getZ();
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 59a77541bbda880ae8f84e3535a2b6112caa78fb..a63dc77db41dab79f03ef7384da55c1cdeca5d98 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -1320,6 +1320,7 @@ 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
index 3f35e93b42efd03ff1002f09962fe3da51fb4c3f..43c37e660a8a7f9d326ad38e66f9aa7c53c7b87c 100644
index 3423de396e0fadfa29714f5fcac4b579a8ff0967..4c0b94a56fab161fca92b594f55e1c846524d5e8 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1839,7 +1839,7 @@ public final class CraftServer implements Server {
@@ -1840,7 +1840,7 @@ public final class CraftServer implements Server {
@Override
public boolean isPrimaryThread() {
@ -361,7 +336,7 @@ index 3f35e93b42efd03ff1002f09962fe3da51fb4c3f..43c37e660a8a7f9d326ad38e66f9aa7c
// Paper start
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
index c519ceca6f7788ca7c5d74ad1001dbc09f62681c..c288b89bf5a22269823ba1d18af217032d7c6a36 100644
index fd48cfe3dfaf7c867becfbf90246af2f33a74612..2904cbda94a8fb986d94022c11061f98938237dd 100644
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -12,6 +12,8 @@ import java.util.logging.Level;
@ -410,7 +385,7 @@ index c519ceca6f7788ca7c5d74ad1001dbc09f62681c..c288b89bf5a22269823ba1d18af21703
try {
options = parser.parse(args);
} catch (joptsimple.OptionException ex) {
@@ -251,8 +283,64 @@ public class Main {
@@ -255,8 +287,64 @@ public class Main {
} catch (Throwable t) {
t.printStackTrace();
}
@ -476,7 +451,7 @@ index c519ceca6f7788ca7c5d74ad1001dbc09f62681c..c288b89bf5a22269823ba1d18af21703
private static List<String> asList(String... params) {
return Arrays.asList(params);
diff --git a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
index 449e99d1b673870ed6892f6ab2c715a2db35c35d..c7ed6e0f8a989cec97700df2b15198c9c481c549 100644
index b4a19d80bbf71591f25729fd0e98590350cb31d0..d752720f2f234b9dbd2117333fee1bfad663ec02 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
@@ -12,12 +12,27 @@ public class ServerShutdownThread extends Thread {
@ -496,7 +471,7 @@ index 449e99d1b673870ed6892f6ab2c715a2db35c35d..c7ed6e0f8a989cec97700df2b15198c9
org.spigotmc.AsyncCatcher.enabled = false; // Spigot
org.spigotmc.AsyncCatcher.shuttingDown = true; // Paper
+ server.forceTicks = true;
server.close();
this.server.close();
+ while (!server.hasFullyShutdown) Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
@ -509,7 +484,7 @@ index 449e99d1b673870ed6892f6ab2c715a2db35c35d..c7ed6e0f8a989cec97700df2b15198c9
}
}
diff --git a/src/main/java/org/spigotmc/RestartCommand.java b/src/main/java/org/spigotmc/RestartCommand.java
index 6dab105cd7cc4340c031c395c0346d4731355d79..6498dc4c6630bfef1a52edf74d8574e5e4876720 100644
index a142a56a920e153ed84c08cece993f10d76f7793..92d97a5810a379b427a99b4c63fb9844d823a84f 100644
--- a/src/main/java/org/spigotmc/RestartCommand.java
+++ b/src/main/java/org/spigotmc/RestartCommand.java
@@ -139,7 +139,7 @@ public class RestartCommand extends Command
@ -522,10 +497,10 @@ index 6dab105cd7cc4340c031c395c0346d4731355d79..6498dc4c6630bfef1a52edf74d8574e5
String[] split = restartScript.split( " " );
if ( split.length > 0 && new File( split[0] ).isFile() )
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
index 33a66322d253c7562ae5acbdbc6cc87f7d72a9af..26c9adf7af4328ce2d8e08568019c5b438e28b05 100644
index 1ffb208094f521883ef0e23baf5fb29380b14273..4d271cae88c16ed2419f896c728fdff612540500 100644
--- a/src/main/java/org/spigotmc/WatchdogThread.java
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
@@ -13,6 +13,7 @@ import org.bukkit.Bukkit;
@@ -12,6 +12,7 @@ import org.bukkit.Bukkit;
public class WatchdogThread extends Thread
{
@ -533,21 +508,21 @@ index 33a66322d253c7562ae5acbdbc6cc87f7d72a9af..26c9adf7af4328ce2d8e08568019c5b4
private static WatchdogThread instance;
private long timeoutTime;
private boolean restart;
@@ -41,6 +42,7 @@ public class WatchdogThread extends Thread
@@ -40,6 +41,7 @@ public class WatchdogThread extends Thread
{
if ( instance == null )
if ( WatchdogThread.instance == null )
{
+ if (timeoutTime <= 0) timeoutTime = 300; // Paper
instance = new WatchdogThread( timeoutTime * 1000L, restart );
instance.start();
WatchdogThread.instance = new WatchdogThread( timeoutTime * 1000L, restart );
WatchdogThread.instance.start();
} else
@@ -71,12 +73,13 @@ public class WatchdogThread extends Thread
// Paper start
Logger log = Bukkit.getServer().getLogger();
long currentTime = monotonicMillis();
- if ( lastTick != 0 && timeoutTime > 0 && currentTime > lastTick + earlyWarningEvery && !Boolean.getBoolean("disable.watchdog") )
long currentTime = WatchdogThread.monotonicMillis();
- 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();
+ 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 || (!server.isRunning() && !server.hasStopped() && currentTime > lastTick + 1000);
@ -561,17 +536,17 @@ index 33a66322d253c7562ae5acbdbc6cc87f7d72a9af..26c9adf7af4328ce2d8e08568019c5b4
@@ -118,7 +121,7 @@ public class WatchdogThread extends Thread
log.log( Level.SEVERE, "------------------------------" );
log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
ChunkTaskManager.dumpAllChunkLoadInfo(); // Paper
- dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
+ dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( server.serverThread.getId(), Integer.MAX_VALUE ), log );
com.destroystokyo.paper.io.chunk.ChunkTaskManager.dumpAllChunkLoadInfo(); // Paper
- WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
+ WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( server.serverThread.getId(), Integer.MAX_VALUE ), log );
log.log( Level.SEVERE, "------------------------------" );
//
// Paper start - Only print full dump on long timeouts
@@ -139,9 +142,25 @@ public class WatchdogThread extends Thread
@@ -138,9 +141,25 @@ public class WatchdogThread extends Thread
if ( isLongTimeout )
{
- if ( restart && !MinecraftServer.getServer().hasStopped() )
- if ( this.restart && !MinecraftServer.getServer().hasStopped() )
+ if ( !server.hasStopped() )
{
- RestartCommand.restart();

View File

@ -7,27 +7,10 @@ Prevents pathfinding from spamming failures for things such as
arrow attacks.
diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
index a362506f38e8d30543b6cd6d215db561290dac76..c501e42b6fef4af065807182dc5b4c444e74e310 100644
index 69edca1ef95c37b11fe3f793e6a8f8a674bd7f6f..3f4d7552e7f219aec043f0cc06a816758e5a3f66 100644
--- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
+++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
@@ -11,6 +11,7 @@ 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;
@@ -32,7 +33,7 @@ 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;
@@ -184,10 +185,30 @@ public abstract class PathNavigation {
@@ -190,9 +190,29 @@ public abstract class PathNavigation {
return this.moveTo(this.createPath(x, y, z, 1), speed);
}
@ -38,21 +21,20 @@ index a362506f38e8d30543b6cd6d215db561290dac76..c501e42b6fef4af065807182dc5b4c44
+
public boolean moveTo(Entity entity, double speed) {
+ // 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;
+ }
+ // Paper end
Path pathentity = this.createPath(entity, 1);
- return pathentity != null && this.moveTo(pathentity, speed);
Path path = this.createPath(entity, 1);
- return path != null && this.moveTo(path, speed);
+ // Paper start - Pathfinding optimizations
+ if (pathentity != null && this.moveTo(pathentity, speed)) {
+ if (path != null && this.moveTo(path, speed)) {
+ this.lastFailure = 0;
+ this.pathfindFailures = 0;
+ return true;
+ } else {
+ this.pathfindFailures++;
+ this.lastFailure = MinecraftServer.currentTick;
+ this.lastFailure = net.minecraft.server.MinecraftServer.currentTick;
+ return false;
+ }
+ // Paper end

View File

@ -7,7 +7,7 @@ In order to get chunk values, we shouldn't need to create
an optional each time.
diff --git a/src/main/java/com/mojang/datafixers/util/Either.java b/src/main/java/com/mojang/datafixers/util/Either.java
index fc8dbdf43833d76d8dc5f4e92575ca2965afa93a..ab71cdb3a8c2bec036ece630a0e0f088653e928f 100644
index a90adac7bd7ebd423f480e9ae0f44cb9d521fa4f..3f65fe71024928e35111fc6719a290aab9a6859e 100644
--- a/src/main/java/com/mojang/datafixers/util/Either.java
+++ b/src/main/java/com/mojang/datafixers/util/Either.java
@@ -22,7 +22,7 @@ public abstract class Either<L, R> implements App<Either.Mu<R>, L> {

View File

@ -0,0 +1,46 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <spottedleaf@spottedleaf.dev>
Date: Mon, 6 Apr 2020 18:10:43 -0700
Subject: [PATCH] Remove streams from PairedQueue
We shouldn't be doing stream calls just to see if the queue is
empty. This creates loads of garbage thanks to how often it's called.
diff --git a/src/main/java/net/minecraft/util/thread/StrictQueue.java b/src/main/java/net/minecraft/util/thread/StrictQueue.java
index 66591e23bc9e0df968fb6b291a3ad3773debdf29..c4a20df21e1fe5556fddac64b52d542579758e2c 100644
--- a/src/main/java/net/minecraft/util/thread/StrictQueue.java
+++ b/src/main/java/net/minecraft/util/thread/StrictQueue.java
@@ -22,9 +22,12 @@ public interface StrictQueue<T, F> {
private final List<Queue<Runnable>> queueList;
public FixedPriorityQueue(int priorityCount) {
- this.queueList = IntStream.range(0, priorityCount).mapToObj((i) -> {
- return Queues.newConcurrentLinkedQueue();
- }).collect(Collectors.toList());
+ // Paper start - remove streams
+ this.queueList = new java.util.ArrayList<>(priorityCount); // queues
+ for (int j = 0; j < priorityCount; ++j) {
+ this.queueList.add(Queues.newConcurrentLinkedQueue());
+ }
+ // Paper end - remove streams
}
@Nullable
@@ -49,7 +52,16 @@ public interface StrictQueue<T, F> {
@Override
public boolean isEmpty() {
- return this.queueList.stream().allMatch(Collection::isEmpty);
+ // Paper start - remove streams
+ // why are we doing streams every time we might want to execute a task?
+ for (int i = 0, len = this.queueList.size(); i < len; ++i) {
+ Queue<Runnable> queue = this.queueList.get(i);
+ if (!queue.isEmpty()) {
+ return false;
+ }
+ }
+ return true;
+ // Paper end - remove streams
}
@Override

View File

@ -8,45 +8,36 @@ is important because we clone chunk data after reading it for safety.
So, reduce the impact of the clone on GC.
diff --git a/src/main/java/net/minecraft/nbt/CompoundTag.java b/src/main/java/net/minecraft/nbt/CompoundTag.java
index a91bf94ed9f2f353a685194fc91c4b101ccc1232..c856ca720a9329a94bb07eaa3060c034f95718b3 100644
index 750df4ab2fbfdcf759f4d3451340e66b6764391d..1aa3af8c7714b2c850fb4264c863db8e639e6284 100644
--- a/src/main/java/net/minecraft/nbt/CompoundTag.java
+++ b/src/main/java/net/minecraft/nbt/CompoundTag.java
@@ -26,6 +26,7 @@ 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;
@@ -47,7 +48,7 @@ public class CompoundTag implements Tag {
@@ -34,7 +34,7 @@ public class CompoundTag implements Tag {
if (i > 512) {
throw new RuntimeException("Tried to read NBT tag with too high complexity, depth > 512");
} else {
- HashMap hashmap = Maps.newHashMap();
+ Object2ObjectOpenHashMap<String, Tag> hashmap = new Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - reduce memory footprint of NBTTagCompound
- Map<String, Tag> map = Maps.newHashMap();
+ 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;
@@ -83,7 +84,7 @@ public class CompoundTag implements Tag {
byte b;
while((b = CompoundTag.readNamedTagType(dataInput, nbtAccounter)) != 0) {
@@ -67,7 +67,7 @@ public class CompoundTag implements Tag {
}
public CompoundTag() {
- 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
@@ -417,9 +418,17 @@ public class CompoundTag implements Tag {
@@ -374,8 +374,16 @@ public class CompoundTag implements Tag {
@Override
public CompoundTag 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);
+ 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()) {
+ Map.Entry<String, Tag> entry = iterator.next();
+ ret.put(entry.getKey(), entry.getValue().copy());
@ -56,4 +47,4 @@ index a91bf94ed9f2f353a685194fc91c4b101ccc1232..c856ca720a9329a94bb07eaa3060c034
+ // Paper end - reduce memory footprint of NBTTagCompound
}
public boolean equals(Object object) {
@Override

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Prevent opening inventories when frozen
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 162b1a8c6ab57aafa4f6deefc842755a8e14208e..efacfcaab444270b985f3a7fe0ef97e33c18a9de 100644
index bfa91166c18110877f751a5325e59623a05325d0..42c2862530cff79a9b09850faccb683df1f2a5c8 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -557,7 +557,7 @@ public class ServerPlayer extends Player implements ContainerListener {
@@ -608,7 +608,7 @@ public class ServerPlayer extends Player {
containerUpdateDelay = level.paperConfig.containerUpdateTickRate;
}
// Paper end
@ -17,43 +17,34 @@ index 162b1a8c6ab57aafa4f6deefc842755a8e14208e..efacfcaab444270b985f3a7fe0ef97e3
this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper
this.containerMenu = this.inventoryMenu;
}
@@ -1404,7 +1404,7 @@ public class ServerPlayer extends Player implements ContainerListener {
@@ -1449,7 +1449,7 @@ public class ServerPlayer extends Player {
} else {
// CraftBukkit start
this.containerMenu = container;
- 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
// CraftBukkit end
container.addSlotListener(this);
this.initMenu(container);
return OptionalInt.of(this.containerCounter);
@@ -2206,7 +2206,7 @@ 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
index a73c6ddd6bf66cc21ae5b25daacdece8cbfeeeac..ae6faa331fcbefd99ee1cd92c88926d767fc50ee 100644
index 43cee8b0b2b94d6db6303a1631731ed515eb806d..31b62dc1ee06b254c398cbfe157283fb199ef0fe 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
@@ -323,7 +323,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
@@ -322,7 +322,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
if (adventure$title == null) adventure$title = io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(container.getBukkitView().getTitle()); // Paper
//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
+ if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper
getHandle().containerMenu = container;
getHandle().containerMenu.addSlotListener(player);
player.containerMenu = container;
player.initMenu(container);
}
@@ -397,7 +397,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
@@ -396,7 +396,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
net.kyori.adventure.text.Component adventure$title = inventory.title(); // Paper
if (adventure$title == null) adventure$title = io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.deserialize(inventory.getTitle()); // Paper
//player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment
- 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.addSlotListener(player);
player.initMenu(container);
}

View File

@ -6,30 +6,19 @@ Subject: [PATCH] Optimise ArraySetSorted#removeIf
Remove iterator allocation and ensure the call is always O(n)
diff --git a/src/main/java/net/minecraft/util/SortedArraySet.java b/src/main/java/net/minecraft/util/SortedArraySet.java
index 93813a508be1e1e600a8211f9822f2087328de70..8f03847eeb95ccdb69ad181b38b8724c9c72a76b 100644
index d1b2ba24ef54e01c6249c3b2ca16e80f03c001a6..5f1c4c6b9e36f2d6ec43b82cc0e2cae24b800dc4 100644
--- a/src/main/java/net/minecraft/util/SortedArraySet.java
+++ b/src/main/java/net/minecraft/util/SortedArraySet.java
@@ -10,8 +10,8 @@ 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;
@@ -22,6 +22,42 @@ public class SortedArraySet<T> extends AbstractSet<T> {
@@ -22,6 +22,41 @@ public class SortedArraySet<T> extends AbstractSet<T> {
this.contents = (T[])castRawArray(new Object[initialCapacity]);
}
}
+ // Paper start - optimise removeIf
+ @Override
+ public boolean removeIf(java.util.function.Predicate<? super T> filter) {
+ // prev. impl used an iterator, which could be n^2 and creates garbage
+ int i = 0, len = this.getSize();
+ T[] backingArray = this.getBackingArray();
+ int i = 0, len = this.size;
+ T[] backingArray = this.contents;
+
+ for (;;) {
+ if (i >= len) {
@ -55,11 +44,10 @@ index 93813a508be1e1e600a8211f9822f2087328de70..8f03847eeb95ccdb69ad181b38b8724c
+
+ // cleanup end
+ Arrays.fill(backingArray, lastIndex, len, null);
+ this.setSize(lastIndex);
+ this.size = lastIndex;
+ return true;
+ }
+ // Paper end - optimise removeIf
+
public static <T extends Comparable<T>> SortedArraySet<T> create(int initialCapacity) {
return new SortedArraySet<>(initialCapacity, (Comparator)Comparator.naturalOrder()); // Paper - decompile fix
}
public static <T extends Comparable<T>> SortedArraySet<T> create() {
return create(10);

View File

@ -7,19 +7,19 @@ Will not run if max entity craming is disabled and
the max collisions per entity is less than or equal to 0
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 43fbe7d220f61802ae0cb0620ad078c5df7b69bc..46b962183e2e27ed93054ad9fb6d8ecbf70bc5f9 100644
index 6cc2d26403aa5074218b4b76e2d8ed9e8409a0ae..0fd79c399e723b5a9db04c8f2fe7b6ec66c0cf44 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -2941,10 +2941,16 @@ public abstract class LivingEntity extends Entity {
@@ -3256,10 +3256,16 @@ public abstract class LivingEntity extends Entity {
protected void serverAiStep() {}
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);
+ if (i <= 0 && level.paperConfig.maxCollisionsPerEntity <= 0) {
+ 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));
if (!list.isEmpty()) {

View File

@ -6,10 +6,10 @@ Subject: [PATCH] Restrict vanilla teleport command to valid locations
Fixes GH-3165, GH-3575
diff --git a/src/main/java/net/minecraft/server/commands/TeleportCommand.java b/src/main/java/net/minecraft/server/commands/TeleportCommand.java
index 774180d9e450199309fee65b1d10e1592f84548a..d04ce9a323b079b4556b8c341fb11186e8d3e05d 100644
index 85ae18b7f8a26f83ea0cf1ae17cfa88b796fcc77..d0109df7fad51fc0444459f5d367254c8f4c355e 100644
--- a/src/main/java/net/minecraft/server/commands/TeleportCommand.java
+++ b/src/main/java/net/minecraft/server/commands/TeleportCommand.java
@@ -141,6 +141,12 @@ public class TeleportCommand {
@@ -148,6 +148,12 @@ public class TeleportCommand {
private static void performTeleport(CommandSourceStack source, Entity target, ServerLevel world, double x, double y, double z, Set<ClientboundPlayerPositionPacket.RelativeArgument> movementFlags, float yaw, float pitch, @Nullable TeleportCommand.LookAt facingLocation) throws CommandSyntaxException {
BlockPos blockposition = new BlockPos(x, y, z);

View File

@ -84,105 +84,57 @@ index 0000000000000000000000000000000000000000..b6f4400df3d8ec7e06a996de54f8cabb
+ .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 1f486cfd77b49568540398b1b3fa6127b17ba6aa..4b43740f9ff4feab4f1cd2f8e91d55be3cf8eb50 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ServerboundClientInformationPacket.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ServerboundClientInformationPacket.java
@@ -41,14 +41,17 @@ 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
index efacfcaab444270b985f3a7fe0ef97e33c18a9de..aa979d17c264840ebd528708df3d6118e69fec68 100644
index 42c2862530cff79a9b09850faccb683df1f2a5c8..aec3ded7f65e4a97796afc01b71eeb89c2b3fb70 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -2,6 +2,7 @@ package net.minecraft.server.level;
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;
@@ -188,7 +189,7 @@ 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;
@@ -1807,6 +1808,7 @@ public class ServerPlayer extends Player implements ContainerListener {
@@ -1801,6 +1801,7 @@ public class ServerPlayer extends Player {
public String locale = null; // CraftBukkit - add, lowercase // Paper - default to null
public java.util.Locale adventure$locale = java.util.Locale.US; // Paper
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
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
index 32f1b180e82f41f3ce1b49ea7d67b7d55d2b9ca7..525cd44411b344bc4b5d43c087094fea88fa41a6 100644
index a3d31cec6d1b8de700b6cd2f7f51398debef5b6d..b916f629c2a0fb018cba19aaa612cbbcbb597dc1 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -130,7 +130,7 @@ 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();
@@ -144,7 +144,7 @@ public abstract class Player extends LivingEntity {
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<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); 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<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);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 20de8e358789d05bb5ac15e4cdd7dda85b61b7f8..eb366396820c9b6731469df4198e0884a431a77c 100644
index 2ed7920b0e046bc9d581878a10b04ad784bb8655..0a6d6ea67eaf8b2a59ec45fb3ffb85096f509997 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1,5 +1,8 @@
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;
@@ -2250,6 +2253,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@@ -516,6 +516,24 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
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
}
+
+ @Override
+ public <T> T getClientOption(ClientOption<T> type) {
+ if(ClientOption.SKIN_PARTS.equals(type)) {
+ return type.getType().cast(new PaperSkinParts(getHandle().getEntityData().get(net.minecraft.world.entity.player.Player.getSkinPartsWatcher())));
+ } else if(ClientOption.CHAT_COLORS_ENABLED.equals(type)) {
+ return type.getType().cast(getHandle().hasChatColorsEnabled());
+ } else if(ClientOption.CHAT_VISIBILITY.equals(type)) {
+ return type.getType().cast(getHandle().getChatVisibility() == null ? ChatVisibility.UNKNOWN : ChatVisibility.valueOf(getHandle().getChatVisibility().name()));
+ } else if(ClientOption.LOCALE.equals(type)) {
+ public <T> T getClientOption(com.destroystokyo.paper.ClientOption<T> type) {
+ if(com.destroystokyo.paper.ClientOption.SKIN_PARTS.equals(type)) {
+ return type.getType().cast(new com.destroystokyo.paper.PaperSkinParts(getHandle().getEntityData().get(net.minecraft.world.entity.player.Player.DATA_PLAYER_MODE_CUSTOMISATION)));
+ } else if(com.destroystokyo.paper.ClientOption.CHAT_COLORS_ENABLED.equals(type)) {
+ return type.getType().cast(getHandle().canChatInColor());
+ } else if(com.destroystokyo.paper.ClientOption.CHAT_VISIBILITY.equals(type)) {
+ return type.getType().cast(getHandle().getChatVisibility() == null ? com.destroystokyo.paper.ClientOption.ChatVisibility.UNKNOWN : com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(getHandle().getChatVisibility().name()));
+ } else if(com.destroystokyo.paper.ClientOption.LOCALE.equals(type)) {
+ 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());
+ } else if(ClientOption.VIEW_DISTANCE.equals(type)) {
+ } else if(com.destroystokyo.paper.ClientOption.VIEW_DISTANCE.equals(type)) {
+ return type.getType().cast(getClientViewDistance());
+ }
+ throw new RuntimeException("Unknown settings type");
+ }
// Paper end
// Spigot start
@Override

View File

@ -25,19 +25,18 @@ This successfully fixed a reoccurring and highly reproduceable crash
for heightmaps.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 49728aab7512ea8486d277d34e80d3c6a4727aac..dbe60f5d24fb39be52c3cb8f933371b1626951df 100644
index c82345c74e0e6246f304283c2e06e2d1fcfe53ca..d3094c8a6a906737d4ca56a76ff40b3586961680 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -181,6 +181,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -189,6 +189,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
};
// CraftBukkit end
+ final CallbackExecutor chunkLoadConversionCallbackExecutor = new CallbackExecutor(); // Paper
+
// Paper start - distance maps
private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<ServerPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>();
@@ -1054,7 +1056,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper start - no-tick view distance
@@ -1028,7 +1029,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return Either.left(chunk);
});
}, (runnable) -> {
@ -47,10 +46,10 @@ index 49728aab7512ea8486d277d34e80d3c6a4727aac..dbe60f5d24fb39be52c3cb8f933371b1
completablefuture1.thenAcceptAsync((either) -> {
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 531fe1259a1d60ff69321c3fefbf97f7141e6475..b45fe750c8ca838e1beebff4077e5819eec2836c 100644
index 751454ad5a2c374c01ff360535428db36c0aa1b3..e4f5f564892836a2e925f419e8fcb60c70b21a47 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -1021,6 +1021,7 @@ public class ServerChunkCache extends ChunkSource {
@@ -985,6 +985,7 @@ public class ServerChunkCache extends ChunkSource {
return super.pollTask() || execChunkTask; // Paper
}
} finally {

View File

@ -7,10 +7,10 @@ Subject: [PATCH] Don't crash if player is attempted to be removed from
I suspect it deals with teleporting as it uses players current x/y/z
diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java
index 71a51cc99e26579e765f88340588e23956888929..90429d3f5c5b725098cfb001d54c70608f3df7bb 100644
index 38eebda226e007c8910e04f502ce218cdfe1d456..b49d380ef088aed3204ec71abc437c348ef004fa 100644
--- a/src/main/java/net/minecraft/server/level/DistanceManager.java
+++ b/src/main/java/net/minecraft/server/level/DistanceManager.java
@@ -245,8 +245,8 @@ public abstract class DistanceManager {
@@ -253,8 +253,8 @@ public abstract class DistanceManager {
ObjectSet<ServerPlayer> objectset = (ObjectSet) this.playersPerChunk.get(i);
if (objectset == null) return; // CraftBukkit - SPIGOT-6208

View File

@ -5,16 +5,16 @@ Subject: [PATCH] Broadcast join message to console
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 984ac19dcab446531c816e365c7c149e2c49d567..e043722436492140162940770c22be47690fb47f 100644
index 3431d28fd69c634ee0a941796308b88bb51bdaac..5432ce5b86b7731fe5d06d334e4e191f2eb2f429 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -284,7 +284,9 @@ public abstract class PlayerList {
@@ -286,7 +286,9 @@ public abstract class PlayerList {
if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // 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
+ server.getPlayerList().sendMessage(joinMessage); // Paper - Adventure
+ this.server.getPlayerList().broadcastMessage(joinMessage, ChatType.SYSTEM, Util.NIL_UUID); // Paper - Adventure
+ // Paper end
}
// CraftBukkit end

View File

@ -28,11 +28,11 @@ receives a deterministic result, and should no longer require 1 tick
delays anymore.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index dbe60f5d24fb39be52c3cb8f933371b1626951df..b3ca4300b280a24f3ed2acaffdd6ae2cdffd140d 100644
index d3094c8a6a906737d4ca56a76ff40b3586961680..2cb807f7095648948527b5b9151770193970cc00 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -1584,7 +1584,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
});
@@ -1529,7 +1529,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper end - per player view distance
}
- protected void addEntity(Entity entity) {
@ -40,7 +40,7 @@ index dbe60f5d24fb39be52c3cb8f933371b1626951df..b3ca4300b280a24f3ed2acaffdd6ae2c
org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot
// Paper start - ignore and warn about illegal addEntity calls instead of crashing server
if (!entity.valid || entity.level != this.level || this.entityMap.containsKey(entity.getId())) {
@@ -1593,6 +1593,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -1538,6 +1538,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
.printStackTrace();
return;
}
@ -49,10 +49,10 @@ index dbe60f5d24fb39be52c3cb8f933371b1626951df..b3ca4300b280a24f3ed2acaffdd6ae2c
if (!(entity instanceof EnderDragonPart)) {
EntityType<?> entitytypes = entity.getType();
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index aa979d17c264840ebd528708df3d6118e69fec68..75a095e0c2177dc1b46b080597ff8f12f1480acc 100644
index aec3ded7f65e4a97796afc01b71eeb89c2b3fb70..a30840b74bc2574725c42735f633630d9b471d54 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -237,6 +237,7 @@ public class ServerPlayer extends Player implements ContainerListener {
@@ -237,6 +237,7 @@ public class ServerPlayer extends Player {
public double maxHealthCache;
public boolean joining = true;
public boolean sentListPacket = false;
@ -61,10 +61,10 @@ index aa979d17c264840ebd528708df3d6118e69fec68..75a095e0c2177dc1b46b080597ff8f12
// CraftBukkit end
public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index e043722436492140162940770c22be47690fb47f..454d60566743e02e7e55868c7bb45e30583dfa8f 100644
index 5432ce5b86b7731fe5d06d334e4e191f2eb2f429..3a13c151066c8784fdc844e1d6310f77ff32e7f1 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -272,6 +272,12 @@ public abstract class PlayerList {
@@ -274,6 +274,12 @@ public abstract class PlayerList {
this.playersByUUID.put(player.getUUID(), player);
// this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, new EntityPlayer[]{entityplayer})); // CraftBukkit - replaced with loop below
@ -75,9 +75,9 @@ index e043722436492140162940770c22be47690fb47f..454d60566743e02e7e55868c7bb45e30
+ mountSavedVehicle(player, worldserver1, nbttagcompound);
+ // Paper end
// CraftBukkit start
PlayerJoinEvent playerJoinEvent = new org.bukkit.event.player.PlayerJoinEvent(cserver.getPlayer(player), PaperAdventure.asAdventure(chatmessage)); // Paper - Adventure
cserver.getPluginManager().callEvent(playerJoinEvent);
@@ -307,6 +313,8 @@ public abstract class PlayerList {
PlayerJoinEvent playerJoinEvent = new org.bukkit.event.player.PlayerJoinEvent(this.cserver.getPlayer(player), PaperAdventure.asAdventure(chatmessage)); // Paper - Adventure
this.cserver.getPluginManager().callEvent(playerJoinEvent);
@@ -309,6 +315,8 @@ public abstract class PlayerList {
player.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, new ServerPlayer[] { entityplayer1}));
}
player.sentListPacket = true;
@ -86,64 +86,34 @@ index e043722436492140162940770c22be47690fb47f..454d60566743e02e7e55868c7bb45e30
// CraftBukkit end
player.connection.send(new ClientboundSetEntityDataPacket(player.getId(), player.getEntityData(), true)); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn
@@ -332,6 +340,11 @@ public abstract class PlayerList {
@@ -334,6 +342,11 @@ public abstract class PlayerList {
playerconnection.send(new ClientboundUpdateMobEffectPacket(player.getId(), mobeffect));
}
+ // Paper start - move vehicle into method so it can be called above - short circuit around that code
+ onPlayerJoinFinish(player, worldserver1, s1);
+ }
+ private void mountSavedVehicle(ServerPlayer entityplayer, ServerLevel worldserver1, CompoundTag nbttagcompound) {
+ private void mountSavedVehicle(ServerPlayer player, ServerLevel worldserver1, CompoundTag nbttagcompound) {
+ // Paper end
if (nbttagcompound != null && nbttagcompound.contains("RootVehicle", 10)) {
CompoundTag nbttagcompound1 = nbttagcompound.getCompound("RootVehicle");
// CraftBukkit start
@@ -354,20 +367,20 @@ 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();
@@ -380,16 +393,20 @@ public abstract class PlayerList {
@@ -382,6 +395,10 @@ public abstract class PlayerList {
}
}
- player.initMenu();
+ // Paper start
+ }
+ public void onPlayerJoinFinish(ServerPlayer entityplayer, ServerLevel worldserver1, String s1) {
+ public void onPlayerJoinFinish(ServerPlayer player, ServerLevel worldserver1, String s1) {
+ // Paper end
+ entityplayer.initMenu();
player.initInventoryMenu();
// CraftBukkit - Moved from above, added world
// Paper start - Add to collideRule team if needed
final Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard();
final PlayerTeam collideRuleTeam = scoreboard.getTeam(collideRuleTeamName);
- 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);
@@ -391,6 +408,7 @@ public abstract class PlayerList {
scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam);
}
// Paper end
// 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 ([{}]{}, {}, {})", entityplayer.getName().getString(), s1, entityplayer.getId(), worldserver1.worldDataServer.getLevelName(), entityplayer.getX(), entityplayer.getY(), entityplayer.getZ());
+ // CraftBukkit - Moved from above, added world
PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ());
}
public void updateEntireScoreboard(ServerScoreboard scoreboard, ServerPlayer player) {

View File

@ -0,0 +1,277 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 19 Apr 2020 04:28:29 -0400
Subject: [PATCH] Load Chunks for Login Asynchronously
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index e4f5f564892836a2e925f419e8fcb60c70b21a47..afc9431b61f2953229765ef90005b7968fbed591 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -630,7 +630,7 @@ public class ServerChunkCache extends ChunkSource {
return this.mainThreadProcessor.pollTask();
}
- boolean runDistanceManagerUpdates() {
+ public boolean runDistanceManagerUpdates() { // Paper - packate-private -> public
boolean flag = this.distanceManager.runAllUpdates(this.chunkMap);
boolean flag1 = this.chunkMap.promoteChunkMap();
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index a30840b74bc2574725c42735f633630d9b471d54..d4ec913a96c5f8f9780d78f6f340d844718a5849 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -177,6 +177,7 @@ public class ServerPlayer extends Player {
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32;
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
public ServerGamePacketListenerImpl connection;
+ public net.minecraft.network.Connection networkManager; // Paper
public final MinecraftServer server;
public final ServerPlayerGameMode gameMode;
private final PlayerAdvancements advancements;
@@ -238,6 +239,7 @@ public class ServerPlayer extends Player {
public boolean joining = true;
public boolean sentListPacket = false;
public boolean supressTrackerForLogin = false; // Paper
+ public boolean didPlayerJoinEvent = false; // Paper
public Integer clientViewDistance;
// CraftBukkit end
public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper
diff --git a/src/main/java/net/minecraft/server/level/TicketType.java b/src/main/java/net/minecraft/server/level/TicketType.java
index be677d437d17b74c6188ce1bd5fc6fdc228fd92f..78fbb4c3e52e900956ae0811aaf934c81ee5ea48 100644
--- a/src/main/java/net/minecraft/server/level/TicketType.java
+++ b/src/main/java/net/minecraft/server/level/TicketType.java
@@ -23,6 +23,7 @@ public class TicketType<T> {
public static final TicketType<ChunkPos> FORCED = TicketType.create("forced", Comparator.comparingLong(ChunkPos::toLong));
public static final TicketType<ChunkPos> LIGHT = TicketType.create("light", Comparator.comparingLong(ChunkPos::toLong));
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<Integer> POST_TELEPORT = TicketType.create("post_teleport", Integer::compareTo, 5);
public static final TicketType<ChunkPos> UNKNOWN = TicketType.create("unknown", Comparator.comparingLong(ChunkPos::toLong), 1);
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
index fcfd57fd7af655aafb330986e8f6f9cc55819165..1263e845a56e96920c71a7ef636ad3437a70c06f 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -221,6 +221,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
private static final int LATENCY_CHECK_INTERVAL = 15000;
public final Connection connection;
private final MinecraftServer server;
+ public Runnable playerJoinReady; // Paper
public ServerPlayer player;
private int tickCount;
private long keepAliveTime = Util.getMillis();
@@ -295,6 +296,15 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
// CraftBukkit end
public void tick() {
+ // Paper start - login async
+ Runnable playerJoinReady = this.playerJoinReady;
+ if (playerJoinReady != null) {
+ this.playerJoinReady = null;
+ playerJoinReady.run();
+ }
+ // Don't tick if not valid (dead), otherwise we load chunks below
+ if (this.player.valid) {
+ // Paper end
this.resetPosition();
this.player.xo = this.player.getX();
this.player.yo = this.player.getY();
@@ -336,7 +346,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
this.lastVehicle = null;
this.clientVehicleIsFloating = false;
this.aboveGroundVehicleTickCount = 0;
- }
+ }} // Paper - end if (valid)
this.server.getProfiler().push("keepAlive");
// Paper Start - give clients a longer time to respond to pings as per pre 1.12.2 timings
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
index 46432534fddbbf78e3bf46385b9638d2f92c951f..49308829885a473906d58fb17797127faabfcf31 100644
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
@@ -88,7 +88,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener
}
// Paper end
} else if (this.state == ServerLoginPacketListenerImpl.State.DELAY_ACCEPT) {
- ServerPlayer entityplayer = this.server.getPlayerList().getPlayer(this.gameProfile.getId());
+ ServerPlayer entityplayer = this.server.getPlayerList().getActivePlayer(this.gameProfile.getId()); // Paper
if (entityplayer == null) {
this.state = ServerLoginPacketListenerImpl.State.READY_TO_ACCEPT;
@@ -194,7 +194,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener
}
this.connection.send(new ClientboundGameProfilePacket(this.gameProfile));
- ServerPlayer entityplayer = this.server.getPlayerList().getPlayer(this.gameProfile.getId());
+ ServerPlayer entityplayer = this.server.getPlayerList().getActivePlayer(this.gameProfile.getId()); // Paper
try {
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
index 3a13c151066c8784fdc844e1d6310f77ff32e7f1..c4242a1602bbb02541c330bc02016f15c8644358 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -38,6 +38,7 @@ import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket;
import net.minecraft.network.protocol.game.ClientboundChatPacket;
import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket;
+import net.minecraft.network.protocol.game.ClientboundDisconnectPacket;
import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
import net.minecraft.network.protocol.game.ClientboundGameEventPacket;
import net.minecraft.network.protocol.game.ClientboundInitializeBorderPacket;
@@ -127,11 +128,12 @@ public abstract class PlayerList {
private static final SimpleDateFormat BAN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");
private final MinecraftServer server;
public final List<ServerPlayer> players = new java.util.concurrent.CopyOnWriteArrayList(); // CraftBukkit - ArrayList -> CopyOnWriteArrayList: Iterator safety
- private final Map<UUID, ServerPlayer> playersByUUID = Maps.newHashMap();
+ private final Map<UUID, ServerPlayer> playersByUUID = Maps.newHashMap();Map<UUID, ServerPlayer> getUUIDMap() { return playersByUUID; } // Paper - OBFHELPER
private final UserBanList bans;
private final IpBanList ipBans;
private final ServerOpList ops;
private final UserWhiteList whitelist;
+ private final Map<UUID, ServerPlayer> pendingPlayers = Maps.newHashMap(); // Paper
// CraftBukkit start
// private final Map<UUID, ServerStatisticManager> o;
// private final Map<UUID, AdvancementDataPlayer> p;
@@ -170,6 +172,11 @@ public abstract class PlayerList {
}
public void placeNewPlayer(Connection connection, ServerPlayer player) {
+ ServerPlayer prev = pendingPlayers.put(player.getUUID(), player);// Paper
+ if (prev != null) {
+ disconnectPendingPlayer(prev);
+ }
+ player.networkManager = connection; // Paper
player.loginTime = System.currentTimeMillis(); // Paper
GameProfile gameprofile = player.getGameProfile();
GameProfileCache usercache = this.server.getProfileCache();
@@ -183,7 +190,7 @@ public abstract class PlayerList {
if (nbttagcompound != null && nbttagcompound.contains("bukkit")) {
CompoundTag bukkit = nbttagcompound.getCompound("bukkit");
s = bukkit.contains("lastKnownName", 8) ? bukkit.getString("lastKnownName") : s;
- }
+ }String lastKnownName = s; // Paper
// CraftBukkit end
if (nbttagcompound != null) {
@@ -257,6 +264,52 @@ public abstract class PlayerList {
player.getRecipeBook().sendInitialRecipeBook(player);
this.updateEntireScoreboard(worldserver1.getScoreboard(), player);
this.server.invalidateStatus();
+ // Paper start - async load spawn in chunk
+ ServerLevel finalWorldserver = worldserver1;
+ int chunkX = loc.getBlockX() >> 4;
+ int chunkZ = loc.getBlockZ() >> 4;
+ final net.minecraft.world.level.ChunkPos pos = new net.minecraft.world.level.ChunkPos(chunkX, chunkZ);
+ net.minecraft.server.level.ChunkMap playerChunkMap = worldserver1.getChunkSource().chunkMap;
+ 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().getChunkAtAsynchronously(chunkX, chunkZ, true, true).thenApply(chunk -> {
+ net.minecraft.server.level.ChunkHolder updatingChunk = playerChunkMap.getUpdatingChunkIfPresent(pos.toLong());
+ if (updatingChunk != null) {
+ return updatingChunk.getEntityTickingFuture();
+ } else {
+ return java.util.concurrent.CompletableFuture.completedFuture(chunk);
+ }
+ }).thenAccept(chunk -> {
+ playerconnection.playerJoinReady = () -> {
+ postChunkLoadJoin(
+ player, finalWorldserver, connection, playerconnection,
+ nbttagcompound, connection.getRemoteAddress().toString(), lastKnownName
+ );
+ };
+ });
+ }
+
+ public ServerPlayer getActivePlayer(UUID uuid) {
+ ServerPlayer player = this.getUUIDMap().get(uuid);
+ return player != null ? player : pendingPlayers.get(uuid);
+ }
+
+ void disconnectPendingPlayer(ServerPlayer entityplayer) {
+ TranslatableComponent msg = new TranslatableComponent("multiplayer.disconnect.duplicate_login", new Object[0]);
+ entityplayer.networkManager.send(new ClientboundDisconnectPacket(msg), (future) -> {
+ entityplayer.networkManager.disconnect(msg);
+ entityplayer.networkManager = null;
+ });
+ }
+
+ private void postChunkLoadJoin(ServerPlayer player, ServerLevel worldserver1, Connection networkmanager, ServerGamePacketListenerImpl playerconnection, CompoundTag nbttagcompound, String s1, String s) {
+ pendingPlayers.remove(player.getUUID(), player);
+ if (!networkmanager.isConnected()) {
+ return;
+ }
+ player.didPlayerJoinEvent = true;
+ // Paper end
TranslatableComponent chatmessage;
if (player.getGameProfile().getName().equalsIgnoreCase(s)) {
@@ -495,6 +548,7 @@ public abstract class PlayerList {
protected void save(ServerPlayer player) {
if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit
+ if (!player.didPlayerJoinEvent) return; // Paper - If we never fired PJE, we disconnected during login. Data has not changed, and additionally, our saved vehicle is not loaded! If we save now, we will lose our vehicle (CraftBukkit bug)
this.playerIo.save(player);
ServerStatsCounter serverstatisticmanager = (ServerStatsCounter) player.getStats(); // CraftBukkit
@@ -522,7 +576,7 @@ public abstract class PlayerList {
}
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())));
- this.cserver.getPluginManager().callEvent(playerQuitEvent);
+ 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());
if (server.isSameThread()) entityplayer.doTick(); // SPIGOT-924 // Paper - don't tick during emergency shutdowns (Watchdog)
@@ -567,6 +621,13 @@ public abstract class PlayerList {
// this.p.remove(uuid);
// CraftBukkit end
}
+ // Paper start
+ entityplayer1 = pendingPlayers.get(uuid);
+ if (entityplayer1 == entityplayer) {
+ pendingPlayers.remove(uuid);
+ }
+ entityplayer.networkManager = null;
+ // Paper end
// CraftBukkit start
// this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[]{entityplayer}));
@@ -584,7 +645,7 @@ public abstract class PlayerList {
this.cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity());
// CraftBukkit end
- return playerQuitEvent.quitMessage(); // Paper - Adventure
+ return entityplayer.didPlayerJoinEvent ? playerQuitEvent.quitMessage() : null; // CraftBukkit // Paper - Adventure // Paper - don't print quit if we never printed join
}
// CraftBukkit start - Whole method, SocketAddress to LoginListener, added hostname to signature, return EntityPlayer
@@ -603,6 +664,13 @@ public abstract class PlayerList {
list.add(entityplayer);
}
}
+ // Paper start - check pending players too
+ entityplayer = pendingPlayers.get(uuid);
+ if (entityplayer != null) {
+ this.pendingPlayers.remove(uuid);
+ disconnectPendingPlayer(entityplayer);
+ }
+ // Paper end
Iterator iterator = list.iterator();
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 85c0656ee8c91cab1e269daea631977c4284295f..ac5f0bf573cbb5aa19dd3326f412010286de4378 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -1490,7 +1490,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
this.yo = y;
this.zo = d4;
this.setPos(d3, y, d4);
- this.level.getChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4); // CraftBukkit
+ if (valid) this.level.getChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4); // CraftBukkit // Paper
}
public void moveTo(Vec3 pos) {

View File

@ -7,10 +7,10 @@ The code following this has better support for null worlds to move
them back to the world spawn.
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 9f0371282f5829d26dc9618c3d466bccaa4cd3af..34226102c50a4353c42e68917d41c44d251e602f 100644
index ac5f0bf573cbb5aa19dd3326f412010286de4378..1ab073aaacbf6af35f97a7d3b0d8ae078335f9a6 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -1808,9 +1808,11 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
@@ -1979,9 +1979,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
bworld = server.getWorld(worldName);
}
@ -23,5 +23,5 @@ index 9f0371282f5829d26dc9618c3d466bccaa4cd3af..34226102c50a4353c42e68917d41c44d
+// }
+ // 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

@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerAttackEntityCooldownResetEvent
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 46b962183e2e27ed93054ad9fb6d8ecbf70bc5f9..cec1e6105b8c2ac3d1482c00482d53d6be0d38d1 100644
index 0fd79c399e723b5a9db04c8f2fe7b6ec66c0cf44..3a83cbe8fb1a5bfc7e7b699686b92561bf0cdba0 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -1928,7 +1928,16 @@ public abstract class LivingEntity extends Entity {
@@ -2033,7 +2033,16 @@ public abstract class LivingEntity extends Entity {
EntityDamageEvent event = CraftEventFactory.handleLivingEntityDamageEvent(this, damagesource, originalDamage, hardHatModifier, blockingModifier, armorModifier, resistanceModifier, magicModifier, absorptionModifier, hardHat, blocking, armor, resistance, magic, absorption);
if (damagesource.getEntity() instanceof net.minecraft.world.entity.player.Player) {

View File

@ -14,45 +14,35 @@ Use an ArrayDeque to store this Queue
We make sure to also implement a pattern that is recursion safe too.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 97a582614ad28f9fa864ae9be4860658e5979214..6c7af93cead523830d32b007cc69b313e59abef1 100644
index 2cb807f7095648948527b5b9151770193970cc00..7fa35cba408d036e649e6d63bace88e6047c02b4 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -160,24 +160,32 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -172,15 +172,27 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
public final CallbackExecutor callbackExecutor = new CallbackExecutor();
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
+ // 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
+ private java.util.ArrayDeque<Runnable> queued = new java.util.ArrayDeque<>();
+ private java.util.Queue<Runnable> queue = new java.util.ArrayDeque<>(); // Paper - remove final
@Override
public void execute(Runnable runnable) {
- if (queued != null) {
- throw new IllegalStateException("Already queued");
+ if (queued == null) {
+ queued = new java.util.ArrayDeque<>();
}
- queued = runnable;
+ queued.add(runnable);
+ if (this.queue == null) {
+ this.queue = new java.util.ArrayDeque<>();
+ }
this.queue.add(runnable);
}
@Override
public void run() {
- Runnable task = queued;
+ if (queued == null) {
+ if (this.queue == null) {
+ return;
+ }
+ java.util.ArrayDeque<Runnable> queue = queued;
queued = null;
- if (task != null) {
+ Runnable task;
+ while ((task = queue.pollFirst()) != null) {
+ java.util.Queue<Runnable> queue = this.queue;
+ this.queue = null;
+ // Paper end
Runnable task;
while ((task = this.queue.poll()) != null) {
task.run();
}
}
+ // Paper end
};
// CraftBukkit end

View File

@ -6,18 +6,18 @@ Subject: [PATCH] Don't fire BlockFade on worldgen threads
Caused a deadlock
diff --git a/src/main/java/net/minecraft/world/level/block/FireBlock.java b/src/main/java/net/minecraft/world/level/block/FireBlock.java
index 31b6c1333c7d0af28385e804e94348cef398748b..ac63c5bef5b35b158e57835d765bbdd15fc60664 100644
index ad0b485dbc77717f16191d6950a2e91faaede94a..c86bf175853197dceaa91a2287ef51de87b9d5f9 100644
--- a/src/main/java/net/minecraft/world/level/block/FireBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java
@@ -93,6 +93,7 @@ public class FireBlock extends BaseFireBlock {
@@ -100,6 +100,7 @@ public class FireBlock extends BaseFireBlock {
@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
+ 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)) {
// Suppress during worldgen
if (!(world instanceof Level)) {
@@ -108,7 +109,7 @@ public class FireBlock extends BaseFireBlock {
@@ -115,7 +116,7 @@ public class FireBlock extends BaseFireBlock {
return blockState.getHandle();
}
}

View File

@ -5,53 +5,40 @@ Subject: [PATCH] Add phantom creative and insomniac controls
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index cd248eb6be663e8be33f2c3c6b06b77b6d5753a4..46ac6d91422423f1e03b86d3efa3241f2599000d 100644
index 9664786d471b949880030f5c6271bf9c12529326..45058c715152e3ffa5ec1c79a472e32d63d69e02 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -625,4 +625,11 @@ public class PaperWorldConfig {
private void lightQueueSize() {
@@ -472,6 +472,13 @@ public class PaperWorldConfig {
lightQueueSize = getInt("light-queue-size", lightQueueSize);
}
+
+ public boolean phantomIgnoreCreative = true;
+ public boolean phantomOnlyAttackInsomniacs = true;
+ private void phantomSettings() {
+ phantomIgnoreCreative = getBoolean("phantoms-do-not-spawn-on-creative-players", phantomIgnoreCreative);
+ 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
index e7facd849e3511c64b4ae44b34382f4a4985f2a4..8ce62148ebaeac9988e7c9d4b2f7ee57f58d883e 100644
index d17b75ad13bbc8a38cdc2f2d77ee5d88438cec31..8fb89326395a7e70982c0d757b506565e98b12a4 100644
--- a/src/main/java/net/minecraft/world/entity/EntitySelector.java
+++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java
@@ -3,6 +3,9 @@ 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;
@@ -31,10 +34,11 @@ public final class EntitySelector {
@@ -26,6 +26,7 @@ public final class EntitySelector {
public static final Predicate<Entity> NO_SPECTATORS = (entity) -> {
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
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
index e37137a2890330b92e05d6f76c46ffc99a527803..a40c23e824652cff59633b7c314e27ec9a515c07 100644
index 2ddb7b4c0a75c6f41910c84c8b9341f56fcb1116..941f86b04fedaf1e3f5d04c9aa8c1cd74da9b7a2 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
@@ -262,6 +262,7 @@ public class Phantom extends FlyingMob implements Enemy {
@@ -547,6 +547,7 @@ public class Phantom extends FlyingMob implements Enemy {
Player entityhuman = (Player) iterator.next();
if (Phantom.this.canAttack((LivingEntity) entityhuman, TargetingConditions.DEFAULT)) {

View File

@ -16,10 +16,10 @@ So even if something NEW comes up, it would be impossible to drop the
same item twice because the source was destroyed.
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 34226102c50a4353c42e68917d41c44d251e602f..2b48c4a2b512c42bed2c767db90a28898c74286a 100644
index 1ab073aaacbf6af35f97a7d3b0d8ae078335f9a6..9897a0ac66dd788b0b22a88b20ca86a386e397e4 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -1973,11 +1973,12 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
@@ -2125,11 +2125,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
} else {
// CraftBukkit start - Capture drops for death event
if (this instanceof net.minecraft.world.entity.LivingEntity && !((net.minecraft.world.entity.LivingEntity) this).forceDrops) {
@ -34,7 +34,7 @@ index 34226102c50a4353c42e68917d41c44d251e602f..2b48c4a2b512c42bed2c767db90a2889
entityitem.setDefaultPickUpDelay();
// CraftBukkit start
@@ -2625,6 +2626,12 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
@@ -2873,6 +2874,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
@Nullable
public Entity teleportTo(ServerLevel worldserver, BlockPos location) {
// CraftBukkit end
@ -44,10 +44,10 @@ index 34226102c50a4353c42e68917d41c44d251e602f..2b48c4a2b512c42bed2c767db90a2889
+ return null;
+ }
+ // Paper end
if (this.level instanceof ServerLevel && !this.removed) {
if (this.level instanceof ServerLevel && !this.isRemoved()) {
this.level.getProfiler().push("changeDimension");
// CraftBukkit start
@@ -2645,6 +2652,11 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
@@ -2893,6 +2900,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
// CraftBukkit end
this.level.getProfiler().popPush("reloading");
@ -59,7 +59,7 @@ index 34226102c50a4353c42e68917d41c44d251e602f..2b48c4a2b512c42bed2c767db90a2889
Entity entity = this.getType().create((Level) worldserver);
if (entity != null) {
@@ -2658,10 +2670,6 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
@@ -2906,10 +2918,6 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
// CraftBukkit start - Forward the CraftEntity to the new entity
this.getBukkitEntity().setHandle(entity);
entity.bukkitEntity = this.getBukkitEntity();
@ -70,7 +70,7 @@ index 34226102c50a4353c42e68917d41c44d251e602f..2b48c4a2b512c42bed2c767db90a2889
// CraftBukkit end
}
@@ -2786,7 +2794,7 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
@@ -3034,7 +3042,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
}
public boolean canChangeDimensions() {
@ -80,10 +80,10 @@ index 34226102c50a4353c42e68917d41c44d251e602f..2b48c4a2b512c42bed2c767db90a2889
public float getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState, float max) {
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
index 33d51852ed6fe3f5adcdecf8f405a23689f4265a..5714aa450ac09788bcf1c2790d4f1581c9a7c28b 100644
index cb9969d768b13863722aad3dc5daad3c10bb264a..5bfec185e15a54ee5fe6eab1aa59d1963d046262 100644
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
@@ -598,7 +598,7 @@ public class ArmorStand extends LivingEntity {
@@ -611,7 +611,7 @@ public class ArmorStand extends LivingEntity {
for (i = 0; i < this.handItems.size(); ++i) {
itemstack = (ItemStack) this.handItems.get(i);
if (!itemstack.isEmpty()) {
@ -92,7 +92,7 @@ index 33d51852ed6fe3f5adcdecf8f405a23689f4265a..5714aa450ac09788bcf1c2790d4f1581
this.handItems.set(i, ItemStack.EMPTY);
}
}
@@ -606,7 +606,7 @@ public class ArmorStand extends LivingEntity {
@@ -619,7 +619,7 @@ public class ArmorStand extends LivingEntity {
for (i = 0; i < this.armorItems.size(); ++i) {
itemstack = (ItemStack) this.armorItems.get(i);
if (!itemstack.isEmpty()) {
@ -102,10 +102,10 @@ index 33d51852ed6fe3f5adcdecf8f405a23689f4265a..5714aa450ac09788bcf1c2790d4f1581
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index 7d9a3b65b2d6b294d3a11414289e64fac88665f0..87fe7f4f5ed70bf1b3dc1e2a392ba42a1f8f568b 100644
index 98bec353d6dbd85c7b329f75e09f4d0bfcfdaa6c..7d43439a13bd109399691ddec60ee99c818db198 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -815,7 +815,8 @@ public class CraftEventFactory {
@@ -807,7 +807,8 @@ public class CraftEventFactory {
for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
if (stack == null || stack.getType() == Material.AIR || stack.getAmount() == 0) continue;

View File

@ -9,8 +9,20 @@ Adds AsyncPlayerSendCommandsEvent
Adds CommandRegisteredEvent
- Allows manipulating the CommandNode to add more children/metadata for the client
diff --git a/build.gradle.kts b/build.gradle.kts
index f0256fe4aea16c9e0d6f5eee360eeec36cfdeebd..2543a4cf2bb58c2265cfc427c427b683d2ff70ca 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -21,6 +21,7 @@ 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
index f74765f31bc7272724ee7fac0cc5a8c852550006..e1f4ffaa36bfffb7741c74b7a094e26a03a9a1e6 100644
index 60b503dd85706bd2593a5e9d3314540ff1012652..42d97bc67c8f4e5b65a81159179c43dc6edc804c 100644
--- a/src/main/java/net/minecraft/commands/CommandSourceStack.java
+++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java
@@ -37,7 +37,7 @@ import net.minecraft.world.phys.Vec2;
@ -22,7 +34,7 @@ index f74765f31bc7272724ee7fac0cc5a8c852550006..e1f4ffaa36bfffb7741c74b7a094e26a
public static final SimpleCommandExceptionType ERROR_NOT_PLAYER = new SimpleCommandExceptionType(new TranslatableComponent("permissions.requires.player"));
public static final SimpleCommandExceptionType ERROR_NOT_ENTITY = new SimpleCommandExceptionType(new TranslatableComponent("permissions.requires.entity"));
@@ -149,6 +149,25 @@ public class CommandSourceStack implements SharedSuggestionProvider {
@@ -153,6 +153,25 @@ public class CommandSourceStack implements SharedSuggestionProvider {
return this.textName;
}
@ -49,10 +61,10 @@ index f74765f31bc7272724ee7fac0cc5a8c852550006..e1f4ffaa36bfffb7741c74b7a094e26a
public boolean hasPermission(int level) {
// CraftBukkit start
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index 8154d9327c5411bbfea3bfa4d99d57feab764664..c63033e3eb50423a7c32acfc0e705623cc4bec68 100644
index 13e358e0eac3bfd426d924b6f745e001df76c64a..7156dea53be828acd01734fa1f9f7b9accf30ff6 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -355,6 +355,7 @@ public class Commands {
@@ -362,6 +362,7 @@ public class Commands {
bukkit.add(node.getName());
}
// Paper start - Async command map building
@ -60,7 +72,7 @@ index 8154d9327c5411bbfea3bfa4d99d57feab764664..c63033e3eb50423a7c32acfc0e705623
MinecraftServer.getServer().execute(() -> {
runSync(entityplayer, bukkit, rootcommandnode);
});
@@ -362,6 +363,7 @@ public class Commands {
@@ -369,6 +370,7 @@ public class Commands {
private void runSync(ServerPlayer entityplayer, Collection<String> bukkit, RootCommandNode<SharedSuggestionProvider> rootcommandnode) {
// Paper end - Async command map building
@ -69,17 +81,17 @@ index 8154d9327c5411bbfea3bfa4d99d57feab764664..c63033e3eb50423a7c32acfc0e705623
event.getPlayer().getServer().getPluginManager().callEvent(event);
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 1bed6e69bf3cc1ab9b0c1259de4f643bf58371aa..5f12987b93f1578624626c4e911d1757dee3d45f 100644
index 1263e845a56e96920c71a7ef636ad3437a70c06f..fbb33cfa62723ac1fd6f426969e747e49abc8ea6 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -768,8 +768,12 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
@@ -760,8 +760,12 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
ParseResults<CommandSourceStack> parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack());
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
- this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestions));
+ // 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());
+ if (!suggestEvent.callEvent()) return;
+ this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), (com.mojang.brigadier.suggestion.Suggestions) suggestEvent.getSuggestions())); // CraftBukkit - decompile error // Paper
@ -87,13 +99,13 @@ index 1bed6e69bf3cc1ab9b0c1259de4f643bf58371aa..5f12987b93f1578624626c4e911d1757
});
});
}
@@ -778,7 +782,11 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
@@ -770,7 +774,11 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
builder = builder.createOffset(builder.getInput().lastIndexOf(' ') + 1);
completions.forEach(builder::suggest);
- player.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), 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());
+ if (!suggestEvent.callEvent()) return;
+ this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestEvent.getSuggestions()));
@ -101,7 +113,7 @@ index 1bed6e69bf3cc1ab9b0c1259de4f643bf58371aa..5f12987b93f1578624626c4e911d1757
// Paper end - async tab completion
}
diff --git a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
index f9a245503c8982d1756503a6179f3715d919d910..b17002abdb43e74da4eb61e65e45c5e0e1dc0f95 100644
index 21971d52fa8ed92c946c519ba93a39aceae10f5f..0bba36d18d56a4dc2d6c6fb7969e5e6f0e1da404 100644
--- a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
+++ b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
@@ -17,7 +17,7 @@ import net.minecraft.commands.CommandSourceStack;

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Villager Restocks API
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
index 4aa34320ef7d6c62ccb17734bfa61d406190b919..a83a7d37f3d769535161fda46fca6f71dcc4d515 100644
index a35ce224b11b44567814207c3821d0cd4cdd9ec1..e99cdbb1d050288b5f1177737b242c331a989471 100644
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
@@ -112,7 +112,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
@@ -127,7 +127,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
private long lastGossipDecayTime;
private int villagerXp;
private long lastRestockGameTime;
@ -16,13 +16,13 @@ index 4aa34320ef7d6c62ccb17734bfa61d406190b919..a83a7d37f3d769535161fda46fca6f71
+ private int numberOfRestocksToday; public int getRestocksToday(){ return this.numberOfRestocksToday; } public void setRestocksToday(int restocksToday){ this.numberOfRestocksToday = restocksToday; } // Paper OBFHELPER
private long lastRestockCheckDayTime;
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
index 5a21e9447c3e0225b07144eec83c277dd101bfd5..d0b933cfd02b237bfe85011831dab6e8e966496e 100644
index 40815c2500a1b4946c502b8ae7f80c4e93e556ae..115f107ac100524ef0fcf8de0fc528d164c845f7 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
@@ -83,6 +83,18 @@ public class CraftVillager extends CraftAbstractVillager implements Villager {
getHandle().setVillagerXp(experience);
this.getHandle().setVillagerXp(experience);
}
+ // Paper start

View File

@ -5,22 +5,22 @@ Subject: [PATCH] Validate PickItem Packet and kick for invalid
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 5f12987b93f1578624626c4e911d1757dee3d45f..3f416479e23c60ec5b4b779cce9ab62c74865ac8 100644
index fbb33cfa62723ac1fd6f426969e747e49abc8ea6..b5325f19458467b307db629a00359af41004124a 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -881,7 +881,14 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
@@ -877,7 +877,14 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
@Override
public void handlePickItem(ServerboundPickItemPacket packet) {
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
+ 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());
+ this.disconnect("Invalid hotbar selection (Hacking?)");
+ 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
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, packet.getSlot(), this.player.inventory.getItem(packet.getSlot())));
this.player.connection.send(new ClientboundSetCarriedItemPacket(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.getInventory().getItem(packet.getSlot())));
this.player.connection.send(new ClientboundSetCarriedItemPacket(this.player.getInventory().selected));

View File

@ -5,11 +5,11 @@ Subject: [PATCH] Expose game version
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 43c37e660a8a7f9d326ad38e66f9aa7c53c7b87c..1bfe96443877e460d22513d59ebc3b5988e8eb43 100644
index 4c0b94a56fab161fca92b594f55e1c846524d5e8..479b4eb8efeeca432bcb21925db18d5c0750f001 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -514,6 +514,13 @@ public final class CraftServer implements Server {
return bukkitVersion;
@@ -517,6 +517,13 @@ public final class CraftServer implements Server {
return this.bukkitVersion;
}
+ // Paper start - expose game version

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 9e0afab2329e560c4b2512548dd4b02dd1a2e69f..06662dbff8180751a8684841aa35f709007078ae 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java
@@ -10,12 +10,33 @@ 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 95428f13dae909bb7de552aa65e4256bd4049c65..94f58332bb1408971fe65e5fd0401457ab986441 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
@@ -337,9 +337,21 @@ 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) {
@@ -347,13 +359,22 @@ 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

@ -7,4 +7,4 @@ pluginManagement {
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