9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-19 15:09:25 +00:00

Apply rest of Minecraft patches

This commit is contained in:
Dreeam
2025-01-18 10:28:38 -05:00
parent ed1cdcd19d
commit 8b3bf19a92
66 changed files with 1643 additions and 2018 deletions

View File

@@ -24,7 +24,7 @@ jobs:
run: git config --global user.email "no-reply@github.com" && git config --global user.name "Github Actions"
- name: Apply patches
run: ./gradlew -Dorg.gradle.jvmargs="-Dgraal.CompilerConfiguration=enterprise -Dgraal.UsePriorityInlining=true -Dgraal.Vectorization=true -Dgraal.OptDuplication=true --add-modules jdk.incubator.vector" applyPatches --stacktrace --no-daemon
run: ./gradlew -Dorg.gradle.jvmargs="-Dgraal.CompilerConfiguration=enterprise -Dgraal.UsePriorityInlining=true -Dgraal.Vectorization=true -Dgraal.OptDuplication=true --add-modules jdk.incubator.vector" applyAllPatches --stacktrace --no-daemon
- name: Create MojmapPaperclipJar
run: ./gradlew -Dorg.gradle.jvmargs="-Dgraal.CompilerConfiguration=enterprise -Dgraal.UsePriorityInlining=true -Dgraal.Vectorization=true -Dgraal.OptDuplication=true --add-modules jdk.incubator.vector" createMojmapPaperclipJar --stacktrace --no-daemon
- name: Create ReobfPaperclipJar

View File

@@ -103,11 +103,10 @@
runtimeOnly(log4jPlugins.output)
alsoShade(log4jPlugins.output)
- implementation("com.velocitypowered:velocity-native:3.3.0-SNAPSHOT") {
+ implementation("com.velocitypowered:velocity-native:3.4.0-SNAPSHOT") {
implementation("com.velocitypowered:velocity-native:3.4.0-SNAPSHOT") {
isTransitive = false
}
- implementation("io.netty:netty-codec-haproxy:4.1.97.Final") // Add support for proxy protocol
- implementation("io.netty:netty-codec-haproxy:4.1.115.Final") // Add support for proxy protocol
- implementation("org.apache.logging.log4j:log4j-iostreams:2.24.1")
+ implementation("io.netty:netty-codec-haproxy:4.1.116.Final") // Add support for proxy protocol
+ implementation("org.apache.logging.log4j:log4j-iostreams:2.24.3")

View File

@@ -200,6 +200,104 @@ index 6f96551ba91da214054b89a255254ca597977cc0..3f1a80db81c0f0cd7bb1d5df4a2c2cb1
// Purpur end - Option for Villager Clerics to farm Nether Wart
ResourceKey<Level> resourceKey = level.dimension();
BlockPos blockPos = entity.blockPosition();
diff --git a/net/minecraft/world/entity/animal/allay/Allay.java b/net/minecraft/world/entity/animal/allay/Allay.java
index 10d2a1138d814b83ce4233205a7f0ab2ed1f399d..e9f683ef9ce55e67748f1a16a45efe26bb4ff331 100644
--- a/net/minecraft/world/entity/animal/allay/Allay.java
+++ b/net/minecraft/world/entity/animal/allay/Allay.java
@@ -287,8 +287,7 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS
private int behaviorTick = 0; // Pufferfish
@Override
protected void customServerAiStep(ServerLevel level) {
- //if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider
- if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish
+ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider
this.getBrain().tick(level, this);
AllayAi.updateActivity(this);
super.customServerAiStep(level);
diff --git a/net/minecraft/world/entity/animal/axolotl/Axolotl.java b/net/minecraft/world/entity/animal/axolotl/Axolotl.java
index 1323cedcacd3072cdf5f1eac644688cd098b53db..ed15200319d0e50b495f2d0d912093d670fdb309 100644
--- a/net/minecraft/world/entity/animal/axolotl/Axolotl.java
+++ b/net/minecraft/world/entity/animal/axolotl/Axolotl.java
@@ -347,8 +347,7 @@ public class Axolotl extends Animal implements VariantHolder<Axolotl.Variant>, B
private int behaviorTick = 0; // Pufferfish
@Override
protected void customServerAiStep(ServerLevel level) {
- //if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider
- if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish
+ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider
this.getBrain().tick(level, this);
AxolotlAi.updateActivity(this);
if (!this.isNoAi()) {
diff --git a/net/minecraft/world/entity/animal/frog/Frog.java b/net/minecraft/world/entity/animal/frog/Frog.java
index 4ecc6b6247a6ab14a5d46f9a05d5df8412ae2a5f..a962b06ac3fc15604b7fbf5e2109f1cc8d238ac7 100644
--- a/net/minecraft/world/entity/animal/frog/Frog.java
+++ b/net/minecraft/world/entity/animal/frog/Frog.java
@@ -241,8 +241,7 @@ public class Frog extends Animal implements VariantHolder<Holder<FrogVariant>> {
private int behaviorTick = 0; // Pufferfish
@Override
protected void customServerAiStep(ServerLevel level) {
- //if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider
- if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish
+ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider
this.getBrain().tick(level, this);
FrogAi.updateActivity(this);
super.customServerAiStep(level);
diff --git a/net/minecraft/world/entity/animal/frog/Tadpole.java b/net/minecraft/world/entity/animal/frog/Tadpole.java
index 0ca35514a920dddf230d749bc1a5fe15f1c7940a..8468f7095e1db7a54042ce9a97d991d3105bd535 100644
--- a/net/minecraft/world/entity/animal/frog/Tadpole.java
+++ b/net/minecraft/world/entity/animal/frog/Tadpole.java
@@ -133,8 +133,7 @@ public class Tadpole extends AbstractFish {
private int behaviorTick = 0; // Pufferfish
@Override
protected void customServerAiStep(ServerLevel level) {
- //if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider
- if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish
+ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider
this.getBrain().tick(level, this);
TadpoleAi.updateActivity(this);
super.customServerAiStep(level);
diff --git a/net/minecraft/world/entity/animal/goat/Goat.java b/net/minecraft/world/entity/animal/goat/Goat.java
index 7107cc2462e7d33bca413a1b051822cc1bd61bfa..2e3ca6b17862494218042e6d84970a60272c2b40 100644
--- a/net/minecraft/world/entity/animal/goat/Goat.java
+++ b/net/minecraft/world/entity/animal/goat/Goat.java
@@ -223,8 +223,7 @@ public class Goat extends Animal {
private int behaviorTick = 0; // Pufferfish
@Override
protected void customServerAiStep(ServerLevel level) {
- //if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider
- if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish
+ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider
this.getBrain().tick(level, this);
GoatAi.updateActivity(this);
super.customServerAiStep(level);
diff --git a/net/minecraft/world/entity/monster/hoglin/Hoglin.java b/net/minecraft/world/entity/monster/hoglin/Hoglin.java
index 24725009d7619b0e9043d7d0039f805c611aedf6..a9d381568625ca871dcaf40b363d46692f45591d 100644
--- a/net/minecraft/world/entity/monster/hoglin/Hoglin.java
+++ b/net/minecraft/world/entity/monster/hoglin/Hoglin.java
@@ -203,8 +203,7 @@ public class Hoglin extends Animal implements Enemy, HoglinBase {
private int behaviorTick; // Pufferfish
@Override
protected void customServerAiStep(ServerLevel level) {
- //if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider
- if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish
+ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider
this.getBrain().tick(level, this);
HoglinAi.updateActivity(this);
if (this.isConverting()) {
diff --git a/net/minecraft/world/entity/monster/piglin/Piglin.java b/net/minecraft/world/entity/monster/piglin/Piglin.java
index 242b2545b6082f567d0bb7900ef06ded3c0fdcdd..85306d8f0fba3b5dcb244df54c949b45e07ee4e7 100644
--- a/net/minecraft/world/entity/monster/piglin/Piglin.java
+++ b/net/minecraft/world/entity/monster/piglin/Piglin.java
@@ -382,8 +382,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento
private int behaviorTick; // Pufferfish
@Override
protected void customServerAiStep(ServerLevel level) {
- //if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider
- if (this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish
+ if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider
this.getBrain().tick(level, this);
PiglinAi.updateActivity(this);
super.customServerAiStep(level);
diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java
index 347affae3cc18e01474734d2da2699c9b7b17e26..5dbf28c15f828505d42dc31c1a2185e01a7542c1 100644
--- a/net/minecraft/world/entity/npc/Villager.java

View File

@@ -21,7 +21,7 @@ index b7829a91a7ef79706ec6d90b8b2673fd369b9931..c798869665397de5b435e992873b566f
// Paper start - rewrite chunk system
private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index b4f2b794ca0c6e04da0355e02c19493c892ebccf..9c323dbaff302ca37850af70ee42c2588f85b20d 100644
index b4f2b794ca0c6e04da0355e02c19493c892ebccf..c334ce5c688ad362ffc96bd90d32c676acd50d4d 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -798,11 +798,11 @@ public abstract class PlayerList {
@@ -42,7 +42,7 @@ index b4f2b794ca0c6e04da0355e02c19493c892ebccf..9c323dbaff302ca37850af70ee42c258
return serverPlayer;
}
+ private boolean isSameLogicalHeight(ServerLevel fromLevel, ServerLevel toLevel) { return fromLevel.getLogicalHeight() == toLevel.getLogicalHeight(); } // Leaf - Slice - Check world height before smooth teleport
+ public static boolean isSameLogicalHeight(ServerLevel fromLevel, ServerLevel toLevel) { return fromLevel.getLogicalHeight() == toLevel.getLogicalHeight(); } // Leaf - Slice - Check world height before smooth teleport
+
public void sendActivePlayerEffects(ServerPlayer player) {
this.sendActiveEffects(player, player.connection);

View File

@@ -22,10 +22,10 @@ index a24ed1747fb8836927ac41b822dc666862701516..d840577023d42dc986e2b811382dfc43
public Armadillo(EntityType<? extends Animal> entityType, Level level) {
diff --git a/net/minecraft/world/entity/animal/frog/Tadpole.java b/net/minecraft/world/entity/animal/frog/Tadpole.java
index 0ca35514a920dddf230d749bc1a5fe15f1c7940a..669f7d6e5f481fb209e800c8e4acc52cf0c6dfce 100644
index 8468f7095e1db7a54042ce9a97d991d3105bd535..fd1aa79d1d1ec05853762df0c99099af3b790c63 100644
--- a/net/minecraft/world/entity/animal/frog/Tadpole.java
+++ b/net/minecraft/world/entity/animal/frog/Tadpole.java
@@ -286,7 +286,7 @@ public class Tadpole extends AbstractFish {
@@ -285,7 +285,7 @@ public class Tadpole extends AbstractFish {
}
}
@@ -35,7 +35,7 @@ index 0ca35514a920dddf230d749bc1a5fe15f1c7940a..669f7d6e5f481fb209e800c8e4acc52c
}
diff --git a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java
index 3e3c72a4a52e72c15e0d3288f805d7887dcac351..38cd62d1a3c17913fdadf02e3c3871dac7619f82 100644
index 4977262e78fe320d72158479c267842837344b67..4190940922af3a00845e6c656873ef8bca409f2c 100644
--- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java
+++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java
@@ -67,7 +67,7 @@ public class TrialSpawnerData {

View File

@@ -580,10 +580,10 @@ index 57c50ce5724b073b1aedf4df3129285143097303..91635b344ac02b66e51aa5620acf9ca4
}
}
diff --git a/net/minecraft/world/entity/animal/frog/Frog.java b/net/minecraft/world/entity/animal/frog/Frog.java
index 4ecc6b6247a6ab14a5d46f9a05d5df8412ae2a5f..2c28e97e76155fe4de309422f4913c1269972ff4 100644
index a962b06ac3fc15604b7fbf5e2109f1cc8d238ac7..035e7eac88ded12f9ca8f7e2a4d99c4156eb311f 100644
--- a/net/minecraft/world/entity/animal/frog/Frog.java
+++ b/net/minecraft/world/entity/animal/frog/Frog.java
@@ -479,9 +479,25 @@ public class Frog extends Animal implements VariantHolder<Holder<FrogVariant>> {
@@ -478,9 +478,25 @@ public class Frog extends Animal implements VariantHolder<Holder<FrogVariant>> {
return pathType != PathType.WATER_BORDER && super.canCutCorner(pathType);
}

View File

@@ -181,7 +181,7 @@ index 231d1905092532acf7e632197ba0e727adc4b1d7..dac802a8c70ff8ab96c000a48e1c5e10
try (DataInputStream out = new DataInputStream(new java.io.BufferedInputStream(new java.util.zip.InflaterInputStream(Files.newInputStream(file))))) {
return net.minecraft.nbt.NbtIo.read((java.io.DataInput) out);
diff --git a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
index 7fff86a4956f59b2f4a9f7e283256879c034c1b8..58d9840d2557fbb9b357bf4e3d5ad19ef40d73c9 100644
index 7fff86a4956f59b2f4a9f7e283256879c034c1b8..329ac5cc12ba3e247ea4f513a347c9daad91a6e0 100644
--- a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -18,7 +18,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
@@ -242,7 +242,7 @@ index 7fff86a4956f59b2f4a9f7e283256879c034c1b8..58d9840d2557fbb9b357bf4e3d5ad19e
this.regionCache.putAndMoveToFirst(key, ret);
@@ -144,7 +148,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
@@ -144,11 +148,11 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
}
final ChunkPos pos = new ChunkPos(chunkX, chunkZ);
@@ -251,6 +251,11 @@ index 7fff86a4956f59b2f4a9f7e283256879c034c1b8..58d9840d2557fbb9b357bf4e3d5ad19e
// note: not required to keep regionfile loaded after this call, as the write param takes a regionfile as input
// (and, the regionfile parameter is unused for writing until the write call)
- final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData writeData = ((ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile)regionFile).moonrise$startWrite(compound, pos);
+ final ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData writeData = regionFile.moonrise$startWrite(compound, pos); // LinearPaper
try { // Paper - implement RegionFileSizeException
try {
@@ -178,7 +182,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise
) throws IOException {
final ChunkPos pos = new ChunkPos(chunkX, chunkZ);

View File

@@ -89,43 +89,6 @@ index 30bd254542d631676494f349ff3f44f52d54ab2f..63e6411d8bac1629e143cc620fe35dba
);
public record Favicon(byte[] iconBytes) {
diff --git a/net/minecraft/network/protocol/status/ServerStatus.java.rej b/net/minecraft/network/protocol/status/ServerStatus.java.rej
new file mode 100644
index 0000000000000000000000000000000000000000..04a6f2fe6563665d8432789e3cbb3278a9408669
--- /dev/null
+++ b/net/minecraft/network/protocol/status/ServerStatus.java.rej
@@ -0,0 +1,31 @@
+diff a/net/minecraft/network/protocol/status/ServerStatus.java b/net/minecraft/network/protocol/status/ServerStatus.java (rejected hunks)
+@@ -22,8 +22,11 @@ public record ServerStatus(
+ Optional<ServerStatus.Favicon> favicon,
+ boolean enforcesSecureChat
+ ) {
++ // Leaf start - Mirai - Configurable chat message signatures
+ public static final Codec<ServerStatus> CODEC = RecordCodecBuilder.create(
+- instance -> instance.group(
++ instance ->
++ org.dreeam.leaf.config.modules.network.ChatMessageSignature.enabled
++ ? instance.group(
+ ComponentSerialization.CODEC.lenientOptionalFieldOf("description", CommonComponents.EMPTY).forGetter(ServerStatus::description),
+ ServerStatus.Players.CODEC.lenientOptionalFieldOf("players").forGetter(ServerStatus::players),
+ ServerStatus.Version.CODEC.lenientOptionalFieldOf("version").forGetter(ServerStatus::version),
+@@ -31,7 +34,16 @@ public record ServerStatus(
+ Codec.BOOL.lenientOptionalFieldOf("enforcesSecureChat", Boolean.valueOf(false)).forGetter(ServerStatus::enforcesSecureChat)
+ )
+ .apply(instance, ServerStatus::new)
++ : instance.group(
++ ComponentSerialization.CODEC.lenientOptionalFieldOf("description", CommonComponents.EMPTY).forGetter(ServerStatus::description),
++ ServerStatus.Players.CODEC.lenientOptionalFieldOf("players").forGetter(ServerStatus::players),
++ ServerStatus.Version.CODEC.lenientOptionalFieldOf("version").forGetter(ServerStatus::version),
++ ServerStatus.Favicon.CODEC.lenientOptionalFieldOf("favicon").forGetter(ServerStatus::favicon),
++ Codec.BOOL.lenientOptionalFieldOf("enforcesSecureChat", Boolean.FALSE).forGetter(x -> true)
++ )
++ .apply(instance, ServerStatus::new)
+ );
++ // Leaf end- Mirai - Configurable chat message signatures
+
+ public static record Favicon(byte[] iconBytes) {
+ private static final String PREFIX = "data:image/png;base64,";
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 22b0f33dc3ef9f51ba2ca3cb665b07a16bd1c9d9..7b1e5addd6a1b815498233ba9032f224494af12a 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
@@ -173,7 +136,7 @@ index ee8cdd532b73180cb484fcc37c36f09c40faacda..eb388c1c94bc6feda6c8757b1800d158
if (packet == null || this.processedDisconnect) { // Spigot
return;
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index e4c3819de8af08f36cd30fafb6ce859005c5cb43..b98e854fb9fad65b176b4915214a0a4c5e424d6c 100644
index 7d7343d4e2c206daf77a61050f2f4c229dd042cd..6855076ef73bbfd23e75ba4ae8eaa0ea598c9d4e 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -1509,7 +1509,7 @@ public abstract class PlayerList {

View File

@@ -6,28 +6,28 @@ Subject: [PATCH] Fix MC-65198
Mojang issues: https://bugs.mojang.com/browse/MC-65198
diff --git a/net/minecraft/world/inventory/ItemCombinerMenu.java b/net/minecraft/world/inventory/ItemCombinerMenu.java
index ac9df238ef0f3d009f25976b95e0b750e963e952..b94daec80a5222468d6065cec4ac693a1de92b38 100644
index c605bd700fd9f5a6596a2bf9648492786306b025..77c0b0b6c63d0a2955fcf3a479581f09067f3e62 100644
--- a/net/minecraft/world/inventory/ItemCombinerMenu.java
+++ b/net/minecraft/world/inventory/ItemCombinerMenu.java
@@ -129,6 +129,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
ItemStack itemstack1 = slot1.getItem();
itemstack = itemstack1.copy();
+ ItemStack itemStack2 = itemstack.copy(); // Leaf - Fix MC-65198
int j = this.getInventorySlotStart();
int k = this.getUseRowEnd();
@@ -165,7 +166,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
@@ -120,6 +120,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
if (slot != null && slot.hasItem()) {
ItemStack item = slot.getItem();
itemStack = item.copy();
+ ItemStack itemStack2 = itemStack.copy(); // Leaf - Fix MC-65198
int inventorySlotStart = this.getInventorySlotStart();
int useRowEnd = this.getUseRowEnd();
if (index == this.getResultSlot()) {
@@ -157,7 +158,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
}
this.activeQuickItem = itemstack; // Purpur - Anvil API
- slot1.onTake(player, itemstack1);
+ slot1.onTake(player, itemStack2); // Leaf - Fix MC-65198
this.activeQuickItem = itemStack; // Purpur - Anvil API
- slot.onTake(player, item);
+ slot.onTake(player, itemStack2); // Leaf - Fix MC-65198
this.activeQuickItem = null; // Purpur - Anvil API
}
diff --git a/net/minecraft/world/inventory/ResultSlot.java b/net/minecraft/world/inventory/ResultSlot.java
index ff30071f3ef37d1b28cf86e26ce4f7477335a07a..78122f7aaa095278095a57974b9906f7999a17df 100644
index 01b8d73b1be9b41d6f51d11a0bead37a7bd9023f..7637eed0dedcdc5ac0dd51cc82010eb4bbf5b784 100644
--- a/net/minecraft/world/inventory/ResultSlot.java
+++ b/net/minecraft/world/inventory/ResultSlot.java
@@ -49,7 +49,7 @@ public class ResultSlot extends Slot {
@@ -40,25 +40,25 @@ index ff30071f3ef37d1b28cf86e26ce4f7477335a07a..78122f7aaa095278095a57974b9906f7
if (this.container instanceof RecipeCraftingHolder recipeCraftingHolder) {
diff --git a/net/minecraft/world/inventory/StonecutterMenu.java b/net/minecraft/world/inventory/StonecutterMenu.java
index ca65965757e6f12abc972250a04817c7547bb0bd..675300ca10b2328be102a7cbc447e1c25ef12f82 100644
index d6854d0ebe5cb4205963e879d71eb3940d54de1f..a32f56d0317b719a0ae38009327d09519038e440 100644
--- a/net/minecraft/world/inventory/StonecutterMenu.java
+++ b/net/minecraft/world/inventory/StonecutterMenu.java
@@ -255,6 +255,7 @@ public class StonecutterMenu extends AbstractContainerMenu {
Item item = itemstack1.getItem();
itemstack = itemstack1.copy();
+ ItemStack itemStack2 = itemstack.copy(); // Leaf - Fix MC-65198
if (slot == 1) {
item.onCraftedBy(itemstack1, player.level(), player);
if (!this.moveItemStackTo(itemstack1, 2, 38, true)) {
@@ -287,9 +288,9 @@ public class StonecutterMenu extends AbstractContainerMenu {
@@ -238,6 +238,7 @@ public class StonecutterMenu extends AbstractContainerMenu {
ItemStack item = slot.getItem();
Item item1 = item.getItem();
itemStack = item.copy();
+ ItemStack itemStack2 = itemStack.copy(); // Leaf - Fix MC-65198
if (index == 1) {
item1.onCraftedBy(item, player.level(), player);
if (!this.moveItemStackTo(item, 2, 38, true)) {
@@ -270,9 +271,9 @@ public class StonecutterMenu extends AbstractContainerMenu {
return ItemStack.EMPTY;
}
- slot1.onTake(player, itemstack1);
+ slot1.onTake(player, itemStack2); // Leaf - Fix MC-65198
if (slot == 1) {
- player.drop(itemstack1, false);
- slot.onTake(player, item);
+ slot.onTake(player, itemStack2); // Leaf - Fix MC-65198
if (index == 1) {
- player.drop(item, false);
+ player.drop(itemStack2, false); // Leaf - Fix MC-65198
}

View File

@@ -0,0 +1,24 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
Date: Sun, 7 Jul 2024 01:29:57 +0800
Subject: [PATCH] Fix-MC-200418
Related MC issue: https://bugs.mojang.com/browse/MC-200418
diff --git a/net/minecraft/world/entity/monster/ZombieVillager.java b/net/minecraft/world/entity/monster/ZombieVillager.java
index 750f63e337661b5448d0d863ab4dc99398fd5655..4adbdf7e1151383bad8b877171b562952ab0c9c9 100644
--- a/net/minecraft/world/entity/monster/ZombieVillager.java
+++ b/net/minecraft/world/entity/monster/ZombieVillager.java
@@ -321,6 +321,12 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder {
if (!this.isSilent()) {
serverLevel.levelEvent(null, 1027, this.blockPosition(), 0);
}
+
+ // Leaf start - Fix MC-200418
+ if (villager.isPassenger() && villager.getVehicle() instanceof net.minecraft.world.entity.animal.Chicken && villager.isBaby()) {
+ villager.removeVehicle();
+ }
+ // Leaf end
// CraftBukkit start
}, org.bukkit.event.entity.EntityTransformEvent.TransformReason.CURED, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CURED // CraftBukkit
);

View File

@@ -6,11 +6,11 @@ Subject: [PATCH] Fix-MC-119417
Related MC issue: https://bugs.mojang.com/browse/MC-119417
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index 3eb3cd1089ec46c64f82e99f25d19cee9e0cdfbe..a27b0a3895290f5abb3a8e07fb886530fdf28c75 100644
index 09c9ca038f359372bda3a3d8b743d497a530ce97..ef20741ab2a7feaa8a86759ee0ae6283e4d4651c 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -2507,6 +2507,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.CHANGE_GAME_MODE, (float) gameMode.getId()));
@@ -2260,6 +2260,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.CHANGE_GAME_MODE, gameMode.getId()));
if (gameMode == GameType.SPECTATOR) {
this.removeEntitiesOnShoulder();
+ this.stopSleeping(); // Leaf - Fix MC-119417

View File

@@ -6,10 +6,10 @@ Subject: [PATCH] Fix-MC-223153
Related MC issue: https://bugs.mojang.com/browse/MC-223153
diff --git a/net/minecraft/world/level/block/Blocks.java b/net/minecraft/world/level/block/Blocks.java
index 63d67d46d30ed8ed57cdc0e59b6cb6b75ab22c1f..539b5625ba0ef7389ff1e7041af86f538640f3d9 100644
index bf047be5b577b0d1bf70458df14618bcfe2d1de2..07a8fbfa7eb6e684ea699f009ce2d19311994e39 100644
--- a/net/minecraft/world/level/block/Blocks.java
+++ b/net/minecraft/world/level/block/Blocks.java
@@ -6611,6 +6611,7 @@ public class Blocks {
@@ -6632,6 +6632,7 @@ public class Blocks {
.mapColor(MapColor.COLOR_ORANGE)
.instrument(NoteBlockInstrument.BASEDRUM)
.requiresCorrectToolForDrops()

View File

@@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Sun, 4 Aug 2024 19:34:29 +0800
Subject: [PATCH] Configurable player knockback zombie
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index d8a93bd85580c4bdc52d6f368b78ad210c265ae5..6aa4153a5368645ad3f1a0b879428f9a60d8fbc6 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -2001,6 +2001,8 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
public void knockback(double strength, double x, double z, @Nullable Entity attacker, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause eventCause) { // Paper - knockback events
+ if (!canKnockback(attacker, this)) return; // Leaf - Configurable player knockback zombie
+
strength *= 1.0 - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE);
if (true || !(strength <= 0.0)) { // CraftBukkit - Call event even when force is 0
// this.hasImpulse = true; // CraftBukkit - Move down
@@ -2031,6 +2033,20 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
}
+ // Leaf start - Configurable player knockback zombie
+ private boolean canKnockback(@Nullable Entity attacker, LivingEntity target) {
+ if (!org.dreeam.leaf.config.modules.gameplay.Knockback.canPlayerKnockbackZombie) {
+ if (attacker instanceof ServerPlayer && target.getType() == EntityType.ZOMBIE) { // Player -> Zombie
+ return false;
+ } else if (attacker instanceof Projectile projectile && projectile.getOwner() instanceof ServerPlayer && target.getType() == EntityType.ZOMBIE) { // Player -> projectile -> Zombie
+ return false;
+ }
+ }
+
+ return true;
+ }
+ // Leaf end - Configurable player knockback zombie
+
public void indicateDamage(double xDistance, double zDistance) {
}

View File

@@ -8,10 +8,10 @@ Original project: https://github.com/PaperMC/Paper
Paper pull request: https://github.com/PaperMC/Paper/pull/10990
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
index eb547af300d8ecea19b3e02e5ebe6139330c9d62..1e4729be4a245a811fd15ea1c02179b37defd67c 100644
index 8b3dfb1385a2252a4aaead5558c0ffbd5c204971..c32086ddf90fafcc55600f9e0724b9f915671482 100644
--- a/net/minecraft/world/entity/Mob.java
+++ b/net/minecraft/world/entity/Mob.java
@@ -239,6 +239,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
@@ -219,6 +219,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
@Override
public void inactiveTick() {
super.inactiveTick();
@@ -24,10 +24,10 @@ index eb547af300d8ecea19b3e02e5ebe6139330c9d62..1e4729be4a245a811fd15ea1c02179b3
if (this.goalSelector.inactiveTick(this.activatedPriority, true) && !isThrottled) { // Pufferfish - pass activated priroity // Pufferfish - throttle inactive goal selector ticking
this.goalSelector.tick();
diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java
index fd373d98f836c057c30c4fbd5d7618cc4e757b78..50f080e91c0701b635b918ff15e07052052afb47 100644
index 5dbf28c15f828505d42dc31c1a2185e01a7542c1..3799cf1059e18448fc6da120d12d08f6bbbfbf49 100644
--- a/net/minecraft/world/entity/npc/Villager.java
+++ b/net/minecraft/world/entity/npc/Villager.java
@@ -321,7 +321,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
@@ -371,7 +371,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
if (this.getUnhappyCounter() > 0) {
this.setUnhappyCounter(this.getUnhappyCounter() - 1);
}

View File

@@ -12,19 +12,20 @@ before spawning, it checks isSpawnPositionOk() for the position which loads the
This patch ensures the chunk at the random location is loaded before trying to spawn the reinforcement zombie in it.
diff --git a/net/minecraft/world/entity/monster/Zombie.java b/net/minecraft/world/entity/monster/Zombie.java
index 5924509cbe36d3fee9d2f119d58e67c4b083e4c4..6efb548b6e1b466628eb70bc45ef98d09604c9df 100644
index cab69c308a0524137636fd50dc7a0dd0d2a4a2c3..660dff3fe7aacfe964dae22bb38b72aa36f0b8e3 100644
--- a/net/minecraft/world/entity/monster/Zombie.java
+++ b/net/minecraft/world/entity/monster/Zombie.java
@@ -405,6 +405,12 @@ public class Zombie extends Monster {
int k1 = k + Mth.nextInt(this.random, 7, 40) * Mth.nextInt(this.random, -1, 1);
BlockPos blockposition = new BlockPos(i1, j1, k1);
@@ -396,6 +396,13 @@ public class Zombie extends Monster {
int i2 = floor1 + Mth.nextInt(this.random, 7, 40) * Mth.nextInt(this.random, -1, 1);
int i3 = floor2 + Mth.nextInt(this.random, 7, 40) * Mth.nextInt(this.random, -1, 1);
BlockPos blockPos = new BlockPos(i1, i2, i3);
+
+ // Paper start - Prevent reinforcement checks from loading chunks
+ if (this.level().getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4) == null) {
+ if (this.level().getChunkIfLoadedImmediately(blockPos.getX() >> 4, blockPos.getZ() >> 4) == null) {
+ continue;
+ }
+ // Paper end - Prevent reinforcement checks from loading chunks
+
if (SpawnPlacements.isSpawnPositionOk(entitytypes, world, blockposition) && SpawnPlacements.checkSpawnRules(entitytypes, world, EntitySpawnReason.REINFORCEMENT, blockposition, world.random)) {
entityzombie.setPos((double) i1, (double) j1, (double) k1);
if (!world.hasNearbyAlivePlayerThatAffectsSpawning((double) i1, (double) j1, (double) k1, 7.0D) && world.isUnobstructed(entityzombie) && world.noCollision((Entity) entityzombie) && (entityzombie.canSpawnInLiquids() || !world.containsAnyLiquid(entityzombie.getBoundingBox()))) { // Paper - affects spawning api
if (SpawnPlacements.isSpawnPositionOk(type, level, blockPos)
&& SpawnPlacements.checkSpawnRules(type, level, EntitySpawnReason.REINFORCEMENT, blockPos, level.random)) {
zombie.setPos(i1, i2, i3);

View File

@@ -14,12 +14,12 @@ Moves the deactivate event call into the onRemove method for the beacon block it
The field I added feels a bit wrong but it works, it's to prevent the activation event being called immediately after loading, can't see any better way to differentiate between a newly placed beacon and a newly loaded one.
diff --git a/net/minecraft/world/level/block/BeaconBlock.java b/net/minecraft/world/level/block/BeaconBlock.java
index debe8dbf1d5f3e58774903c5fcdcea672274ea61..413d6978d3acd441c90cdba6128bd35411048645 100644
index 66eee067b4ffdd72393ca813de995062be5b7a90..38d36a2798b9aa5298ae2936f872fc63d73b7aa2 100644
--- a/net/minecraft/world/level/block/BeaconBlock.java
+++ b/net/minecraft/world/level/block/BeaconBlock.java
@@ -57,4 +57,16 @@ public class BeaconBlock extends BaseEntityBlock implements BeaconBeamBlock {
protected RenderShape getRenderShape(BlockState state) {
return RenderShape.MODEL;
@@ -52,4 +52,16 @@ public class BeaconBlock extends BaseEntityBlock implements BeaconBeamBlock {
return InteractionResult.SUCCESS;
}
+
+ // Paper start - BeaconDeactivatedEvent
@@ -35,51 +35,50 @@ index debe8dbf1d5f3e58774903c5fcdcea672274ea61..413d6978d3acd441c90cdba6128bd354
+ // Paper end
}
diff --git a/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
index 2d190b3a6378b8cbadfa65510df1ccfbd5882ef8..f2f5ef254e21134bf85f10d32541c9fbf883042f 100644
index 80b0feac68813f11dc5cadc5faf413a59ad73e5b..2fbbd384113cf62b64c7ff4e805265a09f55ceb0 100644
--- a/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
@@ -122,6 +122,8 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
return BeaconBlockEntity.VALID_EFFECTS.contains(effect) ? effect : null;
@@ -169,6 +169,8 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
return VALID_EFFECTS.contains(effect) ? effect : null;
}
+ public boolean justLoadedAndPreviouslyActive; // Paper - consider beacon previously active for first tick to skip activate event/sound
+
public BeaconBlockEntity(BlockPos pos, BlockState state) {
super(BlockEntityType.BEACON, pos, state);
this.lockKey = LockCode.NO_LOCK;
@@ -240,10 +242,15 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
public BeaconBlockEntity(BlockPos pos, BlockState blockState) {
super(BlockEntityType.BEACON, pos, blockState);
}
@@ -234,10 +236,15 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
}
}
// Paper start - beacon activation/deactivation events
- if (i1 <= 0 && blockEntity.levels > 0) {
- if (originalLevels <= 0 && blockEntity.levels > 0) {
+ // Paper start
+ final boolean prevActive = i1 > 0 && (!blockEntity.beamSections.isEmpty() || (blockEntity.justLoadedAndPreviouslyActive && !blockEntity.checkingBeamSections.isEmpty()));
+ final boolean prevActive = originalLevels > 0 && (!blockEntity.beamSections.isEmpty() || (blockEntity.justLoadedAndPreviouslyActive && !blockEntity.checkingBeamSections.isEmpty()));
+ blockEntity.justLoadedAndPreviouslyActive = false;
+ final boolean newActive = blockEntity.levels > 0 && !blockEntity.checkingBeamSections.isEmpty();
+ if (!prevActive && newActive) {
+ // Paper end
org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos);
org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
new io.papermc.paper.event.block.BeaconActivatedEvent(block).callEvent();
- } else if (i1 > 0 && blockEntity.levels <= 0) {
- } else if (originalLevels > 0 && blockEntity.levels <= 0) {
+ } else if (prevActive && !newActive) { // Paper
org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos);
org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos);
new io.papermc.paper.event.block.BeaconDeactivatedEvent(block).callEvent();
}
@@ -251,11 +258,11 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
@@ -245,10 +252,10 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
if (blockEntity.lastCheckY >= l) {
blockEntity.lastCheckY = world.getMinY() - 1;
- boolean flag = i1 > 0;
if (blockEntity.lastCheckY >= height) {
blockEntity.lastCheckY = level.getMinY() - 1;
- boolean flag = i > 0;
+ boolean flag = prevActive; // Paper - Fix MC-183981
blockEntity.beamSections = blockEntity.checkingBeamSections;
if (!world.isClientSide) {
if (!level.isClientSide) {
- boolean flag1 = blockEntity.levels > 0;
+ boolean flag1 = newActive; // Paper - Fix MC-183981
if (!flag && flag1) {
BeaconBlockEntity.playSound(world, pos, SoundEvents.BEACON_ACTIVATE);
@@ -305,10 +312,6 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
playSound(level, pos, SoundEvents.BEACON_ACTIVATE);
@@ -292,10 +299,6 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
@Override
public void setRemoved() {
@@ -89,12 +88,12 @@ index 2d190b3a6378b8cbadfa65510df1ccfbd5882ef8..f2f5ef254e21134bf85f10d32541c9fb
- // Paper end - beacon activation/deactivation events
// Paper start - fix MC-153086
if (this.levels > 0 && !this.beamSections.isEmpty()) {
BeaconBlockEntity.playSound(this.level, this.worldPosition, SoundEvents.BEACON_DEACTIVATE);
@@ -466,6 +469,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
this.primaryPower = BeaconBlockEntity.loadEffect(nbt, "primary_effect");
this.secondaryPower = BeaconBlockEntity.loadEffect(nbt, "secondary_effect");
this.levels = nbt.getInt("Levels"); // CraftBukkit - SPIGOT-5053, use where available
playSound(this.level, this.worldPosition, SoundEvents.BEACON_DEACTIVATE);
@@ -426,6 +429,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
this.primaryPower = loadEffect(tag, "primary_effect");
this.secondaryPower = loadEffect(tag, "secondary_effect");
this.levels = tag.getInt("Levels"); // CraftBukkit - SPIGOT-5053, use where available
+ this.justLoadedAndPreviouslyActive = this.levels > 0; // Paper
if (nbt.contains("CustomName", 8)) {
this.name = parseCustomNameSafe(nbt.getString("CustomName"), registries);
if (tag.contains("CustomName", 8)) {
this.name = parseCustomNameSafe(tag.getString("CustomName"), registries);
}

View File

@@ -9,33 +9,33 @@ Original license: MIT
Original project: https://github.com/PurpurMC/Purpur
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
index 709d9997f25369a9a0ac5af94cfe391604081ea1..bea671ae16a90e9cb9d2f312eed3c816da05b23c 100644
index ddf2a5e2cfeaa666a081dd857d6a6003d65d0e00..1b9e34574fb5b8955fa37795baebf588fdaeca2a 100644
--- a/net/minecraft/server/level/ServerEntity.java
+++ b/net/minecraft/server/level/ServerEntity.java
@@ -243,6 +243,8 @@ public class ServerEntity {
flag4 = true;
}
@@ -199,6 +199,8 @@ public class ServerEntity {
}
// Gale end - Airplane - better checking for useless move packets
+ if (org.dreeam.leaf.config.modules.opt.ReduceUselessPackets.reduceUselessEntityMovePackets && isUselessMoveEntityPacket(packet1)) packet1 = null; // Purpur
+ if (org.dreeam.leaf.config.modules.opt.ReduceUselessPackets.reduceUselessEntityMovePackets && isUselessMoveEntityPacket(packet)) packet = null; // Purpur
+
if ((this.trackDelta || this.entity.hasImpulse || this.entity instanceof LivingEntity && ((LivingEntity) this.entity).isFallFlying()) && this.tickCount > 0) {
Vec3 vec3d1 = this.entity.getDeltaMovement();
if (vec3d1 != this.lastSentMovement) { // SparklyPaper start - skip distanceToSqr call in ServerEntity#sendChanges if the delta movement hasn't changed
@@ -349,6 +351,27 @@ public class ServerEntity {
});
if (this.entity.hasImpulse || this.trackDelta || this.entity instanceof LivingEntity && ((LivingEntity)this.entity).isFallFlying()) {
Vec3 deltaMovement = this.entity.getDeltaMovement();
if (deltaMovement != this.lastSentMovement) { // SparklyPaper start - skip distanceToSqr call in ServerEntity#sendChanges if the delta movement hasn't changed
@@ -275,6 +277,27 @@ public class ServerEntity {
}
}
+ // Purpur start
+ private boolean isUselessMoveEntityPacket(@Nullable Packet<?> packet) {
+ if (packet instanceof ClientboundMoveEntityPacket moveEntityPacket) {
+ switch (packet) {
+ case ClientboundMoveEntityPacket.Pos pos -> {
+ case ClientboundMoveEntityPacket.Pos ignored -> {
+ return moveEntityPacket.getXa() == 0 && moveEntityPacket.getYa() == 0 && moveEntityPacket.getZa() == 0;
+ }
+ case ClientboundMoveEntityPacket.PosRot posRot -> {
+ case ClientboundMoveEntityPacket.PosRot ignored -> {
+ return moveEntityPacket.getXa() == 0 && moveEntityPacket.getYa() == 0 && moveEntityPacket.getZa() == 0 && moveEntityPacket.getyRot() == 0 && moveEntityPacket.getxRot() == 0;
+ }
+ case ClientboundMoveEntityPacket.Rot rot -> {
+ case ClientboundMoveEntityPacket.Rot ignored -> {
+ return moveEntityPacket.getyRot() == 0 && moveEntityPacket.getxRot() == 0;
+ }
+ default -> {
@@ -46,6 +46,6 @@ index 709d9997f25369a9a0ac5af94cfe391604081ea1..bea671ae16a90e9cb9d2f312eed3c816
+ }
+ // Purpur end
+
public void removePairing(ServerPlayer player) {
this.entity.stopSeenByPlayer(player);
player.connection.send(new ClientboundRemoveEntitiesPacket(new int[]{this.entity.getId()}));
private void handleMinecartPosRot(NewMinecartBehavior behavior, byte yRot, byte xRot, boolean dirty) {
this.sendDirtyEntityData();
if (behavior.lerpSteps.isEmpty()) {

View File

@@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Tue, 27 Aug 2024 22:53:08 -0400
Subject: [PATCH] Don't spawn if lastSpawnState is null
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
index eacebc190a1f598314a8b812629fecd86d87ff7c..7d80766eab50ef5d63ea06098f177fd95307c1b9 100644
--- a/net/minecraft/server/level/ServerChunkCache.java
+++ b/net/minecraft/server/level/ServerChunkCache.java
@@ -648,7 +648,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
for (LevelChunk levelChunk : chunks) {
ChunkPos pos = levelChunk.getPos();
levelChunk.incrementInhabitedTime(timeInhabited);
- if (!filteredSpawningCategories.isEmpty() && this.level.getWorldBorder().isWithinBounds(pos) && (!org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled || _pufferfish_spawnCountsReady.get()) && this.chunkMap.anyPlayerCloseEnoughForSpawning(pos, true)) { // Spigot // Pufferfish
+ if (!filteredSpawningCategories.isEmpty() && this.level.getWorldBorder().isWithinBounds(pos) && lastSpawnState != null && (!org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled || _pufferfish_spawnCountsReady.get()) && this.chunkMap.anyPlayerCloseEnoughForSpawning(pos, true)) { // Spigot // Pufferfish // Leaf - Don't spawn if lastSpawnState is null
NaturalSpawner.spawnForChunk(this.level, levelChunk, lastSpawnState, filteredSpawningCategories); // Pufferfish
}

View File

@@ -23,30 +23,13 @@ for the case of some NPC plugins which using real entity type, e.g. Citizens.
But it is still recommending to use those packet based, virtual entity
based NPC plugins, e.g. ZNPC Plus, Adyeshach, Fancy NPC, etc.
diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
index e42677bb004201efe1702779a78cc8d0ca05e80f..6676be8304e9415099ed423d3315180cafebd928 100644
--- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
+++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
@@ -42,6 +42,12 @@ class PaperEventManager {
if (event.isAsynchronous() && this.server.isPrimaryThread()) {
throw new IllegalStateException(event.getEventName() + " may only be triggered asynchronously.");
} else if (!event.isAsynchronous() && !this.server.isPrimaryThread() && !this.server.isStopping()) {
+ // Leaf start - Multithreaded tracker
+ if (org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled) {
+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(event::callEvent);
+ return;
+ }
+ // Leaf end - Multithreaded tracker
throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously.");
}
// Leaves start - skip photographer
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
index 2b67936faa5fe058f4927610f01c4dc458117bf0..231f36edefffcbbf7256f73dcae922c17e74ae73 100644
index 5d9d233e3a568aa6297ed9c703fa450f98158602..325f44fc5c07d931d888698dc7f84547d20f78b1 100644
--- a/net/minecraft/server/level/ChunkMap.java
+++ b/net/minecraft/server/level/ChunkMap.java
@@ -240,6 +240,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
return;
@@ -248,6 +248,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
final ServerPlayer[] backingSet = inRange.getRawDataUnchecked();
+ // Leaf start - Multithreaded tracker
+ if (org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled)
@@ -60,7 +43,7 @@ index 2b67936faa5fe058f4927610f01c4dc458117bf0..231f36edefffcbbf7256f73dcae922c1
for (int i = 0, len = inRange.size(); i < len; i++) {
++(backingSet[i].mobCounts[index]);
}
@@ -947,6 +956,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -929,6 +938,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity)entity).moonrise$setTrackedEntity(null); // Paper - optimise entity tracker
}
@@ -82,7 +65,7 @@ index 2b67936faa5fe058f4927610f01c4dc458117bf0..231f36edefffcbbf7256f73dcae922c1
// Paper start - optimise entity tracker
private void newTrackerTick() {
final ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup entityLookup = (ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup)((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getEntityLookup();;
@@ -969,6 +993,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -951,6 +975,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper end - optimise entity tracker
protected void tick() {
@@ -96,18 +79,18 @@ index 2b67936faa5fe058f4927610f01c4dc458117bf0..231f36edefffcbbf7256f73dcae922c1
// Paper start - optimise entity tracker
if (true) {
this.newTrackerTick();
@@ -1118,7 +1149,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -1073,7 +1104,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
final Entity entity;
private final int range;
SectionPos lastSectionPos;
- public final Set<ServerPlayerConnection> seenBy = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl
+ public final Set<ServerPlayerConnection> seenBy = org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled
+ ? Sets.newConcurrentHashSet()
+ ? com.google.common.collect.Sets.newConcurrentHashSet()
+ : new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(); // Paper - Perf: optimise map impl // Leaf - petal - Multithreaded tracker
// Paper start - optimise entity tracker
private long lastChunkUpdate = -1L;
@@ -1145,7 +1178,39 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -1100,7 +1133,39 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.lastTrackedChunk = chunk;
final ServerPlayer[] playersRaw = players.getRawDataUnchecked();
@@ -147,7 +130,7 @@ index 2b67936faa5fe058f4927610f01c4dc458117bf0..231f36edefffcbbf7256f73dcae922c1
for (int i = 0, len = players.size(); i < len; ++i) {
final ServerPlayer player = playersRaw[i];
this.updatePlayer(player);
@@ -1160,6 +1225,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -1115,6 +1180,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
}
}
@@ -156,39 +139,23 @@ index 2b67936faa5fe058f4927610f01c4dc458117bf0..231f36edefffcbbf7256f73dcae922c1
}
@Override
@@ -1219,14 +1286,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -1176,7 +1243,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
public void broadcast(Packet<?> packet) {
- Iterator iterator = this.seenBy.iterator();
-
- while (iterator.hasNext()) {
- ServerPlayerConnection serverplayerconnection = (ServerPlayerConnection) iterator.next();
-
+ // Leaf start - petal - Multithreaded tracker
+ for (ServerPlayerConnection serverplayerconnection : this.seenBy.toArray(new ServerPlayerConnection[0])) {
serverplayerconnection.send(packet);
- for (ServerPlayerConnection serverPlayerConnection : this.seenBy) {
+ for (ServerPlayerConnection serverPlayerConnection : this.seenBy.toArray(new ServerPlayerConnection[0])) {// Leaf - petal - Multithreaded tracker
serverPlayerConnection.send(packet);
}
-
+ // Leaf end - petal - Multithreaded tracker
}
public void broadcastAndSend(Packet<?> packet) {
@@ -1238,18 +1302,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -1189,21 +1256,22 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
public void broadcastRemoved() {
- Iterator iterator = this.seenBy.iterator();
-
- while (iterator.hasNext()) {
- ServerPlayerConnection serverplayerconnection = (ServerPlayerConnection) iterator.next();
-
+ // Leaf start - petal - Multithreaded tracker
+ for (ServerPlayerConnection serverplayerconnection : this.seenBy.toArray(new ServerPlayerConnection[0])) {
this.serverEntity.removePairing(serverplayerconnection.getPlayer());
- for (ServerPlayerConnection serverPlayerConnection : this.seenBy) {
+ for (ServerPlayerConnection serverPlayerConnection : this.seenBy.toArray(new ServerPlayerConnection[0])) {// Leaf - petal - Multithreaded tracker
this.serverEntity.removePairing(serverPlayerConnection.getPlayer());
}
-
+ // Leaf end - petal - Multithreaded tracker
}
public void removePlayer(ServerPlayer player) {
@@ -197,7 +164,6 @@ index 2b67936faa5fe058f4927610f01c4dc458117bf0..231f36edefffcbbf7256f73dcae922c1
if (this.seenBy.remove(player.connection)) {
this.serverEntity.removePairing(player);
}
@@ -1257,8 +1318,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
public void updatePlayer(ServerPlayer player) {
@@ -206,10 +172,10 @@ index 2b67936faa5fe058f4927610f01c4dc458117bf0..231f36edefffcbbf7256f73dcae922c1
if (player != this.entity) {
+ if (org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled && player == null) return; // Leaf - Multithreaded tracker
// Paper start - remove allocation of Vec3D here
// Vec3 vec3d = player.position().subtract(this.entity.position());
double vec3d_dx = player.getX() - this.entity.getX();
// Vec3 vec3 = player.position().subtract(this.entity.position());
double vec3_dx = player.getX() - this.entity.getX();
diff --git a/net/minecraft/server/level/ServerBossEvent.java b/net/minecraft/server/level/ServerBossEvent.java
index 4f91107f9ae42f96c060c310596db9aa869a8dbc..f9889f593ed144ee8f1f5bd380e631c659b0c2b8 100644
index f106373ef3ac4a8685c2939c9e8361688a285913..37c5fd2ba5b3b0ff741222f04737e8928a4b6079 100644
--- a/net/minecraft/server/level/ServerBossEvent.java
+++ b/net/minecraft/server/level/ServerBossEvent.java
@@ -13,7 +13,9 @@ import net.minecraft.util.Mth;
@@ -224,29 +190,33 @@ index 4f91107f9ae42f96c060c310596db9aa869a8dbc..f9889f593ed144ee8f1f5bd380e631c6
public boolean visible = true;
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
index bea671ae16a90e9cb9d2f312eed3c816da05b23c..36026f9f4cad3930cd45918012bf54498f2de973 100644
index 1b9e34574fb5b8955fa37795baebf588fdaeca2a..a0a40c5f0ae22390615d060b1b45c937dd9e2370 100644
--- a/net/minecraft/server/level/ServerEntity.java
+++ b/net/minecraft/server/level/ServerEntity.java
@@ -119,7 +119,13 @@ public class ServerEntity {
this.broadcastAndSend(new ClientboundSetPassengersPacket(this.entity)); // CraftBukkit
ServerEntity.removedPassengers(list, this.lastPassengers).forEach((entity) -> {
if (entity instanceof ServerPlayer entityplayer) {
- entityplayer.connection.teleport(entityplayer.getX(), entityplayer.getY(), entityplayer.getZ(), entityplayer.getYRot(), entityplayer.getXRot());
+ // Leaf start - Multithreaded tracker - Ensure teleport is executed on server thread
+ if (org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled && Thread.currentThread() instanceof org.dreeam.leaf.async.tracker.MultithreadedTracker.MultithreadedTrackerThread) {
+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> entityplayer.connection.teleport(entityplayer.getX(), entityplayer.getY(), entityplayer.getZ(), entityplayer.getYRot(), entityplayer.getXRot()));
+ } else {
+ entityplayer.connection.teleport(entityplayer.getX(), entityplayer.getY(), entityplayer.getZ(), entityplayer.getYRot(), entityplayer.getXRot());
+ }
+ // Leaf end - Multithreaded tracker - Ensure teleport is executed on server thread
}
});
@@ -374,7 +380,11 @@ public class ServerEntity {
@@ -110,8 +110,16 @@ public class ServerEntity {
.forEach(
removedPassenger -> {
if (removedPassenger instanceof ServerPlayer serverPlayer1) {
- serverPlayer1.connection
- .teleport(serverPlayer1.getX(), serverPlayer1.getY(), serverPlayer1.getZ(), serverPlayer1.getYRot(), serverPlayer1.getXRot());
+ // Leaf start - Multithreaded tracker - Ensure teleport is executed on server thread
+ if (org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled && Thread.currentThread() instanceof org.dreeam.leaf.async.tracker.MultithreadedTracker.MultithreadedTrackerThread) {
+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> serverPlayer1.connection
+ .teleport(serverPlayer1.getX(), serverPlayer1.getY(), serverPlayer1.getZ(), serverPlayer1.getYRot(), serverPlayer1.getXRot())
+ );
+ } else {
+ serverPlayer1.connection
+ .teleport(serverPlayer1.getX(), serverPlayer1.getY(), serverPlayer1.getZ(), serverPlayer1.getYRot(), serverPlayer1.getXRot());
+ }
+ // Leaf end - Multithreaded tracker - Ensure teleport is executed on server thread
}
}
);
@@ -335,14 +343,21 @@ public class ServerEntity {
public void removePairing(ServerPlayer player) {
this.entity.stopSeenByPlayer(player);
- player.connection.send(new ClientboundRemoveEntitiesPacket(new int[]{this.entity.getId()}));
- player.connection.send(new ClientboundRemoveEntitiesPacket(this.entity.getId()));
+ // Leaf start - petal - Multithreaded tracker - send in main thread
+ ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() ->
+ player.connection.send(new ClientboundRemoveEntitiesPacket(this.entity.getId()))
@@ -255,56 +225,54 @@ index bea671ae16a90e9cb9d2f312eed3c816da05b23c..36026f9f4cad3930cd45918012bf5449
}
public void addPairing(ServerPlayer player) {
@@ -382,7 +392,11 @@ public class ServerEntity {
Objects.requireNonNull(list);
List<Packet<? super ClientGamePacketListener>> list = new ArrayList<>();
this.sendPairingData(player, list::add);
- player.connection.send(new ClientboundBundlePacket(list));
- this.entity.startSeenByPlayer(player);
+ // Leaf start - petal - Multithreaded tracker - send in main thread
+ ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() ->
+ player.connection.send(new ClientboundBundlePacket(list))
+ player.connection.send(new ClientboundBundlePacket(list))
+ );
+ // Leaf end - petal - Multithreaded tracker - send in main thread
this.entity.startSeenByPlayer(player);
+ // Leaf end - petal - Multithreaded tracker - send in main thread this.entity.startSeenByPlayer(player);
}
@@ -502,19 +516,28 @@ public class ServerEntity {
public void sendPairingData(ServerPlayer player, Consumer<Packet<ClientGamePacketListener>> consumer) {
@@ -435,18 +450,27 @@ public class ServerEntity {
List<SynchedEntityData.DataValue<?>> list = entityData.packDirty();
if (list != null) {
this.trackedDataValues = datawatcher.getNonDefaultValues();
this.trackedDataValues = entityData.getNonDefaultValues();
- this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), list));
+ // Leaf start - petal - Multithreaded tracker - send in main thread
+ ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() ->
+ this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), list))
+ this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), list))
+ );
+ // Leaf end - petal - Multithreaded tracker - send in main thread
}
if (this.entity instanceof LivingEntity) {
Set<AttributeInstance> set = ((LivingEntity) this.entity).getAttributes().getAttributesToSync();
if (!set.isEmpty()) {
+ // Leaf end - petal - Multithreaded tracker - send in main thread
+ final Set<AttributeInstance> copy = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(set);
Set<AttributeInstance> attributesToSync = ((LivingEntity)this.entity).getAttributes().getAttributesToSync();
if (!attributesToSync.isEmpty()) {
+ // Leaf start - petal - Multithreaded tracker - send in main thread
+ final Set<AttributeInstance> copy = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(attributesToSync);
+ ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() -> {
// CraftBukkit start - Send scaled max health
if (this.entity instanceof ServerPlayer) {
- ((ServerPlayer) this.entity).getBukkitEntity().injectScaledMaxHealth(set, false);
+ ((ServerPlayer) this.entity).getBukkitEntity().injectScaledMaxHealth(copy, false);
if (this.entity instanceof ServerPlayer serverPlayer) {
- serverPlayer.getBukkitEntity().injectScaledMaxHealth(attributesToSync, false);
+ serverPlayer.getBukkitEntity().injectScaledMaxHealth(copy, false);
}
// CraftBukkit end
- this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), set));
- this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), attributesToSync));
+ this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), copy));
+ });
+ // Leaf end - petal - Multithreaded tracker - send in main thread
}
set.clear();
attributesToSync.clear();
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 9a7a76599a44dfd51d5e9e9a0e892994528c7680..4a92789d77313e165ab1252cd469e34a8b7eb575 100644
index b3c388f6108360708baf275121af18f46622494f..682024138e792fa4c72189ed06226f0a92ef3d7f 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -2561,7 +2561,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -2494,7 +2494,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@Override
public LevelEntityGetter<Entity> getEntities() {
@@ -314,20 +282,20 @@ index 9a7a76599a44dfd51d5e9e9a0e892994528c7680..4a92789d77313e165ab1252cd469e34a
}
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 0684a8e9e0d91c1724d1e066daa71030bba70904..dd6174a4b695bdaa2229a21c9680e757c6869755 100644
index 14c75c85c062fb9d2b576bb1cd24f942642fbf8c..0ebcaeeda2242d918fbb917076bc99a86ef677f8 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1833,7 +1833,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -1810,7 +1810,7 @@ public class ServerGamePacketListenerImpl
}
public void internalTeleport(PositionMoveRotation positionmoverotation, Set<Relative> set) {
public void internalTeleport(PositionMoveRotation posMoveRotation, Set<Relative> relatives) {
- org.spigotmc.AsyncCatcher.catchOp("teleport"); // Paper
+ //org.spigotmc.AsyncCatcher.catchOp("teleport"); // Paper // Leaf - Multithreaded tracker
// Paper start - Prevent teleporting dead entities
if (player.isRemoved()) {
if (this.player.isRemoved()) {
LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName());
diff --git a/net/minecraft/world/entity/ai/attributes/AttributeInstance.java b/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
index 27a7852a5d3f8c8960f098646ff5587c50556aa5..f492a3d58e43c1ef9ef6652b40d894874471abd3 100644
index 8013594bb4844e7a8abf28123958e7f632d39341..ceff383d565267edd13a6d9006030b8e1f8053e3 100644
--- a/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
+++ b/net/minecraft/world/entity/ai/attributes/AttributeInstance.java
@@ -24,8 +24,11 @@ public class AttributeInstance {
@@ -345,7 +313,7 @@ index 27a7852a5d3f8c8960f098646ff5587c50556aa5..f492a3d58e43c1ef9ef6652b40d89487
private boolean dirty = true;
private double cachedValue;
diff --git a/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/net/minecraft/world/entity/ai/attributes/AttributeMap.java
index 7bc3a6f4dabc6411b6ff17e6dbbd190d57076cd1..4d060255d1446e65214f75fc5d03cabd4fb00576 100644
index 89f4c5b2d61e27acd48063f9f24ce9ea91898b8b..371dd51c62c9a109014851c8a1562a5cb78b18b6 100644
--- a/net/minecraft/world/entity/ai/attributes/AttributeMap.java
+++ b/net/minecraft/world/entity/ai/attributes/AttributeMap.java
@@ -19,11 +19,14 @@ import org.slf4j.Logger;
@@ -365,4 +333,4 @@ index 7bc3a6f4dabc6411b6ff17e6dbbd190d57076cd1..4d060255d1446e65214f75fc5d03cabd
+ // Leaf end - Multithreaded tracker
private final AttributeSupplier supplier;
private final java.util.function.Function<Holder<Attribute>, AttributeInstance> createInstance; // Gale - Airplane - reduce entity allocations
private final net.minecraft.world.entity.LivingEntity entity; // Purpur
private final net.minecraft.world.entity.LivingEntity entity; // Purpur - Ridables

View File

@@ -7,50 +7,49 @@ Original license: GPL v3
Original project: https://github.com/Gensokyo-Reimagined/Nitori
diff --git a/net/minecraft/world/level/storage/LevelStorageSource.java b/net/minecraft/world/level/storage/LevelStorageSource.java
index cdca5ae69991cc068bfbc0686b5defb3604a5440..5ab705731209fd4d4c20cd342ee7bf1bf26f3b0c 100644
index de43e54698125ce9f319d4889dd49f7029fe95e0..1fde2e33af9102017ab17cb766e9784ecec09822 100644
--- a/net/minecraft/world/level/storage/LevelStorageSource.java
+++ b/net/minecraft/world/level/storage/LevelStorageSource.java
@@ -605,7 +605,11 @@ public class LevelStorageSource {
CompoundTag nbttagcompound2 = new CompoundTag();
nbttagcompound2.put("Data", nbttagcompound1);
- this.saveLevelData(nbttagcompound2);
@@ -514,7 +514,11 @@ public class LevelStorageSource {
CompoundTag compoundTag = serverConfiguration.createTag(registries, hostPlayerNBT);
CompoundTag compoundTag1 = new CompoundTag();
compoundTag1.put("Data", compoundTag);
- this.saveLevelData(compoundTag1);
+
+ // Leaf start - Nitori - Async playerdata save
+ Runnable runnable = () -> this.saveLevelData(nbttagcompound2);
+ Runnable runnable = () -> this.saveLevelData(compoundTag1);
+ org.dreeam.leaf.async.AsyncPlayerDataSaving.saveAsync(runnable);
+ // Leaf end - Nitori - Async playerdata save
}
private void saveLevelData(CompoundTag nbt) {
@@ -702,7 +706,11 @@ public class LevelStorageSource {
CompoundTag nbttagcompound = LevelStorageSource.readLevelDataTagRaw(this.levelDirectory.dataFile());
nbtProcessor.accept(nbttagcompound.getCompound("Data"));
- this.saveLevelData(nbttagcompound);
private void saveLevelData(CompoundTag tag) {
@@ -601,7 +605,11 @@ public class LevelStorageSource {
this.checkLock();
CompoundTag levelDataTagRaw = LevelStorageSource.readLevelDataTagRaw(this.levelDirectory.dataFile());
modifier.accept(levelDataTagRaw.getCompound("Data"));
- this.saveLevelData(levelDataTagRaw);
+
+ // Leaf start - Nitori - Async playerdata save
+ Runnable runnable = () -> this.saveLevelData(nbttagcompound);
+ Runnable runnable = () -> this.saveLevelData(levelDataTagRaw);
+ org.dreeam.leaf.async.AsyncPlayerDataSaving.saveAsync(runnable);
+ // Leaf end - Nitori - Async playerdata save
}
public long makeWorldBackup() throws IOException {
diff --git a/net/minecraft/world/level/storage/PlayerDataStorage.java b/net/minecraft/world/level/storage/PlayerDataStorage.java
index b148cf247acdd36f856d0495cde4cc5ad32b5a2f..e825d9e573a38531f5a3b3f9cdccc24570953015 100644
index c44110b123ba5912af18faf0065e9ded780da9b7..06bf26d7e216a0d75811b831ac7ac1cc6106d6e8 100644
--- a/net/minecraft/world/level/storage/PlayerDataStorage.java
+++ b/net/minecraft/world/level/storage/PlayerDataStorage.java
@@ -36,6 +36,13 @@ public class PlayerDataStorage {
@@ -33,6 +33,12 @@ public class PlayerDataStorage {
}
public void save(Player player) {
if (org.spigotmc.SpigotConfig.disablePlayerDataSaving) return; // Spigot
+
+ // Leaf start - Nitori - Async playerdata save
+ Runnable runnable = () -> save0(player);
+ Runnable runnable = () -> saveInternal(player);
+ org.dreeam.leaf.async.AsyncPlayerDataSaving.saveAsync(runnable);
+ }
+ private void save0(Player player) {
+ private void saveInternal(Player player) {
+ // Leaf end - Nitori - Async playerdata save
if (org.spigotmc.SpigotConfig.disablePlayerDataSaving) return; // Spigot
try {
CompoundTag nbttagcompound = player.saveWithoutId(new CompoundTag());
Path path = this.playerDir.toPath();
CompoundTag compoundTag = player.saveWithoutId(new CompoundTag());

View File

@@ -7,11 +7,11 @@ Use SpottedLeaf's nearby players system to avoid iterating over all online playe
and reduce the cost on predicate test
diff --git a/net/minecraft/world/entity/EntitySelector.java b/net/minecraft/world/entity/EntitySelector.java
index 59c4d3753c7084e92402608b7fb3c4adbc6c2f65..68b59afe54fa1dcc1b24e90fb0cdcff83d898232 100644
index 002ec5f1ec14411ca48ae04b3379db0c70f81942..d2ca99f8b5ad46c59b663cd56f3ee2bd66185381 100644
--- a/net/minecraft/world/entity/EntitySelector.java
+++ b/net/minecraft/world/entity/EntitySelector.java
@@ -44,7 +44,7 @@ public final class EntitySelector {
private EntitySelector() {}
@@ -32,7 +32,7 @@ public final class EntitySelector {
// Paper start - Affects Spawning API
public static final Predicate<Entity> PLAYER_AFFECTS_SPAWNING = (entity) -> {
- return !entity.isSpectator() && entity.isAlive() && entity instanceof Player player && player.affectsSpawning;
@@ -20,40 +20,39 @@ index 59c4d3753c7084e92402608b7fb3c4adbc6c2f65..68b59afe54fa1dcc1b24e90fb0cdcff8
// Paper end - Affects Spawning API
diff --git a/net/minecraft/world/entity/monster/Zombie.java b/net/minecraft/world/entity/monster/Zombie.java
index 6efb548b6e1b466628eb70bc45ef98d09604c9df..d053019e3a1fb2d15ad231e31f761d136dca8417 100644
index 660dff3fe7aacfe964dae22bb38b72aa36f0b8e3..4f7a5d6391f045693a6208ff5cd99e5e0b58b194 100644
--- a/net/minecraft/world/entity/monster/Zombie.java
+++ b/net/minecraft/world/entity/monster/Zombie.java
@@ -413,7 +413,7 @@ public class Zombie extends Monster {
if (SpawnPlacements.isSpawnPositionOk(entitytypes, world, blockposition) && SpawnPlacements.checkSpawnRules(entitytypes, world, EntitySpawnReason.REINFORCEMENT, blockposition, world.random)) {
entityzombie.setPos((double) i1, (double) j1, (double) k1);
- if (!world.hasNearbyAlivePlayerThatAffectsSpawning((double) i1, (double) j1, (double) k1, 7.0D) && world.isUnobstructed(entityzombie) && world.noCollision((Entity) entityzombie) && (entityzombie.canSpawnInLiquids() || !world.containsAnyLiquid(entityzombie.getBoundingBox()))) { // Paper - affects spawning api
+ if (!world.hasNearbyAlivePlayerThatAffectsSpawningForZombie(i1, j1, k1, 7.0D) && world.isUnobstructed(entityzombie) && world.noCollision((Entity) entityzombie) && (entityzombie.canSpawnInLiquids() || !world.containsAnyLiquid(entityzombie.getBoundingBox()))) { // Paper - affects spawning api // Leaf - Optimize nearby alive players for spawning
entityzombie.setTarget(entityliving, EntityTargetEvent.TargetReason.REINFORCEMENT_TARGET, true); // CraftBukkit
entityzombie.finalizeSpawn(world, world.getCurrentDifficultyAt(entityzombie.blockPosition()), EntitySpawnReason.REINFORCEMENT, (SpawnGroupData) null);
world.addFreshEntityWithPassengers(entityzombie, CreatureSpawnEvent.SpawnReason.REINFORCEMENTS); // CraftBukkit
@@ -406,7 +406,7 @@ public class Zombie extends Monster {
if (SpawnPlacements.isSpawnPositionOk(type, level, blockPos)
&& SpawnPlacements.checkSpawnRules(type, level, EntitySpawnReason.REINFORCEMENT, blockPos, level.random)) {
zombie.setPos(i1, i2, i3);
- if (!level.hasNearbyAlivePlayerThatAffectsSpawning(i1, i2, i3, 7.0) // Paper - affects spawning api
+ if (!level.hasNearbyAlivePlayerThatAffectsSpawningForZombie(i1, i2, i3, 7.0) // Paper - affects spawning api // Leaf - Optimize nearby alive players for spawning
&& level.isUnobstructed(zombie)
&& level.noCollision(zombie)
&& (zombie.canSpawnInLiquids() || !level.containsAnyLiquid(zombie.getBoundingBox()))) {
diff --git a/net/minecraft/world/level/BaseSpawner.java b/net/minecraft/world/level/BaseSpawner.java
index b23397ae135f31abb7ac6bafd9064d7ef5e94218..37c98981c71b73daa078c49319e124c20628fcc8 100644
index 8de482367f3d9d91048b7c85cbaefcda9f9fbcdc..8c6f8cb08b247dcf497822ae991aa3afbcb784f1 100644
--- a/net/minecraft/world/level/BaseSpawner.java
+++ b/net/minecraft/world/level/BaseSpawner.java
@@ -60,7 +60,7 @@ public abstract class BaseSpawner {
@@ -53,7 +53,7 @@ public abstract class BaseSpawner {
public boolean isNearPlayer(Level world, BlockPos pos) {
if (world.purpurConfig.spawnerDeactivateByRedstone && world.hasNeighborSignal(pos)) return false; // Purpur
- return world.hasNearbyAlivePlayerThatAffectsSpawning((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, (double) this.requiredPlayerRange); // Paper - Affects Spawning API
+ return world.hasNearbyAlivePlayerThatAffectsSpawningForSpawner((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, this.requiredPlayerRange); // Paper - Affects Spawning API // Leaf - Optimize nearby alive players for spawning
public boolean isNearPlayer(Level level, BlockPos pos) {
if (level.purpurConfig.spawnerDeactivateByRedstone && level.hasNeighborSignal(pos)) return false; // Purpur - Redstone deactivates spawners
- return level.hasNearbyAlivePlayerThatAffectsSpawning(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, this.requiredPlayerRange); // Paper - Affects Spawning API
+ return level.hasNearbyAlivePlayerThatAffectsSpawningForSpawner(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, this.requiredPlayerRange); // Paper - Affects Spawning API // Leaf - Optimize nearby alive players for spawning
}
public void clientTick(Level world, BlockPos pos) {
public void clientTick(Level level, BlockPos pos) {
diff --git a/net/minecraft/world/level/EntityGetter.java b/net/minecraft/world/level/EntityGetter.java
index 6b2cda6d578a0983b2401ea20629275431018433..47f80547a4f2285dc097c6f73954419848cfe895 100644
index f41e41d01aa42f3578ffb3bc888416e74d17cd1d..9d3b5ea3f0cd8d662ffe99e70bf0af22f6ba0512 100644
--- a/net/minecraft/world/level/EntityGetter.java
+++ b/net/minecraft/world/level/EntityGetter.java
@@ -180,6 +180,89 @@ public interface EntityGetter extends ca.spottedleaf.moonrise.patches.chunk_syst
}
return false;
@@ -112,6 +112,89 @@ public interface EntityGetter extends ca.spottedleaf.moonrise.patches.chunk_syst
// Paper end - optimise collisions
}
+
+ // Leaf start - Optimize nearby alive players for spawning
+ default boolean hasNearbyAlivePlayerThatAffectsSpawningForSpawner(double x, double y, double z, double range) {
+ if (range > 33) {
@@ -65,7 +64,7 @@ index 6b2cda6d578a0983b2401ea20629275431018433..47f80547a4f2285dc097c6f739544198
+ mutablePos.set(x, y, z);
+
+ final ca.spottedleaf.moonrise.common.list.ReferenceList<net.minecraft.server.level.ServerPlayer> players = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel) this).moonrise$getNearbyPlayers().getPlayers(
+ mutablePos, ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.GENERAL // range: 33
+ mutablePos, ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.GENERAL // NearbyPlayers.GENERAL_AREA_VIEW_DISTANCE: 33
+ );
+
+ if (players == null) {
@@ -110,7 +109,7 @@ index 6b2cda6d578a0983b2401ea20629275431018433..47f80547a4f2285dc097c6f739544198
+ mutablePos.set(x, y, z);
+
+ final ca.spottedleaf.moonrise.common.list.ReferenceList<net.minecraft.server.level.ServerPlayer> players = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel) this).moonrise$getNearbyPlayers().getPlayers(
+ mutablePos, ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.SPAWN_RANGE // range: 8
+ mutablePos, ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.SPAWN_RANGE // NearbyPlayers.PLAYER_SPAWN_TRACK_RANGE: 8
+ );
+
+ if (players == null) {
@@ -136,6 +135,7 @@ index 6b2cda6d578a0983b2401ea20629275431018433..47f80547a4f2285dc097c6f739544198
+ return false;
+ }
+ // Leaf end - Optimize nearby alive players for spawning
// Paper end - Affects Spawning API
default boolean hasNearbyAlivePlayer(double x, double y, double z, double range) {
+
// Paper start - Affects Spawning API
default @Nullable Player findNearbyPlayer(Entity entity, double maxDistance, @Nullable Predicate<Entity> predicate) {
return this.getNearestPlayer(entity.getX(), entity.getY(), entity.getZ(), maxDistance, predicate);

View File

@@ -5,11 +5,11 @@ Subject: [PATCH] Cache blockstate cache
diff --git a/net/minecraft/world/level/block/state/BlockBehaviour.java b/net/minecraft/world/level/block/state/BlockBehaviour.java
index 9b94d8bf3415734776c81297d5d34eea46ad7e78..65d8ac795282117ba88003e7a703ee649a359473 100644
index c13c8c82bf7bd0a9a33fd4027884ad852a7c64b6..36ac6114cc3449a3b344baac5f3034288cf77a63 100644
--- a/net/minecraft/world/level/block/state/BlockBehaviour.java
+++ b/net/minecraft/world/level/block/state/BlockBehaviour.java
@@ -1438,6 +1438,10 @@ public abstract class BlockBehaviour implements FeatureElement {
@@ -1050,6 +1050,10 @@ public abstract class BlockBehaviour implements FeatureElement {
static final class Cache {
private static final Direction[] DIRECTIONS = Direction.values();
private static final int SUPPORT_TYPE_COUNT = SupportType.values().length;
+ // Leaf start - Cache blockstate cache array
@@ -19,21 +19,21 @@ index 9b94d8bf3415734776c81297d5d34eea46ad7e78..65d8ac795282117ba88003e7a703ee64
protected final VoxelShape collisionShape;
protected boolean largeCollisionShape; // Leaf - not final
private final boolean[] faceSturdy;
@@ -1451,7 +1455,7 @@ public abstract class BlockBehaviour implements FeatureElement {
throw new IllegalStateException(String.format(Locale.ROOT, "%s has a collision shape and an offset type, but is not marked as dynamicShape in its properties.", BuiltInRegistries.BLOCK.getKey(block)));
@@ -1068,7 +1072,7 @@ public abstract class BlockBehaviour implements FeatureElement {
);
} else {
// Leaf start - Remove stream
- for (Direction.Axis axis : Direction.Axis.values()) {
+ for (Direction.Axis axis : DIRECTION_AXIS_VALUES) { // Leaf - Cache blockstate cache array
if (this.collisionShape.min(axis) < 0.0D || this.collisionShape.max(axis) > 1.0D) {
if (this.collisionShape.min(axis) < 0.0 || this.collisionShape.max(axis) > 1.0) {
this.largeCollisionShape = true;
break;
@@ -1464,7 +1468,7 @@ public abstract class BlockBehaviour implements FeatureElement {
@@ -1078,7 +1082,7 @@ public abstract class BlockBehaviour implements FeatureElement {
this.faceSturdy = new boolean[DIRECTIONS.length * SUPPORT_TYPE_COUNT];
for (int j = 0; j < i; ++j) {
Direction enumdirection = aenumdirection[j];
- SupportType[] aenumblocksupport = SupportType.values();
+ SupportType[] aenumblocksupport = SUPPORT_TYPE_VALUES; // Leaf - Cache blockstate cache array
int k = aenumblocksupport.length;
for (int l = 0; l < k; ++l) {
for (Direction direction : DIRECTIONS) {
- for (SupportType supportType : SupportType.values()) {
+ for (SupportType supportType : SUPPORT_TYPE_VALUES) { // Leaf - Cache blockstate cache array
this.faceSturdy[getFaceSupportIndex(direction, supportType)] = supportType.isSupporting(
state, EmptyBlockGetter.INSTANCE, BlockPos.ZERO, direction
);

View File

@@ -0,0 +1,209 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
Date: Wed, 23 Oct 2024 23:54:00 +0800
Subject: [PATCH] Asynchronous locator
Original license: MIT
Original project: https://github.com/thebrightspark/AsyncLocator
diff --git a/net/minecraft/server/commands/LocateCommand.java b/net/minecraft/server/commands/LocateCommand.java
index 13bcd8653d766cd0b754a22e9aab261fbc62b0a5..8fcc33505b86ff686dfe3049631044b2b50789d5 100644
--- a/net/minecraft/server/commands/LocateCommand.java
+++ b/net/minecraft/server/commands/LocateCommand.java
@@ -109,6 +109,37 @@ public class LocateCommand {
BlockPos blockPos = BlockPos.containing(source.getPosition());
ServerLevel level = source.getLevel();
Stopwatch stopwatch = Stopwatch.createStarted(Util.TICKER);
+ // Leaf start - Async locator
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled) {
+ net.minecraft.commands.CommandSource locatorSource = source.source;
+ if (locatorSource instanceof net.minecraft.server.level.ServerPlayer ||
+ locatorSource instanceof net.minecraft.server.MinecraftServer) {
+ BlockPos originPos = BlockPos.containing(source.getPosition());
+ org.dreeam.leaf.async.locate.AsyncLocator.locate(source.getLevel(), holderSet, originPos, 100, false)
+ .thenOnServerThread(pair -> {
+ stopwatch.stop();
+ if (pair != null) {
+ showLocateResult(
+ source,
+ structure,
+ originPos,
+ pair,
+ "commands.locate.structure.success",
+ false,
+ stopwatch.elapsed()
+ );
+ } else {
+ source.sendFailure(
+ Component.literal(
+ ERROR_STRUCTURE_NOT_FOUND.create(structure.asPrintable()).getMessage()
+ )
+ );
+ }
+ });
+ return 0;
+ }
+ }
+ // Leaf end - Async locator
Pair<BlockPos, Holder<Structure>> pair = level.getChunkSource().getGenerator().findNearestMapStructure(level, holderSet, blockPos, 100, false);
stopwatch.stop();
if (pair == null) {
diff --git a/net/minecraft/world/entity/animal/Dolphin.java b/net/minecraft/world/entity/animal/Dolphin.java
index 7003b532182737a745491e397a967b72e6b308aa..4f2baa764362c1cfa8ba84b52c54cf820db55ea5 100644
--- a/net/minecraft/world/entity/animal/Dolphin.java
+++ b/net/minecraft/world/entity/animal/Dolphin.java
@@ -500,6 +500,8 @@ public class Dolphin extends AgeableWaterCreature {
static class DolphinSwimToTreasureGoal extends Goal {
private final Dolphin dolphin;
private boolean stuck;
+ @Nullable
+ private org.dreeam.leaf.async.locate.AsyncLocator.LocateTask<?> asyncLocator$locateTask;
DolphinSwimToTreasureGoal(Dolphin dolphin) {
this.dolphin = dolphin;
@@ -519,6 +521,11 @@ public class Dolphin extends AgeableWaterCreature {
@Override
public boolean canContinueToUse() {
+ // Leaf start - Async locator
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && this.asyncLocator$locateTask != null) {
+ return true;
+ }
+ // Leaf end - Async locator
BlockPos treasurePos = this.dolphin.getTreasurePos();
return !BlockPos.containing(treasurePos.getX(), this.dolphin.getY(), treasurePos.getZ()).closerToCenterThan(this.dolphin.position(), 4.0)
&& !this.stuck
@@ -532,6 +539,21 @@ public class Dolphin extends AgeableWaterCreature {
this.stuck = false;
this.dolphin.getNavigation().stop();
BlockPos blockPos = this.dolphin.blockPosition();
+ // Leaf start - Async locator
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled) {
+ asyncLocator$locateTask = org.dreeam.leaf.async.locate.AsyncLocator.locate(serverLevel, StructureTags.DOLPHIN_LOCATED, blockPos, 50, false)
+ .thenOnServerThread(pos -> {
+ asyncLocator$locateTask = null;
+ if (pos != null) {
+ this.dolphin.setTreasurePos(pos);
+ serverLevel.broadcastEntityEvent(this.dolphin, (byte) 38);
+ } else {
+ this.stuck = true;
+ }
+ });
+ return;
+ }
+ // Leaf end - Async locator
BlockPos blockPos1 = serverLevel.findNearestMapStructure(StructureTags.DOLPHIN_LOCATED, blockPos, 50, false);
if (blockPos1 != null) {
this.dolphin.setTreasurePos(blockPos1);
@@ -544,6 +566,12 @@ public class Dolphin extends AgeableWaterCreature {
@Override
public void stop() {
+ // Leaf start - Async locator
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && this.asyncLocator$locateTask != null) {
+ this.asyncLocator$locateTask.cancel();
+ this.asyncLocator$locateTask = null;
+ }
+ // Leaf end - Async locator
BlockPos treasurePos = this.dolphin.getTreasurePos();
if (BlockPos.containing(treasurePos.getX(), this.dolphin.getY(), treasurePos.getZ()).closerToCenterThan(this.dolphin.position(), 4.0) || this.stuck
)
@@ -554,6 +582,11 @@ public class Dolphin extends AgeableWaterCreature {
@Override
public void tick() {
+ // Leaf start - Async locator
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && this.asyncLocator$locateTask != null) {
+ return;
+ }
+ // Leaf end - Async locator
Level level = this.dolphin.level();
if (this.dolphin.closeToNextPos() || this.dolphin.getNavigation().isDone()) {
Vec3 vec3 = Vec3.atCenterOf(this.dolphin.getTreasurePos());
diff --git a/net/minecraft/world/entity/projectile/EyeOfEnder.java b/net/minecraft/world/entity/projectile/EyeOfEnder.java
index 01a9bad80a30a7879a69b800258b616b4d986108..5b6d6afd64181d095d61ce233d6f549710648ada 100644
--- a/net/minecraft/world/entity/projectile/EyeOfEnder.java
+++ b/net/minecraft/world/entity/projectile/EyeOfEnder.java
@@ -26,6 +26,7 @@ public class EyeOfEnder extends Entity implements ItemSupplier {
public double tz;
public int life;
public boolean surviveAfterDeath;
+ public boolean asyncLocator$locateTaskOngoing = false; // Leaf - Async locator
public EyeOfEnder(EntityType<? extends EyeOfEnder> entityType, Level level) {
super(entityType, level);
@@ -112,6 +113,11 @@ public class EyeOfEnder extends Entity implements ItemSupplier {
@Override
public void tick() {
super.tick();
+ // Leaf start - Async locator
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && this.asyncLocator$locateTaskOngoing) {
+ return;
+ }
+ // Leaf end - Async locator
Vec3 deltaMovement = this.getDeltaMovement();
double d = this.getX() + deltaMovement.x;
double d1 = this.getY() + deltaMovement.y;
diff --git a/net/minecraft/world/item/EnderEyeItem.java b/net/minecraft/world/item/EnderEyeItem.java
index 02f2c38b5f9a503097dea44d5c79518b03b63f9a..a2e701d671088a40f15e49a5343598a921d9a651 100644
--- a/net/minecraft/world/item/EnderEyeItem.java
+++ b/net/minecraft/world/item/EnderEyeItem.java
@@ -103,14 +103,47 @@ public class EnderEyeItem extends Item {
} else {
player.startUsingItem(hand);
if (level instanceof ServerLevel serverLevel) {
- BlockPos blockPos = serverLevel.findNearestMapStructure(StructureTags.EYE_OF_ENDER_LOCATED, player.blockPosition(), 100, false);
+ // Leaf start - Async locator
+ BlockPos blockPos;
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled) {
+ blockPos = BlockPos.ZERO;
+ } else {
+ blockPos = serverLevel.findNearestMapStructure(StructureTags.EYE_OF_ENDER_LOCATED, player.blockPosition(), 100, false);
+ }
+ // Leaf end - Async locator
if (blockPos == null) {
return InteractionResult.CONSUME;
}
EyeOfEnder eyeOfEnder = new EyeOfEnder(level, player.getX(), player.getY(0.5), player.getZ());
+
+ // Leaf start - Async locator
+ final boolean isAsyncLocatorEnabled = org.dreeam.leaf.config.modules.async.AsyncLocator.enabled;
+
+ if (isAsyncLocatorEnabled) {
+ eyeOfEnder.asyncLocator$locateTaskOngoing = true;
+ org.dreeam.leaf.async.locate.AsyncLocator.locate(
+ serverLevel,
+ StructureTags.EYE_OF_ENDER_LOCATED,
+ player.blockPosition(),
+ 100,
+ false
+ ).thenOnServerThread(pos -> {
+ eyeOfEnder.asyncLocator$locateTaskOngoing = false;
+ if (pos != null) {
+ eyeOfEnder.signalTo(pos);
+ CriteriaTriggers.USED_ENDER_EYE.trigger((ServerPlayer) player, pos);
+ player.awardStat(Stats.ITEM_USED.get(this));
+ } else {
+ // Set the entity's life to long enough that it dies
+ eyeOfEnder.life = Integer.MAX_VALUE - 100;
+ }
+ });
+ }
+ // Leaf end - Async locator
+
eyeOfEnder.setItem(itemInHand);
- eyeOfEnder.signalTo(blockPos);
+ if (!isAsyncLocatorEnabled) eyeOfEnder.signalTo(blockPos); // Leaf - Async locator
level.gameEvent(GameEvent.PROJECTILE_SHOOT, eyeOfEnder.position(), GameEvent.Context.of(player));
// CraftBukkit start
if (!level.addFreshEntity(eyeOfEnder)) {
@@ -124,7 +157,7 @@ public class EnderEyeItem extends Item {
float f = Mth.lerp(level.random.nextFloat(), 0.33F, 0.5F);
level.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.ENDER_EYE_LAUNCH, SoundSource.NEUTRAL, 1.0F, f);
itemInHand.consume(1, player);
- player.awardStat(Stats.ITEM_USED.get(this));
+ if (!isAsyncLocatorEnabled) player.awardStat(Stats.ITEM_USED.get(this)); // Leaf - Async locator
}
return InteractionResult.SUCCESS_SERVER;

View File

@@ -13,10 +13,10 @@ This offers a 10~15% performance improvement in average.
In best situation, this can give an up to 50% improvement.
diff --git a/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
index 23494aebfa51e7181fb06d123dad429e68ebf922..a5e85005ba9a1d85084c8e54124df9e4227e5273 100644
index b0c5e41fefc7c9adf1a61bd5b52861736657d37e..9b34ea111f43e2e103f2be6ecb186175aed7e175 100644
--- a/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
+++ b/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
@@ -13,17 +13,78 @@ import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities;
@@ -13,6 +13,10 @@ import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities;
import net.minecraft.world.phys.AABB;
public class NearestLivingEntitySensor<T extends LivingEntity> extends Sensor<T> {
@@ -25,21 +25,23 @@ index 23494aebfa51e7181fb06d123dad429e68ebf922..a5e85005ba9a1d85084c8e54124df9e4
+ private static final int BUCKET_SORT_THRESHOLD = (int) Math.floor(NUM_BUCKETS * org.apache.commons.lang3.math.NumberUtils.toDouble(System.getProperty("Leaf.nearestEntitySensorBucketSortThresholdRatio", "2.0"), 2.0D));
+ // Leaf end - Smart sort entities in NearestLivingEntitySensor
@Override
protected void doTick(ServerLevel world, T entity) {
double d = entity.getAttributeValue(Attributes.FOLLOW_RANGE);
AABB aABB = entity.getBoundingBox().inflate(d, d, d);
List<LivingEntity> list = world.getEntitiesOfClass(LivingEntity.class, aABB, e -> e != entity && e.isAlive());
- list.sort(Comparator.comparingDouble(entity::distanceToSqr));
protected void doTick(ServerLevel level, T entity) {
double attributeValue = entity.getAttributeValue(Attributes.FOLLOW_RANGE);
@@ -20,12 +24,73 @@ public class NearestLivingEntitySensor<T extends LivingEntity> extends Sensor<T>
List<LivingEntity> entitiesOfClass = level.getEntitiesOfClass(
LivingEntity.class, aabb, matchableEntity -> matchableEntity != entity && matchableEntity.isAlive()
);
- entitiesOfClass.sort(Comparator.comparingDouble(entity::distanceToSqr));
+ // Leaf start - Smart sort entities in NearestLivingEntitySensor
+ LivingEntity[] sortedEntities = smartSortEntities(list.toArray(new LivingEntity[]{}), entity);
+ LivingEntity[] sortedEntities = smartSortEntities(entitiesOfClass.toArray(new LivingEntity[0]), entity);
+ List<LivingEntity> sortedList = java.util.Arrays.asList(sortedEntities);
+ // Leaf end - Smart sort entities in NearestLivingEntitySensor
Brain<?> brain = entity.getBrain();
- brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, list);
- brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(world, entity, list));
- brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, entitiesOfClass);
- brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(level, entity, entitiesOfClass));
+ // Leaf start - Smart sort entities in NearestLivingEntitySensor
+ brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, sortedList);
+ brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(world, entity, sortedList));
+ brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(level, entity, sortedList));
+ // Leaf end - Smart sort entities in NearestLivingEntitySensor
}
@@ -48,6 +50,7 @@ index 23494aebfa51e7181fb06d123dad429e68ebf922..a5e85005ba9a1d85084c8e54124df9e4
+ if (entities.length <= 1) {
+ return entities;
+ }
+
+ final Comparator<LivingEntity> comparator = Comparator.comparingDouble(referenceEntity::distanceToSqr);
+
+ if (entities.length < BUCKET_SORT_THRESHOLD) {
@@ -58,12 +61,14 @@ index 23494aebfa51e7181fb06d123dad429e68ebf922..a5e85005ba9a1d85084c8e54124df9e4
+ // Create buckets
+ @SuppressWarnings("unchecked")
+ List<LivingEntity>[] buckets = new List[NUM_BUCKETS];
+
+ for (int i = 0; i < NUM_BUCKETS; i++) {
+ buckets[i] = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
+ }
+
+ // Find max distance to normalize bucket distribution - Leaf
+ double maxDistSq = 0.0;
+
+ for (LivingEntity e : entities) {
+ maxDistSq = Math.max(maxDistSq, referenceEntity.distanceToSqr(e));
+ }
@@ -82,6 +87,7 @@ index 23494aebfa51e7181fb06d123dad429e68ebf922..a5e85005ba9a1d85084c8e54124df9e4
+
+ // Sort each bucket and combine results
+ int currentIndex = 0;
+
+ for (List<LivingEntity> bucket : buckets) {
+ if (!bucket.isEmpty()) {
+ bucket.sort(comparator);

View File

@@ -7,13 +7,13 @@ Original license: GPLv3
Original project: https://github.com/embeddedt/ModernFix
diff --git a/net/minecraft/nbt/CompoundTag.java b/net/minecraft/nbt/CompoundTag.java
index ea48637234fdb1e5f54342590def30e11b6a5df0..a7a5e1c70d1e4f7df6533d0531a200fe50b38b7a 100644
index 3bce1e8ef90e95abd8b1111f1160f952d2493e69..468566e8175d71e1562a80fae8e5f0cd32318c35 100644
--- a/net/minecraft/nbt/CompoundTag.java
+++ b/net/minecraft/nbt/CompoundTag.java
@@ -49,7 +49,7 @@ public class CompoundTag implements Tag {
private static CompoundTag loadCompound(DataInput input, NbtAccounter tracker) throws IOException {
tracker.accountBytes(48L);
private static CompoundTag loadCompound(DataInput input, NbtAccounter nbtAccounter) throws IOException {
nbtAccounter.accountBytes(48L);
- it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, Tag> map = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - Reduce memory footprint of CompoundTag
+ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, Tag> map = new org.dreeam.leaf.util.map.StringCanonizingOpenHashMap<>(8, 0.8f); // Paper - Reduce memory footprint of CompoundTag // Leaf - Further reduce memory footprint of CompoundTag

View File

@@ -8,17 +8,26 @@ avoids multiple casting in Entity#distanceTo, using Math#sqrt directly instead o
these methods more able to be inlined by the JIT compiler.
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index d203ab8cd02432e05d6e3b8766d5a733e570173d..c1a7799dc4c44e5988b15f878633dafb20e257eb 100644
index 42a6b0b6fe13b448583988b3d2f840540b5670e7..35d931407f726b7f8e83f40d220313eb472b20a8 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -2310,33 +2310,41 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -2193,30 +2193,38 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return new Vec3(this.xOld, this.yOld, this.zOld);
}
- public float distanceTo(Entity entity) {
- float f = (float) (this.getX() - entity.getX());
- float f1 = (float) (this.getY() - entity.getY());
- float f2 = (float) (this.getZ() - entity.getZ());
- float f = (float)(this.getX() - entity.getX());
- float f1 = (float)(this.getY() - entity.getY());
- float f2 = (float)(this.getZ() - entity.getZ());
- return Mth.sqrt(f * f + f1 * f1 + f2 * f2);
- }
-
- public double distanceToSqr(double x, double y, double z) {
- double d = this.getX() - x;
- double d1 = this.getY() - y;
- double d2 = this.getZ() - z;
- return d * d + d1 * d1 + d2 * d2;
- }
+ // Leaf start - Optimize distanceTo - inlining
+ public final float distanceTo(Entity entity) {
+ // Leaf start - Optimize distanceTo - Avoid casting
@@ -26,57 +35,36 @@ index d203ab8cd02432e05d6e3b8766d5a733e570173d..c1a7799dc4c44e5988b15f878633dafb
+ final double dy = this.getY() - entity.getY();
+ final double dz = this.getZ() - entity.getZ();
+ // Leaf end - Optimize distanceTo - Avoid casting
- return Mth.sqrt(f * f + f1 * f1 + f2 * f2);
+ return (float) Math.sqrt(org.dreeam.leaf.LeafBootstrap.enableFMA ? Math.fma(dx, dx, Math.fma(dy, dy, dz * dz)) : dx * dx + dy * dy + dz * dz); // Leaf - Use Math#sqrt instead of Mojang's Mth#sqrt - only cast once
}
+ }
+ // Leaf end - Optimize distanceTo - inlining
- public double distanceToSqr(double x, double y, double z) {
- double d3 = this.getX() - x;
- double d4 = this.getY() - y;
- double d5 = this.getZ() - z;
+
+ // Leaf start - Optimize distanceToSqr - inlining
+ public final double distanceToSqr(final double x, final double y, final double z) {
+ final double dx = this.getX() - x;
+ final double dy = this.getY() - y;
+ final double dz = this.getZ() - z;
- return d3 * d3 + d4 * d4 + d5 * d5;
+ return org.dreeam.leaf.LeafBootstrap.enableFMA ? Math.fma(dx, dx, Math.fma(dy, dy, dz * dz)) : dx * dx + dy * dy + dz * dz; // Leaf - Use FMA for distanceToSqr
}
+ }
+ // Leaf end - Optimize distanceToSqr
public double distanceToSqr(Entity entity) {
return this.distanceToSqr(entity.position());
}
- public double distanceToSqr(Vec3 vector) {
- double d0 = this.getX() - vector.x;
- double d1 = this.getY() - vector.y;
- double d2 = this.getZ() - vector.z;
- public double distanceToSqr(Vec3 vec) {
- double d = this.getX() - vec.x;
- double d1 = this.getY() - vec.y;
- double d2 = this.getZ() - vec.z;
- return d * d + d1 * d1 + d2 * d2;
+ // Leaf start - Optimize distanceToSqr - inlining
+ public final double distanceToSqr(Vec3 vector) {
+ final double dx = this.getX() - vector.x;
+ final double dy = this.getY() - vector.y;
+ final double dz = this.getZ() - vector.z;
- return d0 * d0 + d1 * d1 + d2 * d2;
+ return org.dreeam.leaf.LeafBootstrap.enableFMA ? Math.fma(dx, dx, Math.fma(dy, dy, dz * dz)) : dx * dx + dy * dy + dz * dz; // Leaf - Use FMA for distanceToSqr
}
+ // Leaf end - Optimize distanceToSqr - inlining
public void playerTouch(Player player) {}
diff --git a/src/main/java/org/dreeam/leaf/LeafBootstrap.java b/src/main/java/org/dreeam/leaf/LeafBootstrap.java
index 316654051b80ac0fd62cf3b7a0e1b91010ec24b7..0ffa8fb14d02bccc44685ece8cb9d128bfaec405 100644
--- a/src/main/java/org/dreeam/leaf/LeafBootstrap.java
+++ b/src/main/java/org/dreeam/leaf/LeafBootstrap.java
@@ -4,6 +4,7 @@ import io.papermc.paper.PaperBootstrap;
import joptsimple.OptionSet;
public class LeafBootstrap {
+ public static final boolean enableFMA = Boolean.parseBoolean(System.getProperty("Leaf.enableFMA", "false")); // Leaf - FMA feature
public static void boot(final OptionSet options) {
runPreBootTasks();
public void playerTouch(Player player) {
}

View File

@@ -9,15 +9,15 @@ Original project: https://github.com/starlis/empirecraft
Also see Leaf's EMC-Default-don-t-use-blockstate-snapshots.patch
diff --git a/net/minecraft/world/level/block/entity/BlockEntity.java b/net/minecraft/world/level/block/entity/BlockEntity.java
index eaa6ece956f90632831f0558924eaf18680a252b..8a20b0ef9ea684a4a5e79b42f11834e3fe78b4fd 100644
index 3fd0f42618e5c2c683335d1d3e0bb74c6d32ef66..9bbd6ee0518d27a7f4e009e8516e1397234e2090 100644
--- a/net/minecraft/world/level/block/entity/BlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BlockEntity.java
@@ -399,7 +399,7 @@ public abstract class BlockEntity {
@@ -361,7 +361,7 @@ public abstract class BlockEntity {
// CraftBukkit start - add method
public InventoryHolder getOwner() {
public org.bukkit.inventory.InventoryHolder getOwner() {
// Paper start
- return getOwner(true);
+ return getOwner(org.dreeam.leaf.config.modules.opt.TileEntitySnapshotCreation.enabled); // Leaf - EMC - don't use snapshots
}
public InventoryHolder getOwner(boolean useSnapshot) {
public org.bukkit.inventory.InventoryHolder getOwner(boolean useSnapshot) {
// Paper end

View File

@@ -6,49 +6,23 @@ Subject: [PATCH] Cache tile entity position
Check if there is a way to cache isRemoved without problem
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
index b8246d7255bffc7e12a67772df2ceac1925b2a05..2ac51b5ed6fe50746f4f64f94e289f5ad75fd715 100644
index d97d8e79034eb1484d4e3646faacc6f11289bb28..a58a36a8a473e610f604fa778df860470caf7176 100644
--- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -1038,13 +1038,16 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
private class RebindableTickingBlockEntityWrapper implements TickingBlockEntity {
private TickingBlockEntity ticker;
+ private BlockPos cachedPos; // Leaf - Cache tile entity position
RebindableTickingBlockEntityWrapper(final LevelChunk wrapped, final TickingBlockEntity tickingblockentity) {
this.ticker = tickingblockentity;
+ this.cachedPos = this.ticker.getPos(); // Leaf - Cache tile entity position
}
void rebind(TickingBlockEntity wrapped) {
this.ticker = wrapped;
+ this.cachedPos = this.ticker.getPos(); // Leaf - Cache tile entity position
}
@Override
@@ -1059,7 +1062,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
@Override
public BlockPos getPos() {
- return this.ticker.getPos();
+ return this.cachedPos; // Leaf - Cache tile entity position
}
@Override
@@ -1077,10 +1080,12 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
@@ -938,10 +938,12 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
private final T blockEntity;
private final BlockEntityTicker<T> ticker;
private boolean loggedInvalidBlockState;
+ private BlockPos cachedPos; // Leaf - Cache tile entity position
BoundTickingBlockEntity(final BlockEntity tileentity, final BlockEntityTicker blockentityticker) {
this.blockEntity = (T) tileentity; // CraftBukkit - decompile error
this.ticker = blockentityticker;
BoundTickingBlockEntity(final T blockEntity, final BlockEntityTicker<T> ticker) {
this.blockEntity = blockEntity;
this.ticker = ticker;
+ this.cachedPos = this.blockEntity.getBlockPos(); // Leaf - Cache tile entity position
}
@Override
@@ -1126,7 +1131,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
@@ -982,7 +984,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
@Override
public BlockPos getPos() {
@@ -56,4 +30,30 @@ index b8246d7255bffc7e12a67772df2ceac1925b2a05..2ac51b5ed6fe50746f4f64f94e289f5a
+ return this.cachedPos; // Leaf - Cache tile entity position
}
@Override
@@ -1009,13 +1011,16 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
static class RebindableTickingBlockEntityWrapper implements TickingBlockEntity {
private TickingBlockEntity ticker;
+ private BlockPos cachedPos; // Leaf - Cache tile entity position
RebindableTickingBlockEntityWrapper(TickingBlockEntity ticker) {
this.ticker = ticker;
+ this.cachedPos = this.ticker.getPos(); // Leaf - Cache tile entity position
}
void rebind(TickingBlockEntity ticker) {
this.ticker = ticker;
+ this.cachedPos = this.ticker.getPos(); // Leaf - Cache tile entity position
}
@Override
@@ -1030,7 +1035,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
@Override
public BlockPos getPos() {
- return this.ticker.getPos();
+ return this.cachedPos; // Leaf - Cache tile entity position
}
@Override

View File

@@ -7,50 +7,44 @@ Original license: AGPL-3.0
Original project: https://github.com/snackbag/TT20
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 244db7e0ae0eb785deb94558eff74714d979d3de..59d5b758471fc00b09ecf84dc1757f543866d480 100644
index 99fb4faa6e8f099ee216eb44793a1df0e6b8c137..f5766b3bed325f42d4bf55d4fe83ef50fed1481f 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -1668,6 +1668,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1556,6 +1556,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.server.spark.tickStart(); // Paper - spark
new com.destroystokyo.paper.event.server.ServerTickStartEvent(this.tickCount+1).callEvent(); // Paper - Server Tick Events
+
+ // Leaf start - Lag compensation tick hook
+ if (org.dreeam.leaf.config.modules.misc.LagCompensation.enabled) {
+ org.dreeam.leaf.misc.LagCompensation.TPSCalculator.onTick();
+ }
+ // Leaf end - Lag Compensation tick hook
+
++this.tickCount;
+ if (org.dreeam.leaf.config.modules.misc.LagCompensation.enabled) org.dreeam.leaf.misc.LagCompensation.TPSCalculator.onTick(); // Leaf - Lag compensation tick hook
this.tickCount++;
this.tickRateManager.tick();
this.tickChildren(shouldKeepTicking);
this.tickChildren(hasTimeLeft);
diff --git a/net/minecraft/world/level/material/LavaFluid.java b/net/minecraft/world/level/material/LavaFluid.java
index 6e643c1a7f7e71cfd20603facaf224985ee81716..442788dfd6a1b0ce2e28b494bda198ae1a2ec34c 100644
index 85629a43f5469a89dd6078d879f475e8212438ec..8eae2979bfee578443bcf19298b362ef4bed4937 100644
--- a/net/minecraft/world/level/material/LavaFluid.java
+++ b/net/minecraft/world/level/material/LavaFluid.java
@@ -181,7 +181,13 @@ public abstract class LavaFluid extends FlowingFluid {
@@ -177,7 +177,13 @@ public abstract class LavaFluid extends FlowingFluid {
@Override
public int getTickDelay(LevelReader world) {
- return world.dimensionType().ultraWarm() ? world.getWorldBorder().world.purpurConfig.lavaSpeedNether : world.getWorldBorder().world.purpurConfig.lavaSpeedNotNether; // Purpur
public int getTickDelay(LevelReader level) {
- return level.dimensionType().ultraWarm() ? level.getWorldBorder().world.purpurConfig.lavaSpeedNether : level.getWorldBorder().world.purpurConfig.lavaSpeedNotNether; // Purpur - Make lava flow speed configurable
+ // Leaf start - Lag compensation
+ if (org.dreeam.leaf.config.modules.misc.LagCompensation.enabled && org.dreeam.leaf.config.modules.misc.LagCompensation.enableForLava) {
+ return world.dimensionType().ultraWarm() ? org.dreeam.leaf.misc.LagCompensation.tt20(world.getWorldBorder().world.purpurConfig.lavaSpeedNether, true) : org.dreeam.leaf.misc.LagCompensation.tt20(world.getWorldBorder().world.purpurConfig.lavaSpeedNotNether, true); // Purpur // Leaf
+ return level.dimensionType().ultraWarm() ? org.dreeam.leaf.misc.LagCompensation.tt20(level.getWorldBorder().world.purpurConfig.lavaSpeedNether, true) : org.dreeam.leaf.misc.LagCompensation.tt20(level.getWorldBorder().world.purpurConfig.lavaSpeedNotNether, true); // Purpur - Make lava flow speed configurable // Leaf
+ } else {
+ return world.dimensionType().ultraWarm() ? world.getWorldBorder().world.purpurConfig.lavaSpeedNether : world.getWorldBorder().world.purpurConfig.lavaSpeedNotNether; // Purpur
+ return level.dimensionType().ultraWarm() ? level.getWorldBorder().world.purpurConfig.lavaSpeedNether : level.getWorldBorder().world.purpurConfig.lavaSpeedNotNether; // Purpur - Make lava flow speed configurable
+ }
+ // Leaf end - Lag compensation
}
@Override
diff --git a/net/minecraft/world/level/material/WaterFluid.java b/net/minecraft/world/level/material/WaterFluid.java
index 1e741f36b79585f33abe413beafe00cf5205d54f..be86cc0043fcfeaab36870830a39764594db199c 100644
index 2e4fed7c27910b6c886f710f33b0841c2a175837..24e0094d5fa5beafdd79eb127d80a71c7a08f43c 100644
--- a/net/minecraft/world/level/material/WaterFluid.java
+++ b/net/minecraft/world/level/material/WaterFluid.java
@@ -123,7 +123,13 @@ public abstract class WaterFluid extends FlowingFluid {
@@ -115,7 +115,13 @@ public abstract class WaterFluid extends FlowingFluid {
@Override
public int getTickDelay(LevelReader world) {
public int getTickDelay(LevelReader level) {
- return 5;
+ // Leaf start - Lag compensation
+ if (org.dreeam.leaf.config.modules.misc.LagCompensation.enabled && org.dreeam.leaf.config.modules.misc.LagCompensation.enableForWater) {

View File

@@ -10,15 +10,15 @@ As part of: C2ME (https://github.com/RelativityMC/C2ME-fabric)
Licensed under: MIT (https://opensource.org/licenses/MIT)
diff --git a/net/minecraft/world/level/levelgen/feature/OreFeature.java b/net/minecraft/world/level/levelgen/feature/OreFeature.java
index 506b2afd099c9b7e9ac3f6f2fcea8e523fae396b..df119e67ffdd73a7c2c93dfb35985d0c850f9e64 100644
index c7b46efd4f08067e2c9c5c8b0e8b71a94a79823d..d14609e932f2ce4e97d1e354b424cc3ec86bd25b 100644
--- a/net/minecraft/world/level/levelgen/feature/OreFeature.java
+++ b/net/minecraft/world/level/levelgen/feature/OreFeature.java
@@ -69,7 +69,7 @@ public class OreFeature extends Feature<OreConfiguration> {
int verticalSize
int height
) {
int i = 0;
- BitSet bitSet = new BitSet(horizontalSize * verticalSize * horizontalSize);
+ BitSet bitSet = org.dreeam.leaf.util.cache.CachedOrNewBitsGetter.getCachedOrNewBitSet(horizontalSize * verticalSize * horizontalSize); // Leaf - C2ME - Reduce Allocations
- BitSet bitSet = new BitSet(width * height * width);
+ BitSet bitSet = org.dreeam.leaf.util.cache.CachedOrNewBitsGetter.getCachedOrNewBitSet(width * height * width); // Leaf - C2ME - Reduce Allocations
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
int j = config.size;
double[] ds = new double[j * 4];
int i1 = config.size;
double[] doubles = new double[i1 * 4];

View File

@@ -12,18 +12,18 @@ As part of: Lithium (https://github.com/CaffeineMC/lithium-fabric)
Licensed under: LGPL-3.0 (https://www.gnu.org/licenses/lgpl-3.0.html)
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index 004cecfe99d279a51c21d610833bbea62c8ff25f..2b8cc1cfeda50721c063429a7d31623dc93089ea 100644
index 6aa4153a5368645ad3f1a0b879428f9a60d8fbc6..4819ff258b3abffcbf8a443b157c3a28afd1c52a 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -2866,6 +2866,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -2732,6 +2732,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
protected void updateSwingTime() {
+ if (!this.swinging && this.swingTime == 0) return; // Leaf - Lithium - entity.fast_hand_swing
int i = this.getCurrentSwingDuration();
int currentSwingDuration = this.getCurrentSwingDuration();
if (this.swinging) {
@@ -3889,6 +3890,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.swingTime++;
@@ -3665,6 +3666,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
protected void updateFallFlying() {
this.checkSlowFallDistance();
if (!this.level().isClientSide) {

View File

@@ -11,7 +11,7 @@ As part of: Lithium (https://github.com/CaffeineMC/lithium-fabric)
Licensed under: LGPL-3.0 (https://www.gnu.org/licenses/lgpl-3.0.html)
diff --git a/net/minecraft/core/Direction.java b/net/minecraft/core/Direction.java
index 6548302d4983bf48cc6bc2b7f4833dc76b59fa5e..dde522cfe64674d9cfc8d26601cad61816a6eaf5 100644
index 216f97207dac88cc1dc3df59c6ee8a62c7614b4a..3a76b1ec8570e4c9f328e9d362b41057b092be45 100644
--- a/net/minecraft/core/Direction.java
+++ b/net/minecraft/core/Direction.java
@@ -217,7 +217,7 @@ public enum Direction implements StringRepresentable, ca.spottedleaf.moonrise.pa
@@ -33,7 +33,7 @@ index 6548302d4983bf48cc6bc2b7f4833dc76b59fa5e..dde522cfe64674d9cfc8d26601cad618
public static Direction getApproximateNearest(double x, double y, double z) {
diff --git a/net/minecraft/world/phys/AABB.java b/net/minecraft/world/phys/AABB.java
index e74866e5195a5eeae7666ad7be750edac5947094..1958656ee368513c96de6635dfe7c969407400ec 100644
index c9c6e4e460ad8435f12761704bb9b0284d6aa708..f64c04b32dd2d0fe143fc8bf9f498e52beb66a58 100644
--- a/net/minecraft/world/phys/AABB.java
+++ b/net/minecraft/world/phys/AABB.java
@@ -18,6 +18,15 @@ public class AABB {
@@ -52,7 +52,7 @@ index e74866e5195a5eeae7666ad7be750edac5947094..1958656ee368513c96de6635dfe7c969
public AABB(double x1, double y1, double z1, double x2, double y2, double z2) {
this.minX = Math.min(x1, x2);
this.minY = Math.min(y1, y2);
@@ -86,11 +95,33 @@ public class AABB {
@@ -79,11 +88,33 @@ public class AABB {
}
public double min(Direction.Axis axis) {

View File

@@ -10,17 +10,17 @@ As part of: Lithium (https://github.com/CaffeineMC/lithium-fabric)
Licensed under: LGPL-3.0 (https://www.gnu.org/licenses/lgpl-3.0.html)
diff --git a/net/minecraft/util/Mth.java b/net/minecraft/util/Mth.java
index 34bfbbabe3dfbf033f4a4e22a049323213fb23f3..c79bf9ea9456ac01533e8aa0326eb2f231626a49 100644
index 85c329437f27fc2fc143d2873572f8d3cf30660d..1ebac20359345630ad56a2578b4b1686617300d2 100644
--- a/net/minecraft/util/Mth.java
+++ b/net/minecraft/util/Mth.java
@@ -29,7 +29,7 @@ public class Mth {
public static final Vector3f Y_AXIS = new Vector3f(0.0F, 1.0F, 0.0F);
public static final Vector3f X_AXIS = new Vector3f(1.0F, 0.0F, 0.0F);
public static final Vector3f Z_AXIS = new Vector3f(0.0F, 0.0F, 1.0F);
- private static final float[] SIN = Util.make(new float[65536], sineTable -> {
+ public static final float[] SIN = Util.make(new float[65536], sineTable -> { // Leaf - Lithium - private -> public
for (int ix = 0; ix < sineTable.length; ix++) {
sineTable[ix] = (float)Math.sin((double)ix * Math.PI * 2.0 / 65536.0);
- private static final float[] SIN = Util.make(new float[65536], floats -> {
+ public static final float[] SIN = Util.make(new float[65536], floats -> { // Leaf - Lithium - private -> public
for (int i1 = 0; i1 < floats.length; i1++) {
floats[i1] = (float)Math.sin(i1 * Math.PI * 2.0 / 65536.0);
}
@@ -46,11 +46,11 @@ public class Mth {
private static final double[] COS_TAB = new double[257];

View File

@@ -8,11 +8,11 @@ As part of: Lithium (https://github.com/CaffeineMC/lithium-fabric)
Licensed under: LGPL-3.0 (https://www.gnu.org/licenses/lgpl-3.0.html)
diff --git a/net/minecraft/core/BlockPos.java b/net/minecraft/core/BlockPos.java
index 21ea63da99c5b3e2e1ab9cc1049c903bba6cf288..350a5d47cca11c0e49437a4b05029ba5c29b7ee5 100644
index 6518d3fff6daf331b24a7bf5b39fa1920b73711d..da491fc59b78f9fc8141e72f810f3fbaf9bc1274 100644
--- a/net/minecraft/core/BlockPos.java
+++ b/net/minecraft/core/BlockPos.java
@@ -344,7 +344,19 @@ public class BlockPos extends Vec3i {
};
@@ -347,7 +347,18 @@ public class BlockPos extends Vec3i {
};
}
+ // JettPack start - lithium: cached iterate outwards
@@ -20,14 +20,13 @@ index 21ea63da99c5b3e2e1ab9cc1049c903bba6cf288..350a5d47cca11c0e49437a4b05029ba5
+ private static final it.unimi.dsi.fastutil.longs.LongList HOGLIN_PIGLIN_CACHE = ITERATE_OUTWARDS_CACHE.getOrCompute(8, 4, 8);
+ // JettPack end
+
+
public static Iterable<BlockPos> withinManhattan(BlockPos center, int rangeX, int rangeY, int rangeZ) {
public static Iterable<BlockPos> withinManhattan(BlockPos pos, int xSize, int ySize, int zSize) {
+ // JettPack start - lithium: cached iterate outwards
+ if (center != org.dreeam.leaf.util.cache.IterateOutwardsCache.POS_ZERO) {
+ final it.unimi.dsi.fastutil.longs.LongList positions = rangeX == 8 && rangeY == 4 && rangeZ == 8 ? HOGLIN_PIGLIN_CACHE : ITERATE_OUTWARDS_CACHE.getOrCompute(rangeX, rangeY, rangeZ);
+ return new org.dreeam.leaf.util.cache.LongList2BlockPosMutableIterable(center, positions);
+ if (pos != org.dreeam.leaf.util.cache.IterateOutwardsCache.POS_ZERO) {
+ final it.unimi.dsi.fastutil.longs.LongList positions = xSize == 8 && ySize == 4 && zSize == 8 ? HOGLIN_PIGLIN_CACHE : ITERATE_OUTWARDS_CACHE.getOrCompute(xSize, ySize, zSize);
+ return new org.dreeam.leaf.util.cache.LongList2BlockPosMutableIterable(pos, positions);
+ }
+ // JettPack end
int i = rangeX + rangeY + rangeZ;
// Paper start - rename variables to fix conflict with anonymous class (remap fix)
int centerX = center.getX();
int i = xSize + ySize + zSize;
int x1 = pos.getX();
int y1 = pos.getY();

View File

@@ -0,0 +1,49 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
Date: Tue, 9 Nov 2077 00:00:00 +0800
Subject: [PATCH] Smooth teleport config
This abuses some of how Minecraft works and attempts to teleport a player to another world without
triggering typical respawn packets. All of natural state of chunk resends, entity adds/removes, etc still
happen but the visual "refresh" of a world change is hidden. Depending on the destination location/world,
this can act as a "smooth teleport" to a world if the new world is very similar looking to the old one.
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index ef20741ab2a7feaa8a86759ee0ae6283e4d4651c..98e20e34287443fa8ba482f65aae663f3c6e0f87 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -1468,6 +1468,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
LevelData worlddata = level.getLevelData();
this.connection.send(new ClientboundRespawnPacket(this.createCommonSpawnInfo(level), (byte) 3));
+ if (!org.dreeam.leaf.config.modules.gameplay.SmoothTeleport.enabled || !PlayerList.isSameLogicalHeight(serverLevel, level)) this.connection.send(new ClientboundRespawnPacket(this.createCommonSpawnInfo(level), (byte) 3)); // Leaf - Smooth teleport
this.connection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
PlayerList playerList = this.server.getPlayerList();
@@ -1477,7 +1478,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
// CraftBukkit end
this.portalPos = io.papermc.paper.util.MCUtil.toBlockPosition(exit); // Purpur - Fix stuck in portals
this.setServerLevel(level);
- this.connection.internalTeleport(PositionMoveRotation.of(teleportTransition), teleportTransition.relatives()); // CraftBukkit - use internal teleport without event
+ if (!org.dreeam.leaf.config.modules.gameplay.SmoothTeleport.enabled || !PlayerList.isSameLogicalHeight(serverLevel, level)) this.connection.internalTeleport(PositionMoveRotation.of(teleportTransition), teleportTransition.relatives()); // CraftBukkit - use internal teleport without event // Leaf - Smooth teleport
this.connection.resetPosition();
level.addDuringTeleport(this);
this.triggerDimensionChangeTriggers(serverLevel);
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 9ac89bd2dcf2bba13a7f12f4902db94f71771fae..3882612e14f71cce81eec23b505611432f5cb50a 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -954,11 +954,11 @@ public abstract class PlayerList {
byte b = (byte)(keepInventory ? 1 : 0);
ServerLevel serverLevel = serverPlayer.serverLevel();
LevelData levelData = serverLevel.getLevelData();
- if (!serverPlayer.smoothWorldTeleport || !isSameLogicalHeight((ServerLevel) fromWorld, level)) serverPlayer.connection.send(new ClientboundRespawnPacket(serverPlayer.createCommonSpawnInfo(serverLevel), b)); // Leaf - Slice
+ if ((!serverPlayer.smoothWorldTeleport && !org.dreeam.leaf.config.modules.gameplay.SmoothTeleport.enabled) || b != 1 || !isSameLogicalHeight((ServerLevel) fromWorld, level)) serverPlayer.connection.send(new ClientboundRespawnPacket(serverPlayer.createCommonSpawnInfo(serverLevel), b)); // Leaf - Slice // Leaf
// serverPlayer.connection.teleport(serverPlayer.getX(), serverPlayer.getY(), serverPlayer.getZ(), serverPlayer.getYRot(), serverPlayer.getXRot());
serverPlayer.connection.send(new ClientboundSetChunkCacheRadiusPacket(serverLevel.spigotConfig.viewDistance)); // Spigot
serverPlayer.connection.send(new ClientboundSetSimulationDistancePacket(serverLevel.spigotConfig.simulationDistance)); // Spigot
- if (!serverPlayer.smoothWorldTeleport || !isSameLogicalHeight((ServerLevel) fromWorld, level)) serverPlayer.connection.teleport(org.bukkit.craftbukkit.util.CraftLocation.toBukkit(serverPlayer.position(), serverLevel.getWorld(), serverPlayer.getYRot(), serverPlayer.getXRot())); // CraftBukkit // Leaf - Slice
+ if ((!serverPlayer.smoothWorldTeleport && !org.dreeam.leaf.config.modules.gameplay.SmoothTeleport.enabled) || b != 1 || !isSameLogicalHeight((ServerLevel) fromWorld, level)) serverPlayer.connection.teleport(org.bukkit.craftbukkit.util.CraftLocation.toBukkit(serverPlayer.position(), serverLevel.getWorld(), serverPlayer.getYRot(), serverPlayer.getXRot())); // CraftBukkit // Leaf - Slice // Leaf
serverPlayer.connection.send(new ClientboundSetDefaultSpawnPositionPacket(level.getSharedSpawnPos(), level.getSharedSpawnAngle()));
serverPlayer.connection.send(new ClientboundChangeDifficultyPacket(levelData.getDifficulty(), levelData.isDifficultyLocked()));
serverPlayer.connection

View File

@@ -23,13 +23,13 @@ Wether there is a high frequnently calls or not. And also thread-safe. So there
a better solution, why not using it?
diff --git a/net/minecraft/server/players/BanListEntry.java b/net/minecraft/server/players/BanListEntry.java
index 8b1da1fb5ca27432a39aff6dbc452b793268dab5..46188a8b8598c36ccb0f5e037a80eb1741c68491 100644
index e111adec2116f922fe67ee434635e50c60dad15c..378ea667007844a08b4f215ca5f0730668e46699 100644
--- a/net/minecraft/server/players/BanListEntry.java
+++ b/net/minecraft/server/players/BanListEntry.java
@@ -10,7 +10,9 @@ import net.minecraft.network.chat.Component;
@@ -9,7 +9,9 @@ import javax.annotation.Nullable;
import net.minecraft.network.chat.Component;
public abstract class BanListEntry<T> extends StoredUserEntry<T> {
- public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z", Locale.ROOT);
+ //public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z", Locale.ROOT); // Leaf - I assume no one will use this, if yes, why?
+ private static final java.time.ZoneId ZONE_ID = java.time.ZoneId.systemDefault();
@@ -37,45 +37,45 @@ index 8b1da1fb5ca27432a39aff6dbc452b793268dab5..46188a8b8598c36ccb0f5e037a80eb17
public static final String EXPIRES_NEVER = "forever";
protected final Date created;
protected final String source;
@@ -32,8 +34,10 @@ public abstract class BanListEntry<T> extends StoredUserEntry<T> {
Date date;
@@ -30,8 +32,10 @@ public abstract class BanListEntry<T> extends StoredUserEntry<T> {
Date date;
try {
- date = json.has("created") ? BanListEntry.DATE_FORMAT.parse(json.get("created").getAsString()) : new Date();
- } catch (ParseException parseexception) {
- date = entryData.has("created") ? DATE_FORMAT.parse(entryData.get("created").getAsString()) : new Date();
- } catch (ParseException var7) {
+ // Leaf start - Use faster and thread-safe ban list date format parsing
+ date = json.has("created") ? parseToDate(json.get("created").getAsString()) : new Date();
+ } catch (java.time.format.DateTimeParseException e) {
+ date = entryData.has("created") ? parseToDate(entryData.get("created").getAsString()) : new Date();
+ } catch (java.time.format.DateTimeParseException var7) {
+ // Leaf end - Use faster and thread-safe ban list date format parsing
date = new Date();
}
@@ -43,8 +47,10 @@ public abstract class BanListEntry<T> extends StoredUserEntry<T> {
Date date1;
@@ -40,8 +44,10 @@ public abstract class BanListEntry<T> extends StoredUserEntry<T> {
Date date1;
try {
- date1 = json.has("expires") ? BanListEntry.DATE_FORMAT.parse(json.get("expires").getAsString()) : null;
- } catch (ParseException parseexception1) {
- date1 = entryData.has("expires") ? DATE_FORMAT.parse(entryData.get("expires").getAsString()) : null;
- } catch (ParseException var6) {
+ // Leaf start - Use faster and thread-safe ban list date format parsing
+ date1 = json.has("expires") ? parseToDate(json.get("expires").getAsString()) : null;
+ } catch (java.time.format.DateTimeParseException e) {
+ date1 = entryData.has("expires") ? parseToDate(entryData.get("expires").getAsString()) : null;
+ } catch (java.time.format.DateTimeParseException var6) {
+ // Leaf end - Use faster and thread-safe ban list date format parsing
date1 = null;
}
@@ -78,9 +84,9 @@ public abstract class BanListEntry<T> extends StoredUserEntry<T> {
@@ -75,9 +81,9 @@ public abstract class BanListEntry<T> extends StoredUserEntry<T> {
@Override
protected void serialize(JsonObject json) {
- json.addProperty("created", BanListEntry.DATE_FORMAT.format(this.created));
+ json.addProperty("created", formateToString(this.created)); // Leaf - Use faster and thread-safe ban list date format parsing
json.addProperty("source", this.source);
- json.addProperty("expires", this.expires == null ? "forever" : BanListEntry.DATE_FORMAT.format(this.expires));
+ json.addProperty("expires", this.expires == null ? "forever" : formateToString(this.expires)); // Leaf - Use faster and thread-safe ban list date format parsing
json.addProperty("reason", this.reason);
protected void serialize(JsonObject data) {
- data.addProperty("created", DATE_FORMAT.format(this.created));
+ data.addProperty("created", formateToString(this.created)); // Leaf - Use faster and thread-safe ban list date format parsing
data.addProperty("source", this.source);
- data.addProperty("expires", this.expires == null ? "forever" : DATE_FORMAT.format(this.expires));
+ data.addProperty("expires", this.expires == null ? "forever" : formateToString(this.expires)); // Leaf - Use faster and thread-safe ban list date format parsing
data.addProperty("reason", this.reason);
}
@@ -89,9 +95,11 @@ public abstract class BanListEntry<T> extends StoredUserEntry<T> {
@@ -86,9 +92,11 @@ public abstract class BanListEntry<T> extends StoredUserEntry<T> {
Date expires = null;
try {
@@ -89,7 +89,7 @@ index 8b1da1fb5ca27432a39aff6dbc452b793268dab5..46188a8b8598c36ccb0f5e037a80eb17
}
if (expires == null || expires.after(new Date())) {
@@ -101,4 +109,15 @@ public abstract class BanListEntry<T> extends StoredUserEntry<T> {
@@ -98,4 +106,15 @@ public abstract class BanListEntry<T> extends StoredUserEntry<T> {
}
}
// CraftBukkit end
@@ -106,19 +106,19 @@ index 8b1da1fb5ca27432a39aff6dbc452b793268dab5..46188a8b8598c36ccb0f5e037a80eb17
+ // Leaf end - Use faster and thread-safe ban list date format parsing
}
diff --git a/net/minecraft/server/players/OldUsersConverter.java b/net/minecraft/server/players/OldUsersConverter.java
index 653856d0b8dcf2baf4cc77a276f17c8cc1fa717e..6416bc12f3d7733a4bd89d208a320f1b68983788 100644
index 7dbcd9d96f052bb10127ad2b061154c23cc9ffd4..0a3b159a8629fad1a240b9be3e6025bfa1183a00 100644
--- a/net/minecraft/server/players/OldUsersConverter.java
+++ b/net/minecraft/server/players/OldUsersConverter.java
@@ -516,8 +516,10 @@ public class OldUsersConverter {
Date date1;
@@ -469,8 +469,10 @@ public class OldUsersConverter {
static Date parseDate(String input, Date defaultValue) {
Date date;
try {
- date1 = BanListEntry.DATE_FORMAT.parse(dateString);
- } catch (ParseException parseexception) {
- date = BanListEntry.DATE_FORMAT.parse(input);
- } catch (ParseException var4) {
+ // Leaf start - Use faster and thread-safe ban list date format parsing
+ date1 = BanListEntry.parseToDate(dateString);
+ } catch (java.time.format.DateTimeParseException e) {
+ date = BanListEntry.parseToDate(input);
+ } catch (java.time.format.DateTimeParseException var4) {
+ // Leaf end - Use faster and thread-safe ban list date format parsing
date1 = fallback;
date = defaultValue;
}

View File

@@ -5,45 +5,43 @@ Subject: [PATCH] Collect then startEachNonRunningBehavior in Brain
diff --git a/net/minecraft/world/entity/ai/Brain.java b/net/minecraft/world/entity/ai/Brain.java
index 65bd8c2cccd0a4a68984ea8ff4cd3cf365330630..aeb74b96704e0f187178e2ae106e0a3f6d95717c 100644
index 5eaa1dec9fbe72a22c34331a28f7b7115fb3aeba..a67f72169d6f4dfbe1dc17918e1bdbeb558d3869 100644
--- a/net/minecraft/world/entity/ai/Brain.java
+++ b/net/minecraft/world/entity/ai/Brain.java
@@ -466,20 +466,30 @@ public class Brain<E extends LivingEntity> {
@@ -466,20 +466,29 @@ public class Brain<E extends LivingEntity> {
}
private void startEachNonRunningBehavior(ServerLevel world, E entity) {
- long l = world.getGameTime();
private void startEachNonRunningBehavior(ServerLevel level, E entity) {
- long gameTime = level.getGameTime();
+ // Leaf start - Collect first then start
+ final long gameTime = world.getGameTime();
+ final long gameTime = level.getGameTime();
+ List<BehaviorControl<? super E>> behaviorsToStart = new ObjectArrayList<>();
- for (Map<Activity, Set<BehaviorControl<? super E>>> map : this.availableBehaviorsByPriority.values()) {
- for (Entry<Activity, Set<BehaviorControl<? super E>>> entry : map.entrySet()) {
- Activity activity = entry.getKey();
- if (this.activeActivities.contains(activity)) {
- for (BehaviorControl<? super E> behaviorControl : entry.getValue()) {
- if (behaviorControl.getStatus() == Behavior.Status.STOPPED) {
- behaviorControl.tryStart(world, entity, l);
+ List<BehaviorControl<? super E>> behaviorsToStart = new ObjectArrayList<>();
+
+ for (Activity activeActivity : this.activeActivities) {
+ for (Map<Activity, Set<BehaviorControl<? super E>>> priorityMap : this.availableBehaviorsByPriority.values()) {
+ Set<BehaviorControl<? super E>> behaviors = priorityMap.get(activeActivity);
+
+ if (behaviors != null && !behaviors.isEmpty()) {
+ for (BehaviorControl<? super E> behavior : behaviors) {
+ if (behavior.getStatus() == Behavior.Status.STOPPED) {
+ behaviorsToStart.add(behavior);
+ for (BehaviorControl<? super E> behaviorControl : behaviors) {
if (behaviorControl.getStatus() == Behavior.Status.STOPPED) {
- behaviorControl.tryStart(level, entity, gameTime);
+ behaviorsToStart.add(behaviorControl);
}
}
}
}
}
+ if (!behaviorsToStart.isEmpty()) {
+ for (BehaviorControl<? super E> behavior : behaviorsToStart) {
+ behavior.tryStart(world, entity, gameTime);
+ for (BehaviorControl<? super E> behaviorControl : behaviorsToStart) {
+ behaviorControl.tryStart(level, entity, gameTime);
+ }
+ }
+ // Leaf end - Collect first then start
}
private void tickEachRunningBehavior(ServerLevel world, E entity) {
private void tickEachRunningBehavior(ServerLevel level, E entity) {

View File

@@ -24,7 +24,7 @@ As part of: Lithium (https://github.com/CaffeineMC/lithium-fabric)
Licensed under: LGPL-3.0 (https://www.gnu.org/licenses/lgpl-3.0.html)
diff --git a/net/minecraft/core/component/PatchedDataComponentMap.java b/net/minecraft/core/component/PatchedDataComponentMap.java
index ceee6345530c3bf91cce988af2da12f0798d8f4b..1289fecee1f05abfce09672ec406caf759943b5c 100644
index a8c6549f772208cd543607224fef2c2389b14f24..f0b9bb52763b994c34048eb540ac60e73dcb227a 100644
--- a/net/minecraft/core/component/PatchedDataComponentMap.java
+++ b/net/minecraft/core/component/PatchedDataComponentMap.java
@@ -14,10 +14,11 @@ import java.util.Map.Entry;
@@ -38,9 +38,9 @@ index ceee6345530c3bf91cce988af2da12f0798d8f4b..1289fecee1f05abfce09672ec406caf7
private boolean copyOnWrite;
+ private net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<PatchedDataComponentMap> subscriber; // Leaf - Lithium equipment tracking
public PatchedDataComponentMap(DataComponentMap baseComponents) {
this(baseComponents, Reference2ObjectMaps.emptyMap(), true);
@@ -133,6 +134,9 @@ public final class PatchedDataComponentMap implements DataComponentMap {
public PatchedDataComponentMap(DataComponentMap prototype) {
this(prototype, Reference2ObjectMaps.emptyMap(), true);
@@ -135,6 +136,9 @@ public final class PatchedDataComponentMap implements DataComponentMap {
}
private void ensureMapOwnership() {
@@ -50,8 +50,8 @@ index ceee6345530c3bf91cce988af2da12f0798d8f4b..1289fecee1f05abfce09672ec406caf7
if (this.copyOnWrite) {
this.patch = new Reference2ObjectArrayMap<>(this.patch);
this.copyOnWrite = false;
@@ -215,6 +219,22 @@ public final class PatchedDataComponentMap implements DataComponentMap {
return new PatchedDataComponentMap(this.prototype, this.patch, true);
@@ -221,6 +225,22 @@ public final class PatchedDataComponentMap implements DataComponentMap {
return (DataComponentMap)(this.patch.isEmpty() ? this.prototype : this.copy());
}
+ // Leaf start - Lithium equipment tracking
@@ -71,22 +71,22 @@ index ceee6345530c3bf91cce988af2da12f0798d8f4b..1289fecee1f05abfce09672ec406caf7
+ // Leaf end - Lithium equipment tracking
+
@Override
public boolean equals(Object object) {
if (this == object) {
public boolean equals(Object other) {
return this == other
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index 2b8cc1cfeda50721c063429a7d31623dc93089ea..ac19c28135debebf0e1055d47571dc068f10e30e 100644
index 4819ff258b3abffcbf8a443b157c3a28afd1c52a..e216bb1cf728698fea018b9064c71f7733e7836d 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -160,7 +160,7 @@ import org.bukkit.event.entity.EntityTeleportEvent;
@@ -159,7 +159,7 @@ import org.bukkit.event.entity.EntityTeleportEvent;
import org.bukkit.event.player.PlayerItemConsumeEvent;
// CraftBukkit end
-public abstract class LivingEntity extends Entity implements Attackable {
+public abstract class LivingEntity extends Entity implements Attackable, net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber.CountChangeSubscriber<ItemStack>, net.caffeinemc.mods.lithium.common.entity.EquipmentEntity, net.caffeinemc.mods.lithium.common.entity.EquipmentEntity.TickableEnchantmentTrackingEntity, net.caffeinemc.mods.lithium.common.entity.EquipmentEntity.EquipmentTrackingEntity { // Leaf - Lithium equipment tracking
private static final Logger LOGGER = LogUtils.getLogger();
private static final String TAG_ACTIVE_EFFECTS = "active_effects";
@@ -301,6 +301,10 @@ public abstract class LivingEntity extends Entity implements Attackable {
private static final ResourceLocation SPEED_MODIFIER_POWDER_SNOW_ID = ResourceLocation.withDefaultNamespace("powder_snow");
@@ -305,6 +305,10 @@ public abstract class LivingEntity extends Entity implements Attackable {
public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API
protected boolean shouldBurnInDay = false; public boolean shouldBurnInDay() { return this.shouldBurnInDay; } public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; } // Purpur - API for any mob to burn daylight
@@ -97,32 +97,32 @@ index 2b8cc1cfeda50721c063429a7d31623dc93089ea..ac19c28135debebf0e1055d47571dc06
@Override
public float getBukkitYaw() {
return this.getYHeadRot();
@@ -454,7 +458,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
Level world = this.level();
- if (world instanceof ServerLevel worldserver) {
+ if (this.maybeHasTickableEnchantments && world instanceof ServerLevel worldserver) { // Leaf - Lithium equipment tracking
EnchantmentHelper.tickEffects(worldserver, this);
@@ -445,7 +449,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.getSleepingPos().ifPresent(this::setPosToBed);
}
@@ -751,6 +755,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
boolean flag = itemstack1.isEmpty() && itemstack.isEmpty();
- if (this.level() instanceof ServerLevel serverLevel) {
+ if (this.maybeHasTickableEnchantments && this.level() instanceof ServerLevel serverLevel) { // Leaf - Lithium equipment tracking
EnchantmentHelper.tickEffects(serverLevel, this);
}
if (!flag && !ItemStack.isSameItemSameComponents(itemstack, itemstack1) && !this.firstTick) {
+ this.onEquipmentReplaced(itemstack, itemstack1); // Leaf - Lithium equipment tracking
Equippable equippable = (Equippable) itemstack1.get(DataComponents.EQUIPPABLE);
if (!this.isSilent() && equippable != null && enumitemslot == equippable.slot() && !silent) { // CraftBukkit
@@ -3517,6 +3522,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -738,6 +742,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (!this.level().isClientSide() && !this.isSpectator()) {
boolean flag = newItem.isEmpty() && oldItem.isEmpty();
if (!flag && !ItemStack.isSameItemSameComponents(oldItem, newItem) && !this.firstTick) {
+ this.onEquipmentReplaced(oldItem, newItem); // Leaf - Lithium equipment tracking
Equippable equippable = newItem.get(DataComponents.EQUIPPABLE);
if (!this.isSilent() && equippable != null && slot == equippable.slot() && !silent) { // CraftBukkit
this.level()
@@ -3348,6 +3353,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
public void detectEquipmentUpdatesPublic() { // CraftBukkit
Map<EquipmentSlot, ItemStack> map = this.collectEquipmentChanges();
if (map != null) {
+ if (!(this instanceof net.minecraft.world.entity.player.Player)) this.equipmentChanged = false; // Leaf - Lithium equipment tracking
this.handleHandSwap(map);
if (!map.isEmpty()) {
this.handleEquipmentChanges(map);
@@ -3527,6 +3533,10 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -3357,6 +3363,10 @@ public abstract class LivingEntity extends Entity implements Attackable {
@Nullable
private Map<EquipmentSlot, ItemStack> collectEquipmentChanges() {
@@ -131,12 +131,12 @@ index 2b8cc1cfeda50721c063429a7d31623dc93089ea..ac19c28135debebf0e1055d47571dc06
+ if (!isArmorStandUpdateNoTick && !this.equipmentChanged) return null;
+ // Leaf end - Lithium equipment tracking
Map<EquipmentSlot, ItemStack> map = null;
Iterator iterator = EquipmentSlot.VALUES.iterator();
@@ -4985,6 +4995,79 @@ public abstract class LivingEntity extends Entity implements Attackable {
public int getLastHurtByPlayerTime() {
for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) {
@@ -4698,6 +4708,81 @@ public abstract class LivingEntity extends Entity implements Attackable {
return this.lastHurtByPlayerTime;
}
+ // Leaf start - Lithium entity equipment tracking
+ @Override
+ public void updateHasTickableEnchantments(ItemStack oldStack, ItemStack newStack) {
@@ -171,6 +171,7 @@ index 2b8cc1cfeda50721c063429a7d31623dc93089ea..ac19c28135debebf0e1055d47571dc06
+ }
+ return false;
+ }
+
+ @Override
+ public void notify(@Nullable ItemStack publisher, int zero) {
+ if (this instanceof EquipmentTrackingEntity equipmentTrackingEntity) {
@@ -210,60 +211,61 @@ index 2b8cc1cfeda50721c063429a7d31623dc93089ea..ac19c28135debebf0e1055d47571dc06
+ }
+ }
+ // Leaf end - Lithium entity equipment tracking
public static record Fallsounds(SoundEvent small, SoundEvent big) {
+
public record Fallsounds(SoundEvent small, SoundEvent big) {
}
}
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
index 1e4729be4a245a811fd15ea1c02179b37defd67c..5814d9b6b0fc5346c24dd268ec147a67c5acbfdb 100644
index c32086ddf90fafcc55600f9e0724b9f915671482..5e03f3536010951ac378c1856ac355a18dec9dd6 100644
--- a/net/minecraft/world/entity/Mob.java
+++ b/net/minecraft/world/entity/Mob.java
@@ -98,7 +98,7 @@ import org.bukkit.event.entity.EntityUnleashEvent;
@@ -94,7 +94,7 @@ import org.bukkit.event.entity.EntityUnleashEvent;
import org.bukkit.event.entity.EntityUnleashEvent.UnleashReason;
// CraftBukkit end
-public abstract class Mob extends LivingEntity implements EquipmentUser, Leashable, Targeting {
+public abstract class Mob extends LivingEntity implements EquipmentUser, Leashable, Targeting, net.caffeinemc.mods.lithium.common.entity.EquipmentEntity { // Leaf - Lithium equipment tracking
private static final EntityDataAccessor<Byte> DATA_MOB_FLAGS_ID = SynchedEntityData.defineId(Mob.class, EntityDataSerializers.BYTE);
private static final int MOB_FLAG_NO_AI = 1;
@@ -577,6 +577,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
private static final int MOB_FLAG_LEFTHANDED = 2;
@@ -516,6 +516,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
@Override
public void readAdditionalSaveData(CompoundTag nbt) {
public void readAdditionalSaveData(CompoundTag compound) {
+ ItemStack prevBodyArmor = this.bodyArmorItem; // Leaf - Lithium equipment tracking
super.readAdditionalSaveData(nbt);
super.readAdditionalSaveData(compound);
// CraftBukkit start - If looting or persistence is false only use it if it was set after we started using it
@@ -601,7 +602,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
if (compound.contains("CanPickUpLoot", 99)) {
@@ -535,7 +536,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
for (i = 0; i < this.armorItems.size(); ++i) {
nbttagcompound1 = nbttaglist.getCompound(i);
- this.armorItems.set(i, ItemStack.parseOptional(this.registryAccess(), nbttagcompound1));
for (int i = 0; i < this.armorItems.size(); i++) {
CompoundTag compound1 = list.getCompound(i);
- this.armorItems.set(i, ItemStack.parseOptional(this.registryAccess(), compound1));
+ // Leaf start - Lithium equipment tracking
+ ItemStack currStack = ItemStack.parseOptional(this.registryAccess(), nbttagcompound1);
+ ItemStack currStack = ItemStack.parseOptional(this.registryAccess(), compound1);
+ ItemStack prevStack = this.armorItems.set(i, currStack);
+ this.trackEquipChange(prevStack, currStack);
+ // Leaf end - Lithium equipment tracking
}
}
} else {
this.armorItems.replaceAll(itemStack -> ItemStack.EMPTY);
@@ -556,7 +561,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
@@ -618,7 +623,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
for (i = 0; i < this.handItems.size(); ++i) {
nbttagcompound1 = nbttaglist.getCompound(i);
- this.handItems.set(i, ItemStack.parseOptional(this.registryAccess(), nbttagcompound1));
for (int i = 0; i < this.handItems.size(); i++) {
CompoundTag compound1 = list.getCompound(i);
- this.handItems.set(i, ItemStack.parseOptional(this.registryAccess(), compound1));
+ // Leaf start - Lithium equipment tracking
+ ItemStack currStack = ItemStack.parseOptional(this.registryAccess(), nbttagcompound1);
+ ItemStack currStack = ItemStack.parseOptional(this.registryAccess(), compound1);
+ ItemStack prevStack = this.handItems.set(i, currStack);
+ this.trackEquipChange(prevStack, currStack);
+ // Leaf end - Lithium equipment tracking
}
} else {
this.handItems.replaceAll(itemStack -> ItemStack.EMPTY);
@@ -599,6 +608,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
this.ticksSinceLastInteraction = compound.getInt("Purpur.ticksSinceLastInteraction");
}
@@ -655,6 +664,11 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
this.ticksSinceLastInteraction = nbt.getInt("Purpur.ticksSinceLastInteraction");
}
// Purpur end
// Purpur end - Entity lifespan
+ // Leaf start - Lithium equipment tracking
+ if (prevBodyArmor != this.bodyArmorItem) {
+ this.trackEquipChange(prevBodyArmor, this.bodyArmorItem);
@@ -272,10 +274,10 @@ index 1e4729be4a245a811fd15ea1c02179b37defd67c..5814d9b6b0fc5346c24dd268ec147a67
}
@Override
@@ -1870,4 +1884,10 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
@@ -1748,4 +1762,10 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
}
}
// Purpur end
// Purpur end - Ridables
+
+ // Leaf start - Lithium equipment tracking
+ private void trackEquipChange(ItemStack prevStack, ItemStack currStack) {
@@ -284,57 +286,57 @@ index 1e4729be4a245a811fd15ea1c02179b37defd67c..5814d9b6b0fc5346c24dd268ec147a67
+ // Leaf end - Lithium equipment tracking
}
diff --git a/net/minecraft/world/entity/decoration/ArmorStand.java b/net/minecraft/world/entity/decoration/ArmorStand.java
index a3c284976b37e865c51ee91166c4046a3c4f3a16..b34522a57cf3ee5679481ead61ae52ac9a28f6f9 100644
index 8c0ab32487c56e2caf42404184f86c9bcf5f8b41..ccdbc67a50056ea1033f1f963c9f9a95326800a0 100644
--- a/net/minecraft/world/entity/decoration/ArmorStand.java
+++ b/net/minecraft/world/entity/decoration/ArmorStand.java
@@ -54,7 +54,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerArmorStandManipulateEvent;
// CraftBukkit end
@@ -46,7 +46,7 @@ import net.minecraft.world.level.material.PushReaction;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
-public class ArmorStand extends LivingEntity {
+public class ArmorStand extends LivingEntity implements net.caffeinemc.mods.lithium.common.entity.EquipmentEntity { // Leaf - Lithium equipment tracking
public static final int WOBBLE_TIME = 5;
private static final boolean ENABLE_ARMS = true;
@@ -112,7 +112,7 @@ public class ArmorStand extends LivingEntity {
public static final Rotations DEFAULT_HEAD_POSE = new Rotations(0.0F, 0.0F, 0.0F);
@@ -91,7 +91,7 @@ public class ArmorStand extends LivingEntity {
public boolean canTick = true;
public boolean canTickSetByAPI = false;
private boolean noTickPoseDirty = false;
- private boolean noTickEquipmentDirty = false;
+ public boolean noTickEquipmentDirty = false; // Leaf - Lithium equipment tracking - private -> public
// Paper end - Allow ArmorStands not to tick
public boolean canMovementTick = true; // Purpur
public boolean canMovementTick = true; // Purpur - Movement options for armor stands
@@ -274,7 +274,11 @@ public class ArmorStand extends LivingEntity {
@@ -233,7 +233,11 @@ public class ArmorStand extends LivingEntity {
for (i = 0; i < this.armorItems.size(); ++i) {
nbttagcompound1 = nbttaglist.getCompound(i);
- this.armorItems.set(i, ItemStack.parseOptional(this.registryAccess(), nbttagcompound1));
for (int i = 0; i < this.armorItems.size(); i++) {
CompoundTag compound1 = list.getCompound(i);
- this.armorItems.set(i, ItemStack.parseOptional(this.registryAccess(), compound1));
+ // Leaf start - Lithium equipment tracking
+ ItemStack currElement = ItemStack.parseOptional(this.registryAccess(), nbttagcompound1);
+ ItemStack currElement = ItemStack.parseOptional(this.registryAccess(), compound1);
+ ItemStack prevElement = this.armorItems.set(i, currElement);
+ this.trackEquipChange(prevElement, currElement);
+ // Leaf end - Lithium equipment tracking
}
}
@@ -283,7 +287,11 @@ public class ArmorStand extends LivingEntity {
@@ -242,7 +246,11 @@ public class ArmorStand extends LivingEntity {
for (i = 0; i < this.handItems.size(); ++i) {
nbttagcompound1 = nbttaglist.getCompound(i);
- this.handItems.set(i, ItemStack.parseOptional(this.registryAccess(), nbttagcompound1));
for (int i = 0; i < this.handItems.size(); i++) {
CompoundTag compound1 = list.getCompound(i);
- this.handItems.set(i, ItemStack.parseOptional(this.registryAccess(), compound1));
+ // Leaf start - Lithium equipment tracking
+ ItemStack currStack = ItemStack.parseOptional(this.registryAccess(), nbttagcompound1);
+ ItemStack currStack = ItemStack.parseOptional(this.registryAccess(), compound1);
+ ItemStack prevStack = this.handItems.set(i, currStack);
+ this.trackEquipChange(prevStack, currStack);
+ // Leaf end - Lithium equipment tracking
}
}
@@ -638,7 +646,11 @@ public class ArmorStand extends LivingEntity {
itemstack = (ItemStack) this.handItems.get(i);
if (!itemstack.isEmpty()) {
this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
@@ -578,7 +586,11 @@ public class ArmorStand extends LivingEntity {
ItemStack itemStack = this.handItems.get(i);
if (!itemStack.isEmpty()) {
this.drops.add(new DefaultDrop(itemStack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
- this.handItems.set(i, ItemStack.EMPTY);
+ // Leaf start - Lithium equipment tracking
+ ItemStack emptyStack = ItemStack.EMPTY;
@@ -344,20 +346,20 @@ index a3c284976b37e865c51ee91166c4046a3c4f3a16..b34522a57cf3ee5679481ead61ae52ac
}
}
@@ -646,7 +658,11 @@ public class ArmorStand extends LivingEntity {
itemstack = (ItemStack) this.armorItems.get(i);
if (!itemstack.isEmpty()) {
this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
- this.armorItems.set(i, ItemStack.EMPTY);
@@ -586,7 +598,11 @@ public class ArmorStand extends LivingEntity {
ItemStack itemStack = this.armorItems.get(ix);
if (!itemStack.isEmpty()) {
this.drops.add(new DefaultDrop(itemStack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
- this.armorItems.set(ix, ItemStack.EMPTY);
+ // Leaf start - Lithium equipment tracking
+ ItemStack emptyStack = ItemStack.EMPTY;
+ ItemStack prevStack = this.armorItems.set(i, ItemStack.EMPTY);
+ ItemStack prevStack = this.armorItems.set(ix, ItemStack.EMPTY);
+ this.trackEquipChange(prevStack, emptyStack);
+ // Leaf end - Lithium equipment tracking
}
}
return this.dropAllDeathLoot(world, damageSource); // CraftBukkit - moved from above // Paper
@@ -693,10 +709,12 @@ public class ArmorStand extends LivingEntity {
return this.dropAllDeathLoot(level, damageSource); // CraftBukkit - moved from above // Paper
@@ -632,10 +648,12 @@ public class ArmorStand extends LivingEntity {
this.updatePose();
}
@@ -371,10 +373,10 @@ index a3c284976b37e865c51ee91166c4046a3c4f3a16..b34522a57cf3ee5679481ead61ae52ac
return;
}
@@ -1032,4 +1050,10 @@ public class ArmorStand extends LivingEntity {
@@ -968,4 +986,10 @@ public class ArmorStand extends LivingEntity {
if (this.canMovementTick && this.canMove) super.aiStep();
}
// Purpur end
// Purpur end - Movement options for armor stands
+
+ // Leaf start - Lithium equipment tracking
+ private void trackEquipChange(ItemStack prevStack, ItemStack currStack) {
@@ -383,20 +385,20 @@ index a3c284976b37e865c51ee91166c4046a3c4f3a16..b34522a57cf3ee5679481ead61ae52ac
+ // Leaf end - Lithium equipment tracking
}
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
index 1029499ce8fb236a23beb9dae168b82039734e59..4a5d6767bf4ead62f3c533fa33f7ce98637cce31 100644
index aa2c00be86f42a6674694a20545399e441b75199..e183298a7fb538ee35ea1dc4f46d052be3d117ae 100644
--- a/net/minecraft/world/item/ItemStack.java
+++ b/net/minecraft/world/item/ItemStack.java
@@ -125,7 +125,7 @@ import org.bukkit.event.player.PlayerItemDamageEvent;
import org.bukkit.event.world.StructureGrowEvent;
// CraftBukkit end
@@ -95,7 +95,7 @@ import net.minecraft.world.level.saveddata.maps.MapId;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.slf4j.Logger;
-public final class ItemStack implements DataComponentHolder {
+public final class ItemStack implements DataComponentHolder, net.caffeinemc.mods.lithium.common.util.change_tracking.ChangePublisher<ItemStack>, net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<PatchedDataComponentMap> { // Leaf - Lithium equipment tracking
public static final Codec<ItemStack> CODEC = Codec.lazyInitialized(() -> {
return RecordCodecBuilder.<ItemStack>create((instance) -> { // CraftBukkit - decompile error
@@ -227,6 +227,11 @@ public final class ItemStack implements DataComponentHolder {
private PatchedDataComponentMap components;
private static final List<Component> OP_NBT_WARNING = List.of(
Component.translatable("item.op_warning.line1").withStyle(ChatFormatting.RED, ChatFormatting.BOLD),
Component.translatable("item.op_warning.line2").withStyle(ChatFormatting.RED),
@@ -202,6 +202,11 @@ public final class ItemStack implements DataComponentHolder {
PatchedDataComponentMap components;
@Nullable
private Entity entityRepresentation;
+ // Leaf start - Lithium equipment tracking
@@ -406,8 +408,8 @@ index 1029499ce8fb236a23beb9dae168b82039734e59..4a5d6767bf4ead62f3c533fa33f7ce98
+ // Leaf end - Lithium equipment tracking
private static DataResult<ItemStack> validateStrict(ItemStack stack) {
DataResult<Unit> dataresult = ItemStack.validateComponents(stack.getComponents());
@@ -1454,6 +1459,21 @@ public final class ItemStack implements DataComponentHolder {
DataResult<Unit> dataResult = validateComponents(stack.getComponents());
@@ -1375,6 +1380,21 @@ public final class ItemStack implements DataComponentHolder {
}
public void setCount(int count) {
@@ -429,11 +431,11 @@ index 1029499ce8fb236a23beb9dae168b82039734e59..4a5d6767bf4ead62f3c533fa33f7ce98
this.count = count;
}
@@ -1515,4 +1535,87 @@ public final class ItemStack implements DataComponentHolder {
return repairable != null && repairable.isValidRepairItem(ingredient);
@@ -1430,4 +1450,87 @@ public final class ItemStack implements DataComponentHolder {
Repairable repairable = this.get(DataComponents.REPAIRABLE);
return repairable != null && repairable.isValidRepairItem(item);
}
+
+
+ // Leaf start - Lithium equipment tracking
+ @Override
+ public void subscribe(net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber<ItemStack> subscriber, int subscriberData) {

View File

@@ -13,79 +13,71 @@ Licensed under: MIT
Co-authored-by: Taiyou06 <kaandindar21@gmail.com>
diff --git a/net/minecraft/world/level/ChunkPos.java b/net/minecraft/world/level/ChunkPos.java
index 0639e4565c3324d757dec1226adb4e99d841f2c0..78fdfa78ff6d2a5307a0a6959b051cd2dce442fe 100644
index 55ce935a2fab7e32904d9ff599867269035d703f..f758602f1929fe0e19b91989d240b24d9d0d1ca6 100644
--- a/net/minecraft/world/level/ChunkPos.java
+++ b/net/minecraft/world/level/ChunkPos.java
@@ -110,7 +110,12 @@ public class ChunkPos {
@Override
public boolean equals(Object object) {
- return this == object || object instanceof ChunkPos chunkPos && this.x == chunkPos.x && this.z == chunkPos.z;
public boolean equals(Object other) {
- return this == other || other instanceof ChunkPos chunkPos && this.x == chunkPos.x && this.z == chunkPos.z;
+ // Leaf start - Use standard equals
+ if (object == this) return true;
+ if (object == null || object.getClass() != this.getClass()) return false;
+ ChunkPos thatPos = (ChunkPos) object;
+ if (other == this) return true;
+ if (other == null || other.getClass() != this.getClass()) return false;
+ ChunkPos thatPos = (ChunkPos) other;
+ return this.x == thatPos.x && this.z == thatPos.z;
+ // Leaf end - Use standard equals
}
public int getMiddleBlockX() {
diff --git a/net/minecraft/world/level/levelgen/Beardifier.java b/net/minecraft/world/level/levelgen/Beardifier.java
index ca93a97256350789ca56f910862c9d717ca7670b..3a1a5257e1a98cc1d520f407bb1f8c745cadd3df 100644
index 131923282c9ecbcb1d7f45a826da907c02bd2716..3c05e8258902bf46cca3b7274858b7528cce6437 100644
--- a/net/minecraft/world/level/levelgen/Beardifier.java
+++ b/net/minecraft/world/level/levelgen/Beardifier.java
@@ -132,8 +132,14 @@ public class Beardifier implements DensityFunctions.BeardifierOrMarker {
}
private static double getBuryContribution(double x, double y, double z) {
- double d = Mth.length(x, y, z);
- return Mth.clampedMap(d, 0.0, 6.0, 1.0, 0.0);
- double len = Mth.length(x, y, z);
- return Mth.clampedMap(len, 0.0, 6.0, 1.0, 0.0);
+ // Leaf start - Optimize method for beardifier
+ double d = Math.sqrt(x * x + y * y + z * z);
+ if (d > 6.0) {
+ double len = Math.sqrt(x * x + y * y + z * z);
+ if (len > 6.0) {
+ return 0.0;
+ } else {
+ return 1.0 - d / 6.0;
+ return 1.0 - len / 6.0;
+ }
+ // Leaf end - Optimize method for beardifier
}
private static double getBeardContribution(int x, int y, int z, int yy) {
private static double getBeardContribution(int x, int y, int z, int height) {
diff --git a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
index bd0eaa7d5253fd4ea9f9a6f0c7bfcf11fbc675a7..1a514189eb0b43548b075a6cfb571431892ad674 100644
index 57ae4aaf1431021daf77c5638038d4910a358155..846d44798655ca11c311fd3fda3613de45b93906 100644
--- a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
+++ b/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
@@ -76,14 +76,13 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
}
private static Aquifer.FluidPicker createFluidPicker(NoiseGeneratorSettings settings) {
@@ -68,8 +68,10 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
Aquifer.FluidStatus fluidStatus = new Aquifer.FluidStatus(-54, Blocks.LAVA.defaultBlockState());
int seaLevel = settings.seaLevel();
Aquifer.FluidStatus fluidStatus1 = new Aquifer.FluidStatus(seaLevel, settings.defaultFluid());
- Aquifer.FluidStatus fluidStatus2 = new Aquifer.FluidStatus(DimensionType.MIN_Y * 2, Blocks.AIR.defaultBlockState());
- return (x, y, z) -> y < Math.min(-54, seaLevel) ? fluidStatus : fluidStatus1;
+ // Leaf start - Optimize world gen
Aquifer.FluidStatus aquifer_b = new Aquifer.FluidStatus(-54, Blocks.LAVA.defaultBlockState());
int i = settings.seaLevel();
Aquifer.FluidStatus aquifer_b1 = new Aquifer.FluidStatus(i, settings.defaultFluid());
- Aquifer.FluidStatus aquifer_b2 = new Aquifer.FluidStatus(DimensionType.MIN_Y * 2, Blocks.AIR.defaultBlockState());
-
- return (j, k, l) -> {
- return k < Math.min(-54, i) ? aquifer_b : aquifer_b1;
- };
+ final int min = Math.min(-54, i);
+ return (j, k, l) -> k < min ? aquifer_b : aquifer_b1;
+ final int min = Math.min(-54, seaLevel);
+ return (x, y, z) -> y < min ? fluidStatus : fluidStatus1;
+ // Leaf end - Optimize world gen
}
@Override
diff --git a/net/minecraft/world/level/levelgen/synth/PerlinNoise.java b/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
index 022dda9dded1bd96dcaf377b1d1a9711ea9c49e7..1b0c92f3c20a4edc85a976a0eec620d0a96b5bba 100644
index 2c28bb2fed04542a2ee126fe0c1c1f0253a3e2eb..3ede9b09feface73096db746b8a7960b654a7eaf 100644
--- a/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
+++ b/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
@@ -215,7 +215,9 @@ public class PerlinNoise {
@@ -215,7 +215,7 @@ public class PerlinNoise {
}
public static double wrap(double value) {
- return value - (double)Mth.lfloor(value / 3.3554432E7 + 0.5) * 3.3554432E7;
+ // Leaf start - Avoid casting
+ return value - Math.floor(value / 3.3554432E7 + 0.5) * 3.3554432E7;
+ // Leaf end - Avoid casting
- return value - Mth.lfloor(value / 3.3554432E7 + 0.5) * 3.3554432E7;
+ return value - Math.floor(value / 3.3554432E7 + 0.5) * 3.3554432E7; // Leaf - Avoid casting
}
protected int firstOctave() {

View File

@@ -8,10 +8,10 @@ This patch didn't cahce SectionPos or BlockPos to chunkKey, since it needs to co
TODO: Cache block pos and section pos, whether need?
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
index 7e440b4a46b040365df7317035e577d93e7d855d..b5d98bb35f95ca068f32ed3a8314ca272aa3b262 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
diff --git a/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
index 1b8193587814225c2ef2c5d9e667436eb50ff6c5..d7d1d4b31043279753888b9c1e299acead7c91e1 100644
--- a/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
+++ b/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
@@ -127,7 +127,7 @@ public final class NearbyPlayers {
}
@@ -30,34 +30,11 @@ index 7e440b4a46b040365df7317035e577d93e7d855d..b5d98bb35f95ca068f32ed3a8314ca27
}
public ReferenceList<ServerPlayer> getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) {
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/CoordinateUtils.java b/src/main/java/ca/spottedleaf/moonrise/common/util/CoordinateUtils.java
index 036c1a287db04c0191e5f84b027ea68d31447cbc..753c3e99e2f677ee1704b206a3196eb05c83f4ea 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/util/CoordinateUtils.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/CoordinateUtils.java
@@ -20,15 +20,15 @@ public final class CoordinateUtils {
}
public static long getChunkKey(final ChunkPos pos) {
- return ((long)pos.z << 32) | (pos.x & 0xFFFFFFFFL);
+ return ((long)pos.z << 32) | (pos.x & 0xFFFFFFFFL); // Leaf - Cache chunk key
}
public static long getChunkKey(final SectionPos pos) {
- return ((long)pos.getZ() << 32) | (pos.getX() & 0xFFFFFFFFL);
+ return ((long)pos.getZ() << 32) | (pos.getX() & 0xFFFFFFFFL); // Leaf - Cache chunk key
}
public static long getChunkKey(final int x, final int z) {
- return ((long)z << 32) | (x & 0xFFFFFFFFL);
+ return ((long)z << 32) | (x & 0xFFFFFFFFL); // Leaf - Cache chunk key
}
public static int getChunkX(final long chunkKey) {
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
index 91a6f57f35fc1553159cca138a0619e703b2b014..180fc6faee310c0157295e2f59c3a57507104227 100644
--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
@@ -505,7 +505,7 @@ public final class ChunkHolderManager {
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
index b5817aa8f537593f6d9fc6b612c82ccccb250ac7..a43b8b9549b308c5143344b633aacda0e538510f 100644
--- a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/ChunkHolderManager.java
@@ -506,7 +506,7 @@ public final class ChunkHolderManager {
public <T> boolean addTicketAtLevel(final TicketType<T> type, final ChunkPos chunkPos, final int level,
final T identifier) {
@@ -66,7 +43,7 @@ index 91a6f57f35fc1553159cca138a0619e703b2b014..180fc6faee310c0157295e2f59c3a575
}
public <T> boolean addTicketAtLevel(final TicketType<T> type, final int chunkX, final int chunkZ, final int level,
@@ -603,7 +603,7 @@ public final class ChunkHolderManager {
@@ -604,7 +604,7 @@ public final class ChunkHolderManager {
}
public <T> boolean removeTicketAtLevel(final TicketType<T> type, final ChunkPos chunkPos, final int level, final T identifier) {
@@ -75,7 +52,7 @@ index 91a6f57f35fc1553159cca138a0619e703b2b014..180fc6faee310c0157295e2f59c3a575
}
public <T> boolean removeTicketAtLevel(final TicketType<T> type, final int chunkX, final int chunkZ, final int level, final T identifier) {
@@ -1223,7 +1223,7 @@ public final class ChunkHolderManager {
@@ -1224,7 +1224,7 @@ public final class ChunkHolderManager {
}
public static <T> TicketOperation<T, T> addOp(final ChunkPos chunk, final TicketType<T> type, final int ticketLevel, final T identifier) {
@@ -84,7 +61,7 @@ index 91a6f57f35fc1553159cca138a0619e703b2b014..180fc6faee310c0157295e2f59c3a575
}
public static <T> TicketOperation<T, T> addOp(final int chunkX, final int chunkZ, final TicketType<T> type, final int ticketLevel, final T identifier) {
@@ -1235,7 +1235,7 @@ public final class ChunkHolderManager {
@@ -1236,7 +1236,7 @@ public final class ChunkHolderManager {
}
public static <T> TicketOperation<T, T> removeOp(final ChunkPos chunk, final TicketType<T> type, final int ticketLevel, final T identifier) {
@@ -93,10 +70,10 @@ index 91a6f57f35fc1553159cca138a0619e703b2b014..180fc6faee310c0157295e2f59c3a575
}
public static <T> TicketOperation<T, T> removeOp(final int chunkX, final int chunkZ, final TicketType<T> type, final int ticketLevel, final T identifier) {
diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java
diff --git a/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java b/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java
index 571db5f9bf94745a8afe2cd313e593fb15db5e37..108db549eeb4a33c9a9c0c19833766139f7625b4 100644
--- a/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java
+++ b/src/main/java/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java
--- a/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java
+++ b/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java
@@ -818,7 +818,7 @@ public final class StarLightInterface {
}
@@ -107,20 +84,29 @@ index 571db5f9bf94745a8afe2cd313e593fb15db5e37..108db549eeb4a33c9a9c0c1983376613
valueInMap = new ServerChunkTasks(
keyInMap, ServerLightQueue.this.lightInterface, ServerLightQueue.this, priority
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 4a92789d77313e165ab1252cd469e34a8b7eb575..9469f9edd9f94f7644dc28c9be2fb1b9843e84e1 100644
index 682024138e792fa4c72189ed06226f0a92ef3d7f..44c7f1cb7aab6861836f653ddac5e2c9b6e35471 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -2638,7 +2638,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@@ -508,7 +508,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@Override
public final void moonrise$markChunkForPlayerTicking(final LevelChunk chunk) {
final ChunkPos pos = chunk.getPos();
- if (!this.playerTickingRequests.containsKey(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(pos))) {
+ if (!this.playerTickingRequests.containsKey(pos.chunkKey)) { // Leaf - Cache chunk key
return;
}
public boolean isNaturalSpawningAllowed(ChunkPos pos) {
@@ -2567,7 +2567,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
public boolean isNaturalSpawningAllowed(ChunkPos chunkPos) {
// Paper start - rewrite chunk system
- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(pos));
+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(pos.chunkKey); // Leaf - Cache chunk key
- final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(chunkPos));
+ final ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkHolder = this.moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkPos.chunkKey); // Leaf - Cache chunk key
return chunkHolder != null && chunkHolder.isEntityTickingReady();
// Paper end - rewrite chunk system
}
diff --git a/net/minecraft/world/level/ChunkPos.java b/net/minecraft/world/level/ChunkPos.java
index 78fdfa78ff6d2a5307a0a6959b051cd2dce442fe..1a20d1ed779caf5eba260d21cc0afdf7edff5bf6 100644
index f758602f1929fe0e19b91989d240b24d9d0d1ca6..619cfa7eba6ed662278293c524c158ce798cd194 100644
--- a/net/minecraft/world/level/ChunkPos.java
+++ b/net/minecraft/world/level/ChunkPos.java
@@ -47,6 +47,7 @@ public class ChunkPos {
@@ -133,7 +119,7 @@ index 78fdfa78ff6d2a5307a0a6959b051cd2dce442fe..1a20d1ed779caf5eba260d21cc0afdf7
private static final int HASH_Z_XOR = -559038737;
@@ -55,18 +56,21 @@ public class ChunkPos {
this.x = x;
this.z = z;
this.z = y;
this.longKey = asLong(this.x, this.z); // Paper
+ this.chunkKey = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(this.x, this.z); // Leaf - Cache chunk key
}
@@ -145,11 +131,11 @@ index 78fdfa78ff6d2a5307a0a6959b051cd2dce442fe..1a20d1ed779caf5eba260d21cc0afdf7
+ this.chunkKey = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(this.x, this.z); // Leaf - Cache chunk key
}
public ChunkPos(long pos) {
this.x = (int)pos;
this.z = (int)(pos >> 32);
public ChunkPos(long packedPos) {
this.x = (int)packedPos;
this.z = (int)(packedPos >> 32);
this.longKey = asLong(this.x, this.z); // Paper
+ this.chunkKey = ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkKey(this.x, this.z); // Leaf - Cache chunk key
}
public static ChunkPos minFromRegion(int x, int z) {
public static ChunkPos minFromRegion(int chunkX, int chunkZ) {

View File

@@ -5,10 +5,10 @@ Subject: [PATCH] Cache random tick block status
diff --git a/net/minecraft/world/level/chunk/LevelChunkSection.java b/net/minecraft/world/level/chunk/LevelChunkSection.java
index e4ae25c83ab9dd1aaa530a5456275ef63cdb8511..f19d9bba70957fc652c3222cadd247eb837c2a13 100644
index 412e7b1cf8c24f0ddf6d174967bedad576f10aba..b8ac6a9ba7b56ccd034757f7d135d272b8e69e90 100644
--- a/net/minecraft/world/level/chunk/LevelChunkSection.java
+++ b/net/minecraft/world/level/chunk/LevelChunkSection.java
@@ -22,6 +22,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
@@ -21,6 +21,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
short nonEmptyBlockCount; // Paper - package private
private short tickingBlockCount;
private short tickingFluidCount;
@@ -16,21 +16,21 @@ index e4ae25c83ab9dd1aaa530a5456275ef63cdb8511..f19d9bba70957fc652c3222cadd247eb
public final PalettedContainer<BlockState> states;
private PalettedContainer<Holder<Biome>> biomes; // CraftBukkit - read/write
@@ -55,6 +56,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
@@ -54,6 +55,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
this.tickingFluidCount = section.tickingFluidCount;
this.states = section.states.copy();
this.biomes = section.biomes.copy();
+ this.isRandomlyTickingBlocksStatus = this.tickingBlockCount > 0; // Leaf - Cache random tick block status
}
public LevelChunkSection(PalettedContainer<BlockState> datapaletteblock, PalettedContainer<Holder<Biome>> palettedcontainerro) { // CraftBukkit - read/write
public LevelChunkSection(PalettedContainer<BlockState> states, PalettedContainer<Holder<Biome>> biomes) { // CraftBukkit - read/write
@@ -165,6 +167,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
}
this.updateBlockCallback(x, y, z, state, iblockdata1); // Paper - block counting
this.updateBlockCallback(x, y, z, state, blockState); // Paper - block counting
+ this.isRandomlyTickingBlocksStatus = this.tickingBlockCount > 0; // Leaf - Cache random tick block status
return iblockdata1;
return blockState;
}
@@ -178,7 +181,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_
}

View File

@@ -10,10 +10,10 @@ which the contains iteration call is very expensive if called everytime
In the test, it can improve ~30% performance in ~1577000 times of canHoldAnyFluid calls (~159ms -> ~111ms)
diff --git a/net/minecraft/world/level/block/state/BlockBehaviour.java b/net/minecraft/world/level/block/state/BlockBehaviour.java
index 65d8ac795282117ba88003e7a703ee649a359473..b0df5ac8efdca17498f7f87bb86e376122aa6fe3 100644
index 36ac6114cc3449a3b344baac5f3034288cf77a63..82c36a031e883033a76968b7dfccc2c1f2a3d687 100644
--- a/net/minecraft/world/level/block/state/BlockBehaviour.java
+++ b/net/minecraft/world/level/block/state/BlockBehaviour.java
@@ -836,6 +836,8 @@ public abstract class BlockBehaviour implements FeatureElement {
@@ -454,6 +454,8 @@ public abstract class BlockBehaviour implements FeatureElement {
private VoxelShape[] occlusionShapesByFace;
private boolean propagatesSkylightDown;
private int lightBlock;
@@ -22,17 +22,17 @@ index 65d8ac795282117ba88003e7a703ee649a359473..b0df5ac8efdca17498f7f87bb86e3761
// Paper start - rewrite chunk system
private boolean isConditionallyFullOpaque;
@@ -991,6 +993,8 @@ public abstract class BlockBehaviour implements FeatureElement {
@@ -603,6 +605,8 @@ public abstract class BlockBehaviour implements FeatureElement {
this.propagatesSkylightDown = ((Block) this.owner).propagatesSkylightDown(this.asState());
this.lightBlock = ((Block) this.owner).getLightBlock(this.asState());
this.propagatesSkylightDown = this.owner.propagatesSkylightDown(this.asState());
this.lightBlock = this.owner.getLightBlock(this.asState());
+ this.canHoldAnyFluidInternal = false; // Leaf - Cache canHoldAnyFluid result
+ this.canHoldAnyFluidInternalInit = false; // Leaf - Cache canHoldAnyFluid result
// Paper start - rewrite chunk system
this.isConditionallyFullOpaque = this.canOcclude & this.useShapeForLightOcclusion;
// Paper end - rewrite chunk system
@@ -1050,6 +1054,18 @@ public abstract class BlockBehaviour implements FeatureElement {
return this.legacySolid;
@@ -654,6 +658,18 @@ public abstract class BlockBehaviour implements FeatureElement {
return block != Blocks.COBWEB && block != Blocks.BAMBOO_SAPLING && this.isSolid();
}
+ // Leaf start - Cache canHoldAnyFluid result
@@ -47,27 +47,37 @@ index 65d8ac795282117ba88003e7a703ee649a359473..b0df5ac8efdca17498f7f87bb86e3761
+ }
+ // Leaf end - Cache canHoldAnyFluid result
+
// Paper start - Protect Bedrock and End Portal/Frames from being destroyed
public final boolean isDestroyable() {
return getBlock().isDestroyable();
@Deprecated
public boolean isSolid() {
return this.legacySolid;
diff --git a/net/minecraft/world/level/material/FlowingFluid.java b/net/minecraft/world/level/material/FlowingFluid.java
index 408e7c61d87a0e6d8502bf1f5ca76fd728c5d10c..de761ea851d47e59538b4d0d3cec5624bf37b84a 100644
index c535cd03c577d76c3b19da5a8426d0cbee3069f0..efa4f2e2a2ee8b12cdcc7b674f29eae89179b409 100644
--- a/net/minecraft/world/level/material/FlowingFluid.java
+++ b/net/minecraft/world/level/material/FlowingFluid.java
@@ -494,14 +494,14 @@ public abstract class FlowingFluid extends Fluid {
@@ -384,7 +384,7 @@ public abstract class FlowingFluid extends Fluid {
BlockGetter level, BlockPos pos, BlockState state, Direction direction, BlockPos spreadPos, BlockState spreadState, FluidState fluidState
) {
return !this.isSourceBlockOfThisType(fluidState)
- && canHoldAnyFluid(spreadState)
+ && state.canHoldAnyFluidInternal() // Leaf - Cache canHoldAnyFluid result
&& canPassThroughWall(direction, level, pos, state, spreadPos, spreadState);
}
@@ -450,7 +450,7 @@ public abstract class FlowingFluid extends Fluid {
return map;
}
- private static boolean canHoldAnyFluid(BlockState state) {
+ public static boolean canHoldAnyFluid(BlockState state) { // Leaf - Cache canHoldAnyFluid result - private -> public
Block block = state.getBlock();
return block instanceof LiquidBlockContainer ? true : (state.blocksMotion() ? false : !(block instanceof DoorBlock) && !state.is(BlockTags.SIGNS) && !state.is(Blocks.LADDER) && !state.is(Blocks.SUGAR_CANE) && !state.is(Blocks.BUBBLE_COLUMN) && !state.is(Blocks.NETHER_PORTAL) && !state.is(Blocks.END_PORTAL) && !state.is(Blocks.END_GATEWAY) && !state.is(Blocks.STRUCTURE_VOID));
return block instanceof LiquidBlockContainer
|| !state.blocksMotion()
@@ -466,7 +466,7 @@ public abstract class FlowingFluid extends Fluid {
}
private static boolean canHoldFluid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) {
- return FlowingFluid.canHoldAnyFluid(state) && FlowingFluid.canHoldSpecificFluid(world, pos, state, fluid);
+ return /*FlowingFluid.canHoldAnyFluid(state)*/ state.canHoldAnyFluidInternal() && FlowingFluid.canHoldSpecificFluid(world, pos, state, fluid); // Leaf - Cache canHoldAnyFluid result
private static boolean canHoldFluid(BlockGetter level, BlockPos pos, BlockState state, Fluid fluid) {
- return canHoldAnyFluid(state) && canHoldSpecificFluid(level, pos, state, fluid);
+ return /*canHoldAnyFluid(state)*/ state.canHoldAnyFluidInternal() && canHoldSpecificFluid(level, pos, state, fluid); // Leaf - Cache canHoldAnyFluid result
}
private static boolean canHoldSpecificFluid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) {
private static boolean canHoldSpecificFluid(BlockGetter level, BlockPos pos, BlockState state, Fluid fluid) {

View File

@@ -0,0 +1,20 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Tue, 24 Dec 2024 13:28:56 -0500
Subject: [PATCH] Configurable tripwire dupe
Bring back MC-59471, MC-129055 on 1.21.2+, which fixed in 1.21.2 snapshots 24w33a and 24w36a
diff --git a/net/minecraft/world/level/block/TripWireHookBlock.java b/net/minecraft/world/level/block/TripWireHookBlock.java
index 6a7e5a642e2eaf7d5dffadb81738f7385a38c0af..fa7e2c5406bb4bb755fb6e215dda5fe704b6bdf4 100644
--- a/net/minecraft/world/level/block/TripWireHookBlock.java
+++ b/net/minecraft/world/level/block/TripWireHookBlock.java
@@ -215,7 +215,7 @@ public class TripWireHookBlock extends Block {
BlockState blockState2 = blockStates[i2];
if (blockState2 != null) {
BlockState blockState3 = level.getBlockState(blockPos1);
- if (blockState3.is(Blocks.TRIPWIRE) || blockState3.is(Blocks.TRIPWIRE_HOOK)) {
+ if (org.dreeam.leaf.config.modules.gameplay.ConfigurableTripWireDupe.enabled || blockState3.is(Blocks.TRIPWIRE) || blockState3.is(Blocks.TRIPWIRE_HOOK)) { // Leaf - Configurable tripwire dupe
level.setBlock(blockPos1, blockState2.trySetValue(ATTACHED, Boolean.valueOf(flag2)), 3);
}
}

View File

@@ -124,22 +124,6 @@ index 0b5979723bb30f9011ac64c36d894aa41713ec9b..e220f5601f6b92b7b280ce8ebe64117d
Properties properties = new Properties();
if (stream != null) {
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java.rej b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java.rej
new file mode 100644
index 0000000000000000000000000000000000000000..0d8c2c5d1c88f635a1f0b6a9fc311d9921a0a3d7
--- /dev/null
+++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java.rej
@@ -0,0 +1,10 @@
+diff a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java (rejected hunks)
+@@ -11,7 +11,7 @@ public final class Versioning {
+ public static String getBukkitVersion() {
+ String result = "Unknown-Version";
+
+- InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/org.galemc.gale/gale-api/pom.properties"); // Gale - branding changes
++ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/cn.dreeam.leaf/leaf-api/pom.properties"); // Gale - branding changes // Leaf
+ Properties properties = new Properties();
+
+ if (stream != null) {
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
index 64e3c7bd0a1ff93dd87e688f9e49e213c8f6670e..6bc6a318286cd6a1d5464a9b139fb9b8ca4a219e 100644
--- a/src/main/java/org/spigotmc/WatchdogThread.java

View File

@@ -0,0 +1,16 @@
package net.caffeinemc.mods.lithium.common.entity;
import net.caffeinemc.mods.lithium.common.util.change_tracking.ChangeSubscriber;
import net.minecraft.world.item.ItemStack;
public interface EquipmentEntity {
void onEquipmentReplaced(ItemStack oldStack, ItemStack newStack);
interface EquipmentTrackingEntity {
void onEquipmentChanged();
}
interface TickableEnchantmentTrackingEntity extends ChangeSubscriber.EnchantmentSubscriber<ItemStack> {
void updateHasTickableEnchantments(ItemStack oldStack, ItemStack newStack);
}
}

View File

@@ -0,0 +1,17 @@
package net.caffeinemc.mods.lithium.common.util.change_tracking;
import net.minecraft.world.item.ItemStack;
public interface ChangePublisher<T> {
void subscribe(ChangeSubscriber<T> subscriber, int subscriberData);
int unsubscribe(ChangeSubscriber<T> subscriber);
default void unsubscribeWithData(ChangeSubscriber<T> subscriber, int index) {
throw new UnsupportedOperationException("Only implemented for ItemStacks");
}
default boolean isSubscribedWithData(ChangeSubscriber<ItemStack> subscriber, int subscriberData) {
throw new UnsupportedOperationException("Only implemented for ItemStacks");
}
}

View File

@@ -0,0 +1,190 @@
package net.caffeinemc.mods.lithium.common.util.change_tracking;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import net.minecraft.world.item.ItemStack;
public interface ChangeSubscriber<T> {
static <T> ChangeSubscriber<T> combine(ChangeSubscriber<T> prevSubscriber, int prevSData, @NotNull ChangeSubscriber<T> newSubscriber, int newSData) {
if (prevSubscriber == null) {
return newSubscriber;
} else if (prevSubscriber instanceof Multi) {
ArrayList<ChangeSubscriber<T>> subscribers = new ArrayList<>(((Multi<T>) prevSubscriber).subscribers);
IntArrayList subscriberDatas = new IntArrayList(((Multi<T>) prevSubscriber).subscriberDatas);
subscribers.add(newSubscriber);
subscriberDatas.add(newSData);
return new Multi<>(subscribers, subscriberDatas);
} else {
ArrayList<ChangeSubscriber<T>> subscribers = new ArrayList<>();
IntArrayList subscriberDatas = new IntArrayList();
subscribers.add(prevSubscriber);
subscriberDatas.add(prevSData);
subscribers.add(newSubscriber);
subscriberDatas.add(newSData);
return new Multi<>(subscribers, subscriberDatas);
}
}
static <T> ChangeSubscriber<T> without(ChangeSubscriber<T> prevSubscriber, ChangeSubscriber<T> removedSubscriber) {
return without(prevSubscriber, removedSubscriber, 0, false);
}
static <T> ChangeSubscriber<T> without(ChangeSubscriber<T> prevSubscriber, ChangeSubscriber<T> removedSubscriber, int removedSubscriberData, boolean matchData) {
if (prevSubscriber == removedSubscriber) {
return null;
} else if (prevSubscriber instanceof Multi<T> multi) {
int index = multi.indexOf(removedSubscriber, removedSubscriberData, matchData);
if (index != -1) {
if (multi.subscribers.size() == 2) {
return multi.subscribers.get(1 - index);
} else {
ArrayList<ChangeSubscriber<T>> subscribers = new ArrayList<>(multi.subscribers);
IntArrayList subscriberDatas = new IntArrayList(multi.subscriberDatas);
subscribers.remove(index);
subscriberDatas.removeInt(index);
return new Multi<>(subscribers, subscriberDatas);
}
} else {
return prevSubscriber;
}
} else {
return prevSubscriber;
}
}
static <T> int dataWithout(ChangeSubscriber<T> prevSubscriber, ChangeSubscriber<T> removedSubscriber, int subscriberData) {
return dataWithout(prevSubscriber, removedSubscriber, subscriberData, 0, false);
}
static <T> int dataWithout(ChangeSubscriber<T> prevSubscriber, ChangeSubscriber<T> removedSubscriber, int subscriberData, int removedSubscriberData, boolean matchData) {
if (prevSubscriber instanceof Multi<T> multi) {
int index = multi.indexOf(removedSubscriber, removedSubscriberData, matchData);
if (index != -1) {
if (multi.subscribers.size() == 2) {
return multi.subscriberDatas.getInt(1 - index);
} else {
return subscriberData;
}
} else {
return subscriberData;
}
}
return prevSubscriber == removedSubscriber ? 0 : subscriberData;
}
static int dataOf(ChangeSubscriber<?> subscribers, ChangeSubscriber<?> subscriber, int subscriberData) {
return subscribers instanceof Multi<?> multi ? multi.subscriberDatas.getInt(multi.subscribers.indexOf(subscriber)) : subscriberData;
}
static boolean containsSubscriber(ChangeSubscriber<ItemStack> subscriber, int subscriberData, ChangeSubscriber<ItemStack> subscriber1, int subscriberData1) {
if (subscriber instanceof Multi<ItemStack> multi) {
return multi.indexOf(subscriber1, subscriberData1, true) != -1;
}
return subscriber == subscriber1 && subscriberData == subscriberData1;
}
/**
* Notify the subscriber that the publisher will be changed immediately after this call.
* @param publisher The publisher that is about to change
* @param subscriberData The data associated with the subscriber, given when the subscriber was added
*/
void notify(@Nullable T publisher, int subscriberData);
/**
* Notify the subscriber about being unsubscribed from the publisher. Used when the publisher becomes invalid.
* The subscriber should not attempt to unsubscribe itself from the publisher in this method.
*
* @param publisher The publisher unsubscribed from
* @param subscriberData The data associated with the subscriber, given when the subscriber was added
*/
void forceUnsubscribe(T publisher, int subscriberData);
interface CountChangeSubscriber<T> extends ChangeSubscriber<T> {
/**
* Notify the subscriber that the publisher's count data will be changed immediately after this call.
* @param publisher The publisher that is about to change
* @param subscriberData The data associated with the subscriber, given when the subscriber was added
* @param newCount The new count of the publisher
*/
void notifyCount(T publisher, int subscriberData, int newCount);
}
interface EnchantmentSubscriber<T> extends ChangeSubscriber<T> {
/**
* Notify the subscriber that the publisher's enchantment data has been changed immediately before this call.
* @param publisher The publisher that has changed
* @param subscriberData The data associated with the subscriber, given when the subscriber was added
*/
void notifyAfterEnchantmentChange(T publisher, int subscriberData);
}
class Multi<T> implements CountChangeSubscriber<T>, EnchantmentSubscriber<T> {
private final ArrayList<ChangeSubscriber<T>> subscribers;
private final IntArrayList subscriberDatas;
public Multi(ArrayList<ChangeSubscriber<T>> subscribers, IntArrayList subscriberDatas) {
this.subscribers = subscribers;
this.subscriberDatas = subscriberDatas;
}
@Override
public void notify(T publisher, int subscriberData) {
ArrayList<ChangeSubscriber<T>> changeSubscribers = this.subscribers;
for (int i = 0; i < changeSubscribers.size(); i++) {
ChangeSubscriber<T> subscriber = changeSubscribers.get(i);
subscriber.notify(publisher, this.subscriberDatas.getInt(i));
}
}
@Override
public void forceUnsubscribe(T publisher, int subscriberData) {
ArrayList<ChangeSubscriber<T>> changeSubscribers = this.subscribers;
for (int i = 0; i < changeSubscribers.size(); i++) {
ChangeSubscriber<T> subscriber = changeSubscribers.get(i);
subscriber.forceUnsubscribe(publisher, this.subscriberDatas.getInt(i));
}
}
@Override
public void notifyCount(T publisher, int subscriberData, int newCount) {
ArrayList<ChangeSubscriber<T>> changeSubscribers = this.subscribers;
for (int i = 0; i < changeSubscribers.size(); i++) {
ChangeSubscriber<T> subscriber = changeSubscribers.get(i);
if (subscriber instanceof ChangeSubscriber.CountChangeSubscriber<T> countChangeSubscriber) {
countChangeSubscriber.notifyCount(publisher, this.subscriberDatas.getInt(i), newCount);
}
}
}
int indexOf(ChangeSubscriber<T> subscriber, int subscriberData, boolean matchData) {
if (!matchData) {
return this.subscribers.indexOf(subscriber);
} else {
for (int i = 0; i < this.subscribers.size(); i++) {
if (this.subscribers.get(i) == subscriber && this.subscriberDatas.getInt(i) == subscriberData) {
return i;
}
}
return -1;
}
}
@Override
public void notifyAfterEnchantmentChange(T publisher, int subscriberData) {
ArrayList<ChangeSubscriber<T>> changeSubscribers = this.subscribers;
for (int i = 0; i < changeSubscribers.size(); i++) {
ChangeSubscriber<T> subscriber = changeSubscribers.get(i);
if (subscriber instanceof ChangeSubscriber.EnchantmentSubscriber<T> enchantmentSubscriber) {
enchantmentSubscriber.notifyAfterEnchantmentChange(publisher, this.subscriberDatas.getInt(i));
}
}
}
}
}

View File

@@ -132,7 +132,7 @@ public class MultithreadedTracker {
}
((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity) tracker).moonrise$tick(((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity) entity).moonrise$getChunkData().nearbyPlayers);
if (((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity) tracker).moonrise$hasPlayers()
|| ((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity) entity).moonrise$getChunkStatus().isOrAfter(FullChunkStatus.ENTITY_TICKING)) {
|| ((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity) entity).moonrise$getChunkStatus().isOrAfter(FullChunkStatus.ENTITY_TICKING)) {
tracker.serverEntity.sendChanges();
}
}

View File

@@ -6,10 +6,11 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.file.Path;
import ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.ChunkPos;
public interface IRegionFile extends AutoCloseable {
public interface IRegionFile extends AutoCloseable, ChunkSystemRegionFile {
Path getPath();
void flush() throws IOException;
void clear(ChunkPos pos) throws IOException;

View File

@@ -1,5 +1,6 @@
package org.stupidcraft.linearpaper.region;
import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO;
import com.github.luben.zstd.ZstdInputStream;
import com.github.luben.zstd.ZstdOutputStream;
import com.mojang.logging.LogUtils;
@@ -32,7 +33,7 @@ import net.minecraft.world.level.ChunkPos;
import org.dreeam.leaf.config.modules.misc.RegionFormatConfig;
import org.slf4j.Logger;
public class LinearRegionFile implements IRegionFile, AutoCloseable {
public class LinearRegionFile implements IRegionFile {
private static final long SUPERBLOCK = -4323716122432332390L;
private static final byte VERSION = 2;
private static final int HEADER_SIZE = 32;
@@ -224,6 +225,16 @@ public class LinearRegionFile implements IRegionFile, AutoCloseable {
return new DataOutputStream(new BufferedOutputStream(new ChunkBuffer(pos)));
}
@Override
public MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite(CompoundTag data, ChunkPos pos) throws IOException {
final DataOutputStream out = this.getChunkDataOutputStream(pos);
return new ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData(
data, ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO.RegionDataController.WriteData.WriteResult.WRITE,
out, regionFile -> out.close()
);
}
private byte[] toByteArray(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] tempBuffer = new byte[4096];

View File

@@ -1,24 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
Date: Sun, 7 Jul 2024 01:29:57 +0800
Subject: [PATCH] Fix-MC-200418
Related MC issue: https://bugs.mojang.com/browse/MC-200418
diff --git a/net/minecraft/world/entity/monster/ZombieVillager.java b/net/minecraft/world/entity/monster/ZombieVillager.java
index 160fcd1f8917d69dde01089111661337827da20a..0963ccca2f5f38a415bc733333976d9df67378a1 100644
--- a/net/minecraft/world/entity/monster/ZombieVillager.java
+++ b/net/minecraft/world/entity/monster/ZombieVillager.java
@@ -327,6 +327,12 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder {
if (!this.isSilent()) {
world.levelEvent((Player) null, 1027, this.blockPosition(), 0);
}
+
+ // Leaf start - Fix MC-200418
+ if (entityvillager.isPassenger() && entityvillager.getVehicle() instanceof net.minecraft.world.entity.animal.Chicken && entityvillager.isBaby()) {
+ entityvillager.removeVehicle();
+ }
+ // Leaf end
// CraftBukkit start
}, EntityTransformEvent.TransformReason.CURED, CreatureSpawnEvent.SpawnReason.CURED);
if (converted == null) {

View File

@@ -1,445 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Sat, 13 Jul 2024 21:23:12 +0800
Subject: [PATCH] Optimize LeavesProtocolManager init protocol
In original LeavesProtocolManager, it will init for all protocol support modules even they are disabled.
And the "protocol support event" will be fired in every tick and when player joined to do the module enable check
It is no necessary to check whether enable every tick..., so I changed the init part, it will only load enabled
modules and will do init again when server reload or config reload
diff --git a/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java
index eb51acf0351769af0910ebb2d4a5abf542cbfb90..1e5d14690d92c7f9eccecd1cd0f3ecc6c90fc258 100644
--- a/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java
+++ b/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java
@@ -33,6 +33,10 @@ public class AppleSkinProtocol {
private static final Map<ServerPlayer, Set<String>> subscribedChannels = new HashMap<>();
+ public static boolean shouldEnable() {
+ return org.dreeam.leaf.config.modules.network.ProtocolSupport.appleskinProtocol;
+ }
+
@Contract("_ -> new")
public static @NotNull ResourceLocation id(String path) {
return new ResourceLocation(PROTOCOL_ID, path);
@@ -40,17 +44,13 @@ public class AppleSkinProtocol {
@ProtocolHandler.PlayerJoin
public static void onPlayerLoggedIn(@NotNull ServerPlayer player) {
- if (org.dreeam.leaf.config.modules.network.ProtocolSupport.appleskinProtocol) {
- resetPlayerData(player);
- }
+ resetPlayerData(player);
}
@ProtocolHandler.PlayerLeave
public static void onPlayerLoggedOut(@NotNull ServerPlayer player) {
- if (org.dreeam.leaf.config.modules.network.ProtocolSupport.appleskinProtocol) {
subscribedChannels.remove(player);
resetPlayerData(player);
- }
}
@ProtocolHandler.MinecraftRegister(ignoreId = true)
@@ -62,7 +62,6 @@ public class AppleSkinProtocol {
@ProtocolHandler.Ticker
public static void tick() {
- if (org.dreeam.leaf.config.modules.network.ProtocolSupport.appleskinProtocol) {
if (MinecraftServer.getServer().getTickCount() % org.dreeam.leaf.config.modules.network.ProtocolSupport.appleskinSyncTickInterval != 0) {
return;
}
@@ -102,7 +101,6 @@ public class AppleSkinProtocol {
}
}
}
- }
}
@ProtocolHandler.ReloadServer
diff --git a/src/main/java/org/leavesmc/leaves/protocol/AsteorBarProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/AsteorBarProtocol.java
index e6f3a52c3b6a23d8a8f7c4ae7828efa5dd51523e..1f22ebe756bd19afca3b7f826ff12cd6735da59f 100644
--- a/src/main/java/org/leavesmc/leaves/protocol/AsteorBarProtocol.java
+++ b/src/main/java/org/leavesmc/leaves/protocol/AsteorBarProtocol.java
@@ -30,6 +30,10 @@ public class AsteorBarProtocol {
private static final Set<ServerPlayer> players = new HashSet<>();
+ public static boolean shouldEnable() {
+ return org.dreeam.leaf.config.modules.network.ProtocolSupport.asteorBarProtocol;
+ }
+
@Contract("_ -> new")
public static @NotNull ResourceLocation id(String path) {
return ResourceLocation.fromNamespaceAndPath(PROTOCOL_ID, path);
@@ -37,29 +41,22 @@ public class AsteorBarProtocol {
@ProtocolHandler.PlayerJoin
public static void onPlayerLoggedIn(@NotNull ServerPlayer player) {
- if (org.dreeam.leaf.config.modules.network.ProtocolSupport.asteorBarProtocol) {
- resetPlayerData(player);
- }
+ resetPlayerData(player);
}
@ProtocolHandler.PlayerLeave
public static void onPlayerLoggedOut(@NotNull ServerPlayer player) {
- if (org.dreeam.leaf.config.modules.network.ProtocolSupport.asteorBarProtocol) {
- players.remove(player);
- resetPlayerData(player);
- }
+ players.remove(player);
+ resetPlayerData(player);
}
@ProtocolHandler.MinecraftRegister(ignoreId = true)
public static void onPlayerSubscribed(@NotNull ServerPlayer player) {
- if (org.dreeam.leaf.config.modules.network.ProtocolSupport.asteorBarProtocol) {
- players.add(player);
- }
+ players.add(player);
}
@ProtocolHandler.Ticker
public static void tick() {
- if (org.dreeam.leaf.config.modules.network.ProtocolSupport.asteorBarProtocol) {
for (ServerPlayer player : players) {
FoodData data = player.getFoodData();
@@ -83,7 +80,6 @@ public class AsteorBarProtocol {
previousExhaustionLevels.put(player.getUUID(), exhaustion);
}
}
- }
}
@ProtocolHandler.ReloadServer
diff --git a/src/main/java/org/leavesmc/leaves/protocol/ChatImageProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/ChatImageProtocol.java
index dd652437c0e999f0b523b69bca8f5803611ead6c..364922e9756193130608c51e052ddc9679854ced 100644
--- a/src/main/java/org/leavesmc/leaves/protocol/ChatImageProtocol.java
+++ b/src/main/java/org/leavesmc/leaves/protocol/ChatImageProtocol.java
@@ -31,6 +31,10 @@ public class ChatImageProtocol {
public static int MAX_STRING = 532767;
private static final Gson gson = new Gson();
+ public static boolean shouldEnable() {
+ return org.dreeam.leaf.config.modules.network.ProtocolSupport.chatImageProtocol;
+ }
+
public record FileInfoChannelPacket(
String message) implements LeavesCustomPayload<LeavesProtocolManager.LeavesPayload> {
private static final ResourceLocation FILE_INFO = ChatImageProtocol.id("file_info");
diff --git a/src/main/java/org/leavesmc/leaves/protocol/XaeroMapProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/XaeroMapProtocol.java
index 9e35dfaf8bb5511b4cd0a71175d7ecb6d835042f..5ef19098512ae8a070dea270a68c27695c34624b 100644
--- a/src/main/java/org/leavesmc/leaves/protocol/XaeroMapProtocol.java
+++ b/src/main/java/org/leavesmc/leaves/protocol/XaeroMapProtocol.java
@@ -16,6 +16,10 @@ public class XaeroMapProtocol {
private static final ResourceLocation MINIMAP_KEY = idMini("main");
private static final ResourceLocation WORLDMAP_KEY = idWorld("main");
+ public static boolean shouldEnable() {
+ return org.dreeam.leaf.config.modules.network.ProtocolSupport.xaeroMapProtocol;
+ }
+
@Contract("_ -> new")
public static @NotNull ResourceLocation idMini(String path) {
return new ResourceLocation(PROTOCOL_ID_MINI, path);
@@ -27,7 +31,7 @@ public class XaeroMapProtocol {
}
public static void onSendWorldInfo(@NotNull ServerPlayer player) {
- if (org.dreeam.leaf.config.modules.network.ProtocolSupport.xaeroMapProtocol) {
+ if (shouldEnable()) {
ProtocolUtils.sendPayloadPacket(player, MINIMAP_KEY, buf -> {
buf.writeByte(0);
buf.writeInt(org.dreeam.leaf.config.modules.network.ProtocolSupport.xaeroMapServerID);
diff --git a/src/main/java/org/leavesmc/leaves/protocol/core/LeavesProtocolManager.java b/src/main/java/org/leavesmc/leaves/protocol/core/LeavesProtocolManager.java
index 87b1502c1b980d33cae205ae35d336f7450e5e94..89cc2bc49c9a8d6ae5dd3ff10ac96e4282d9a727 100644
--- a/src/main/java/org/leavesmc/leaves/protocol/core/LeavesProtocolManager.java
+++ b/src/main/java/org/leavesmc/leaves/protocol/core/LeavesProtocolManager.java
@@ -10,30 +10,21 @@ import org.bukkit.event.player.PlayerKickEvent;
import org.jetbrains.annotations.NotNull;
import org.leavesmc.leaves.LeavesLogger;
-import java.io.File;
-import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.net.JarURLConnection;
-import java.net.URL;
-import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
-import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
public class LeavesProtocolManager {
@@ -51,8 +42,16 @@ public class LeavesProtocolManager {
private static final List<Method> RELOAD_SERVER = new ArrayList<>();
private static final Map<LeavesProtocol, Map<ProtocolHandler.MinecraftRegister, Method>> MINECRAFT_REGISTER = new HashMap<>();
+ public static void reload() {
+ handleServerReload();
+ cleanProtocols(); // Do cleanup
+ init();
+ }
+
public static void init() {
- for (Class<?> clazz : getClasses("org.leavesmc.leaves.protocol")) {
+ boolean shouldEnable;
+
+ for (Class<?> clazz : org.dreeam.leaf.config.LeafConfig.getClasses("org.leavesmc.leaves.protocol")) {
final LeavesProtocol protocol = clazz.getAnnotation(LeavesProtocol.class);
if (protocol != null) {
Set<Method> methods;
@@ -62,7 +61,12 @@ public class LeavesProtocolManager {
methods = new HashSet<>(publicMethods.length + privateMethods.length, 1.0f);
Collections.addAll(methods, publicMethods);
Collections.addAll(methods, privateMethods);
- } catch (NoClassDefFoundError error) {
+
+ Object instance = clazz.getConstructor().newInstance();
+ Method method = clazz.getMethod("shouldEnable");
+ shouldEnable = (boolean) method.invoke(instance);
+ } catch (NoClassDefFoundError | InvocationTargetException | InstantiationException |
+ IllegalAccessException | NoSuchMethodException error) {
LOGGER.severe("Failed to load class " + clazz.getName() + " due to missing dependencies, " + error.getCause() + ": " + error.getMessage());
return;
}
@@ -75,6 +79,16 @@ public class LeavesProtocolManager {
method.setAccessible(true);
+ final ProtocolHandler.ReloadServer reloadServer = method.getAnnotation(ProtocolHandler.ReloadServer.class);
+ if (reloadServer != null) {
+ RELOAD_SERVER.add(method);
+ continue;
+ }
+
+ if (!shouldEnable) {
+ continue;
+ }
+
final ProtocolHandler.Init init = method.getAnnotation(ProtocolHandler.Init.class);
if (init != null) {
try {
@@ -140,12 +154,6 @@ public class LeavesProtocolManager {
continue;
}
- final ProtocolHandler.ReloadServer reloadServer = method.getAnnotation(ProtocolHandler.ReloadServer.class);
- if (reloadServer != null) {
- RELOAD_SERVER.add(method);
- continue;
- }
-
final ProtocolHandler.MinecraftRegister minecraftRegister = method.getAnnotation(ProtocolHandler.MinecraftRegister.class);
if (minecraftRegister != null) {
if (!MINECRAFT_REGISTER.containsKey(protocol)) {
@@ -174,6 +182,17 @@ public class LeavesProtocolManager {
ALL_KNOWN_ID = ImmutableSet.copyOf(ALL_KNOWN_ID);
}
+ private static void cleanProtocols() {
+ KNOWN_TYPES.clear();
+ KNOW_RECEIVERS.clear();
+ //ALL_KNOWN_ID.clear(); // No need
+ TICKERS.clear();
+ PLAYER_JOIN.clear();
+ PLAYER_LEAVE.clear();
+ //RELOAD_SERVER.clear(); // No need
+ MINECRAFT_REGISTER.clear();
+ }
+
public static LeavesCustomPayload<?> decode(ResourceLocation id, FriendlyByteBuf buf) {
for (LeavesProtocol protocol : KNOWN_TYPES.keySet()) {
if (!ArrayUtils.contains(protocol.namespace(), id.getNamespace())) {
@@ -296,81 +315,6 @@ public class LeavesProtocolManager {
}
}
- public static Set<Class<?>> getClasses(String pack) {
- Set<Class<?>> classes = new LinkedHashSet<>();
- String packageDirName = pack.replace('.', '/');
- Enumeration<URL> dirs;
- try {
- dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
- while (dirs.hasMoreElements()) {
- URL url = dirs.nextElement();
- String protocol = url.getProtocol();
- if ("file".equals(protocol)) {
- String filePath = URLDecoder.decode(url.getFile(), StandardCharsets.UTF_8);
- findClassesInPackageByFile(pack, filePath, classes);
- } else if ("jar".equals(protocol)) {
- JarFile jar;
- try {
- jar = ((JarURLConnection) url.openConnection()).getJarFile();
- Enumeration<JarEntry> entries = jar.entries();
- findClassesInPackageByJar(pack, entries, packageDirName, classes);
- } catch (IOException exception) {
- LOGGER.warning("Failed to load jar file, " + exception.getCause() + ": " + exception.getMessage());
- }
- }
- }
- } catch (IOException exception) {
- LOGGER.warning("Failed to load classes, " + exception.getCause() + ": " + exception.getMessage());
- }
- return classes;
- }
-
- private static void findClassesInPackageByFile(String packageName, String packagePath, Set<Class<?>> classes) {
- File dir = new File(packagePath);
- if (!dir.exists() || !dir.isDirectory()) {
- return;
- }
- File[] dirfiles = dir.listFiles((file) -> file.isDirectory() || file.getName().endsWith(".class"));
- if (dirfiles != null) {
- for (File file : dirfiles) {
- if (file.isDirectory()) {
- findClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), classes);
- } else {
- String className = file.getName().substring(0, file.getName().length() - 6);
- try {
- classes.add(Class.forName(packageName + '.' + className));
- } catch (ClassNotFoundException exception) {
- LOGGER.warning("Failed to load class " + className + ", " + exception.getCause() + ": " + exception.getMessage());
- }
- }
- }
- }
- }
-
- private static void findClassesInPackageByJar(String packageName, Enumeration<JarEntry> entries, String packageDirName, Set<Class<?>> classes) {
- while (entries.hasMoreElements()) {
- JarEntry entry = entries.nextElement();
- String name = entry.getName();
- if (name.charAt(0) == '/') {
- name = name.substring(1);
- }
- if (name.startsWith(packageDirName)) {
- int idx = name.lastIndexOf('/');
- if (idx != -1) {
- packageName = name.substring(0, idx).replace('/', '.');
- }
- if (name.endsWith(".class") && !entry.isDirectory()) {
- String className = name.substring(packageName.length() + 1, name.length() - 6);
- try {
- classes.add(Class.forName(packageName + '.' + className));
- } catch (ClassNotFoundException exception) {
- LOGGER.warning("Failed to load class " + className + ", " + exception.getCause() + ": " + exception.getMessage());
- }
- }
- }
- }
- }
-
public record ErrorPayload(ResourceLocation id, String[] protocolID, String[] packetID) implements LeavesCustomPayload<ErrorPayload> {
@Override
public void write(@NotNull FriendlyByteBuf buf) {
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java
index 3f21db1707c961242090f2edd54b72f233c59d79..a7d9bd324f8a83e0424194711af66f691172b3f6 100644
--- a/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java
+++ b/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java
@@ -89,6 +89,10 @@ public class JadeProtocol {
public static final PairHierarchyLookup<IServerDataProvider<BlockAccessor>> blockDataProviders = new PairHierarchyLookup<>(new HierarchyLookup<>(Block.class), new HierarchyLookup<>(BlockEntity.class));
public static final WrappedHierarchyLookup<IServerExtensionProvider<ItemStack>> itemStorageProviders = WrappedHierarchyLookup.forAccessor();
+ public static boolean shouldEnable() {
+ return org.dreeam.leaf.config.modules.network.ProtocolSupport.jadeProtocol;
+ }
+
@Contract("_ -> new")
public static @NotNull ResourceLocation id(String path) {
return new ResourceLocation(PROTOCOL_ID, path);
@@ -161,19 +165,11 @@ public class JadeProtocol {
@ProtocolHandler.PlayerJoin
public static void onPlayerJoin(ServerPlayer player) {
- if (!org.dreeam.leaf.config.modules.network.ProtocolSupport.jadeProtocol) {
- return;
- }
-
sendPingPacket(player);
}
@ProtocolHandler.PayloadReceiver(payload = RequestEntityPayload.class, payloadId = "request_entity")
public static void requestEntityData(ServerPlayer player, RequestEntityPayload payload) {
- if (!org.dreeam.leaf.config.modules.network.ProtocolSupport.jadeProtocol) {
- return;
- }
-
MinecraftServer.getServer().execute(() -> {
EntityAccessor accessor = payload.data().unpack(player);
if (accessor == null) {
@@ -210,10 +206,6 @@ public class JadeProtocol {
@ProtocolHandler.PayloadReceiver(payload = RequestBlockPayload.class, payloadId = "request_block")
public static void requestBlockData(ServerPlayer player, RequestBlockPayload payload) {
- if (!org.dreeam.leaf.config.modules.network.ProtocolSupport.jadeProtocol) {
- return;
- }
-
MinecraftServer server = MinecraftServer.getServer();
server.execute(() -> {
BlockAccessor accessor = payload.data().unpack(player);
diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java
index 0704ac7825c69e69097b3e7c77763044f9fa9e1e..c039765237d56def91a1e630a0510062305fd585 100644
--- a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java
+++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java
@@ -48,6 +48,10 @@ public class CommunicationManager {
public CommunicationManager() {
}
+ public static boolean shouldEnable() {
+ return org.dreeam.leaf.config.modules.network.ProtocolSupport.syncmaticaProtocol;
+ }
+
public static GameProfile getGameProfile(final ExchangeTarget exchangeTarget) {
return playerMap.get(exchangeTarget).getGameProfile();
}
@@ -66,9 +70,6 @@ public class CommunicationManager {
@ProtocolHandler.PlayerJoin
public static void onPlayerJoin(ServerPlayer player) {
- if (!org.dreeam.leaf.config.modules.network.ProtocolSupport.syncmaticaProtocol) {
- return;
- }
final ExchangeTarget newPlayer = player.connection.exchangeTarget;
final VersionHandshakeServer hi = new VersionHandshakeServer(newPlayer);
playerMap.put(newPlayer, player);
@@ -79,9 +80,6 @@ public class CommunicationManager {
@ProtocolHandler.PlayerLeave
public static void onPlayerLeave(ServerPlayer player) {
- if (!org.dreeam.leaf.config.modules.network.ProtocolSupport.syncmaticaProtocol) {
- return;
- }
final ExchangeTarget oldPlayer = player.connection.exchangeTarget;
final Collection<Exchange> potentialMessageTarget = oldPlayer.getExchanges();
if (potentialMessageTarget != null) {
@@ -96,9 +94,6 @@ public class CommunicationManager {
@ProtocolHandler.PayloadReceiver(payload = SyncmaticaPayload.class, payloadId = "main")
public static void onPacketGet(ServerPlayer player, SyncmaticaPayload payload) {
- if (!org.dreeam.leaf.config.modules.network.ProtocolSupport.syncmaticaProtocol) {
- return;
- }
onPacket(player.connection.exchangeTarget, payload.packetType(), payload.data());
}

View File

@@ -1,210 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Sun, 28 Jul 2024 17:44:10 +0800
Subject: [PATCH] Cache CraftEntityType#minecraftToBukkit convert
The minecraftToBukkit EntityType convert call is expensive in mob spawn. This convert call is ued for spawn event call,
and the results are always same, thus there is no need to do the convert process every time, just cache it.
Save ~0.16ms per tick, and improve 11660ms -> 60ms in around 1 hour.
diff --git a/net/minecraft/util/SpawnUtil.java b/net/minecraft/util/SpawnUtil.java
index 34c3bf85473b3ad89355ebc21b68c59b3c683b84..a86955c3afc3468e92fb54c5ee0bf9c592f0b0cb 100644
--- a/net/minecraft/util/SpawnUtil.java
+++ b/net/minecraft/util/SpawnUtil.java
@@ -38,7 +38,7 @@ public class SpawnUtil {
// Paper start - PreCreatureSpawnEvent
com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
io.papermc.paper.util.MCUtil.toLocation(worldserver, blockposition),
- org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkit(entitytypes),
+ org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkitCached(entitytypes), // Leaf - Cache CraftEntityType#minecraftToBukkit convert
reason
);
if (!event.callEvent()) {
diff --git a/net/minecraft/world/entity/EntityType.java b/net/minecraft/world/entity/EntityType.java
index 002795df9c9c8d27f07f855dff148dfe353bef68..ca9459d3f8dbde237329dad1ec62f0791edb6a6c 100644
--- a/net/minecraft/world/entity/EntityType.java
+++ b/net/minecraft/world/entity/EntityType.java
@@ -512,7 +512,7 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
// Paper start - PreCreatureSpawnEvent
com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
io.papermc.paper.util.MCUtil.toLocation(worldserver, blockposition),
- org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkit(this),
+ org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkitCached(this), // Leaf - Cache CraftEntityType#minecraftToBukkit convert
spawnReason
);
if (!event.callEvent()) {
diff --git a/net/minecraft/world/level/BaseSpawner.java b/net/minecraft/world/level/BaseSpawner.java
index bb4411cfdf1bc7adc12c2f918d2eec830299f38b..b23397ae135f31abb7ac6bafd9064d7ef5e94218 100644
--- a/net/minecraft/world/level/BaseSpawner.java
+++ b/net/minecraft/world/level/BaseSpawner.java
@@ -137,7 +137,7 @@ public abstract class BaseSpawner {
// Paper start - PreCreatureSpawnEvent
com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent event = new com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent(
io.papermc.paper.util.MCUtil.toLocation(world, d0, d1, d2),
- org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkit(optional.get()),
+ org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkitCached(optional.get()), // Leaf - Cache CraftEntityType#minecraftToBukkit convert
io.papermc.paper.util.MCUtil.toLocation(world, pos)
);
if (!event.callEvent()) {
diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
index 88b3715df673c6d12aea69fde075ad3caa8c51e8..cc07f55e65589549c349cc078afa3b0fa81c203d 100644
--- a/net/minecraft/world/level/NaturalSpawner.java
+++ b/net/minecraft/world/level/NaturalSpawner.java
@@ -368,7 +368,7 @@ public final class NaturalSpawner {
// Paper start - PreCreatureSpawnEvent
com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
io.papermc.paper.util.MCUtil.toLocation(world, pos),
- org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkit(entitytypes), SpawnReason.NATURAL
+ org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkitCached(entitytypes), SpawnReason.NATURAL // Leaf - Cache CraftEntityType#minecraftToBukkit convert
);
if (!event.callEvent()) {
if (event.shouldAbortSpawn()) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java b/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java
index ccee1f637db5b8c34a5c125938edaa1361233e4d..a62f311e3f4dff63aa5c5d57ebc0bfa28c93b9b0 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java
@@ -187,7 +187,7 @@ public enum CraftStatistic {
public static EntityType getEntityTypeFromStatistic(net.minecraft.stats.Stat<net.minecraft.world.entity.EntityType<?>> statistic) {
Preconditions.checkArgument(statistic != null, "NMS Statistic cannot be null");
- return CraftEntityType.minecraftToBukkit(statistic.getValue());
+ return CraftEntityType.minecraftToBukkitCached(statistic.getValue()); // Leaf - Cache CraftEntityType#minecraftToBukkit convert
}
public static Material getMaterialFromStatistic(net.minecraft.stats.Stat<?> statistic) {
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java b/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java
index 146dde200845abcbe11015dda2c826a1aa711e42..881ce7c18efab9ef6f678be1a64afeaa3731b387 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java
@@ -47,7 +47,7 @@ public class CraftCreatureSpawner extends CraftBlockEntityState<SpawnerBlockEnti
}
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(spawnData.getEntityToSpawn());
- return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
+ return type.map(CraftEntityType::minecraftToBukkitCached).orElse(null); // Leaf - Cache CraftEntityType#minecraftToBukkit convert
}
@Override
@@ -177,7 +177,7 @@ public class CraftCreatureSpawner extends CraftBlockEntityState<SpawnerBlockEnti
}
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(spawnData.getEntityToSpawn());
- return type.map(CraftEntityType::minecraftToBukkit).map(CraftEntityType::bukkitToString).orElse(null);
+ return type.map(CraftEntityType::minecraftToBukkitCached).map(CraftEntityType::bukkitToString).orElse(null); // Leaf - Cache CraftEntityType#minecraftToBukkit convert
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftTrialSpawnerConfiguration.java b/src/main/java/org/bukkit/craftbukkit/block/CraftTrialSpawnerConfiguration.java
index 1e7a27bc783e68f9579d4d3c72ec165bde7175b9..72dfd388bb784009ac77ff0c93db56eb641c7ffc 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftTrialSpawnerConfiguration.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftTrialSpawnerConfiguration.java
@@ -60,7 +60,7 @@ public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration
}
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(this.spawnPotentialsDefinition.unwrap().get(0).data().getEntityToSpawn());
- return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
+ return type.map(CraftEntityType::minecraftToBukkitCached).orElse(null); // Leaf - Cache CraftEntityType#minecraftToBukkit convert
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 410b42fe4f5b4f545f2f035c84f0786003bf1915..0332266782d326d557709b360b9c647e464c0726 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -84,7 +84,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
public CraftEntity(final CraftServer server, final Entity entity) {
this.server = server;
this.entity = entity;
- this.entityType = CraftEntityType.minecraftToBukkit(entity.getType());
+ this.entityType = CraftEntityType.minecraftToBukkitCached(entity.getType()); // Leaf - Cache CraftEntityType#minecraftToBukkit convert
this.taskScheduler = new io.papermc.paper.threadedregions.EntityScheduler(this.entity.getServer(), this); // SparklyPaper - skip EntityScheduler's executeTick checks if there isn't any tasks to be run
}
@@ -124,7 +124,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
}
}
- CraftEntityTypes.EntityTypeData<?, T> entityTypeData = CraftEntityTypes.getEntityTypeData(CraftEntityType.minecraftToBukkit(entity.getType()));
+ CraftEntityTypes.EntityTypeData<?, T> entityTypeData = CraftEntityTypes.getEntityTypeData(CraftEntityType.minecraftToBukkitCached(entity.getType())); // Leaf - Cache CraftEntityType#minecraftToBukkit convert
if (entityTypeData != null) {
return (CraftEntity) entityTypeData.convertFunction().apply(server, entity);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityFactory.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityFactory.java
index b605924b96a9ec20bdccebdfa34067c1c1f95ada..32a0009c3c4f5fbb5ce3caa602416d253e5e87ab 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityFactory.java
@@ -35,7 +35,7 @@ public class CraftEntityFactory implements EntityFactory {
throw new IllegalArgumentException("Could not parse Entity: " + input);
}
- return CraftEntitySnapshot.create(tag, CraftEntityType.minecraftToBukkit(type));
+ return CraftEntitySnapshot.create(tag, CraftEntityType.minecraftToBukkitCached(type)); // Leaf - Cache CraftEntityType#minecraftToBukkit convert
}
public static CraftEntityFactory instance() {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java
index 6642bdc117d54aa2560518d4e08438a88e6fb3a1..14858bf98a4e3a88d0fb8a1ed7503fa2fda999b9 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java
@@ -82,7 +82,7 @@ public class CraftEntitySnapshot implements EntitySnapshot {
}
public static CraftEntitySnapshot create(CompoundTag tag) {
- EntityType type = net.minecraft.world.entity.EntityType.by(tag).map(CraftEntityType::minecraftToBukkit).orElse(null);
+ EntityType type = net.minecraft.world.entity.EntityType.by(tag).map(CraftEntityType::minecraftToBukkitCached).orElse(null); // Leaf - Cache CraftEntityType#minecraftToBukkit convert
return CraftEntitySnapshot.create(tag, type);
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityType.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityType.java
index d230cbc26f61d8ac5880825aca4dfab197c20401..1fdf2d7880f6b4f05702c5742c2b33e7eeba3af9 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityType.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityType.java
@@ -14,6 +14,23 @@ import org.bukkit.entity.EntityType;
public class CraftEntityType {
+ // Leaf start - Cache CraftEntityType#minecraftToBukkit convert
+ public static final java.util.Map<net.minecraft.world.entity.EntityType<?>, EntityType> MINECRAFT_TO_BUKKIT_KEY_CACHE = new java.util.concurrent.ConcurrentHashMap<>();
+ public static EntityType minecraftToBukkitCached(net.minecraft.world.entity.EntityType<?> minecraft) {
+ if (org.dreeam.leaf.config.modules.opt.EnableCachedMTBEntityTypeConvert.enabled) {
+ EntityType asBukkit = MINECRAFT_TO_BUKKIT_KEY_CACHE.get(minecraft);
+
+ if (asBukkit == null) {
+ asBukkit = minecraftToBukkit(minecraft);
+ MINECRAFT_TO_BUKKIT_KEY_CACHE.put(minecraft, asBukkit);
+ }
+
+ return asBukkit;
+ }
+
+ return minecraftToBukkit(minecraft);
+ }
+ // Leaf end - Cache CraftEntityType#minecraftToBukkit convert
public static EntityType minecraftToBukkit(net.minecraft.world.entity.EntityType<?> minecraft) {
Preconditions.checkArgument(minecraft != null);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java
index e8ece01669373ecf6552d33b2ed72668524e2650..f862ad6acf769ec336b826b4bb248154cbebd35f 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java
@@ -29,7 +29,7 @@ final class CraftMinecartMobSpawner extends CraftMinecart implements SpawnerMine
}
Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(spawnData.getEntityToSpawn());
- return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
+ return type.map(CraftEntityType::minecraftToBukkitCached).orElse(null); // Leaf - Cache CraftEntityType#minecraftToBukkit convert
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/tag/CraftEntityTag.java b/src/main/java/org/bukkit/craftbukkit/tag/CraftEntityTag.java
index 4270b771ff15d398b4788cb2fe27236989077614..97a87083f651434e51a9176009230e09301c3af2 100644
--- a/src/main/java/org/bukkit/craftbukkit/tag/CraftEntityTag.java
+++ b/src/main/java/org/bukkit/craftbukkit/tag/CraftEntityTag.java
@@ -21,6 +21,6 @@ public class CraftEntityTag extends CraftTag<net.minecraft.world.entity.EntityTy
@Override
public Set<EntityType> getValues() {
- return this.getHandle().stream().map(Holder::value).map(CraftEntityType::minecraftToBukkit).collect(Collectors.toUnmodifiableSet());
+ return this.getHandle().stream().map(Holder::value).map(CraftEntityType::minecraftToBukkitCached).collect(Collectors.toUnmodifiableSet()); // Leaf - Cache CraftEntityType#minecraftToBukkit convert
}
}

View File

@@ -1,63 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Sun, 4 Aug 2024 19:34:29 +0800
Subject: [PATCH] Configurable player knockback zombie
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index 7aab6970bf73108435e79a6ef39896e9fca8659e..b816d4509f5d1154fdbe462a0534a17c0d238281 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -2109,6 +2109,8 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
public void knockback(double d0, double d1, double d2, @Nullable Entity attacker, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause cause) { // Paper - knockback events
+ if (!canKnockback(attacker, this)) return; // Leaf - Configurable player knockback zombie
+
d0 *= 1.0D - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE);
if (true || d0 > 0.0D) { // CraftBukkit - Call event even when force is 0
//this.hasImpulse = true; // CraftBukkit - Move down
@@ -2136,6 +2138,20 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
}
+ // Leaf start - Configurable player knockback zombie
+ private boolean canKnockback(@Nullable Entity attacker, LivingEntity target) {
+ if (!org.dreeam.leaf.config.modules.gameplay.Knockback.canPlayerKnockbackZombie) {
+ if (attacker instanceof ServerPlayer && target.getType() == EntityType.ZOMBIE) { // Player -> Zombie
+ return false;
+ } else if (attacker instanceof Projectile projectile && projectile.getOwner() instanceof ServerPlayer && target.getType() == EntityType.ZOMBIE) { // Player -> projectile -> Zombie
+ return false;
+ }
+ }
+
+ return true;
+ }
+ // Leaf end - Configurable player knockback zombie
+
public void indicateDamage(double deltaX, double deltaZ) {}
@Nullable
diff --git a/src/main/java/org/dreeam/leaf/config/modules/gameplay/Knockback.java b/src/main/java/org/dreeam/leaf/config/modules/gameplay/Knockback.java
index 7b434158818834450ea43611e2ab5636917bb938..3499b1e60bde373bff79f007990fdd1a88fa48bf 100644
--- a/src/main/java/org/dreeam/leaf/config/modules/gameplay/Knockback.java
+++ b/src/main/java/org/dreeam/leaf/config/modules/gameplay/Knockback.java
@@ -11,6 +11,7 @@ public class Knockback extends ConfigModules {
public static boolean snowballCanKnockback = false;
public static boolean eggCanKnockback = false;
+ public static boolean canPlayerKnockbackZombie = true;
@Override
public void onLoaded() {
@@ -24,5 +25,10 @@ public class Knockback extends ConfigModules {
"Make egg can knockback players.",
"使鸡蛋可以击退玩家."
));
+ canPlayerKnockbackZombie = config.getBoolean(getBasePath() + ".can-player-knockback-zombie", canPlayerKnockbackZombie,
+ config.pickStringRegionBased(
+ "Make players can knockback zombie.",
+ "使玩家可以击退僵尸."
+ ));
}
}

View File

@@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Tue, 27 Aug 2024 22:53:08 -0400
Subject: [PATCH] Don't spawn if lastSpawnState is null
diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java
index 09e06dbb8e3f9ce65fb0f9010aeb3066b6c21671..c649a21b2631ed8a2abe1b8d2ff1a5fbf5f511ec 100644
--- a/net/minecraft/server/level/ServerChunkCache.java
+++ b/net/minecraft/server/level/ServerChunkCache.java
@@ -633,7 +633,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
ChunkPos chunkcoordintpair = chunk.getPos();
chunk.incrementInhabitedTime(timeDelta);
- if (!list1.isEmpty() && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair) && (!org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled || _pufferfish_spawnCountsReady.get()) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkcoordintpair, true)) { // Spigot // Pufferfish
+ if (!list1.isEmpty() && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair) && lastSpawnState != null && (!org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled || _pufferfish_spawnCountsReady.get()) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkcoordintpair, true)) { // Spigot // Pufferfish // Leaf - Don't spawn if lastSpawnState is null
NaturalSpawner.spawnForChunk(this.level, chunk, lastSpawnState, list1); // Pufferfish
}

View File

@@ -1,116 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: FallingKey <FallingKey@Outlook.com>
Date: Sun, 11 Aug 2024 14:20:37 +0800
Subject: [PATCH] Change max stack count
TODO - Dreeam:
- Check shulkerbox unpack whether correct
- stacked dropped shulkerbox unpack issue, need to base on box's item count
- dropped itemstack -> hopper behavior, need to transfer into hopper with correct count
- ...still testing lol
diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java
index 8eed7d70d5716f6d58c46b31a526b5de2a891f16..baf50c2f50325c64951dc37b1d57076b4a9c5b99 100644
--- a/net/minecraft/world/entity/item/ItemEntity.java
+++ b/net/minecraft/world/entity/item/ItemEntity.java
@@ -351,7 +351,13 @@ public class ItemEntity extends Entity implements TraceableEntity {
private boolean isMergable() {
ItemStack itemstack = this.getItem();
- return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < this.despawnRate && itemstack.getCount() < itemstack.getMaxStackSize(); // Paper - Alternative item-despawn-rate
+ // Leaf start - Change max stack count
+ if (org.dreeam.leaf.config.modules.gameplay.MaxItemsStackCount.maxItemStackCount < 1) {
+ return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < this.despawnRate && itemstack.getCount() < itemstack.getMaxStackSize(); // Paper - Alternative item-despawn-rate
+ } else {
+ return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < this.despawnRate && itemstack.getCount() < org.dreeam.leaf.config.modules.gameplay.MaxItemsStackCount.maxItemStackCount; // Paper - Alternative item-despawn-rate
+ }
+ // Leaf end - Change max stack count
}
private void tryToMerge(ItemEntity other) {
@@ -369,11 +375,24 @@ public class ItemEntity extends Entity implements TraceableEntity {
}
public static boolean areMergable(ItemStack stack1, ItemStack stack2) {
- return stack2.getCount() + stack1.getCount() > stack2.getMaxStackSize() ? false : ItemStack.isSameItemSameComponents(stack1, stack2);
+ // Leaf start - Change max stack count
+ if (org.dreeam.leaf.config.modules.gameplay.MaxItemsStackCount.maxItemStackCount == 0) {
+ return stack2.getCount() + stack1.getCount() > stack2.getMaxStackSize() ? false : ItemStack.isSameItemSameComponents(stack1, stack2);
+ } else {
+ return stack2.getCount() + stack1.getCount() > org.dreeam.leaf.config.modules.gameplay.MaxItemsStackCount.maxItemStackCount ? false : ItemStack.isSameItemSameComponents(stack1, stack2);
+ }
+ // Leaf end - Change max stack count
}
public static ItemStack merge(ItemStack stack1, ItemStack stack2, int maxCount) {
- int j = Math.min(Math.min(stack1.getMaxStackSize(), maxCount) - stack1.getCount(), stack2.getCount());
+ // Leaf start - Change max stack count
+ int j;
+ if (org.dreeam.leaf.config.modules.gameplay.MaxItemsStackCount.maxItemStackCount == 0) {
+ j = Math.min(Math.min(stack1.getMaxStackSize(), maxCount) - stack1.getCount(), stack2.getCount());
+ } else {
+ j = Math.min(Math.min(org.dreeam.leaf.config.modules.gameplay.MaxItemsStackCount.maxItemStackCount, maxCount) - stack1.getCount(), stack2.getCount());
+ }
+ // Leaf end - Change max stack count
ItemStack itemstack2 = stack1.copyWithCount(stack1.getCount() + j);
stack2.shrink(j);
@@ -381,7 +400,14 @@ public class ItemEntity extends Entity implements TraceableEntity {
}
private static void merge(ItemEntity targetEntity, ItemStack stack1, ItemStack stack2) {
- ItemStack itemstack2 = ItemEntity.merge(stack1, stack2, 64);
+ // Leaf start - Change max stack count
+ ItemStack itemstack2;
+ if (org.dreeam.leaf.config.modules.gameplay.MaxItemsStackCount.maxItemStackCount < 1) {
+ itemstack2 = ItemEntity.merge(stack1, stack2, 64);
+ } else {
+ itemstack2 = ItemEntity.merge(stack1, stack2, org.dreeam.leaf.config.modules.gameplay.MaxItemsStackCount.maxItemStackCount);
+ }
+ // Leaf end - Change max stack count
targetEntity.setItem(itemstack2);
}
diff --git a/net/minecraft/world/item/ItemUtils.java b/net/minecraft/world/item/ItemUtils.java
index 0c4074ed8b4fd9d6fcb838e8843d66f6f286ed5d..4728dd8bcbfc514eb5beeee716d849e578d5a53e 100644
--- a/net/minecraft/world/item/ItemUtils.java
+++ b/net/minecraft/world/item/ItemUtils.java
@@ -42,14 +42,32 @@ public class ItemUtils {
Level level = itemEntity.level();
if (!level.isClientSide) {
// Paper start - call EntityDropItemEvent
- contents.forEach(stack -> {
- ItemEntity droppedItem = new ItemEntity(level, itemEntity.getX(), itemEntity.getY(), itemEntity.getZ(), stack);
- org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(itemEntity.getBukkitEntity(), (org.bukkit.entity.Item) droppedItem.getBukkitEntity());
- if (event.callEvent()) {
- level.addFreshEntity(droppedItem);
+ // Leaf start - Change max stack count
+ if (org.dreeam.leaf.config.modules.gameplay.MaxItemsStackCount.maxContainerDestroyCount == 0) {
+ contents.forEach(stack -> {
+ addFreshEntityWithCallEvent(itemEntity, level, stack);
+ });
+ } else {
+ java.util.Iterator<ItemStack> iterator = contents.iterator();
+ for (int count = Math.min(itemEntity.getItem().getCount(), org.dreeam.leaf.config.modules.gameplay.MaxItemsStackCount.maxContainerDestroyCount); count > 0; count--) {
+ if (!iterator.hasNext()) break;
+
+ ItemStack stack = iterator.next();
+ addFreshEntityWithCallEvent(itemEntity, level, stack);
}
- });
+ }
+ // Leaf end - Change max stack count
// Paper end - call EntityDropItemEvent
}
}
+
+ // Leaf start - Change max stack count
+ private static void addFreshEntityWithCallEvent(ItemEntity itemEntity, Level level, ItemStack stack) {
+ ItemEntity droppedItem = new ItemEntity(level, itemEntity.getX(), itemEntity.getY(), itemEntity.getZ(), stack);
+ org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(itemEntity.getBukkitEntity(), (org.bukkit.entity.Item) droppedItem.getBukkitEntity());
+ if (event.callEvent()) {
+ level.addFreshEntity(droppedItem);
+ }
+ }
+ // Leaf end - Change max stack count
}

View File

@@ -1,250 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
Date: Wed, 23 Oct 2024 23:54:00 +0800
Subject: [PATCH] Asynchronous locator
Original license: MIT
Original project: https://github.com/thebrightspark/AsyncLocator
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
index 217d1f908a36a5177ba3cbb80a33f73d4dab0fa0..da658e24ad6e10d6ce55cebf944871d3cbde7f4a 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
@@ -80,6 +80,12 @@ public class TickThread extends Thread {
this(null, run, name);
}
+ // Leaf start - Async locator
+ public TickThread(final Runnable run, final String name, final int id) {
+ this(null, run, name, id);
+ }
+ // Leaf end - Async locator
+
public TickThread(final ThreadGroup group, final Runnable run, final String name) {
this(group, run, name, ID_GENERATOR.incrementAndGet());
}
diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
index 6676be8304e9415099ed423d3315180cafebd928..30b56382e9574004e344c1c8289d7dcbb177386b 100644
--- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
+++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
@@ -48,6 +48,12 @@ class PaperEventManager {
return;
}
// Leaf end - Multithreaded tracker
+ // Leaf start - Async locator
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled) {
+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(event::callEvent);
+ return;
+ }
+ // Leaf end - Async locator
throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously.");
}
// Leaves start - skip photographer
diff --git a/net/minecraft/server/commands/LocateCommand.java b/net/minecraft/server/commands/LocateCommand.java
index dcdde4cd7f15d34eabba4b3802971db20e6ae9d2..e33f31ae83edc4e04ad1f3fa3216b90219d902dc 100644
--- a/net/minecraft/server/commands/LocateCommand.java
+++ b/net/minecraft/server/commands/LocateCommand.java
@@ -105,6 +105,37 @@ public class LocateCommand {
BlockPos blockPos = BlockPos.containing(source.getPosition());
ServerLevel serverLevel = source.getLevel();
Stopwatch stopwatch = Stopwatch.createStarted(Util.TICKER);
+ // Leaf start - Async locator
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled) {
+ net.minecraft.commands.CommandSource locatorSource = source.source;
+ if (locatorSource instanceof net.minecraft.server.level.ServerPlayer ||
+ locatorSource instanceof net.minecraft.server.MinecraftServer) {
+ BlockPos originPos = BlockPos.containing(source.getPosition());
+ org.dreeam.leaf.async.locate.AsyncLocator.locate(source.getLevel(), holderSet, originPos, 100, false)
+ .thenOnServerThread(pair -> {
+ stopwatch.stop();
+ if (pair != null) {
+ showLocateResult(
+ source,
+ predicate,
+ originPos,
+ pair,
+ "commands.locate.structure.success",
+ false,
+ stopwatch.elapsed()
+ );
+ } else {
+ source.sendFailure(
+ Component.literal(
+ ERROR_STRUCTURE_NOT_FOUND.create(predicate.asPrintable()).getMessage()
+ )
+ );
+ }
+ });
+ return 0;
+ }
+ }
+ // Leaf end - Async locator
Pair<BlockPos, Holder<Structure>> pair = serverLevel.getChunkSource()
.getGenerator()
.findNearestMapStructure(serverLevel, holderSet, blockPos, 100, false);
diff --git a/net/minecraft/world/entity/animal/Dolphin.java b/net/minecraft/world/entity/animal/Dolphin.java
index c1842894f96a567707992d8ff938dbf689dd0df6..0792629152937b5107dbf444ce7f67e747f30c10 100644
--- a/net/minecraft/world/entity/animal/Dolphin.java
+++ b/net/minecraft/world/entity/animal/Dolphin.java
@@ -494,6 +494,8 @@ public class Dolphin extends AgeableWaterCreature {
private final Dolphin dolphin;
private boolean stuck;
+ @Nullable
+ private org.dreeam.leaf.async.locate.AsyncLocator.LocateTask<?> asyncLocator$locateTask;
DolphinSwimToTreasureGoal(Dolphin dolphin) {
this.dolphin = dolphin;
@@ -513,6 +515,11 @@ public class Dolphin extends AgeableWaterCreature {
@Override
public boolean canContinueToUse() {
+ // Leaf start - Async locator
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && this.asyncLocator$locateTask != null) {
+ return true;
+ }
+ // Leaf end - Async locator
BlockPos blockposition = this.dolphin.getTreasurePos();
return !BlockPos.containing((double) blockposition.getX(), this.dolphin.getY(), (double) blockposition.getZ()).closerToCenterThan(this.dolphin.position(), 4.0D) && !this.stuck && this.dolphin.getAirSupply() >= 100;
@@ -526,6 +533,21 @@ public class Dolphin extends AgeableWaterCreature {
this.stuck = false;
this.dolphin.getNavigation().stop();
BlockPos blockposition = this.dolphin.blockPosition();
+ // Leaf start - Async locator
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled) {
+ asyncLocator$locateTask = org.dreeam.leaf.async.locate.AsyncLocator.locate(worldserver, StructureTags.DOLPHIN_LOCATED, blockposition, 50, false)
+ .thenOnServerThread(pos -> {
+ asyncLocator$locateTask = null;
+ if (pos != null) {
+ this.dolphin.setTreasurePos(pos);
+ worldserver.broadcastEntityEvent(this.dolphin, (byte) 38);
+ } else {
+ this.stuck = true;
+ }
+ });
+ return;
+ }
+ // Leaf end - Async locator
BlockPos blockposition1 = worldserver.findNearestMapStructure(StructureTags.DOLPHIN_LOCATED, blockposition, 50, false);
if (blockposition1 != null) {
@@ -539,6 +561,12 @@ public class Dolphin extends AgeableWaterCreature {
@Override
public void stop() {
+ // Leaf start - Async locator
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && this.asyncLocator$locateTask != null) {
+ this.asyncLocator$locateTask.cancel();
+ this.asyncLocator$locateTask = null;
+ }
+ // Leaf end - Async locator
BlockPos blockposition = this.dolphin.getTreasurePos();
if (BlockPos.containing((double) blockposition.getX(), this.dolphin.getY(), (double) blockposition.getZ()).closerToCenterThan(this.dolphin.position(), 4.0D) || this.stuck) {
@@ -549,6 +577,11 @@ public class Dolphin extends AgeableWaterCreature {
@Override
public void tick() {
+ // Leaf start - Async locator
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && this.asyncLocator$locateTask != null) {
+ return;
+ }
+ // Leaf end - Async locator
Level world = this.dolphin.level();
if (this.dolphin.closeToNextPos() || this.dolphin.getNavigation().isDone()) {
diff --git a/net/minecraft/world/entity/projectile/EyeOfEnder.java b/net/minecraft/world/entity/projectile/EyeOfEnder.java
index fd1f5de7dc151dfd187d23e022b2c5435ed8accc..35037b0d7d243d614aa6945330ae7186a6f20af5 100644
--- a/net/minecraft/world/entity/projectile/EyeOfEnder.java
+++ b/net/minecraft/world/entity/projectile/EyeOfEnder.java
@@ -30,6 +30,7 @@ public class EyeOfEnder extends Entity implements ItemSupplier {
public double tz;
public int life;
public boolean surviveAfterDeath;
+ public boolean asyncLocator$locateTaskOngoing = false; // Leaf - Async locator
public EyeOfEnder(EntityType<? extends EyeOfEnder> type, Level world) {
super(type, world);
@@ -121,6 +122,11 @@ public class EyeOfEnder extends Entity implements ItemSupplier {
@Override
public void tick() {
super.tick();
+ // Leaf start - Async locator
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && this.asyncLocator$locateTaskOngoing) {
+ return;
+ }
+ // Leaf end - Async locator
Vec3 vec3d = this.getDeltaMovement();
double d0 = this.getX() + vec3d.x;
double d1 = this.getY() + vec3d.y;
diff --git a/net/minecraft/world/item/EnderEyeItem.java b/net/minecraft/world/item/EnderEyeItem.java
index c71a426c47e0ebc57ecb8c9c1d171737a084ccab..0edd6efc7a6dc7f62f07691fdd73fbb212c82173 100644
--- a/net/minecraft/world/item/EnderEyeItem.java
+++ b/net/minecraft/world/item/EnderEyeItem.java
@@ -113,7 +113,14 @@ public class EnderEyeItem extends Item {
user.startUsingItem(hand);
if (world instanceof ServerLevel) {
ServerLevel worldserver = (ServerLevel) world;
- BlockPos blockposition = worldserver.findNearestMapStructure(StructureTags.EYE_OF_ENDER_LOCATED, user.blockPosition(), 100, false);
+ // Leaf start - Async locator
+ BlockPos blockposition;
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled) {
+ blockposition = BlockPos.ZERO;
+ } else {
+ blockposition = worldserver.findNearestMapStructure(StructureTags.EYE_OF_ENDER_LOCATED, user.blockPosition(), 100, false);
+ }
+ // Leaf end - Async locator
if (blockposition == null) {
return InteractionResult.CONSUME;
@@ -121,8 +128,35 @@ public class EnderEyeItem extends Item {
EyeOfEnder entityendersignal = new EyeOfEnder(world, user.getX(), user.getY(0.5D), user.getZ());
+ // Leaf start - Async locator
+ final boolean isAsyncLocatorEnabled = org.dreeam.leaf.config.modules.async.AsyncLocator.enabled;
+ if (isAsyncLocatorEnabled) {
+ entityendersignal.asyncLocator$locateTaskOngoing = true;
+ org.dreeam.leaf.async.locate.AsyncLocator.locate(
+ worldserver,
+ StructureTags.EYE_OF_ENDER_LOCATED,
+ user.blockPosition(),
+ 100,
+ false
+ ).thenOnServerThread(pos -> {
+ entityendersignal.asyncLocator$locateTaskOngoing = false;
+ if (pos != null) {
+ entityendersignal.signalTo(pos);
+ CriteriaTriggers.USED_ENDER_EYE.trigger((ServerPlayer) user, pos);
+ user.awardStat(Stats.ITEM_USED.get(this));
+ } else {
+ // Set the entity's life to long enough that it dies
+ entityendersignal.life = Integer.MAX_VALUE - 100;
+ }
+ });
+ }
+ // Leaf end - Async locator
entityendersignal.setItem(itemstack);
- entityendersignal.signalTo(blockposition);
+ // Leaf start - Async locator
+ if (!isAsyncLocatorEnabled) {
+ entityendersignal.signalTo(blockposition);
+ }
+ // Leaf end - Async locator
world.gameEvent((Holder) GameEvent.PROJECTILE_SHOOT, entityendersignal.position(), GameEvent.Context.of((Entity) user));
// CraftBukkit start
if (!world.addFreshEntity(entityendersignal)) {
@@ -139,7 +173,11 @@ public class EnderEyeItem extends Item {
world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_EYE_LAUNCH, SoundSource.NEUTRAL, 1.0F, f);
itemstack.consume(1, user);
- user.awardStat(Stats.ITEM_USED.get(this));
+ // Leaf start - Async locator
+ if (!isAsyncLocatorEnabled) {
+ user.awardStat(Stats.ITEM_USED.get(this));
+ }
+ // Leaf end - Async locator
}
return InteractionResult.SUCCESS_SERVER;

View File

@@ -1,34 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Thu, 28 Jun 2018 22:13:44 -0400
Subject: [PATCH] EMC: Default don't use blockstate snapshots
Original license: MIT
Original project: https://github.com/starlis/empirecraft
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 5cb69d0b822e11a99a96aef4f59986d083b079f4..e9d43d9c4ad7cc1e12880e671f42e32dda85f17b 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -331,7 +331,7 @@ public class CraftBlock implements Block {
@Override
public BlockState getState() {
- return CraftBlockStates.getBlockState(this);
+ return CraftBlockStates.getBlockState(this, org.dreeam.leaf.config.modules.opt.TileEntitySnapshotCreation.enabled); // Leaf - EMC - default to not use snapshots
}
// Paper start
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
index 56453454cbd4b9e9270fc833f8ab38d5fa7a3763..99f9335e6e36bb97710b30135648c9dbf72d833b 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
@@ -238,7 +238,7 @@ public final class CraftBlockStates {
public static BlockState getBlockState(Block block) {
// Paper start
- return CraftBlockStates.getBlockState(block, true);
+ return CraftBlockStates.getBlockState(block, org.dreeam.leaf.config.modules.opt.TileEntitySnapshotCreation.enabled); // Leaf - default to not use snapshots
}
public static BlockState getBlockState(Block block, boolean useSnapshot) {
// Paper end

View File

@@ -1,28 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Taiyou06 <kaandindar21@gmail.com>
Date: Fri, 8 Nov 2024 00:14:03 +0100
Subject: [PATCH] Lithium: HashedList
This patch is based on the following mixins:
* "me/jellysquid/mods/lithium/mixin/world/block_entity_ticking/collections/WorldMixin.java" (1.16.x/dev branch)
* "net/caffeinemc/mods/lithium/common/util/collections/HashedReferenceList.java"
By: 2No2Name <2No2Name@web.de>
As part of: Lithium (https://github.com/CaffeineMC/lithium-fabric)
Licensed under: LGPL-3.0 (https://www.gnu.org/licenses/lgpl-3.0.html)
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
index 859708f1ab4b9f1bd318ca08c73cb67b1c3fe010..c1a3dbefc8d0ef0c36b8cc40a4cfd3c1015d8509 100644
--- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java
@@ -116,9 +116,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
public static final int TICKS_PER_DAY = 24000;
public static final int MAX_ENTITY_SPAWN_Y = 20000000;
public static final int MIN_ENTITY_SPAWN_Y = -20000000;
- public final List<TickingBlockEntity> blockEntityTickers = Lists.newArrayList(); // Paper - public
+ public final List<TickingBlockEntity> blockEntityTickers = new org.dreeam.leaf.util.HashedReferenceList<>(Lists.newArrayList()); // Paper - public // Leaf - Lithium - hashed list
protected final NeighborUpdater neighborUpdater;
- private final List<TickingBlockEntity> pendingBlockEntityTickers = Lists.newArrayList();
+ private final List<TickingBlockEntity> pendingBlockEntityTickers = new org.dreeam.leaf.util.HashedReferenceList<>(Lists.newArrayList()); // Leaf - Lithium - hashed list
private boolean tickingBlockEntities;
public final Thread thread;
private final boolean isDebug;

View File

@@ -1,53 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
Date: Tue, 9 Nov 2077 00:00:00 +0800
Subject: [PATCH] Smooth teleport config
This abuses some of how Minecraft works and attempts to teleport a player to another world without
triggering typical respawn packets. All of natural state of chunk resends, entity adds/removes, etc still
happen but the visual "refresh" of a world change is hidden. Depending on the destination location/world,
this can act as a "smooth teleport" to a world if the new world is very similar looking to the old one.
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index a27b0a3895290f5abb3a8e07fb886530fdf28c75..94288122eccd23b145e19f0e82750b7d610ea49b 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -1681,7 +1681,11 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
this.isChangingDimension = true; // CraftBukkit - Set teleport invulnerability only if player changing worlds
LevelData worlddata = worldserver.getLevelData();
- this.connection.send(new ClientboundRespawnPacket(this.createCommonSpawnInfo(worldserver), (byte) 3));
+ // Leaf start - Smooth teleport
+ int previousLogicalHeight = worldserver1.getLogicalHeight();
+ int currentLogicalHeight = worldserver.getLogicalHeight();
+ if (!org.dreeam.leaf.config.modules.gameplay.SmoothTeleport.enabled || previousLogicalHeight != currentLogicalHeight) this.connection.send(new ClientboundRespawnPacket(this.createCommonSpawnInfo(worldserver), (byte) 3));
+ // Leaf end - Smooth teleport
this.connection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
PlayerList playerlist = this.server.getPlayerList();
@@ -1691,7 +1695,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
// CraftBukkit end
this.portalPos = io.papermc.paper.util.MCUtil.toBlockPosition(exit); // Purpur - Fix stuck in portals
this.setServerLevel(worldserver);
- this.connection.internalTeleport(PositionMoveRotation.of(teleportTarget), teleportTarget.relatives()); // CraftBukkit - use internal teleport without event
+ if (!org.dreeam.leaf.config.modules.gameplay.SmoothTeleport.enabled || previousLogicalHeight != currentLogicalHeight) this.connection.internalTeleport(PositionMoveRotation.of(teleportTarget), teleportTarget.relatives()); // CraftBukkit - use internal teleport without event // Leaf
this.connection.resetPosition();
worldserver.addDuringTeleport(this);
this.triggerDimensionChangeTriggers(worldserver1);
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 2ccecc0a81c62d96978906aec2124563f3be7541..c6d57c6016b8e410bceddf19827ec43eb2a06229 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -1021,10 +1021,10 @@ public abstract class PlayerList {
ServerLevel worldserver1 = entityplayer1.serverLevel();
LevelData worlddata = worldserver1.getLevelData();
- if (!entityplayer.smoothWorldTeleport || !isSameLogicalHeight((ServerLevel) fromWorld, worldserver)) entityplayer1.connection.send(new ClientboundRespawnPacket(entityplayer1.createCommonSpawnInfo(worldserver1), (byte) i)); // Slice // Leaf
+ if ((!entityplayer.smoothWorldTeleport && !org.dreeam.leaf.config.modules.gameplay.SmoothTeleport.enabled) || i != 1 || !isSameLogicalHeight((ServerLevel) fromWorld, worldserver)) entityplayer1.connection.send(new ClientboundRespawnPacket(entityplayer1.createCommonSpawnInfo(worldserver1), (byte) i)); // Slice // Leaf
entityplayer1.connection.send(new ClientboundSetChunkCacheRadiusPacket(worldserver1.spigotConfig.viewDistance)); // Spigot
entityplayer1.connection.send(new ClientboundSetSimulationDistancePacket(worldserver1.spigotConfig.simulationDistance)); // Spigot
- if (!entityplayer.smoothWorldTeleport || !isSameLogicalHeight((ServerLevel) fromWorld, worldserver)) entityplayer1.connection.teleport(CraftLocation.toBukkit(entityplayer1.position(), worldserver1.getWorld(), entityplayer1.getYRot(), entityplayer1.getXRot())); // CraftBukkit // Slice // Leaf
+ if ((!entityplayer.smoothWorldTeleport && !org.dreeam.leaf.config.modules.gameplay.SmoothTeleport.enabled) || i != 1 || !isSameLogicalHeight((ServerLevel) fromWorld, worldserver)) entityplayer1.connection.teleport(CraftLocation.toBukkit(entityplayer1.position(), worldserver1.getWorld(), entityplayer1.getYRot(), entityplayer1.getXRot())); // CraftBukkit // Slice // Leaf
entityplayer1.connection.send(new ClientboundSetDefaultSpawnPositionPacket(worldserver.getSharedSpawnPos(), worldserver.getSharedSpawnAngle()));
entityplayer1.connection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
entityplayer1.connection.send(new ClientboundSetExperiencePacket(entityplayer1.experienceProgress, entityplayer1.totalExperience, entityplayer1.experienceLevel));

View File

@@ -1,22 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
Date: Tue, 9 Nov 2077 00:00:00 +0800
Subject: [PATCH] Faster CraftServer#getworlds list creation
CraftServer#getWorlds/Bukkit#getWorlds is frequently used in plugins,
replacing ArrayList with Fastutil ObjectArrayList
brings about 40% performance improvement in benchmark.
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index c20ab80b92196c71664a945babaafce561f764ed..6aacd5254ecd4078459a51a2857ffb7caa111261 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -991,7 +991,7 @@ public final class CraftServer implements Server {
@Override
public List<World> getWorlds() {
- return new ArrayList<World>(this.worlds.values());
+ return new it.unimi.dsi.fastutil.objects.ObjectArrayList<World>(this.worlds.values()); // Leaf - Faster CraftServer#getWorlds list creation
}
@Override

View File

@@ -1,20 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Tue, 24 Dec 2024 13:28:56 -0500
Subject: [PATCH] Configurable tripwire dupe
Bring back MC-59471, MC-129055 on 1.21.2+, which fixed in 1.21.2 snapshots 24w33a and 24w36a
diff --git a/net/minecraft/world/level/block/TripWireHookBlock.java b/net/minecraft/world/level/block/TripWireHookBlock.java
index c2589f42c467ca672417c24076313da51bb2dcbb..fda1f2840f5a79d99217bd0fa72f4a1b1a75eb7e 100644
--- a/net/minecraft/world/level/block/TripWireHookBlock.java
+++ b/net/minecraft/world/level/block/TripWireHookBlock.java
@@ -206,7 +206,7 @@ public class TripWireHookBlock extends Block {
if (iblockdata4 != null) {
BlockState iblockdata5 = world.getBlockState(blockposition2);
- if (iblockdata5.is(Blocks.TRIPWIRE) || iblockdata5.is(Blocks.TRIPWIRE_HOOK)) {
+ if (org.dreeam.leaf.config.modules.gameplay.ConfigurableTripWireDupe.enabled || iblockdata5.is(Blocks.TRIPWIRE) || iblockdata5.is(Blocks.TRIPWIRE_HOOK)) { // Leaf - Configurable tripwire dupe
world.setBlock(blockposition2, (BlockState) iblockdata4.trySetValue(TripWireHookBlock.ATTACHED, flag4), 3);
}
}

View File

@@ -3,12 +3,14 @@ From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
Date: Wed, 23 Oct 2024 20:20:16 +0800
Subject: [PATCH] Fix MC-177381
Removed since Paper 1.21.4, thanks Doritos
Related MC issue: https://bugs.mojang.com/browse/MC-177381
diff --git a/net/minecraft/server/commands/LocateCommand.java b/net/minecraft/server/commands/LocateCommand.java
diff --git a/src/main/java/net/minecraft/server/commands/LocateCommand.java b/src/main/java/net/minecraft/server/commands/LocateCommand.java
index 2972f041eea95b92b37c2ab869f9f8ed3d142a27..dcdde4cd7f15d34eabba4b3802971db20e6ae9d2 100644
--- a/net/minecraft/server/commands/LocateCommand.java
+++ b/net/minecraft/server/commands/LocateCommand.java
--- a/src/main/java/net/minecraft/server/commands/LocateCommand.java
+++ b/src/main/java/net/minecraft/server/commands/LocateCommand.java
@@ -196,8 +196,10 @@ public class LocateCommand {
}

View File

@@ -0,0 +1,318 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Taiyou06 <kaandindar21@gmail.com>
Date: Fri, 8 Nov 2024 00:14:03 +0100
Subject: [PATCH] Lithium: HashedList
Removed since Leaf 1.21.4, replaced by Paper#9970
This patch is based on the following mixins:
* "me/jellysquid/mods/lithium/mixin/world/block_entity_ticking/collections/WorldMixin.java" (1.16.x/dev branch)
* "net/caffeinemc/mods/lithium/common/util/collections/HashedReferenceList.java"
By: 2No2Name <2No2Name@web.de>
As part of: Lithium (https://github.com/CaffeineMC/lithium-fabric)
Licensed under: LGPL-3.0 (https://www.gnu.org/licenses/lgpl-3.0.html)
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 859708f1ab4b9f1bd318ca08c73cb67b1c3fe010..c1a3dbefc8d0ef0c36b8cc40a4cfd3c1015d8509 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -116,9 +116,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
public static final int TICKS_PER_DAY = 24000;
public static final int MAX_ENTITY_SPAWN_Y = 20000000;
public static final int MIN_ENTITY_SPAWN_Y = -20000000;
- public final List<TickingBlockEntity> blockEntityTickers = Lists.newArrayList(); // Paper - public
+ public final List<TickingBlockEntity> blockEntityTickers = new org.dreeam.leaf.util.HashedReferenceList<>(Lists.newArrayList()); // Paper - public // Leaf - Lithium - hashed list
protected final NeighborUpdater neighborUpdater;
- private final List<TickingBlockEntity> pendingBlockEntityTickers = Lists.newArrayList();
+ private final List<TickingBlockEntity> pendingBlockEntityTickers = new org.dreeam.leaf.util.HashedReferenceList<>(Lists.newArrayList()); // Leaf - Lithium - hashed list
private boolean tickingBlockEntities;
public final Thread thread;
private final boolean isDebug;
diff --git a/src/main/java/org/dreeam/leaf/util/HashedReferenceList.java b/src/main/java/org/dreeam/leaf/util/HashedReferenceList.java
new file mode 100644
index 0000000000000000000000000000000000000000..8c08207496fac9b0cc839293354674e3ce7083ad
--- /dev/null
+++ b/src/main/java/org/dreeam/leaf/util/HashedReferenceList.java
@@ -0,0 +1,282 @@
+package org.dreeam.leaf.util;
+
+import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
+import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
+import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Wraps a {@link List} with a hash table which provides O(1) lookups for {@link Collection#contains(Object)}. The type
+ * contained by this list must use reference-equality semantics.
+ */
+@SuppressWarnings("SuspiciousMethodCalls")
+public class HashedReferenceList<T> implements List<T> {
+ private final ReferenceArrayList<T> list;
+ private final Reference2IntOpenHashMap<T> counter;
+
+ public HashedReferenceList(List<T> list) {
+ this.list = new ReferenceArrayList<>();
+ this.list.addAll(list);
+
+ this.counter = new Reference2IntOpenHashMap<>();
+ this.counter.defaultReturnValue(0);
+
+ for (T obj : this.list) {
+ this.counter.addTo(obj, 1);
+ }
+ }
+
+ @Override
+ public int size() {
+ return this.list.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return this.list.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return this.counter.containsKey(o);
+ }
+
+ @Override
+ public Iterator<T> iterator() {
+ return this.listIterator();
+ }
+
+ @Override
+ public Object[] toArray() {
+ return this.list.toArray();
+ }
+
+ @SuppressWarnings("SuspiciousToArrayCall")
+ @Override
+ public <T1> T1[] toArray(T1 @NotNull [] a) {
+ return this.list.toArray(a);
+ }
+
+ @Override
+ public boolean add(T t) {
+ this.trackReferenceAdded(t);
+
+ return this.list.add(t);
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ this.trackReferenceRemoved(o);
+
+ return this.list.remove(o);
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> c) {
+ for (Object obj : c) {
+ if (!this.counter.containsKey(obj)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends T> c) {
+ for (T obj : c) {
+ this.trackReferenceAdded(obj);
+ }
+
+ return this.list.addAll(c);
+ }
+
+ @Override
+ public boolean addAll(int index, Collection<? extends T> c) {
+ for (T obj : c) {
+ this.trackReferenceAdded(obj);
+ }
+
+ return this.list.addAll(index, c);
+ }
+
+ @Override
+ public boolean removeAll(@NotNull Collection<?> c) {
+ if (this.size() >= 2 && c.size() > 4 && c instanceof List) {
+ //HashReferenceList uses reference equality, so using ReferenceOpenHashSet is fine
+ c = new ReferenceOpenHashSet<>(c);
+ }
+ this.counter.keySet().removeAll(c);
+ return this.list.removeAll(c);
+ }
+
+ @Override
+ public boolean retainAll(@NotNull Collection<?> c) {
+ this.counter.keySet().retainAll(c);
+ return this.list.retainAll(c);
+ }
+
+ @Override
+ public void clear() {
+ this.counter.clear();
+ this.list.clear();
+ }
+
+ @Override
+ public T get(int index) {
+ return this.list.get(index);
+ }
+
+ @Override
+ public T set(int index, T element) {
+ T prev = this.list.set(index, element);
+
+ if (prev != element) {
+ if (prev != null) {
+ this.trackReferenceRemoved(prev);
+ }
+
+ this.trackReferenceAdded(element);
+ }
+
+ return prev;
+ }
+
+ @Override
+ public void add(int index, T element) {
+ this.trackReferenceAdded(element);
+
+ this.list.add(index, element);
+ }
+
+ @Override
+ public T remove(int index) {
+ T prev = this.list.remove(index);
+
+ if (prev != null) {
+ this.trackReferenceRemoved(prev);
+ }
+
+ return prev;
+ }
+
+ @Override
+ public int indexOf(Object o) {
+ return this.list.indexOf(o);
+ }
+
+ @Override
+ public int lastIndexOf(Object o) {
+ return this.list.lastIndexOf(o);
+ }
+
+ @Override
+ public ListIterator<T> listIterator() {
+ return this.listIterator(0);
+ }
+
+ @Override
+ public ListIterator<T> listIterator(int index) {
+ return new ListIterator<>() {
+ private final ListIterator<T> inner = HashedReferenceList.this.list.listIterator(index);
+
+ @Override
+ public boolean hasNext() {
+ return this.inner.hasNext();
+ }
+
+ @Override
+ public T next() {
+ return this.inner.next();
+ }
+
+ @Override
+ public boolean hasPrevious() {
+ return this.inner.hasPrevious();
+ }
+
+ @Override
+ public T previous() {
+ return this.inner.previous();
+ }
+
+ @Override
+ public int nextIndex() {
+ return this.inner.nextIndex();
+ }
+
+ @Override
+ public int previousIndex() {
+ return this.inner.previousIndex();
+ }
+
+ @Override
+ public void remove() {
+ int last = this.previousIndex();
+
+ if (last == -1) {
+ throw new NoSuchElementException();
+ }
+
+ T prev = HashedReferenceList.this.get(last);
+
+ if (prev != null) {
+ HashedReferenceList.this.trackReferenceRemoved(prev);
+ }
+
+ this.inner.remove();
+ }
+
+ @Override
+ public void set(T t) {
+ int last = this.previousIndex();
+
+ if (last == -1) {
+ throw new NoSuchElementException();
+ }
+
+ T prev = HashedReferenceList.this.get(last);
+
+ if (prev != t) {
+ if (prev != null) {
+ HashedReferenceList.this.trackReferenceRemoved(prev);
+ }
+
+ HashedReferenceList.this.trackReferenceAdded(t);
+ }
+
+ this.inner.remove();
+ }
+
+ @Override
+ public void add(T t) {
+ HashedReferenceList.this.trackReferenceAdded(t);
+
+ this.inner.add(t);
+ }
+ };
+ }
+
+ @Override
+ public List<T> subList(int fromIndex, int toIndex) {
+ return this.list.subList(fromIndex, toIndex);
+ }
+
+ private void trackReferenceAdded(T t) {
+ this.counter.addTo(t, 1);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void trackReferenceRemoved(Object o) {
+ if (this.counter.addTo((T) o, -1) <= 1) {
+ this.counter.removeInt(o);
+ }
+ }
+
+}

View File

@@ -2,7 +2,7 @@ group=cn.dreeam.leaf
mcVersion=1.21.4
version=1.21.4-R0.1-SNAPSHOT
galeCommit=11e614cd6079f8485dbee0881eb4e56ed04f7f35
galeCommit=b8d86ad9ba8d5cfaf304386e47b4fb18b1f57e8c
org.gradle.configuration-cache=true
org.gradle.caching=true

View File

@@ -9,6 +9,8 @@
- [ ] Add server full join config explaination to docs
- [ ] leaf at
- [ ] Add purpur config changes to docs moved config
- [ ] Check linear
- [ ] Merge changes from Tramontane
# Cleanup
- [ ] 检查注释都应该start end - patch名或者合理注释