Compare commits
3
Commits
1192f2e674
...
2edb70257d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2edb70257d | ||
|
|
c9f8dd4595 | ||
|
|
9eb5c767ed |
+45
-43
@@ -1,15 +1,17 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
From: MrHua269 <mrhua269@gmail.com>
|
From: NanaChiyo0721 <nanachiyo0721@163.com>
|
||||||
Date: Thu, 9 Jul 2026 11:54:24 +0800
|
Date: Mon, 17 Aug 2026 23:38:00 +0800
|
||||||
Subject: [PATCH] Leaves Vanilla Hopper
|
Subject: [PATCH] Leaves: Vanilla hopper
|
||||||
|
|
||||||
A part from leaves
|
Co-Authored-By: Creeam <102713261+HaHaWTH@users.noreply.github.com>
|
||||||
|
|
||||||
Origin patch link: https://github.com/LeavesMC/Leaves/blob/master/leaves-server/minecraft-patches/features/0092-Vanilla-hopper.patch
|
Original license: GPL-3.0-only
|
||||||
Origin license: https://github.com/LeavesMC/Leaves/blob/master/LICENSE.md
|
Original project: https://github.com/LeavesMC/Leaves
|
||||||
|
|
||||||
|
This is a temporary solution designed to attempt to restore the vanilla behavior of the funnel while preserving optimizations as much as possible. It should ultimately be replaced by the optimization solution provided by lithium.
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||||
index a858cb658af70f07614fa1f4d9e8a3435d5c161f..95f0b3276137cb9d1fc296e97cc25a08a5200c95 100644
|
index a858cb658af70f07614fa1f4d9e8a3435d5c161f..9f7f8edaf3261cc0377dab33404ca1d30c548ff9 100644
|
||||||
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||||
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||||
@@ -281,36 +281,67 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
@@ -281,36 +281,67 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||||
@@ -18,7 +20,25 @@ index a858cb658af70f07614fa1f4d9e8a3435d5c161f..95f0b3276137cb9d1fc296e97cc25a08
|
|||||||
final int movedItemCount = Math.min(level.spigotConfig.hopperAmount, originalItemCount);
|
final int movedItemCount = Math.min(level.spigotConfig.hopperAmount, originalItemCount);
|
||||||
- container.setChanged(); // original logic always marks source inv as changed even if no move happens.
|
- container.setChanged(); // original logic always marks source inv as changed even if no move happens.
|
||||||
- movedItem.setCount(movedItemCount);
|
- movedItem.setCount(movedItemCount);
|
||||||
-
|
+ // Leaves start - Vanilla hopper
|
||||||
|
+ if (org.dreeam.leaf.config.modules.gameplay.VanillaHopper.enabled && movedItemCount == 1) {
|
||||||
|
+ movedItem.setCount(movedItemCount);
|
||||||
|
+ container.setChanged();
|
||||||
|
+ if (!skipPullModeEventFire) {
|
||||||
|
+ movedItem = callPullMoveEvent(hopper, container, movedItem);
|
||||||
|
+ if (movedItem == null) { // cancelled
|
||||||
|
+ origItemStack.setCount(originalItemCount);
|
||||||
|
+ // Drastically improve performance by returning true.
|
||||||
|
+ // No plugin could have relied on the behavior of false as the other call
|
||||||
|
+ // site for IMIE did not exhibit the same behavior
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ final boolean removeOriginalItem = movedItem == origItemStack;
|
||||||
|
+ if (removeOriginalItem) {
|
||||||
|
+ movedItem = container.removeItem(i, movedItemCount);
|
||||||
|
+ }
|
||||||
|
|
||||||
- if (!worldData.skipPullModeEventFire) { // Folia - region threading
|
- if (!worldData.skipPullModeEventFire) { // Folia - region threading
|
||||||
- movedItem = callPullMoveEvent(hopper, container, movedItem);
|
- movedItem = callPullMoveEvent(hopper, container, movedItem);
|
||||||
- if (movedItem == null) { // cancelled
|
- if (movedItem == null) { // cancelled
|
||||||
@@ -26,21 +46,11 @@ index a858cb658af70f07614fa1f4d9e8a3435d5c161f..95f0b3276137cb9d1fc296e97cc25a08
|
|||||||
- // Drastically improve performance by returning true.
|
- // Drastically improve performance by returning true.
|
||||||
- // No plugin could have relied on the behavior of false as the other call
|
- // No plugin could have relied on the behavior of false as the other call
|
||||||
- // site for IMIE did not exhibit the same behavior
|
- // site for IMIE did not exhibit the same behavior
|
||||||
+ // Leaves start - fix vanilla hopper
|
+ final int itemCountToMove = movedItem.getCount();
|
||||||
+ if (movedItem.getCount() <= movedItemCount) {
|
+ final ItemStack remainingItem = addItem(container, hopper, movedItem, null);
|
||||||
+ if (!worldData.skipPullModeEventFire) {
|
+ if (remainingItem.getCount() != itemCountToMove) {
|
||||||
+ movedItem = callPullMoveEvent(hopper, container, movedItem);
|
+ origItemStack.setCount(removeOriginalItem ? originalItemCount - movedItemCount : originalItemCount);
|
||||||
+ if (movedItem == null) { // cancelled
|
+ container.setItem(i, origItemStack);
|
||||||
+ origItemStack.setCount(originalItemCount);
|
|
||||||
+ container.setChanged(); // keep parity with vanilla: source inv always marked changed
|
|
||||||
+ return true;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ final int toRemove = Math.min(movedItem.getCount(), container.getItem(i).getCount());
|
|
||||||
+ final ItemStack remainingItem = addItem(container, hopper, container.removeItem(i, toRemove), null);
|
|
||||||
+ final int remainingItemCount = remainingItem.getCount();
|
|
||||||
+ if (remainingItem.isEmpty()) {
|
|
||||||
+ container.setChanged();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
- }
|
- }
|
||||||
@@ -49,23 +59,10 @@ index a858cb658af70f07614fa1f4d9e8a3435d5c161f..95f0b3276137cb9d1fc296e97cc25a08
|
|||||||
- final int remainingItemCount = remainingItem.getCount();
|
- final int remainingItemCount = remainingItem.getCount();
|
||||||
- if (remainingItemCount != movedItemCount) {
|
- if (remainingItemCount != movedItemCount) {
|
||||||
- origItemStack = origItemStack.copy(true);
|
- origItemStack = origItemStack.copy(true);
|
||||||
- origItemStack.setCount(originalItemCount);
|
origItemStack.setCount(originalItemCount);
|
||||||
- if (!origItemStack.isEmpty()) {
|
- if (!origItemStack.isEmpty()) {
|
||||||
- origItemStack.setCount(originalItemCount - movedItemCount + remainingItemCount);
|
- origItemStack.setCount(originalItemCount - movedItemCount + remainingItemCount);
|
||||||
+ if (remainingItemCount != toRemove) {
|
+ container.setItem(i, origItemStack);
|
||||||
+ IGNORE_TILE_UPDATES.set(true); // Folia - region threading
|
|
||||||
+ container.setItem(i, remainingItem);
|
|
||||||
+ IGNORE_TILE_UPDATES.set(false); // Folia - region threading
|
|
||||||
+ container.setChanged();
|
|
||||||
+ return true;
|
|
||||||
}
|
|
||||||
-
|
|
||||||
IGNORE_TILE_UPDATES.set(true); // Folia - region threading
|
|
||||||
- container.setItem(i, origItemStack);
|
|
||||||
+ container.setItem(i, remainingItem);
|
|
||||||
IGNORE_TILE_UPDATES.set(false); // Folia - region threading
|
|
||||||
container.setChanged();
|
|
||||||
- return true;
|
|
||||||
+ } else {
|
+ } else {
|
||||||
+ container.setChanged(); // original logic always marks source inv as changed even if no move happens.
|
+ container.setChanged(); // original logic always marks source inv as changed even if no move happens.
|
||||||
+ movedItem.setCount(movedItemCount);
|
+ movedItem.setCount(movedItemCount);
|
||||||
@@ -79,8 +76,13 @@ index a858cb658af70f07614fa1f4d9e8a3435d5c161f..95f0b3276137cb9d1fc296e97cc25a08
|
|||||||
+ // site for IMIE did not exhibit the same behavior
|
+ // site for IMIE did not exhibit the same behavior
|
||||||
+ return true;
|
+ return true;
|
||||||
+ }
|
+ }
|
||||||
+ }
|
}
|
||||||
+
|
|
||||||
|
- IGNORE_TILE_UPDATES.set(true); // Folia - region threading
|
||||||
|
- container.setItem(i, origItemStack);
|
||||||
|
- IGNORE_TILE_UPDATES.set(false); // Folia - region threading
|
||||||
|
- container.setChanged();
|
||||||
|
- return true;
|
||||||
+ final ItemStack remainingItem = addItem(container, hopper, movedItem, null);
|
+ final ItemStack remainingItem = addItem(container, hopper, movedItem, null);
|
||||||
+ final int remainingItemCount = remainingItem.getCount();
|
+ final int remainingItemCount = remainingItem.getCount();
|
||||||
+ if (remainingItemCount != movedItemCount) {
|
+ if (remainingItemCount != movedItemCount) {
|
||||||
@@ -90,16 +92,16 @@ index a858cb658af70f07614fa1f4d9e8a3435d5c161f..95f0b3276137cb9d1fc296e97cc25a08
|
|||||||
+ origItemStack.setCount(originalItemCount - movedItemCount + remainingItemCount);
|
+ origItemStack.setCount(originalItemCount - movedItemCount + remainingItemCount);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ IGNORE_TILE_UPDATES.set(true);
|
+ IGNORE_TILE_UPDATES.set(true); // Folia - region threading
|
||||||
+ container.setItem(i, origItemStack);
|
+ container.setItem(i, origItemStack);
|
||||||
+ IGNORE_TILE_UPDATES.set(false);
|
+ IGNORE_TILE_UPDATES.set(false); // Folia - region threading
|
||||||
+ container.setChanged();
|
+ container.setChanged();
|
||||||
+ return true;
|
+ return true;
|
||||||
+ }
|
+ }
|
||||||
+ origItemStack.setCount(originalItemCount);
|
+ origItemStack.setCount(originalItemCount);
|
||||||
}
|
}
|
||||||
- origItemStack.setCount(originalItemCount);
|
- origItemStack.setCount(originalItemCount);
|
||||||
+ // Leaves end - fix vanilla hopper
|
+ // Leaves end - Vanilla hopper
|
||||||
|
|
||||||
if (level.paperConfig().hopper.cooldownWhenFull) {
|
if (level.paperConfig().hopper.cooldownWhenFull) {
|
||||||
applyCooldown(hopper);
|
applyCooldown(hopper);
|
||||||
+1
-1
@@ -1573,7 +1573,7 @@ index 6109d8da984b398bb1eb6cd6ab9a55f0511a615c..d3d6b3aeb24da7f3bf92c327095a9dc9
|
|||||||
+ // Leaves end - Lithium Sleeping Block Entity
|
+ // Leaves end - Lithium Sleeping Block Entity
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||||
index 95f0b3276137cb9d1fc296e97cc25a08a5200c95..26afe1f74b50b60d6c04e08967610a3d50183483 100644
|
index 9f7f8edaf3261cc0377dab33404ca1d30c548ff9..6dea8c7354708db69406575a03bf847e3e0b1194 100644
|
||||||
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||||
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||||
@@ -27,8 +27,29 @@ import net.minecraft.world.level.storage.ValueInput;
|
@@ -27,8 +27,29 @@ import net.minecraft.world.level.storage.ValueInput;
|
||||||
|
|||||||
+4
-4
@@ -96,22 +96,22 @@ public class CpuAffinityConfig implements IConfigModule {
|
|||||||
|
|
||||||
if (enabledForTickRegion) {
|
if (enabledForTickRegion) {
|
||||||
tickRegionRunnableWrapper = new AffinityRunnableWrapper("tick_region", parseAffinity(tickRegionAffinity));
|
tickRegionRunnableWrapper = new AffinityRunnableWrapper("tick_region", parseAffinity(tickRegionAffinity));
|
||||||
LOGGER.info("Tick region thread now bound to: {}", tickRegionRunnableWrapper.getAffinity());
|
LOGGER.info("Tick region thread now bound to: {}", tickRegionRunnableWrapper.affinity());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enabledForChunkSystemIo) {
|
if (enabledForChunkSystemIo) {
|
||||||
chunkSystemIoRunnableWrapper = new AffinityRunnableWrapper("chunk_system_io", parseAffinity(chunkSystemIoAffinity));
|
chunkSystemIoRunnableWrapper = new AffinityRunnableWrapper("chunk_system_io", parseAffinity(chunkSystemIoAffinity));
|
||||||
LOGGER.info("Chunk system I/O thread now bound to: {}", chunkSystemIoRunnableWrapper.getAffinity());
|
LOGGER.info("Chunk system I/O thread now bound to: {}", chunkSystemIoRunnableWrapper.affinity());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enabledForChunkSystemWorker) {
|
if (enabledForChunkSystemWorker) {
|
||||||
chunkSystemWorkerRunnableWrapper = new AffinityRunnableWrapper("chunk_system_worker", parseAffinity(chunkSystemWorkerAffinity));
|
chunkSystemWorkerRunnableWrapper = new AffinityRunnableWrapper("chunk_system_worker", parseAffinity(chunkSystemWorkerAffinity));
|
||||||
LOGGER.info("Chunk system worker thread now bound to: {}", chunkSystemWorkerRunnableWrapper.getAffinity());
|
LOGGER.info("Chunk system worker thread now bound to: {}", chunkSystemWorkerRunnableWrapper.affinity());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enableForNettyIo) {
|
if (enableForNettyIo) {
|
||||||
nettyIoRunnableWrapper = new AffinityRunnableWrapper("netty_io", parseAffinity(nettyIoAffinity));
|
nettyIoRunnableWrapper = new AffinityRunnableWrapper("netty_io", parseAffinity(nettyIoAffinity));
|
||||||
LOGGER.info("Netty I/O thread now bound to: {}", nettyIoRunnableWrapper.getAffinity());
|
LOGGER.info("Netty I/O thread now bound to: {}", nettyIoRunnableWrapper.affinity());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-10
@@ -5,14 +5,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
|
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
|
|
||||||
public class AffinityRunnableWrapper {
|
public record AffinityRunnableWrapper(String name, BitSet affinity) {
|
||||||
private final BitSet affinity;
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
public AffinityRunnableWrapper(String name, BitSet affinity) {
|
|
||||||
this.name = name;
|
|
||||||
this.affinity = affinity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Runnable wrap(Runnable original) {
|
public Runnable wrap(Runnable original) {
|
||||||
return () -> {
|
return () -> {
|
||||||
@@ -22,13 +15,15 @@ public class AffinityRunnableWrapper {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public String getName() {
|
public String name() {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public BitSet getAffinity() {
|
public BitSet affinity() {
|
||||||
return this.affinity;
|
return this.affinity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import java.util.jar.JarEntry;
|
|||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
|
|
||||||
public class ClassScanUtil {
|
public class ClassScanUtil {
|
||||||
public static @NotNull Collection<Class<?>> scanClassesUnder(String packag3, ClassLoader loader) {
|
public static @NotNull Collection<Class<?>> scanClassesUnder(@NonNull String packag3, @NonNull ClassLoader loader) {
|
||||||
Set<Class<?>> classes = new HashSet<>();
|
Set<Class<?>> classes = new HashSet<>();
|
||||||
String packageDirName = packag3.replace('.', '/');
|
String packageDirName = packag3.replace('.', '/');
|
||||||
Enumeration<URL> dirs;
|
Enumeration<URL> dirs;
|
||||||
|
|||||||
Reference in New Issue
Block a user