Compare commits

..

4 Commits

Author SHA1 Message Date
MrHua269
9ba08a6ce6 Removed paper hopper optimizations 2025-02-06 23:19:17 +08:00
Klop233
2274af4415 [ci skip] Update readme 2025-02-05 16:39:22 +08:00
MrHua269
1fe23949f0 Tidy codes 2025-02-05 16:12:51 +08:00
MrHua269
92fb91fb08 Raytracing entity tracker
Based on the framework of EntityCulling(((((((
2025-02-05 15:30:33 +08:00
7 changed files with 1483 additions and 21 deletions

View File

@@ -24,7 +24,7 @@
要构建一个paperclip jar你需要运行以下命令。你可以在build/libs中找到jar注意需要`JDK21`
```shell
./gradlew applyPatches && ./gradlew createMojmapPaperclipJar
./gradlew applyAllPatches && ./gradlew createMojmapPaperclipJar
```
## 使用API

View File

@@ -25,7 +25,7 @@ Any versions are available in the [release](https://github.com/LuminolMC/Luminol
To build a paperclip jar, you need to run the following command. You can find the jar in build/libs(Note: JDK21 is needed)
```shell
./gradlew applyPatches && ./gradlew createMojmapPaperclipJar
./gradlew applyAllPatches && ./gradlew createMojmapPaperclipJar
```
## Using API

View File

@@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Sun, 12 Jan 2025 11:03:09 +0800
Subject: [PATCH] Merge Paper #11945 for temporary hopper behavior fix
A hopper optimization fix on Paper's pr : https://github.com/PaperMC/Paper/pull/11945
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
index ae988c4910421fb720177178ef6136e595ae6946..72a81e29be6570fb119b159210453a86f003f893 100644
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
@@ -698,6 +698,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
} else if (canMergeItems(item, stack)) {
int i = Math.min(stack.getMaxStackSize(), destination.getMaxStackSize()) - item.getCount(); // Paper - Make hoppers respect inventory max stack size
int min = Math.min(stack.getCount(), i);
+ stack = stack.copy(true); // Luminol
stack.shrink(min);
item.grow(min);
flag = min > 0;

View File

@@ -0,0 +1,280 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Thu, 6 Feb 2025 23:15:04 +0800
Subject: [PATCH] Removed paper hopper optimizations
diff --git a/net/minecraft/world/level/block/entity/BlockEntity.java b/net/minecraft/world/level/block/entity/BlockEntity.java
index 003e9db957023486278679803b313ce89d573587..2ce2f94e53a8e9cb4240ab1102b30b4fa07c92dc 100644
--- a/net/minecraft/world/level/block/entity/BlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BlockEntity.java
@@ -203,7 +203,7 @@ public abstract class BlockEntity {
public void setChanged() {
if (this.level != null) {
- if (IGNORE_TILE_UPDATES.get().booleanValue()) return; // Paper - Perf: Optimize Hoppers // Folia - region threading
+ //if (IGNORE_TILE_UPDATES.get().booleanValue()) return; // Paper - Perf: Optimize Hoppers // Folia - region threading // Luminol - Disable paper hooper optimizations
setChanged(this.level, this.worldPosition, this.blockState);
}
}
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
index ae988c4910421fb720177178ef6136e595ae6946..17c1bf710e6cb2ac0a6f41b6ec85e98e253d25e5 100644
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
@@ -298,9 +298,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
origItemStack.setCount(originalItemCount - movedItemCount + remainingItemCount);
}
- IGNORE_TILE_UPDATES.set(true); // Folia - region threading
+ //IGNORE_TILE_UPDATES.set(true); // Folia - region threading // Luminol - Disable paper hooper optimizations
container.setItem(i, origItemStack);
- IGNORE_TILE_UPDATES.set(false); // Folia - region threading
+ //IGNORE_TILE_UPDATES.set(false); // Folia - region threading // Luminol - Disable paper hooper optimizations
container.setChanged();
return true;
}
@@ -433,58 +433,60 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
return false;
} else {
// Paper start - Perf: Optimize Hoppers
- return hopperPush(level, attachedContainer, opposite, blockEntity);
- //for (int i = 0; i < blockEntity.getContainerSize(); i++) {
- // ItemStack item = blockEntity.getItem(i);
- // if (!item.isEmpty()) {
- // int count = item.getCount();
- // // CraftBukkit start - Call event when pushing items into other inventories
- // ItemStack original = item.copy();
- // org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(
- // blockEntity.removeItem(i, level.spigotConfig.hopperAmount)
- // ); // Spigot
-
- // org.bukkit.inventory.Inventory destinationInventory;
- // // Have to special case large chests as they work oddly
- // if (attachedContainer instanceof final net.minecraft.world.CompoundContainer compoundContainer) {
- // destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest(compoundContainer);
- // } else if (attachedContainer.getOwner() != null) {
- // destinationInventory = attachedContainer.getOwner().getInventory();
- // } else {
- // destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventory(attachedContainer);
- // }
-
- // org.bukkit.event.inventory.InventoryMoveItemEvent event = new org.bukkit.event.inventory.InventoryMoveItemEvent(
- // blockEntity.getOwner().getInventory(),
- // oitemstack,
- // destinationInventory,
- // true
- // );
- // if (!event.callEvent()) {
- // blockEntity.setItem(i, original);
- // blockEntity.setCooldown(level.spigotConfig.hopperTransfer); // Delay hopper checks // Spigot
- // return false;
- // }
- // int origCount = event.getItem().getAmount(); // Spigot
- // ItemStack itemStack = HopperBlockEntity.addItem(blockEntity, attachedContainer, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem()), opposite);
- // // CraftBukkit end
-
- // if (itemStack.isEmpty()) {
- // attachedContainer.setChanged();
- // return true;
- // }
-
- // item.setCount(count);
- // // Spigot start
- // item.shrink(origCount - itemStack.getCount());
- // if (count <= level.spigotConfig.hopperAmount) {
- // // Spigot end
- // blockEntity.setItem(i, item);
- // }
- // }
- //}
-
- //return false;
+ //return hopperPush(level, attachedContainer, opposite, blockEntity); // Luminol - Disable paper hopper optimization
+ // Luminol start - Disable paper hopper optimization
+ for (int i = 0; i < blockEntity.getContainerSize(); i++) {
+ ItemStack item = blockEntity.getItem(i);
+ if (!item.isEmpty()) {
+ int count = item.getCount();
+ // CraftBukkit start - Call event when pushing items into other inventories
+ ItemStack original = item.copy();
+ org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(
+ blockEntity.removeItem(i, level.spigotConfig.hopperAmount)
+ ); // Spigot
+
+ org.bukkit.inventory.Inventory destinationInventory;
+ // Have to special case large chests as they work oddly
+ if (attachedContainer instanceof final net.minecraft.world.CompoundContainer compoundContainer) {
+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest(compoundContainer);
+ } else if (attachedContainer.getOwner() != null) {
+ destinationInventory = attachedContainer.getOwner().getInventory();
+ } else {
+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventory(attachedContainer);
+ }
+
+ org.bukkit.event.inventory.InventoryMoveItemEvent event = new org.bukkit.event.inventory.InventoryMoveItemEvent(
+ blockEntity.getOwner().getInventory(),
+ oitemstack,
+ destinationInventory,
+ true
+ );
+ if (!event.callEvent()) {
+ blockEntity.setItem(i, original);
+ blockEntity.setCooldown(level.spigotConfig.hopperTransfer); // Delay hopper checks // Spigot
+ return false;
+ }
+ int origCount = event.getItem().getAmount(); // Spigot
+ ItemStack itemStack = HopperBlockEntity.addItem(blockEntity, attachedContainer, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem()), opposite);
+ // CraftBukkit end
+
+ if (itemStack.isEmpty()) {
+ attachedContainer.setChanged();
+ return true;
+ }
+
+ item.setCount(count);
+ // Spigot start
+ item.shrink(origCount - itemStack.getCount());
+ if (count <= level.spigotConfig.hopperAmount) {
+ // Spigot end
+ blockEntity.setItem(i, item);
+ }
+ }
+ }
+
+ return false;
+ // Luminol end
// Paper end - Perf: Optimize Hoppers
}
}
@@ -568,57 +570,59 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
ItemStack item = container.getItem(slot);
if (!item.isEmpty() && canTakeItemFromContainer(hopper, container, item, slot, direction)) {
// Paper start - Perf: Optimize Hoppers
- return hopperPull(level, hopper, container, item, slot);
- //int count = item.getCount();
- //// CraftBukkit start - Call event on collection of items from inventories into the hopper
- //ItemStack original = item.copy();
- //org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(
- // container.removeItem(slot, level.spigotConfig.hopperAmount) // Spigot
- //);
-
- //org.bukkit.inventory.Inventory sourceInventory;
- //// Have to special case large chests as they work oddly
- //if (container instanceof final net.minecraft.world.CompoundContainer compoundContainer) {
- // sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest(compoundContainer);
- //} else if (container.getOwner() != null) {
- // sourceInventory = container.getOwner().getInventory();
- //} else {
- // sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventory(container);
- //}
-
- //org.bukkit.event.inventory.InventoryMoveItemEvent event = new org.bukkit.event.inventory.InventoryMoveItemEvent(
- // sourceInventory,
- // oitemstack,
- // hopper.getOwner().getInventory(),
- // false
- //);
-
- //if (!event.callEvent()) {
- // container.setItem(slot, original);
-
- // if (hopper instanceof final HopperBlockEntity hopperBlockEntity) {
- // hopperBlockEntity.setCooldown(level.spigotConfig.hopperTransfer); // Spigot
- // }
-
- // return false;
- //}
- //int origCount = event.getItem().getAmount(); // Spigot
- //ItemStack itemStack = HopperBlockEntity.addItem(container, hopper, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem()), null);
- //// CraftBukkit end
-
- //if (itemStack.isEmpty()) {
- // container.setChanged();
- // return true;
- //}
-
- //item.setCount(count);
- //// Spigot start
- //item.shrink(origCount - itemStack.getCount());
- //if (count <= level.spigotConfig.hopperAmount) {
- // // Spigot end
- // container.setItem(slot, item);
- //}
- // Paper end - Perf: Optimize Hoppers
+ //return hopperPull(level, hopper, container, item, slot); // Luminol - Disable paper hooper optimizations
+ // Luminol start - Disable paper hooper optimizations
+ int count = item.getCount();
+ // CraftBukkit start - Call event on collection of items from inventories into the hopper
+ ItemStack original = item.copy();
+ org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(
+ container.removeItem(slot, level.spigotConfig.hopperAmount) // Spigot
+ );
+
+ org.bukkit.inventory.Inventory sourceInventory;
+ // Have to special case large chests as they work oddly
+ if (container instanceof final net.minecraft.world.CompoundContainer compoundContainer) {
+ sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest(compoundContainer);
+ } else if (container.getOwner() != null) {
+ sourceInventory = container.getOwner().getInventory();
+ } else {
+ sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventory(container);
+ }
+
+ org.bukkit.event.inventory.InventoryMoveItemEvent event = new org.bukkit.event.inventory.InventoryMoveItemEvent(
+ sourceInventory,
+ oitemstack,
+ hopper.getOwner().getInventory(),
+ false
+ );
+
+ if (!event.callEvent()) {
+ container.setItem(slot, original);
+
+ if (hopper instanceof final HopperBlockEntity hopperBlockEntity) {
+ hopperBlockEntity.setCooldown(level.spigotConfig.hopperTransfer); // Spigot
+ }
+
+ return false;
+ }
+ int origCount = event.getItem().getAmount(); // Spigot
+ ItemStack itemStack = HopperBlockEntity.addItem(container, hopper, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem()), null);
+ // CraftBukkit end
+
+ if (itemStack.isEmpty()) {
+ container.setChanged();
+ return true;
+ }
+
+ item.setCount(count);
+ // Spigot start
+ item.shrink(origCount - itemStack.getCount());
+ if (count <= level.spigotConfig.hopperAmount) {
+ // Spigot end
+ container.setItem(slot, item);
+ }
+ // Luminol end
+ //Paper end - Perf: Optimize Hoppers
}
return false;
@@ -690,9 +694,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
stack = stack.split(destination.getMaxStackSize());
}
// Spigot end
- IGNORE_TILE_UPDATES.set(Boolean.TRUE); // Paper - Perf: Optimize Hoppers // Folia - region threading
+ //IGNORE_TILE_UPDATES.set(Boolean.TRUE); // Paper - Perf: Optimize Hoppers // Folia - region threading // Luminol - Disable paper hooper optimizations
destination.setItem(slot, stack);
- IGNORE_TILE_UPDATES.set(Boolean.FALSE); // Paper - Perf: Optimize Hoppers // Folia - region threading
+ //IGNORE_TILE_UPDATES.set(Boolean.FALSE); // Paper - Perf: Optimize Hoppers // Folia - region threading // Luminol - Disable paper hooper optimizations
stack = leftover; // Paper - Make hoppers respect inventory max stack size
flag = true;
} else if (canMergeItems(item, stack)) {
@@ -780,7 +784,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
@Nullable
public static Container getContainerAt(Level level, BlockPos pos) {
- return getContainerAt(level, pos, level.getBlockState(pos), pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, true); // Paper - Optimize hoppers
+ return getContainerAt(level, pos, level.getBlockState(pos), pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, false); // Paper - Optimize hoppers // Luminol - Disable paper hooper optimizations
}
@Nullable

View File

@@ -0,0 +1,159 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <wangxyper@163.com>
Date: Wed, 5 Feb 2025 15:22:19 +0800
Subject: [PATCH] Raytracing tracker experiment
Based on the framework of EntityCulling(((((((
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
index 7eff847790394aecd058e7a61905da86163b4c6e..9099457f55a2829297ac1db8a69a98ff717d9a86 100644
--- a/net/minecraft/server/level/ChunkMap.java
+++ b/net/minecraft/server/level/ChunkMap.java
@@ -1208,7 +1208,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
double d1 = vec3_dx * vec3_dx + vec3_dz * vec3_dz; // Paper
double d2 = d * d;
// Paper start - Configurable entity tracking range by Y
- boolean flag = d1 <= d2;
+ boolean flag = d1 <= d2 && !entity.isCulled(); // Luminol - Ray tracing entity tracker
if (flag && level.paperConfig().entities.trackingRangeY.enabled) {
double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1);
if (rangeY != -1) {
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 6f9cfd8c72853d9cb30c9731a96e7f1e8f0644c4..b1ded501047f75d2e7af775bf8866fd6a5400a91 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -136,7 +136,7 @@ import net.minecraft.world.scores.ScoreHolder;
import net.minecraft.world.scores.Team;
import org.slf4j.Logger;
-public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder, ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity, ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity { // Paper - rewrite chunk system // Paper - optimise entity tracker
+public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder, ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity, ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity, dev.tr7zw.entityculling.versionless.access.Cullable { // Paper - rewrite chunk system // Paper - optimise entity tracker // Luminol - Ray tracing entity tracker
// CraftBukkit start
private static final int CURRENT_LEVEL = 2;
@@ -6050,4 +6050,46 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
// Paper end - Expose entity id counter
public boolean shouldTickHot() { return this.tickCount > 20 * 10 && this.isAlive(); } // KioCG
+
+ private long lasttime = 0;
+ private boolean culled = false;
+ private boolean outOfCamera = false;
+
+ @Override
+ public void setTimeout() {
+ this.lasttime = System.currentTimeMillis() + 1000;
+ }
+
+ @Override
+ public boolean isForcedVisible() {
+ return this.lasttime > System.currentTimeMillis();
+ }
+
+ @Override
+ public void setCulled(boolean value) {
+ this.culled = value;
+ if (!value) {
+ setTimeout();
+ }
+ }
+
+ @Override
+ public boolean isCulled() {
+ if (!me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.enabled)
+ return false;
+ return this.culled;
+ }
+
+ @Override
+ public void setOutOfCamera(boolean value) {
+ this.outOfCamera = value;
+ }
+
+ @Override
+ public boolean isOutOfCamera() {
+ if (!me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.enabled)
+ return false;
+ return this.outOfCamera;
+ }
+
}
diff --git a/net/minecraft/world/entity/EntityType.java b/net/minecraft/world/entity/EntityType.java
index d9cc1d7e56c37d5ce92544edc10e89dbc89dd15d..39e7689be243b9c99b507d665f6591359115287b 100644
--- a/net/minecraft/world/entity/EntityType.java
+++ b/net/minecraft/world/entity/EntityType.java
@@ -1097,6 +1097,9 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
public final int passengerTickTimerId;
public final int passengerInactiveTickTimerId;
// Folia end - profiler
+ // Luminol - Raytracing entity tracker
+ public boolean skipRaytracningCheck = false;
+ // Luminol end
public EntityType(
EntityType.EntityFactory<T> factory,
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
index 0e020dfebe06dce4c19beb10c961ea9e8a35a415..49f927c20b84e47ed2b0e57beecb3aa746448f5a 100644
--- a/net/minecraft/world/entity/player/Player.java
+++ b/net/minecraft/world/entity/player/Player.java
@@ -210,6 +210,25 @@ public abstract class Player extends LivingEntity {
return (org.bukkit.craftbukkit.entity.CraftHumanEntity) super.getBukkitEntity();
}
// CraftBukkit end
+ // Luminol start - Raytracing entity tracker
+ public dev.tr7zw.entityculling.CullTask cullTask;
+ {
+ if (!me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.enabled) {
+ this.cullTask = null;
+ }else {
+ final com.logisticscraft.occlusionculling.OcclusionCullingInstance culling = new com.logisticscraft.occlusionculling.OcclusionCullingInstance(
+ me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.tracingDistance,
+ new dev.tr7zw.entityculling.DefaultChunkDataProvider(this.level())
+ );
+
+ this.cullTask = new dev.tr7zw.entityculling.CullTask(
+ culling, this,
+ me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.hitboxLimit,
+ me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.checkIntervalMs
+ );
+ }
+ }
+ // Luminol end
public Player(Level level, BlockPos pos, float yRot, GameProfile gameProfile) {
super(EntityType.PLAYER, level);
@@ -262,6 +281,26 @@ public abstract class Player extends LivingEntity {
@Override
public void tick() {
+ // Luminol start - Ray tracing entity tracker
+ if (!me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.enabled) {
+ if (this.cullTask != null) this.cullTask.signalStop();
+ this.cullTask = null;
+ }else {
+ final com.logisticscraft.occlusionculling.OcclusionCullingInstance culling = new com.logisticscraft.occlusionculling.OcclusionCullingInstance(
+ me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.tracingDistance,
+ new dev.tr7zw.entityculling.DefaultChunkDataProvider(this.level())
+ );
+
+ this.cullTask = new dev.tr7zw.entityculling.CullTask(
+ culling, this,
+ me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.hitboxLimit,
+ me.earthme.luminol.config.modules.experiment.RayTrackingEntityTrackerConfig.checkIntervalMs
+ );
+ }
+ if (this.cullTask != null) this.cullTask.setup();
+ if (this.cullTask != null) this.cullTask.requestCullSignal(); // Luminol - Ray tracing entity tracker
+ // Luminol end
+
this.noPhysics = this.isSpectator();
if (this.isSpectator() || this.isPassenger()) {
this.setOnGround(false);
@@ -1502,6 +1541,7 @@ public abstract class Player extends LivingEntity {
if (this.containerMenu != null && this.hasContainerOpen()) {
this.doCloseContainer();
}
+ if (this.cullTask != null) this.cullTask.signalStop(); // Luminol - Ray tracing entity tracker
}
// Folia start - region threading

File diff suppressed because it is too large Load Diff