From 915f755b01a6ac80e0b30baebb3febe5c6d5f62e Mon Sep 17 00:00:00 2001 From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> Date: Wed, 11 Jun 2025 06:00:32 +0800 Subject: [PATCH] Updated Upstream (Paper/Purpur/Leaves) Upstream has released updates that appear to apply and compile correctly Paper Changes: PaperMC/Paper@03efecf0 Do not fire PlayerDropItemEvent for /give command PaperMC/Paper@3527ccdf feat: expose updateDemand and restock on Villager (#12608) PaperMC/Paper@320f25cb fix sponge-absorb deleting chest content (#12647) PaperMC/Paper@95565e0f Add missing attribute serialization updater PaperMC/Paper@519e4224 Fix infinite loop in RegionFile IO Purpur Changes: PurpurMC/Purpur@eb0ba67d Updated Upstream (Paper) PurpurMC/Purpur@7c6502dc Updated Upstream (Paper) PurpurMC/Purpur@aa289e2c Updated Upstream (Paper) Leaves Changes: LeavesMC/Leaves@f09fbb24 1.21.5 (#470) LeavesMC/Leaves@f1cc3ef9 Fix version fetch LeavesMC/Leaves@73bd42af Remove fast resume, mojang added it LeavesMC/Leaves@59856751 Configurable trading with the void LeavesMC/Leaves@9d32c5bd Fix protocols (#534) --- gradle.properties | 2 +- .../features/0013-Purpur-API-Changes.patch | 10 ++++---- ...r-Fix-infinite-loop-in-RegionFile-IO.patch | 2 ++ ...0099-Purpur-Server-Minecraft-Changes.patch | 14 +++++------ .../features/0113-Leaves-Protocol-Core.patch | 2 +- ...nvalid-flatten-text-component-parse.patch} | 0 .../0009-Purpur-Server-Paper-Changes.patch | 11 ++++---- .../features/0030-Leaves-Protocol-Core.patch | 2 +- .../ItemStorageExtensionProvider.java | 4 +++ .../org/leavesmc/leaves/replay/Recorder.java | 25 ++++--------------- .../leavesmc/leaves/replay/ReplayFile.java | 20 +++++++++++---- 11 files changed, 46 insertions(+), 46 deletions(-) rename {leaf-server/minecraft-patches/features => leaf-archived-patches/removed/hardfork/server}/0280-Paper-Fix-infinite-loop-in-RegionFile-IO.patch (96%) rename leaf-server/minecraft-patches/features/{0281-do-not-log-invalid-flatten-text-component-parse.patch => 0280-do-not-log-invalid-flatten-text-component-parse.patch} (100%) diff --git a/gradle.properties b/gradle.properties index 310e1171..6144b7cd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ group=cn.dreeam.leaf mcVersion=1.21.5 version=1.21.5-R0.1-SNAPSHOT -paperCommit=94f2903584945d71012050bcef830da4271fdb90 +paperCommit=519e4224b1ba73a99c58c8fc53aab003eb6af37a org.gradle.configuration-cache=true org.gradle.caching=true diff --git a/leaf-api/paper-patches/features/0013-Purpur-API-Changes.patch b/leaf-api/paper-patches/features/0013-Purpur-API-Changes.patch index 44ba5f55..e9f0a5fa 100644 --- a/leaf-api/paper-patches/features/0013-Purpur-API-Changes.patch +++ b/leaf-api/paper-patches/features/0013-Purpur-API-Changes.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Purpur API Changes Original license: MIT Original project: https://github.com/PurpurMC/Purpur -Commit: 916df1a858c46e240fa966540cf1cc819cfb3c36 +Commit: aa289e2c6ff801551fb2f585269ccffed3a154fa Patches listed below are removed in this patch, They exists in Gale or Leaf: * "co/aikar/timings/TimedEventExecutor.java.patch" @@ -1170,13 +1170,13 @@ index 7fbfdb07585c7b28acea1f0c1f58ada0cc744441..21fcca092e2e31baa5ece0de9e44e3fa + // Purpur end } diff --git a/src/main/java/org/bukkit/entity/Villager.java b/src/main/java/org/bukkit/entity/Villager.java -index 02b86d9615f8150b13ff0beefd5ca502c0494f99..dcf836b6db1a9b17e5e7aa945318e4b60012112b 100644 +index 4d88bb2eaa43709fb6103a6f77d8c01e83bfe743..bb3773e002ebcfd8eced792bf0236c4cfbae8663 100644 --- a/src/main/java/org/bukkit/entity/Villager.java +++ b/src/main/java/org/bukkit/entity/Villager.java -@@ -391,4 +391,13 @@ public interface Villager extends AbstractVillager { - * reputation regardless of its impact and the player associated. +@@ -408,4 +408,13 @@ public interface Villager extends AbstractVillager { + * Demand is still updated even if all events are canceled. */ - public void clearReputations(); + public void restock(); + + // Purpur start + /** diff --git a/leaf-server/minecraft-patches/features/0280-Paper-Fix-infinite-loop-in-RegionFile-IO.patch b/leaf-archived-patches/removed/hardfork/server/0280-Paper-Fix-infinite-loop-in-RegionFile-IO.patch similarity index 96% rename from leaf-server/minecraft-patches/features/0280-Paper-Fix-infinite-loop-in-RegionFile-IO.patch rename to leaf-archived-patches/removed/hardfork/server/0280-Paper-Fix-infinite-loop-in-RegionFile-IO.patch index e26612e0..a13220d8 100644 --- a/leaf-server/minecraft-patches/features/0280-Paper-Fix-infinite-loop-in-RegionFile-IO.patch +++ b/leaf-archived-patches/removed/hardfork/server/0280-Paper-Fix-infinite-loop-in-RegionFile-IO.patch @@ -3,6 +3,8 @@ From: Spottedleaf Date: Mon, 9 Jun 2025 02:46:34 -0700 Subject: [PATCH] Paper: Fix infinite loop in RegionFile IO +Removed since Leaf 1.21.5/Paper 1.21.4, added on Paper + Original license: GPLv3 Original project: https://github.com/PaperMC/Paper diff --git a/leaf-server/minecraft-patches/features/0099-Purpur-Server-Minecraft-Changes.patch b/leaf-server/minecraft-patches/features/0099-Purpur-Server-Minecraft-Changes.patch index 9bda7308..0e21a75f 100644 --- a/leaf-server/minecraft-patches/features/0099-Purpur-Server-Minecraft-Changes.patch +++ b/leaf-server/minecraft-patches/features/0099-Purpur-Server-Minecraft-Changes.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Purpur Server Minecraft Changes Original license: MIT Original project: https://github.com/PurpurMC/Purpur -Commit: 916df1a858c46e240fa966540cf1cc819cfb3c36 +Commit: aa289e2c6ff801551fb2f585269ccffed3a154fa Patches listed below are removed in this patch, They exists in Gale or Leaf: * "net/minecraft/CrashReport.java.patch" @@ -465,7 +465,7 @@ index c44cdbbdc06b25bd20a208386545a10af9b96df8..a88b8f999b181071ebb492bc1afa2d72 for (ServerPlayer serverPlayer : players) { diff --git a/net/minecraft/server/commands/GiveCommand.java b/net/minecraft/server/commands/GiveCommand.java -index b81f98738ef166336e4cc3092b6ba63f385b68e3..ca4bad763602f202423409ffb16f797f91a5dadc 100644 +index f04bc30a836b6eec80b0e2cf76831b0fdccd8149..5e48519f1669ddecaca479126270012373879752 100644 --- a/net/minecraft/server/commands/GiveCommand.java +++ b/net/minecraft/server/commands/GiveCommand.java @@ -66,6 +66,7 @@ public class GiveCommand { @@ -474,7 +474,7 @@ index b81f98738ef166336e4cc3092b6ba63f385b68e3..ca4bad763602f202423409ffb16f797f boolean flag = serverPlayer.getInventory().add(itemStack1); + if (org.purpurmc.purpur.PurpurConfig.disableGiveCommandDrops) continue; // Purpur - add config option for toggling give command dropping if (flag && itemStack1.isEmpty()) { - ItemEntity itemEntity = serverPlayer.drop(itemStack, false); + ItemEntity itemEntity = serverPlayer.drop(itemStack, false, false, false, null); // Paper - do not fire PlayerDropItemEvent for /give command if (itemEntity != null) { diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java index 349eafa321c955c6bda7a5aa6931311d85867565..cdfb9004dd4f4ea1bbb77895b7fc020d628c485d 100644 @@ -12253,7 +12253,7 @@ index e282b6ab6d0d1c11ee40f5f436bd50fa90ddc88b..d6ae13c19481ce33bfa0b6c9db632830 this.spawnCat(pos, level, true); } diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java -index cb9c722251e01cbbd827af9aff5f5942c62d2011..530a7873a0796bb5e8e25b91586d6c4cfa00a08c 100644 +index 202bcb28218b0d9a2a5e211fee173ecd5f625896..acb0789b3e791cbb81c23efb9bbeae736db5f48c 100644 --- a/net/minecraft/world/entity/npc/Villager.java +++ b/net/minecraft/world/entity/npc/Villager.java @@ -178,6 +178,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @@ -12436,7 +12436,7 @@ index cb9c722251e01cbbd827af9aff5f5942c62d2011..530a7873a0796bb5e8e25b91586d6c4c @@ -506,7 +616,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - private void updateDemand() { + public void updateDemand() { for (MerchantOffer merchantOffer : this.getOffers()) { - merchantOffer.updateDemand(); + merchantOffer.updateDemand(this.level().purpurConfig.villagerMinimumDemand); // Purpur - Configurable minimum demand for trades @@ -15903,7 +15903,7 @@ index e8d7b6adbcb84e8d89067b54318e0feb3c3276a6..2076474168410f376beebc072af4959e int i = 15 + level.random.nextInt(15) + level.random.nextInt(15); // this.popExperience(level, pos, i); diff --git a/net/minecraft/world/level/block/SpongeBlock.java b/net/minecraft/world/level/block/SpongeBlock.java -index 5d1b8c55bffc42924c4a95b1b4bd2e1e0b064af3..69822d21d0e71f4b29349af0bee2d80fa0802a3b 100644 +index ad5daac30b85fead93637c83fb9d96e02c6df216..8661443ed346cfb193138b5f37c3dd931a6d6644 100644 --- a/net/minecraft/world/level/block/SpongeBlock.java +++ b/net/minecraft/world/level/block/SpongeBlock.java @@ -53,8 +53,8 @@ public class SpongeBlock extends Block { @@ -15925,7 +15925,7 @@ index 5d1b8c55bffc42924c4a95b1b4bd2e1e0b064af3..69822d21d0e71f4b29349af0bee2d80f + if (!fluidState.is(FluidTags.WATER) && (!level.purpurConfig.spongeAbsorbsLava || !fluidState.is(FluidTags.LAVA)) && (!level.purpurConfig.spongeAbsorbsWaterFromMud || !blockState.is(Blocks.MUD))) { // Purpur - Option for sponges to work on lava and mud return BlockPos.TraversalNodeStatus.SKIP; } else if (blockState.getBlock() instanceof BucketPickup bucketPickup - && !bucketPickup.pickupBlock(null, blockList, blockPos, blockState).isEmpty()) { // CraftBukkit + && !bucketPickup.pickupBlock(null, level, blockPos, blockState).isEmpty()) { @@ -76,6 +76,10 @@ public class SpongeBlock extends Block { } else { if (blockState.getBlock() instanceof LiquidBlock) { diff --git a/leaf-server/minecraft-patches/features/0113-Leaves-Protocol-Core.patch b/leaf-server/minecraft-patches/features/0113-Leaves-Protocol-Core.patch index 27d6b72c..01a8eaf5 100644 --- a/leaf-server/minecraft-patches/features/0113-Leaves-Protocol-Core.patch +++ b/leaf-server/minecraft-patches/features/0113-Leaves-Protocol-Core.patch @@ -9,7 +9,7 @@ and change store way to sql maybe? Original license: GPLv3 Original project: https://github.com/LeavesMC/Leaves -Commit: 358d3d232c88d0d089e2bcd2de9f814384572b8b +Commit: 9d32c5bd3df7c76055aff886ed9efda02e45a45a diff --git a/net/minecraft/network/protocol/common/custom/CustomPacketPayload.java b/net/minecraft/network/protocol/common/custom/CustomPacketPayload.java index fb263fa1f30a7dfcb7ec2656abfb38e5fe88eac9..56fd1ed7ccaf96e7eedea60fbdbf7f934939d563 100644 diff --git a/leaf-server/minecraft-patches/features/0281-do-not-log-invalid-flatten-text-component-parse.patch b/leaf-server/minecraft-patches/features/0280-do-not-log-invalid-flatten-text-component-parse.patch similarity index 100% rename from leaf-server/minecraft-patches/features/0281-do-not-log-invalid-flatten-text-component-parse.patch rename to leaf-server/minecraft-patches/features/0280-do-not-log-invalid-flatten-text-component-parse.patch diff --git a/leaf-server/paper-patches/features/0009-Purpur-Server-Paper-Changes.patch b/leaf-server/paper-patches/features/0009-Purpur-Server-Paper-Changes.patch index 0495829c..99bfa9b5 100644 --- a/leaf-server/paper-patches/features/0009-Purpur-Server-Paper-Changes.patch +++ b/leaf-server/paper-patches/features/0009-Purpur-Server-Paper-Changes.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Purpur Server Paper Changes Original license: MIT Original project: https://github.com/PurpurMC/Purpur -Commit: 916df1a858c46e240fa966540cf1cc819cfb3c36 +Commit: aa289e2c6ff801551fb2f585269ccffed3a154fa Patches listed below are removed in this patch, They exists in Gale or Leaf: * "Rebrand.patch" @@ -1233,14 +1233,13 @@ index f03f9f94c51ef2f2eb24e4f65ec69b542b1c0a07..af60e3ef00ce1e98708d9963d466e72b + // Purpur end - Summoner API } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java -index 258e149a4c239328f4b068ac4617ca63b788dab3..a69b1b56a0e34673005e5da700943c656d2ec724 100644 +index 8523cadccc67fa172041be0316b979a34fac6b26..61e983c425ceec2bbd470f36497e616b4cb94ed2 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java -@@ -380,4 +380,12 @@ public class CraftVillager extends CraftAbstractVillager implements Villager { - public void clearReputations() { - getHandle().getGossips().gossips.clear(); +@@ -390,4 +390,11 @@ public class CraftVillager extends CraftAbstractVillager implements Villager { + public void restock() { + getHandle().restock(); } -+ // Paper end + + // Purpur start - Lobotomize stuck villagers + @Override diff --git a/leaf-server/paper-patches/features/0030-Leaves-Protocol-Core.patch b/leaf-server/paper-patches/features/0030-Leaves-Protocol-Core.patch index c1d16cd8..b42015dc 100644 --- a/leaf-server/paper-patches/features/0030-Leaves-Protocol-Core.patch +++ b/leaf-server/paper-patches/features/0030-Leaves-Protocol-Core.patch @@ -9,7 +9,7 @@ and change store way to sql maybe? Original license: GPLv3 Original project: https://github.com/LeavesMC/Leaves -Commit: 358d3d232c88d0d089e2bcd2de9f814384572b8b +Commit: 9d32c5bd3df7c76055aff886ed9efda02e45a45a diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index fd956a7c81e4b7407f70dee6a65f973d43f747b2..d877dbabb4e0ee1b167c9f56669ecd5b629b6146 100644 diff --git a/leaf-server/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageExtensionProvider.java b/leaf-server/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageExtensionProvider.java index a0916567..2999e795 100644 --- a/leaf-server/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageExtensionProvider.java +++ b/leaf-server/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageExtensionProvider.java @@ -13,6 +13,7 @@ import net.minecraft.world.entity.vehicle.ContainerEntity; import net.minecraft.world.inventory.PlayerEnderChestContainer; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.ChestBlock; +import net.minecraft.world.level.block.EnderChestBlock; import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; import net.minecraft.world.level.block.entity.ChestBlockEntity; import net.minecraft.world.level.block.entity.EnderChestBlockEntity; @@ -99,6 +100,9 @@ public enum ItemStorageExtensionProvider implements IServerExtensionProvider { return List.of(); } + case EnderChestBlockEntity enderChest when request.getPlayer().getEnderChestInventory().isEmpty() -> { + return List.of(); + } default -> { } } diff --git a/leaf-server/src/main/java/org/leavesmc/leaves/replay/Recorder.java b/leaf-server/src/main/java/org/leavesmc/leaves/replay/Recorder.java index d8ea3495..d1d34793 100644 --- a/leaf-server/src/main/java/org/leavesmc/leaves/replay/Recorder.java +++ b/leaf-server/src/main/java/org/leavesmc/leaves/replay/Recorder.java @@ -46,21 +46,19 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; -import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executor; import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; public class Recorder extends Connection { - private static final LeavesLogger LOGGER = LeavesLogger.LOGGER; + public static final Executor saveService = Executors.newVirtualThreadPerTaskExecutor(); + public static final LeavesLogger LOGGER = LeavesLogger.LOGGER; private final ReplayFile replayFile; private final ServerPhotographer photographer; private final RecorderOption recorderOption; private final RecordMetaData metaData; - private final ExecutorService saveService = Executors.newSingleThreadExecutor(); - private boolean stopped = false; private boolean paused = false; private boolean resumeOnNextPacket = true; @@ -209,7 +207,7 @@ public class Recorder extends Connection { } private void saveMetadata() { - saveService.submit(() -> { + saveService.execute(() -> { try { replayFile.saveMetaData(metaData); } catch (IOException e) { @@ -225,14 +223,7 @@ public class Recorder extends Connection { private void savePacket(Packet packet, final ConnectionProtocol protocol) { try { final long timestamp = getCurrentTimeAndUpdate(); - saveService.submit(() -> { - try { - replayFile.savePacket(timestamp, packet, protocol); - } catch (Exception e) { - LOGGER.severe("Error saving packet"); - e.printStackTrace(); - } - }); + replayFile.savePacket(timestamp, packet, protocol); } catch (Exception e) { LOGGER.severe("Error saving packet"); e.printStackTrace(); @@ -250,13 +241,7 @@ public class Recorder extends Connection { metaData.duration = (int) lastPacket; return CompletableFuture.runAsync(() -> { saveMetadata(); - saveService.shutdown(); boolean interrupted = false; - try { - saveService.awaitTermination(10, TimeUnit.SECONDS); - } catch (InterruptedException e) { - interrupted = true; - } try { if (save) { replayFile.closeAndSave(dest); diff --git a/leaf-server/src/main/java/org/leavesmc/leaves/replay/ReplayFile.java b/leaf-server/src/main/java/org/leavesmc/leaves/replay/ReplayFile.java index 8d96445f..4b1579b1 100644 --- a/leaf-server/src/main/java/org/leavesmc/leaves/replay/ReplayFile.java +++ b/leaf-server/src/main/java/org/leavesmc/leaves/replay/ReplayFile.java @@ -3,6 +3,7 @@ package org.leavesmc.leaves.replay; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import net.minecraft.SharedConstants; import net.minecraft.network.ConnectionProtocol; @@ -37,6 +38,9 @@ import java.util.zip.CRC32; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import static org.leavesmc.leaves.replay.Recorder.LOGGER; +import static org.leavesmc.leaves.replay.Recorder.saveService; + public class ReplayFile { private static final String RECORDING_FILE = "recording.tmcpr"; @@ -93,8 +97,7 @@ public class ReplayFile { protocol.codec().encode(buf, packet); buf.readerIndex(0); - byte[] ret = new byte[buf.readableBytes()]; - buf.readBytes(ret); + byte[] ret = ByteBufUtil.getBytes(buf); buf.release(); return ret; } @@ -118,9 +121,16 @@ public class ReplayFile { public void savePacket(long timestamp, Packet packet, ConnectionProtocol protocol) throws Exception { byte[] data = getPacketBytes(packet, protocol); - packetStream.writeInt((int) timestamp); - packetStream.writeInt(data.length); - packetStream.write(data); + saveService.execute(() -> { + try { + packetStream.writeInt((int) timestamp); + packetStream.writeInt(data.length); + packetStream.write(data); + } catch (Exception e) { + LOGGER.severe("Error saving packet"); + e.printStackTrace(); + } + }); } public synchronized void closeAndSave(File file) throws IOException {