Update to 1.20.2

Very early build, network configuration switching is supported
but not tested (note: changes need to be backported to Paper)

Changes:
 - Supports per player mob caps
 - Adds entity tracker optimisations which are not in Paper
   (and will not be ported to Paper due to plugin conflicts)
 - No longer reverts paper distance map optimisations, as
   those are replaced by the NearbyPlayers class

These changes should bring Folia in-line with Paper's optimisations
at least (probably more given the entity tracker optimisations),
still missing features like world loading / some commands
This commit is contained in:
Spottedleaf 2023-09-26 13:20:12 -07:00
parent edafbcef68
commit 4a59238743
29 changed files with 1824 additions and 2750 deletions

View File

@ -4,7 +4,7 @@ plugins {
java
`maven-publish`
id("com.github.johnrengelman.shadow") version "8.1.1" apply false
id("io.papermc.paperweight.patcher") version "1.5.5"
id("io.papermc.paperweight.patcher") version "1.5.6"
}
val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"

View File

@ -1,8 +1,8 @@
group=dev.folia
version=1.20.1-R0.1-SNAPSHOT
mcVersion=1.20.1
paperRef=fb06829845db10be0405966f874a16f135f73229
version=1.20.2-R0.1-SNAPSHOT
mcVersion=1.20.2
paperRef=fe54a13b1301312304d9c1e46ad91b039657120b
org.gradle.caching=true
org.gradle.parallel=true

View File

@ -5,7 +5,7 @@ Subject: [PATCH] Build changes
diff --git a/build.gradle.kts b/build.gradle.kts
index fb98936bb8a5488db75d676c5bcb4060597fbbf8..9ee90bc753e65f9dd532f28ec75cc16bf16486c8 100644
index 683159586641dd9aa42ae96fa51602469755723f..521ff85fcf10fc85fe706d6fa3778e0569551829 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -13,8 +13,12 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) {
@ -32,7 +32,7 @@ index fb98936bb8a5488db75d676c5bcb4060597fbbf8..9ee90bc753e65f9dd532f28ec75cc16b
"Implementation-Vendor" to date, // Paper
"Specification-Title" to "Bukkit",
"Specification-Version" to project.version,
@@ -149,7 +153,7 @@ fun TaskContainer.registerRunTask(
@@ -156,7 +160,7 @@ fun TaskContainer.registerRunTask(
name: String,
block: JavaExec.() -> Unit
): TaskProvider<JavaExec> = register<JavaExec>(name) {
@ -93,10 +93,10 @@ index 9d687da5bdf398bb3f6c84cdf1249a7213d09f2e..e2f704c115fd6e00960bb56bb0779f11
).openBufferedStream()) {
JsonObject json = new Gson().fromJson(reader, JsonObject.class);
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 67ee3a4ca8a6cdeb275653d492a1fea8037c51fb..211408450ab4bf714860a52a9deff63e75ec20d1 100644
index 97745f0bab8d82d397c6c2a5775aed92bca0a034..a17160766eb15e8d11ddcce23747f8ab1923b676 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1692,7 +1692,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1697,7 +1697,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@DontObfuscate
public String getServerModName() {
@ -106,10 +106,10 @@ index 67ee3a4ca8a6cdeb275653d492a1fea8037c51fb..211408450ab4bf714860a52a9deff63e
public SystemReport fillSystemReport(SystemReport details) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index ec4b73321205b472f19fa5bd4ad95893020d1340..3cb207d02824af2c688e0ac9ea81860569042d65 100644
index fcd5096d64edfaf6bce3ecce8c9b9afb84462786..c9fbd5b27d01e440ad858711827698b602d660bd 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -265,7 +265,7 @@ import javax.annotation.Nullable; // Paper
@@ -267,7 +267,7 @@ import javax.annotation.Nullable; // Paper
import javax.annotation.Nonnull; // Paper
public final class CraftServer implements Server {

View File

@ -5,7 +5,7 @@ Subject: [PATCH] MC-Dev fixes
diff --git a/src/main/java/net/minecraft/world/entity/ai/Brain.java b/src/main/java/net/minecraft/world/entity/ai/Brain.java
index ef6e968ed2708272eab407a983928382a2f2049c..a2de99709ce14303a309806c683da6b3548659c1 100644
index dea20f16ac97402f754c8e47d03e9ef38de73190..21e5d1451f90194aa415cf0a183d1a731854f605 100644
--- a/src/main/java/net/minecraft/world/entity/ai/Brain.java
+++ b/src/main/java/net/minecraft/world/entity/ai/Brain.java
@@ -72,15 +72,15 @@ public class Brain<E extends LivingEntity> {

File diff suppressed because it is too large Load Diff

View File

@ -6,30 +6,30 @@ Subject: [PATCH] Max pending logins
Should help the floodgates on launch
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
index 2e96377d628b3a07fb565020074d665f594f32e8..75b1877f8c3e4da3183437f327ef3376fd0a3c21 100644
index 57649d7fd11bef6395e04c075980e4c34eeffaa8..106b06a1d8fbda3fae7229252e78b9c17793e988 100644
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
@@ -85,7 +85,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
UUID uniqueId = UUIDUtil.getOrCreatePlayerUUID(this.gameProfile);
@@ -88,7 +88,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
if (this.server.getPlayerList().pushPendingJoin(name, uniqueId, this.connection)) {
this.handleAcceptedLogin();
- }
+ } else { --this.tick; } // Folia - max concurrent logins
// Folia end - region threading - rewrite login process
} // Folia - region threading - remove delayed accept
this.verifyLoginAndFinishConnectionSetup((GameProfile) Objects.requireNonNull(this.authenticatedProfile));
- } // Folia - region threading - rewrite login process
+ } else { --this.tick; } // Folia - region threading - rewrite login process // Folia - max concurrent logins
}
if (this.state == ServerLoginPacketListenerImpl.State.WAITING_FOR_DUPE_DISCONNECT && !this.isPlayerAlreadyInWorld((GameProfile) Objects.requireNonNull(this.authenticatedProfile))) {
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 82c7235ad9f4bc4a9f6e018c9905d49790396918..1f70b0810ab992851662fe27c7522bc9eabf5f5f 100644
index 3f3d3cfa046124197bf7ed8d7f4b651bf8a73416..3ed41fc4c73e418ea11ed11e365423e014c88715 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -180,6 +180,17 @@ public abstract class PlayerList {
@@ -173,6 +173,17 @@ public abstract class PlayerList {
conflictingId = this.connectionById.get(byId);
if (conflictingName == null && conflictingId == null) {
+ // Folia start - max concurrent login
+ int loggedInCount = 0;
+ for (Connection value : this.connectionById.values()) {
+ if (value.isPlayerConnected()) {
+ if (value.getPacketListener() instanceof ServerGamePacketListenerImpl) {
+ ++loggedInCount;
+ }
+ }

View File

@ -5,7 +5,7 @@ Subject: [PATCH] Add chunk system throughput counters to /tps
diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkFullTask.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkFullTask.java
index 300700477ee34bc22b31315825c0e40f61070cd5..0b78d1eb90500e0123b7281d722805dc65d551d0 100644
index 679ed4d53269e1113035b462cf74ab16a231e22e..8a48238fac0949cfddcdd9ccf179d16befe9c4d4 100644
--- a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkFullTask.java
+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkFullTask.java
@@ -22,6 +22,9 @@ public final class ChunkFullTask extends ChunkProgressionTask implements Runnabl

View File

@ -29,10 +29,10 @@ index 41bf71d116ffc5431586ce54abba7f8def6c1dcf..519da6886613b8460e989767b1a21e31
}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 71830b5fbeda3c7c63460c7cee05217dcc084882..fa35d2c1c8de225acd68e08f15976c92f7ab82aa 100644
index 47061546345d0f367aa64c2d562a53509829d499..e1b6673729e71bdc929bc7b76983108a59e55891 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2821,6 +2821,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -2872,6 +2872,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
if (!force && (!this.canRide(entity) || !entity.canAddPassenger(this))) {
return false;
} else {
@ -40,7 +40,7 @@ index 71830b5fbeda3c7c63460c7cee05217dcc084882..fa35d2c1c8de225acd68e08f15976c92
// CraftBukkit start
if (entity.getBukkitEntity() instanceof Vehicle && this.getBukkitEntity() instanceof LivingEntity) {
VehicleEnterEvent event = new VehicleEnterEvent((Vehicle) entity.getBukkitEntity(), this.getBukkitEntity());
@@ -2842,6 +2843,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -2893,6 +2894,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
if (event.isCancelled()) {
return false;
}
@ -48,7 +48,7 @@ index 71830b5fbeda3c7c63460c7cee05217dcc084882..fa35d2c1c8de225acd68e08f15976c92
// Spigot end
if (this.isPassenger()) {
this.stopRiding();
@@ -2924,6 +2926,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -2971,6 +2973,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
throw new IllegalStateException("Use x.stopRiding(y), not y.removePassenger(x)");
} else {
// CraftBukkit start
@ -56,7 +56,7 @@ index 71830b5fbeda3c7c63460c7cee05217dcc084882..fa35d2c1c8de225acd68e08f15976c92
CraftEntity craft = (CraftEntity) entity.getBukkitEntity().getVehicle();
Entity orig = craft == null ? null : craft.getHandle();
if (this.getBukkitEntity() instanceof Vehicle && entity.getBukkitEntity() instanceof LivingEntity) {
@@ -2951,6 +2954,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
@@ -2998,6 +3001,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
if (event.isCancelled()) {
return false;
}
@ -246,10 +246,10 @@ index 56bc26f227b97e8e935a20c6393d3f2eb806b285..5cf8ea3a7dd4e8ea96ca6061aa1aaefc
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java
index 00201cf495355939a4f35306b0e7b130c07e5c02..fd0e0eee97c3872cebeb66dabf895ccfa40a6392 100644
index c13d7fd15d8614f1ced30569fd1eae732a31b800..a0979910520442b2cabd9e87b78448e40e753641 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java
@@ -25,8 +25,16 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud
@@ -26,8 +26,16 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud
super(server, entity);
}
@ -288,7 +288,7 @@ index dc26be80f2c1f058451c0d446165bc78a0ff8c47..774f0f90ad66a0f5f33d1008c036ff51
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
index 9f30946c7a198e2a277b65c02fcd75570c5dbad6..8c73acf622e04a7a43b1be3bf96a5420d4caa2e0 100644
index 96a20efc60efef4485eca9ebffed92dc195ed357..4a7ec1c1b479c68d0ec08b78e06b53255d725c08 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
@@ -142,8 +142,16 @@ public class CraftArrow extends AbstractProjectile implements AbstractArrow {
@ -456,10 +456,10 @@ index 80e571c977db5cdf43bfbfce035f37a3fa325c95..6fafba37dd7128a397ba046be7b33067
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java
index 533a339a2c7369475f1a66ae2c8bb1df04914614..d4e3baefd84a10e29ce1156608d36ecffbd7b634 100644
index 6c9531c018be29b5794d047b50007fde1b50b494..cb2f710a48c1e42cf800f657befaac4e2b8a82ff 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java
@@ -13,8 +13,16 @@ public class CraftCat extends CraftTameableAnimal implements Cat {
@@ -15,8 +15,16 @@ public class CraftCat extends CraftTameableAnimal implements Cat {
super(server, entity);
}
@ -666,7 +666,7 @@ index 6ccb32786b3abe1109dcc2d083cd231b70d8c6b4..c3a489167197ab6392491257d9d11d80
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftDisplay.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftDisplay.java
index 2fd4a8a495fd8f750fbac4fb3c571e1303fd1fab..979a26b3fc9989c0c61971fd20163f1630ddd9da 100644
index dcfac4aebb058becafee88a334bbf1449124a2e6..4a40d50d456fbd8d736a87c887adaefdd8301257 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftDisplay.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftDisplay.java
@@ -12,8 +12,16 @@ public class CraftDisplay extends CraftEntity implements Display {
@ -897,10 +897,10 @@ index d657fd2c507a5b215aeab0a5f3e9c2ee892a27c8..9fc90b162aab15a9cd60b02aba563181
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index cba19dc27925b38f48182726a8ed6f3691ce87cc..ffc3c9908281a3018ca5b4e244690d459c456d83 100644
index b2e5ae982331555e6eb3569c88d6ab8c259ee9bc..ef5d2e221463c9bae5a1275223acce7c2027fac2 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -827,7 +827,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@@ -826,7 +826,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@Override
public UUID getUniqueId() {
@ -909,7 +909,7 @@ index cba19dc27925b38f48182726a8ed6f3691ce87cc..ffc3c9908281a3018ca5b4e244690d45
}
@Override
@@ -842,6 +842,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
@@ -841,6 +841,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
}
public Entity getHandle() {
@ -1128,10 +1128,10 @@ index 6149067a14b950e727d3387055016a19e55c0fc6..929c817b7101973c4cc9f8f5a23f1941
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFrog.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFrog.java
index 38f16446f21761d009974930d587dafc6f700e4d..43d4027af0a1408bcef71c0f381a629c9099fe97 100644
index 20284ba684d29c619532e076f46e11572b50d367..ad5dcae61a58dd85e01b4dcb915348acc7e74642 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFrog.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFrog.java
@@ -14,8 +14,16 @@ public class CraftFrog extends CraftAnimals implements org.bukkit.entity.Frog {
@@ -16,8 +16,16 @@ public class CraftFrog extends CraftAnimals implements org.bukkit.entity.Frog {
super(server, entity);
}
@ -1359,7 +1359,7 @@ index 8b13f6c315675bca8362be16f6511b5b7da34670..584703f2d7d14efd79568663cd833cb3
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
index 7db63d9ef93902872937b69f431137336e4abc3a..5a2557570a78ef04270c2b418a63081cf3995cb7 100644
index 017e97c1618b8ee4640b36a0ec1b07026047bfc3..546a7fd563cc0291b5e15e8f67b4c3b8fc4067af 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
@@ -291,8 +291,16 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
@ -1569,7 +1569,7 @@ index dbb435ec7a930c3b410fc4311f7eb0a4d2faa987..61f7630d2160411f35cc3ca33def30b9
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index b25f5931f836fd4d8695120f0bcb7c52deff8583..d2ab898c0f3902f5f0f9847232dac244b4095854 100644
index fe2124694eb080cab685a1ce1f6a66e2fcdf6a17..28062755016008d0796676119fdd53d4a3947e20 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -417,6 +417,13 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
@ -1806,11 +1806,11 @@ index 79b608e89d4d1f76a58868c585bb87c82e2689b1..7767a342b3d8bf9c07fbd73ad4ccacd8
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
index 18b9b0dc70f6872a9d71c120bcd2edca531b0ac4..148d0393b093a326f76fc34c035768f4758f3f1b 100644
index 153e4c88c168097eb4a78650e7c9c120bec202a3..d03069ef4e2b2b82d399cc5d4d6c093a9a763a88 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
@@ -55,8 +55,16 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob {
return (sound != null) ? CraftSound.getBukkit(sound) : null;
return (sound != null) ? CraftSound.minecraftToBukkit(sound) : null;
}
+ // Folia start - region threading
@ -1857,7 +1857,7 @@ index 11b23670cd80a643f266c59542a380b42b17dfbd..d3b655ab5adacd60f04f912187662c57
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
index 1efc208dbb00b693de0c1d883e90b310cbf253e7..7c41ca305e4bb6e7aa858714763a3b6071ce2b18 100644
index efecddaa165decac6e0958b202ad838405220627..c79bb57c3734fb313ae1a02c2c5185ba35d676f1 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
@@ -10,8 +10,16 @@ public class CraftMushroomCow extends CraftCow implements MushroomCow, io.paperm
@ -1899,10 +1899,10 @@ index b6c10507d4d62178cdf82033cc379d66d763aa9b..e0cc8454d7c2e6f3ae1805c686f3ee25
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java
index 7f4b7ce6b85b4774f58be2c9afd4230a821dd9cc..1f1b4a7b7f6a74d9830402bfb03bf85335fd9825 100644
index 3d13a79f9add2e45db7f8538ee15e0d4e37a1314..bf06c6250c98ecc10b3585a1a0a4a2385e9a789e 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java
@@ -51,8 +51,16 @@ public class CraftPainting extends CraftHanging implements Painting {
@@ -50,8 +50,16 @@ public class CraftPainting extends CraftHanging implements Painting {
return false;
}
@ -2025,7 +2025,7 @@ index fd9a841ed8a0062ece142d0cd2591786104fdda7..45653b31d2b4febe8d14bc6e1b9aa86a
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
index f69c81e801569deae8a2536a1a57767cd2e3897f..35fab47b32808395b787d29cdfc686f5344b1bcd 100644
index 03e74b29ebf0f9b9a0dbc6ffc872e22a22be20f0..c7411045c4901b6a66c62d68be911a4d7d1f7a9c 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
@@ -75,8 +75,16 @@ public class CraftPiglin extends CraftPiglinAbstract implements Piglin, com.dest
@ -2109,10 +2109,10 @@ index 2638c341bc02f201f7ab17fdebcdbdf3a7ec05bf..0f5c2d31a2dea13a46ba81e353393633
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 2d9667e4af4629982d449249169bb55d2112dd26..8d63d9c4b2665fffcf019e69e837ba461ab017f6 100644
index be7904a09181ce00acb887a35eec92070515fc05..27ace1119456c92b456d08a464c58d4231685f9c 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -609,7 +609,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@@ -611,7 +611,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public void kick(net.kyori.adventure.text.Component message, org.bukkit.event.player.PlayerKickEvent.Cause cause) {
@ -2121,7 +2121,7 @@ index 2d9667e4af4629982d449249169bb55d2112dd26..8d63d9c4b2665fffcf019e69e837ba46
final ServerGamePacketListenerImpl connection = this.getHandle().connection;
if (connection != null) {
connection.disconnect(message == null ? net.kyori.adventure.text.Component.empty() : message, cause);
@@ -2146,9 +2146,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@@ -2148,9 +2148,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
return this;
}
@ -2139,7 +2139,7 @@ index 2d9667e4af4629982d449249169bb55d2112dd26..8d63d9c4b2665fffcf019e69e837ba46
}
public void setHandle(final ServerPlayer entity) {
@@ -3148,7 +3155,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@@ -3164,7 +3171,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
{
if ( CraftPlayer.this.getHealth() <= 0 && CraftPlayer.this.isOnline() )
{
@ -2234,7 +2234,7 @@ index 1a1dfb9e5164f9962059ebf11a9c3334a1987153..38972d1aec6b32aee12972cbca2411ca
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftRaider.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftRaider.java
index c3185e189ed06e27e518d29b8577b8f694220b12..cfb231848766414297a13fea16308597546c86ce 100644
index 763c368e299588f9a0e085a8a5e04e97e1f33428..58de24aeb98f19b2cf3fa9b0ad17e8b14bc1e475 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftRaider.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftRaider.java
@@ -16,8 +16,16 @@ public abstract class CraftRaider extends CraftMonster implements Raider {
@ -2802,10 +2802,10 @@ index 04bcb1f26db12556d70e41541a5df0700d20d964..6bbb6f2720ed8fc8b54edc3922d84232
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftTippedArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftTippedArrow.java
index bf1de518b8429a1543fbc863cf72a2b1e23f05d4..a491a6d96cb267c661d9af9d8c6828e05adb23b2 100644
index 182e8e9ecb789d639b2dd7348a68e37096da53ac..3d3ce1392dc9d86965c4baf80e3d92089da5ed2c 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftTippedArrow.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftTippedArrow.java
@@ -21,8 +21,16 @@ public class CraftTippedArrow extends CraftArrow implements Arrow {
@@ -22,8 +22,16 @@ public class CraftTippedArrow extends CraftArrow implements Arrow {
super(server, entity);
}
@ -2928,10 +2928,10 @@ index 6079581ba2eef8ac9272d0bbbf77e31f593edf0f..f89b72a75dc685c08641105c8445f4e1
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
index f29e221e5b850516c169c03bfbd2b0885d1a841b..1e201709b65b7c74d43d1fbf37bb8f968385358d 100644
index a67b5d20b956e0bf801c9eeb9330567c21927010..6f353590ff2de58fb147bf65495018045976c1f6 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
@@ -29,8 +29,16 @@ public class CraftVillager extends CraftAbstractVillager implements Villager {
@@ -31,8 +31,16 @@ public class CraftVillager extends CraftAbstractVillager implements Villager {
super(server, entity);
}
@ -2949,10 +2949,10 @@ index f29e221e5b850516c169c03bfbd2b0885d1a841b..1e201709b65b7c74d43d1fbf37bb8f96
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillagerZombie.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillagerZombie.java
index 3c14554a6a657223441eee97258734ea05965bc7..bc2588621a80d81a757469a2b65675353da14828 100644
index fd968881eeec6dc5bdf90decc23a2bfc619c410d..96dba371b8fe88f8e15eee5fbc152a0b85bc0511 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillagerZombie.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillagerZombie.java
@@ -18,8 +18,16 @@ public class CraftVillagerZombie extends CraftZombie implements ZombieVillager {
@@ -14,8 +14,16 @@ public class CraftVillagerZombie extends CraftZombie implements ZombieVillager {
super(server, entity);
}

View File

@ -10,10 +10,10 @@ the impact from scaling the region threads, but is not a fix
to the underlying issue.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 99f1e6c72c734079dfc2c2a8b8093554e945fc6a..75eb95c330d6ab7ac1e4a69da13695bbd40f894e 100644
index 3f283e1a5c181819b223c0f44cc5d8f274fd88a6..f9cf331202d0768a054e575c8909369920b3d59f 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -2874,6 +2874,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -2877,6 +2877,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
public final void executeMidTickTasks() {

View File

@ -5,10 +5,10 @@ Subject: [PATCH] Throw UnsupportedOperationException() for broken APIs
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index a6ba1d101dc23b8c27a1498f3f0d21270dfcc18c..a8bf1f542ab20eb7c40c80b5e42b55982677373d 100644
index 7d35722cbf2da92fb0fb8a6306f18472f2499595..249ff636a40f6493444a6ea8b8a5e017cb2c30eb 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1284,6 +1284,7 @@ public final class CraftServer implements Server {
@@ -1266,6 +1266,7 @@ public final class CraftServer implements Server {
@Override
public World createWorld(WorldCreator creator) {
@ -16,7 +16,7 @@ index a6ba1d101dc23b8c27a1498f3f0d21270dfcc18c..a8bf1f542ab20eb7c40c80b5e42b5598
Preconditions.checkState(this.console.getAllLevels().iterator().hasNext(), "Cannot create additional worlds on STARTUP");
//Preconditions.checkState(!this.console.isIteratingOverLevels, "Cannot create a world while worlds are being ticked"); // Paper - Cat - Temp disable. We'll see how this goes.
Preconditions.checkArgument(creator != null, "WorldCreator cannot be null");
@@ -1425,6 +1426,7 @@ public final class CraftServer implements Server {
@@ -1407,6 +1408,7 @@ public final class CraftServer implements Server {
@Override
public boolean unloadWorld(World world, boolean save) {
@ -53,7 +53,7 @@ index a8c5bfc54ed2b8bd873f124c7080d73fe73a86ad..f59e9e6dd21a7d034b5e3b6e7787458d
this.board.setDisplayObjective(CraftScoreboardTranslations.fromBukkitSlot(slot), null);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
index 500f2eb0df5a07637cd278c263e95592b0037eb6..7ab760a57d1305bc4dccec97526328972c2ddfc3 100644
index 7a2f46579352870cfbb32c343d7c68919758ffe3..7fb12a9124a8436f87028269599c40ccf5b1b78f 100644
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
@@ -42,6 +42,7 @@ public final class CraftScoreboardManager implements ScoreboardManager {

View File

@ -6,7 +6,7 @@ Subject: [PATCH] Fix tests by removing them
We don't care about this one, some commands just need to be removed.
diff --git a/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java b/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java
index 4f43882d930ab8816e75b216d9a61a06b79df265..79f39ef98920b87ac196eefbaa46fe7ad6a41a2d 100644
index afeb4271fffb7546209f1e651214065187c88302..6927b8f9f426300c3a85feb4711244ba59ab5c1d 100644
--- a/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java
+++ b/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java
@@ -36,6 +36,7 @@ public class MinecraftCommandPermissionsTest extends AbstractTestingBase {

View File

@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Wed, 29 Mar 2023 10:15:40 -0700
Subject: [PATCH] Work around https://github.com/PaperMC/paperweight/issues/194
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 0114f9e669d3d54a61e909ff2a706d4fe27d53bc..678bba9d636a0eb34270a2d26b5b3d0d6d900115 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -506,7 +506,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
this.disconnect(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(s), cause);
}
- @io.papermc.paper.annotation.DoNotUse // Paper
+ @Deprecated(forRemoval = true) // Folia - https://github.com/PaperMC/paperweight/issues/194
public void disconnect(final Component reason) {
this.disconnect(PaperAdventure.asAdventure(reason), org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN);
}

View File

@ -9,10 +9,10 @@ add explicit block update suppression techniques, it's better
than the server crashing.
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 3a760887aa1469963c34886b38cdb51e91408cd3..916df0c8d263f90e04564c5f512fd5ed5eaaa6d5 100644
index fb889cea13d8f83f193a461ebd58fdcb115a5b34..f9641a54b2d1f2eed2a48323cfa6cdd67dafdf00 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -1429,7 +1429,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
@@ -1744,7 +1744,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
Direction enumdirection = (Direction) iterator.next();
BlockPos blockposition1 = pos.relative(enumdirection);
@ -54,7 +54,7 @@ index 7fddb6fa8fd30ef88346a59f7867aae792f13772..b963f364b4763091c3b5d0f938eaa679
} else {
RailShape blockpropertytrackposition1 = (RailShape) iblockdata.getValue(PoweredRailBlock.SHAPE);
diff --git a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java
index 858f81db707a73edeec2bb4ee62e69ad2f64200c..7b479d0c093732a5a8899b8f3d49a77139ef8826 100644
index f695d81a646307846abb490b484f166be2993382..fe0ae679f3803156c253cc9caa166e7a9c6ddeed 100644
--- a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java
@@ -193,8 +193,9 @@ public class RedStoneWireBlock extends Block {
@ -69,7 +69,7 @@ index 858f81db707a73edeec2bb4ee62e69ad2f64200c..7b479d0c093732a5a8899b8f3d49a771
BlockState iblockdata1 = world.getBlockState(blockposition_mutableblockposition);
diff --git a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
index d50c7dd008af14fce9073666e0fd1b609f89559c..5ddd8108e077bc7c1a9524854ac591c6ab99c174 100644
index 8a139bcfc9c3de5793b1b590be6cafaae01c86e1..a61672154c4f733cdadd9ac34ca5507355d06c68 100644
--- a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
+++ b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
@@ -119,7 +119,8 @@ public class CollectingNeighborUpdater implements NeighborUpdater {

View File

@ -1,55 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 10 Apr 2023 14:14:31 -0700
Subject: [PATCH] Lag compensate block breaking
Due to TPS catchup being removed, a lost tick will always
affect block breaking.
Additionally, constant low TPS would affect block breaking
in an intrusive manner to the user when there is no need
for that to occur.
diff --git a/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java b/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java
index 41db6c61de36ebb1c214423dca0ba6a0c5a95cc1..65c4e158d81ac5c5788cf4dcb379061aebd23dcd 100644
--- a/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java
+++ b/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java
@@ -432,11 +432,25 @@ public final class RegionizedWorldData {
return this.tickData;
}
+ // Folia start - lag compensation
+ public static final long SERVER_INIT = System.nanoTime();
+
+ private long lagCompensationTick;
+
+ public long getLagCompensationTick() {
+ return this.lagCompensationTick;
+ }
+ // Folia end - lag compensation
+
public void updateTickData() {
this.tickData = this.world.tickData;
this.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
this.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
this.skipHopperEvents = this.world.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper
+ // Folia start - lag compensation
+ // always subtract from server init so that the tick starts at zero, allowing us to cast to int without much worry
+ this.lagCompensationTick = (System.nanoTime() - SERVER_INIT) / TickRegionScheduler.TIME_BETWEEN_TICKS;
+ // Folia end - lag compensation
}
// connections
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
index 82e9307e4c95edc30c9dd78cd3fefa8725140361..658effccd87cd4c940da806bcfccf47b28684d1e 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
@@ -124,7 +124,7 @@ public class ServerPlayerGameMode {
}
public void tick() {
- ++this.gameTicks; // CraftBukkit; // Folia - region threading
+ this.gameTicks = (int)this.level.getCurrentWorldData().getLagCompensationTick(); // CraftBukkit; // Folia - region threading // Folia - lag compensation
BlockState iblockdata;
if (this.hasDelayedDestroy) {

View File

@ -9,10 +9,10 @@ data deserialization and is racey even in Vanilla. But in Folia,
some accesses may throw and as such we need to fix this directly.
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 587934b8e96a3d8b8a57cda8730eb331aa63ef65..7cb6a0b99c8e51f7f767b704071473c5d8bded7d 100644
index 914910653d90c9519062a0f1ccc9bb2f1e3ec417..500b05ce2cda7b2c0e5332e2921d55a3101fc451 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -629,7 +629,7 @@ public class ServerPlayer extends Player {
@@ -636,7 +636,7 @@ public class ServerPlayer extends Player {
this.getBukkitEntity().readExtraData(nbt); // CraftBukkit
if (this.isSleeping()) {
@ -22,10 +22,10 @@ index 587934b8e96a3d8b8a57cda8730eb331aa63ef65..7cb6a0b99c8e51f7f767b704071473c5
// CraftBukkit start
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 50e1390f455cf8e6da9153760f32ccb81aa20bd1..17d6349ccdbb6ac91b2705be0b855e768423c50a 100644
index a4f2d8cc7ca428c276ad509f34c02370b13d60a3..af739286a752b50a2e207d243cd393e492729441 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -4280,6 +4280,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -4343,6 +4343,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
});

View File

@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: WillQi <williamqipizza@gmail.com>
Date: Mon, 15 May 2023 23:45:09 -0600
Subject: [PATCH] Fix off region raid heroes
This patch aims to solve a potential incorrect thread call when completing a raid.
If a player is a hero of the village but proceeds to leave the region of the
raid before it's completion, it would throw an exception due to not being on the
same region thread anymore.
diff --git a/src/main/java/net/minecraft/world/entity/raid/Raid.java b/src/main/java/net/minecraft/world/entity/raid/Raid.java
index 8fc22de1aa17cd8cb52d3804533d56cbb0e6bfeb..49c0f085756889a176684922206b27ca0c660949 100644
--- a/src/main/java/net/minecraft/world/entity/raid/Raid.java
+++ b/src/main/java/net/minecraft/world/entity/raid/Raid.java
@@ -410,14 +410,22 @@ public class Raid {
LivingEntity entityliving = (LivingEntity) entity;
if (!entity.isSpectator()) {
- entityliving.addEffect(new MobEffectInstance(MobEffects.HERO_OF_THE_VILLAGE, 48000, this.badOmenLevel - 1, false, false, true));
+ //entityliving.addEffect(new MobEffectInstance(MobEffects.HERO_OF_THE_VILLAGE, 48000, this.badOmenLevel - 1, false, false, true)); // Folia - Fix off region raid heroes - move down
if (entityliving instanceof ServerPlayer) {
ServerPlayer entityplayer = (ServerPlayer) entityliving;
- entityplayer.awardStat(Stats.RAID_WIN);
- CriteriaTriggers.RAID_WIN.trigger(entityplayer);
+ // Folia start - Fix off region raid heroes - moved down
winners.add(entityplayer.getBukkitEntity()); // CraftBukkit
}
+ // Folia start - Fix off region raid heroes
+ entityliving.getBukkitEntity().taskScheduler.schedule((LivingEntity lv) -> {
+ lv.addEffect(new MobEffectInstance(MobEffects.HERO_OF_THE_VILLAGE, 48000, this.badOmenLevel - 1, false, false, true));
+ if (lv instanceof ServerPlayer entityplayer) {
+ entityplayer.awardStat(Stats.RAID_WIN);
+ CriteriaTriggers.RAID_WIN.trigger(entityplayer);
+ }
+ }, null, 1L);
+ // Folia end - Fix off region raid heroes
}
}
}

View File

@ -45,10 +45,10 @@ index 8b96d1b7548d354fbcabe6d1b5e9d6c3e2a5cb9d..e8fb179c5f443efd70293f31cdf00ca2
public static record TicksToSave(SerializableTickContainer<Block> blocks, SerializableTickContainer<Fluid> fluids) {
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 e270816f5bbdfcfeaaaf647beb2298a314569a93..94edc970f64a2c0f89eb6666de21f0f01d1c1c9d 100644
index 197462de762592c129cc504cac17515ebd5aa38a..c474dec43f4c46421cdabc1154e22a3b269b0f11 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -306,7 +306,7 @@ public class LevelChunk extends ChunkAccess {
@@ -264,7 +264,7 @@ public class LevelChunk extends ChunkAccess {
}
}
@ -57,7 +57,7 @@ index e270816f5bbdfcfeaaaf647beb2298a314569a93..94edc970f64a2c0f89eb6666de21f0f0
this.setLightCorrect(protoChunk.isLightCorrect());
this.unsaved = true;
this.needsDecoration = true; // CraftBukkit
@@ -498,7 +498,7 @@ public class LevelChunk extends ChunkAccess {
@@ -456,7 +456,7 @@ public class LevelChunk extends ChunkAccess {
ProfilerFiller gameprofilerfiller = this.level.getProfiler();
gameprofilerfiller.push("updateSkyLightSources");

View File

@ -1,43 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: WillQi <williamqipizza@gmail.com>
Date: Mon, 15 May 2023 23:45:09 -0600
Subject: [PATCH] Fix off region raid heroes
This patch aims to solve a potential incorrect thread call when completing a raid.
If a player is a hero of the village but proceeds to leave the region of the
raid before it's completion, it would throw an exception due to not being on the
same region thread anymore.
diff --git a/src/main/java/net/minecraft/world/entity/raid/Raid.java b/src/main/java/net/minecraft/world/entity/raid/Raid.java
index 113583d0d9de744e314bc7ee15cb8e21ec4a92f9..ddec5251b335a25cb9d8726396d90d94572dbd6b 100644
--- a/src/main/java/net/minecraft/world/entity/raid/Raid.java
+++ b/src/main/java/net/minecraft/world/entity/raid/Raid.java
@@ -407,12 +407,25 @@ public class Raid {
if (entity instanceof LivingEntity && !entity.isSpectator()) {
LivingEntity entityliving = (LivingEntity) entity;
- entityliving.addEffect(new MobEffectInstance(MobEffects.HERO_OF_THE_VILLAGE, 48000, this.badOmenLevel - 1, false, false, true));
+ // Folia start - Fix off region raid heroes
+ entityliving.getBukkitLivingEntity().taskScheduler.schedule(task -> {
+ entityliving.addEffect(new MobEffectInstance(MobEffects.HERO_OF_THE_VILLAGE, 48000, this.badOmenLevel - 1, false, false, true));
+
+ if (entityliving instanceof ServerPlayer) {
+ ServerPlayer entityplayer = (ServerPlayer) entityliving;
+
+ entityplayer.awardStat(Stats.RAID_WIN);
+ CriteriaTriggers.RAID_WIN.trigger(entityplayer);
+ }
+ }, null, 0);
+ // Folia end
if (entityliving instanceof ServerPlayer) {
ServerPlayer entityplayer = (ServerPlayer) entityliving;
- entityplayer.awardStat(Stats.RAID_WIN);
- CriteriaTriggers.RAID_WIN.trigger(entityplayer);
+ // Folia start - Fix off region raid heroes
+ // entityplayer.awardStat(Stats.RAID_WIN);
+ // CriteriaTriggers.RAID_WIN.trigger(entityplayer);
+ // Folia end
winners.add(entityplayer.getBukkitEntity()); // CraftBukkit
}
}

View File

@ -7,10 +7,10 @@ This allows the player to be re-positioned before logging into
the world without causing thread checks to trip on Folia.
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 1f70b0810ab992851662fe27c7522bc9eabf5f5f..4f7a9a4ca030c8349a684080b44547f66ed0d2d7 100644
index 3ed41fc4c73e418ea11ed11e365423e014c88715..7bfbcda5cf086c3c50f8cb202ceaf685a899141c 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -506,7 +506,13 @@ public abstract class PlayerList {
@@ -492,7 +492,13 @@ public abstract class PlayerList {
CompoundTag nbttagcompound1 = nbttagcompound.getCompound("RootVehicle");
// CraftBukkit start
ServerLevel finalWorldServer = worldserver1;

View File

@ -1,50 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sun, 18 Jun 2023 22:56:19 -0700
Subject: [PATCH] fixup! Rewrite chunk system
diff --git a/src/main/java/io/papermc/paper/chunk/system/RegionizedPlayerChunkLoader.java b/src/main/java/io/papermc/paper/chunk/system/RegionizedPlayerChunkLoader.java
index 7b664f32868028758d0c6ee1eaa82efcd83661d2..c5df121d6194a97b20dc390698991b9c72dba538 100644
--- a/src/main/java/io/papermc/paper/chunk/system/RegionizedPlayerChunkLoader.java
+++ b/src/main/java/io/papermc/paper/chunk/system/RegionizedPlayerChunkLoader.java
@@ -788,20 +788,34 @@ public class RegionizedPlayerChunkLoader {
// try to push more chunk generations
final long maxGens = Math.max(0L, Math.min(MAX_RATE, Math.min(this.genQueue.size(), this.getMaxChunkGenerates())));
final int maxGensThisTick = (int)this.chunkGenerateTicketLimiter.takeAllocation(time, genRate, maxGens);
- for (int i = 0; i < maxGensThisTick; ++i) {
- final long chunk = this.genQueue.dequeueLong();
- final byte prev = this.chunkTicketStage.put(chunk, CHUNK_TICKET_STAGE_GENERATING);
+ int ratedGensThisTick = 0;
+ while (!this.genQueue.isEmpty()) {
+ final long chunkKey = this.genQueue.firstLong();
+ final int chunkX = CoordinateUtils.getChunkX(chunkKey);
+ final int chunkZ = CoordinateUtils.getChunkZ(chunkKey);
+ final ChunkAccess chunk = this.world.chunkSource.getChunkAtImmediately(chunkX, chunkZ);
+ if (chunk.getStatus() != ChunkStatus.FULL) {
+ // only rate limit actual generations
+ if ((ratedGensThisTick + 1) > maxGensThisTick) {
+ break;
+ }
+ ++ratedGensThisTick;
+ }
+
+ this.genQueue.dequeueLong();
+
+ final byte prev = this.chunkTicketStage.put(chunkKey, CHUNK_TICKET_STAGE_GENERATING);
if (prev != CHUNK_TICKET_STAGE_LOADED) {
throw new IllegalStateException("Previous state should be " + CHUNK_TICKET_STAGE_LOADED + ", not " + prev);
}
this.pushDelayedTicketOp(
ChunkHolderManager.TicketOperation.addAndRemove(
- chunk,
+ chunkKey,
REGION_PLAYER_TICKET, GENERATED_TICKET_LEVEL, this.idBoxed,
REGION_PLAYER_TICKET, LOADED_TICKET_LEVEL, this.idBoxed
)
);
- this.generatingQueue.enqueue(chunk);
+ this.generatingQueue.enqueue(chunkKey);
}
// try to pull ticking chunks

View File

@ -1,50 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sun, 18 Jun 2023 23:04:46 -0700
Subject: [PATCH] Do not read tile entities in chunks that are positioned
outside of the chunk
The tile entities are not accessible and so should not be loaded.
This can happen as a result of users moving regionfiles around,
which would cause a crash on Folia but would appear to function
fine on Paper.
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
index bc938c2a4cb30f3151b600ab88ca5c4e9734f326..035b06d00aadc67eb247efd7b25aea92ba0532a2 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
@@ -381,6 +381,13 @@ public class ChunkSerializer {
for (int k1 = 0; k1 < nbttaglist3.size(); ++k1) {
CompoundTag nbttagcompound4 = nbttaglist3.getCompound(k1);
+ // Paper start - do not read tile entities positioned outside the chunk
+ BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound4);
+ if ((blockposition.getX() >> 4) != chunkPos.x || (blockposition.getZ() >> 4) != chunkPos.z) {
+ LOGGER.warn("Tile entity serialized in chunk " + chunkPos + " in world '" + world.getWorld().getName() + "' positioned at " + blockposition + " is located outside of the chunk");
+ continue;
+ }
+ // Paper end - do not read tile entities positioned outside the chunk
((ChunkAccess) object1).setBlockEntityNbt(nbttagcompound4);
}
@@ -679,10 +686,19 @@ public class ChunkSerializer {
CompoundTag nbttagcompound1 = nbttaglist1.getCompound(i);
boolean flag = nbttagcompound1.getBoolean("keepPacked");
+ // Paper start - do not read tile entities positioned outside the chunk
+ BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound1); // moved up
+ ChunkPos chunkPos = chunk.getPos();
+ if ((blockposition.getX() >> 4) != chunkPos.x || (blockposition.getZ() >> 4) != chunkPos.z) {
+ LOGGER.warn("Tile entity serialized in chunk " + chunkPos + " in world '" + world.getWorld().getName() + "' positioned at " + blockposition + " is located outside of the chunk");
+ continue;
+ }
+ // Paper end - do not read tile entities positioned outside the chunk
+
if (flag) {
chunk.setBlockEntityNbt(nbttagcompound1);
} else {
- BlockPos blockposition = BlockEntity.getPosFromTag(nbttagcompound1);
+ // Paper - do not read tile entities positioned outside the chunk - move up
BlockEntity tileentity = BlockEntity.loadStatic(blockposition, chunk.getBlockState(blockposition), nbttagcompound1);
if (tileentity != null) {

View File

@ -1,174 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sun, 18 Jun 2023 23:25:29 -0700
Subject: [PATCH] fixup! Rewrite chunk system
diff --git a/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java b/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java
index 26d1e1af418f980b61a57479cbc64b5bc59e0864..0cdf092d5c3f65a23e26f201768c0e2fea1ffe09 100644
--- a/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java
+++ b/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java
@@ -17,6 +17,7 @@ import net.minecraft.util.AbortableIterationConsumer;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
+import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.entity.EntityInLevelCallback;
import net.minecraft.world.level.entity.EntityTypeTest;
import net.minecraft.world.level.entity.LevelCallback;
@@ -24,6 +25,7 @@ import net.minecraft.server.level.FullChunkStatus;
import net.minecraft.world.level.entity.LevelEntityGetter;
import net.minecraft.world.level.entity.Visibility;
import net.minecraft.world.phys.AABB;
+import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
@@ -319,22 +321,55 @@ public final class EntityLookup implements LevelEntityGetter<Entity> {
this.getChunk(x, z).updateStatus(newStatus, this);
}
- public void addLegacyChunkEntities(final List<Entity> entities) {
- for (int i = 0, len = entities.size(); i < len; ++i) {
- this.addEntity(entities.get(i), true);
- }
+ public void addLegacyChunkEntities(final List<Entity> entities, final ChunkPos forChunk) {
+ this.addEntityChunk(entities, forChunk, true);
}
- public void addEntityChunkEntities(final List<Entity> entities) {
- for (int i = 0, len = entities.size(); i < len; ++i) {
- this.addEntity(entities.get(i), true);
+ public void addEntityChunkEntities(final List<Entity> entities, final ChunkPos forChunk) {
+ this.addEntityChunk(entities, forChunk, true);
+ }
+
+ public void addWorldGenChunkEntities(final List<Entity> entities, final ChunkPos forChunk) {
+ this.addEntityChunk(entities, forChunk, false);
+ }
+
+ private void addRecursivelySafe(final Entity root, final boolean fromDisk) {
+ if (!this.addEntity(root, fromDisk)) {
+ // possible we are a passenger, and so should dismount from any valid entity in the world
+ root.stopRiding(true);
+ return;
+ }
+ for (final Entity passenger : root.getPassengers()) {
+ this.addRecursivelySafe(passenger, fromDisk);
}
}
- public void addWorldGenChunkEntities(final List<Entity> entities) {
+ private void addEntityChunk(final List<Entity> entities, final ChunkPos forChunk, final boolean fromDisk) {
for (int i = 0, len = entities.size(); i < len; ++i) {
- this.addEntity(entities.get(i), false);
- }
+ final Entity entity = entities.get(i);
+ if (entity.isPassenger()) {
+ continue;
+ }
+
+ if (!entity.chunkPosition().equals(forChunk)) {
+ LOGGER.warn("Root entity " + entity + " is outside of serialized chunk " + forChunk);
+ // can't set removed here, as we may not own the chunk position
+ // skip the entity
+ continue;
+ }
+
+ final Vec3 rootPosition = entity.position();
+
+ // always adjust positions before adding passengers in case plugins access the entity, and so that
+ // they are added to the right entity chunk
+ for (final Entity passenger : entity.getIndirectPassengers()) {
+ if (!passenger.chunkPosition().equals(forChunk)) {
+ passenger.setPosRaw(rootPosition.x, rootPosition.y, rootPosition.z, true);
+ }
+ }
+
+ this.addRecursivelySafe(entity, fromDisk);
+ }
}
public boolean addNewEntity(final Entity entity) {
diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkFullTask.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkFullTask.java
index 0b78d1eb90500e0123b7281d722805dc65d551d0..8a48238fac0949cfddcdd9ccf179d16befe9c4d4 100644
--- a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkFullTask.java
+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkFullTask.java
@@ -83,7 +83,7 @@ public final class ChunkFullTask extends ChunkProgressionTask implements Runnabl
final ServerLevel world = this.world;
final ProtoChunk protoChunk = (ProtoChunk)this.fromChunk;
chunk = new LevelChunk(this.world, protoChunk, (final LevelChunk unused) -> {
- ChunkMap.postLoadProtoChunk(world, protoChunk.getEntities());
+ ChunkMap.postLoadProtoChunk(world, protoChunk.getEntities(), protoChunk.getPos()); // Paper - rewrite chunk system
});
}
diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java
index f1c68d9850ece7532a8607db955eaa4fc3a4bf05..08075b8895f816420c2a940bf551dfada3c0cd9e 100644
--- a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java
+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java
@@ -115,7 +115,7 @@ public final class NewChunkHolder {
if (entityChunk != null) {
final List<Entity> entities = EntityStorage.readEntities(this.world, entityChunk);
- this.world.getEntityLookup().addEntityChunkEntities(entities);
+ this.world.getEntityLookup().addEntityChunkEntities(entities, new ChunkPos(this.chunkX, this.chunkZ));
}
}
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 475edb726964f3757957474856c61ac89812c15e..6885961c7eaa07b8b25e48ca0e33e310379f6114 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -595,7 +595,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return chunkstatus1;
}
- public static void postLoadProtoChunk(ServerLevel world, List<CompoundTag> nbt) { // Paper - public
+ public static void postLoadProtoChunk(ServerLevel world, List<CompoundTag> nbt, ChunkPos position) { // Paper - public and add chunk position parameter
if (!nbt.isEmpty()) {
// CraftBukkit start - these are spawned serialized (DefinedStructure) and we don't call an add event below at the moment due to ordering complexities
world.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(nbt, world).filter((entity) -> {
@@ -611,7 +611,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
checkDupeUUID(world, entity); // Paper
return !needsRemoval;
- }));
+ }), position); // Paper - rewrite chunk system
// CraftBukkit end
}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index bb07ad1bb895297356b88dfc4cd17e5e93795c38..60b409e873d8f5d7975cce6e86ee2ed5525d348c 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -2663,12 +2663,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
return this.entityLookup; // Paper - rewrite chunk system
}
- public void addLegacyChunkEntities(Stream<Entity> entities) {
- this.entityLookup.addLegacyChunkEntities(entities.toList()); // Paper - rewrite chunk system
+ public void addLegacyChunkEntities(Stream<Entity> entities, ChunkPos forChunk) { // Paper - rewrite chunk system
+ this.entityLookup.addLegacyChunkEntities(entities.toList(), forChunk); // Paper - rewrite chunk system
}
- public void addWorldGenChunkEntities(Stream<Entity> entities) {
- this.entityLookup.addWorldGenChunkEntities(entities.toList()); // Paper - rewrite chunk system
+ public void addWorldGenChunkEntities(Stream<Entity> entities, ChunkPos forChunk) { // Paper - rewrite chunk system
+ this.entityLookup.addWorldGenChunkEntities(entities.toList(), forChunk); // Paper - rewrite chunk system
}
public void startTickingChunk(LevelChunk chunk) {
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
index 035b06d00aadc67eb247efd7b25aea92ba0532a2..97533c4a31ab6137072b79dc4377fd602fef9ea8 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
@@ -678,7 +678,7 @@ public class ChunkSerializer {
return nbttaglist == null && nbttaglist1 == null ? null : (chunk) -> {
if (nbttaglist != null) {
- world.addLegacyChunkEntities(EntityType.loadEntitiesRecursive(nbttaglist, world));
+ world.addLegacyChunkEntities(EntityType.loadEntitiesRecursive(nbttaglist, world), chunk.getPos()); // Paper - rewrite chunk system
}
if (nbttaglist1 != null) {

View File

@ -1,21 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Tue, 25 Jul 2023 11:47:18 -0700
Subject: [PATCH] Make loadChunksAsync callback thread-safe
Need to perform synchronisation on the return list to avoid CMEs
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 60b409e873d8f5d7975cce6e86ee2ed5525d348c..cf8f93734121e5c1959959f0ba13ee4e6db31959 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -347,7 +347,9 @@ public class ServerLevel extends Level implements WorldGenLevel {
java.util.function.Consumer<net.minecraft.world.level.chunk.ChunkAccess> consumer = (net.minecraft.world.level.chunk.ChunkAccess chunk) -> {
if (chunk != null) {
+ synchronized (ret) { // Folia - region threading - make callback thread-safe TODO rebase
ret.add(chunk);
+ } // Folia - region threading - make callback thread-safe TODO rebase
chunkProvider.addTicketAtLevel(TicketType.FUTURE_AWAIT, chunk.getPos(), ticketLevel, holderIdentifier);
}
if (loadedChunks.incrementAndGet() == requiredChunks) {

View File

@ -1,27 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Tue, 8 Aug 2023 17:29:33 -0700
Subject: [PATCH] Fix race condition on UpgradeData.BlockFixers class init
The CHUNKY_FIXERS field is modified during the constructors
of the BlockFixers, but the code that uses CHUNKY_FIXERS does
not properly ensure that BlockFixers has been initialised before
using it, leading to a possible race condition where instances of
BlockFixers are accessed before they have initialised correctly.
We can force the class to initialise fully before accessing the
field by calling any method on the class, and for convenience
we use values().
diff --git a/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java b/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java
index 62709ed72faf823e18ad77477eb2f5dbf9c98660..c4f9057305007ae5aea0d8655965a51080f1438a 100644
--- a/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java
+++ b/src/main/java/net/minecraft/world/level/chunk/UpgradeData.java
@@ -139,6 +139,7 @@ public class UpgradeData {
Fluid fluid = tick.type() == Fluids.EMPTY ? level.getFluidState(tick.pos()).getType() : tick.type();
level.scheduleTick(tick.pos(), fluid, tick.delay(), tick.priority());
});
+ UpgradeData.BlockFixers.values(); // Folia - force the class init so that we don't access CHUNKY_FIXERS before all BlockFixers are initialised
CHUNKY_FIXERS.forEach((logic) -> {
logic.processChunk(level);
});

View File

@ -1,201 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sun, 27 Aug 2023 01:07:34 -0700
Subject: [PATCH] fixup! Optimize Hoppers
diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
index 1eebd3969735bff3e5559ed01ab4a2ec1c3c2de6..81d8de7c80bac16d874faf990cb08f1556a46adc 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
@@ -151,6 +151,43 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
}
+ // Paper start - optimize hoppers
+ private static final int HOPPER_EMPTY = 0;
+ private static final int HOPPER_HAS_ITEMS = 1;
+ private static final int HOPPER_IS_FULL = 2;
+
+ private static int getFullState(final HopperBlockEntity tileEntity) {
+ tileEntity.unpackLootTable(null);
+
+ final List<ItemStack> hopperItems = tileEntity.getItems();
+
+ boolean empty = true;
+ boolean full = true;
+
+ for (int i = 0, len = hopperItems.size(); i < len; ++i) {
+ final ItemStack stack = hopperItems.get(i);
+ if (stack.isEmpty()) {
+ full = false;
+ continue;
+ }
+
+ if (!full) {
+ // can't be full
+ return HOPPER_HAS_ITEMS;
+ }
+
+ empty = false;
+
+ if (stack.getCount() != stack.getMaxStackSize()) {
+ // can't be full or empty
+ return HOPPER_HAS_ITEMS;
+ }
+ }
+
+ return empty ? HOPPER_EMPTY : (full ? HOPPER_IS_FULL : HOPPER_HAS_ITEMS);
+ }
+ // Paper end - optimize hoppers
+
private static boolean tryMoveItems(Level world, BlockPos pos, BlockState state, HopperBlockEntity blockEntity, BooleanSupplier booleansupplier) {
if (world.isClientSide) {
return false;
@@ -158,11 +195,13 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
if (!blockEntity.isOnCooldown() && (Boolean) state.getValue(HopperBlock.ENABLED)) {
boolean flag = false;
- if (!blockEntity.isEmpty()) {
+ int fullState = getFullState(blockEntity); // Paper - optimize hoppers
+
+ if (fullState != HOPPER_EMPTY) { // Paper - optimize hoppers
flag = HopperBlockEntity.ejectItems(world, pos, state, (Container) blockEntity, blockEntity); // CraftBukkit
}
- if (!blockEntity.inventoryFull()) {
+ if (fullState != HOPPER_IS_FULL || flag) { // Paper - optimize hoppers
flag |= booleansupplier.getAsBoolean();
}
@@ -454,7 +493,25 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
}
private static boolean isFullContainer(Container inventory, Direction direction) {
- return allMatch(inventory, direction, STACK_SIZE_TEST); // Paper - no streams
+ // Paper start - optimize hoppers
+ if (inventory instanceof WorldlyContainer worldlyContainer) {
+ for (final int slot : worldlyContainer.getSlotsForFace(direction)) {
+ final ItemStack stack = inventory.getItem(slot);
+ if (stack.getCount() < stack.getMaxStackSize()) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ for (int slot = 0, max = inventory.getContainerSize(); slot < max; ++slot) {
+ final ItemStack stack = inventory.getItem(slot);
+ if (stack.getCount() < stack.getMaxStackSize()) {
+ return false;
+ }
+ }
+ return true;
+ }
+ // Paper end - optimize hoppers
}
private static boolean isEmptyContainer(Container inv, Direction facing) {
@@ -470,29 +527,43 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
// Paper start - optimize hoppers and remove streams
worldData.skipPullModeEventFire = worldData.skipHopperEvents; // Folia - region threading
- return !HopperBlockEntity.isEmptyContainer(iinventory, enumdirection) && anyMatch(iinventory, enumdirection, (item, i) -> {
- // Logic copied from below to avoid extra getItem calls
- if (!item.isEmpty() && canTakeItemFromContainer(hopper, iinventory, item, i, enumdirection)) {
- return hopperPull(world, hopper, iinventory, item, i);
- } else {
- return false;
+ // merge container isEmpty check and move logic into one loop
+ if (iinventory instanceof WorldlyContainer worldlyContainer) {
+ for (final int slot : worldlyContainer.getSlotsForFace(enumdirection)) {
+ ItemStack item = worldlyContainer.getItem(slot);
+ if (item.isEmpty() || !canTakeItemFromContainer(hopper, iinventory, item, slot, enumdirection)) {
+ continue;
+ }
+ if (hopperPull(world, hopper, iinventory, item, slot)) {
+ return true;
+ }
}
- // Paper end
- });
+ return false;
+ } else {
+ for (int slot = 0, max = iinventory.getContainerSize(); slot < max; ++slot) {
+ ItemStack item = iinventory.getItem(slot);
+ if (item.isEmpty() || !canTakeItemFromContainer(hopper, iinventory, item, slot, enumdirection)) {
+ continue;
+ }
+ if (hopperPull(world, hopper, iinventory, item, slot)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ // Paper end
} else {
- Iterator iterator = HopperBlockEntity.getItemsAtAndAbove(world, hopper).iterator();
+ final List<ItemEntity> items = HopperBlockEntity.getItemsAtAndAbove(world, hopper); // Paper - optimize hoppers
- ItemEntity entityitem;
-
- do {
- if (!iterator.hasNext()) {
- return false;
+ // Paper start - optimize hoppers
+ for (int i = 0, len = items.size(); i < len; ++i) {
+ if (HopperBlockEntity.addItem(hopper, items.get(i))) {
+ return true;
}
+ }
- entityitem = (ItemEntity) iterator.next();
- } while (!HopperBlockEntity.addItem(hopper, entityitem));
-
- return true;
+ return false;
+ // Paper end - optimize hoppers
}
}
@@ -550,23 +621,25 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
public static boolean addItem(Container inventory, ItemEntity itemEntity) {
boolean flag = false;
// CraftBukkit start
+ if (InventoryPickupItemEvent.getHandlerList().getRegisteredListeners().length > 0) { // Paper - optimize hoppers
InventoryPickupItemEvent event = new InventoryPickupItemEvent(getInventory(inventory), (org.bukkit.entity.Item) itemEntity.getBukkitEntity()); // Paper - use getInventory() to avoid snapshot creation
itemEntity.level().getCraftServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return false;
}
// CraftBukkit end
+ } // Paper - optimize hoppers
ItemStack itemstack = itemEntity.getItem().copy();
ItemStack itemstack1 = HopperBlockEntity.addItem((Container) null, inventory, itemstack, (Direction) null);
+ // Paper start - optimize hoppers
+ itemEntity.setItem(itemstack1);
if (itemstack1.isEmpty()) {
- flag = true;
itemEntity.discard();
- } else {
- itemEntity.setItem(itemstack1);
+ return true;
}
-
- return flag;
+ return false;
+ // Paper end - optimize hoppers
}
public static ItemStack addItem(@Nullable Container from, Container to, ItemStack stack, @Nullable Direction side) {
@@ -786,8 +859,8 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
}
}
- if (object == null && (!optimizeEntities || !world.paperConfig().hopper.ignoreOccludingBlocks || !org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(block).isOccluding())) { // Paper
- List<Entity> list = world.getEntities((Entity) null, new AABB(x - 0.5D, y - 0.5D, z - 0.5D, x + 0.5D, y + 0.5D, z + 0.5D), EntitySelector.CONTAINER_ENTITY_SELECTOR);
+ if (object == null && (!optimizeEntities || !world.paperConfig().hopper.ignoreOccludingBlocks || !iblockdata.getBukkitMaterial().isOccluding())) { // Paper
+ List<Entity> list = world.getEntitiesOfClass((Class)Container.class, new AABB(x - 0.5D, y - 0.5D, z - 0.5D, x + 0.5D, y + 0.5D, z + 0.5D), EntitySelector.CONTAINER_ENTITY_SELECTOR); // Paper - optimize hoppers, use getEntitiesOfClass
if (!list.isEmpty()) {
object = (Container) list.get(world.random.nextInt(list.size()));