Files
Shiroha/camellia-server/minecraft-patches/features/0043-Add-status-bar.patch
T
2026-07-14 11:32:51 +08:00

349 lines
18 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrHua269 <mrhua269@gmail.com>
Date: Thu, 9 Jul 2026 12:10:04 +0800
Subject: [PATCH] Add status bar
diff --git a/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java b/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java
index 52dcbcf64c3a510d4a4524b7d0ee226d9a73511d..051d601e7e809518e8d82ae4ae3259054d704f51 100644
--- a/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java
+++ b/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java
@@ -122,6 +122,7 @@ public abstract class BaseChunkSystemHooks implements ca.spottedleaf.moonrise.co
@Override
public void onChunkNotTicking(final LevelChunk chunk, final ChunkHolder holder) {
+ chunk.getChunkHot().clear(); // KioCG
chunk.getLevel().getCurrentWorldData().removeTickingChunk(chunk); // Folia - region threading
}
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 4ce5bdd16b04f76c2e98a5465343a82ed5f28ab7..ab8d69fa54203175760d394a5425601073fcd0d9 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -1731,7 +1731,46 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Folia end - region threading
//this.tickCount++; // Folia - region threading
//this.tickRateManager.tick(); // Folia - region threading
+ // KioCG start - ChunkHot
+ final ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet<net.minecraft.world.level.chunk.LevelChunk> chunks = new ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet<>();
+ if (region != null){
+ for (net.minecraft.world.level.chunk.LevelChunk chunk : region.world.getCurrentWorldData().getTickingChunks()) {
+ /* wait for rewrite - temporarily crash fix
+ for (net.minecraft.server.level.ServerChunkCache.ChunkAndHolder chunkAndHolder : region.world.getCurrentWorldData().getTickingChunks()){
+ final net.minecraft.world.level.chunk.LevelChunk chunk = chunkAndHolder.chunk();
+ */
+ if (!ca.spottedleaf.moonrise.common.util.TickThread.isTickThreadFor(region.world, chunk.locX, chunk.locZ)){
+ continue;
+ }
+
+ chunks.add(chunk);
+ }
+ }
+ if (region != null && io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick() % 20 == 0){
+ final java.util.Iterator<net.minecraft.world.level.chunk.LevelChunk> chunkIterator = chunks.unsafeIterator();
+ while (chunkIterator.hasNext()){
+ final net.minecraft.world.level.chunk.LevelChunk targetChunk = chunkIterator.next();
+
+ targetChunk.getChunkHot().nextTick();
+ targetChunk.getChunkHot().start();
+ }
+ }
+ //KioCG end
this.tickChildren(haveTime, region); // Folia - region threading
+ // KioCG start - ChunkHot
+ if (region != null && io.papermc.paper.threadedregions.RegionizedServer.getCurrentTick() % 20 == 0){
+ final java.util.Iterator<net.minecraft.world.level.chunk.LevelChunk> chunkIterator = chunks.unsafeIterator();
+ while (chunkIterator.hasNext()){
+ final net.minecraft.world.level.chunk.LevelChunk targetChunk = chunkIterator.next();
+
+ if (!targetChunk.getChunkHot().isStarted()){
+ continue;
+ }
+
+ targetChunk.getChunkHot().stop();
+ }
+ }
+ //KioCG end
if (false && nano - this.lastServerStatus >= STATUS_EXPIRE_TIME_NANOS) { // Folia - region threading
this.lastServerStatus = nano;
this.status = this.buildServerStatus();
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 1a0e5fbc823c328d16f48f2df4507bf240915c79..bd1368def6c2656902bae28dc07b98f8709107a9 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -1484,6 +1484,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
public void tickNonPassenger(final Entity entity) {
// Paper start - log detailed entity tick information
ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot tick an entity off-main");
+ LevelChunk levelChunk = entity.shouldTickHot() ? this.getChunkIfLoaded(entity.moonrise$getSectionX(),entity.moonrise$getSectionZ()) : null; // KioCG
+ if (levelChunk != null) levelChunk.getChunkHot().startTicking(); try { // KioCG
try {
// Folia - region threading
// Paper end - log detailed entity tick information
@@ -1560,6 +1562,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
} finally {
// Folia - region threading
}
+ } finally { if (levelChunk != null) levelChunk.getChunkHot().stopTickingAndCount(); } // KioCG
// Paper end - log detailed entity tick information
}
@@ -1571,6 +1574,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
final int timerId = isActive ? entity.getType().tickTimerId : entity.getType().inactiveTickTimerId;
final ca.spottedleaf.leafprofiler.RegionizedProfiler.Handle foliaProfiler = io.papermc.paper.threadedregions.TickRegionScheduler.getProfiler();
foliaProfiler.startTimer(timerId);
+ LevelChunk levelChunk = !(entity instanceof Player) ? this.getChunkIfLoaded(entity.blockPosition()) : null; // KioCG
+ if (levelChunk != null) levelChunk.getChunkHot().startTicking(); try { // KioCG
try {
// Folia end - profiler
entity.setOldPosAndRot();
@@ -1612,6 +1617,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
this.tickPassenger(entity, passenger, isActive); // Paper - EAR 2
}
} finally { foliaProfiler.stopTimer(timerId); } // Folia - profiler
+ } finally { if (levelChunk != null) levelChunk.getChunkHot().stopTickingAndCount(); } // KioCG
}
}
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index f22b5fdec6da8bcff9aef3d9fed5dbe61d39250a..336a1ae13810207696a699a936d4031eb904d0dd 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -889,6 +889,9 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@Override
public void tick() {
+ // Shiroha start - Add status bars
+ this.statusBarList.tick();
+ // Shiroha end - Add status bars
// CraftBukkit start
if (this.joining) {
this.joining = false;
@@ -949,7 +952,34 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
this.trackEnteredOrExitedLavaOnVehicle();
this.updatePlayerAttributes();
this.advancements.flushDirty(this, true);
+
+ // KioCG start - ChunkHot
+ if (this.tickCount % 20 == 0){
+ this.nearbyChunkHot = this.refreshNearbyChunkHot();
+ }
+ // KioCG end
+ }
+
+ // KioCG start - ChunkHot
+ private volatile long nearbyChunkHot = 0;
+
+ public long getNearbyChunkHot() { return this.nearbyChunkHot; }
+
+ private long refreshNearbyChunkHot() {
+ long total = 0L;
+ int searchRadius = ((ServerLevel) this.level()).moonrise$getViewDistanceHolder().getViewDistances().tickViewDistance();
+ for (int i = this.moonrise$getSectionX() - searchRadius; i <= this.moonrise$getSectionX() + searchRadius; ++i) {
+ for (int j = this.moonrise$getSectionZ() - searchRadius; j <= this.moonrise$getSectionZ() + searchRadius; ++j) {
+ net.minecraft.world.level.chunk.LevelChunk targetChunk = this.level().getChunkIfLoaded(i, j);
+ if (targetChunk != null) {
+ total += targetChunk.getChunkHot().getAverage();
+ }
+ }
+ }
+ return total;
}
+ // KioCG end
+
private void updatePlayerAttributes() {
AttributeInstance blockInteractionRange = this.getAttribute(Attributes.BLOCK_INTERACTION_RANGE);
diff --git a/net/minecraft/world/entity/AreaEffectCloud.java b/net/minecraft/world/entity/AreaEffectCloud.java
index f03fa06c0ba56f7f5e1e45bc1568a490751efde3..eee1c14249addbf4714df733870da9747bda2245 100644
--- a/net/minecraft/world/entity/AreaEffectCloud.java
+++ b/net/minecraft/world/entity/AreaEffectCloud.java
@@ -415,4 +415,11 @@ public class AreaEffectCloud extends Entity implements TraceableEntity {
return super.applyImplicitComponent(type, value);
}
}
+
+ // KioCG start
+ @Override
+ public boolean shouldTickHot() {
+ return false;
+ }
+ // KioCG end
}
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 5d2f1a90a8e78a95b47c580f6dc4b893dc98f067..18e0572fe28461e57edb13e6ed6f5a0b6b3604c9 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -6347,4 +6347,6 @@ public abstract class Entity
return ((ServerLevel) this.level()).isPositionEntityTicking(this.blockPosition());
}
// Paper end
+
+ public boolean shouldTickHot() { return this.tickCount > 20 * 10 && this.isAlive(); } // KioCG
}
diff --git a/net/minecraft/world/entity/LightningBolt.java b/net/minecraft/world/entity/LightningBolt.java
index 5b19fee8a4861e5dbfb545bbe4dabda7787c430a..0afca6f5f5b02609fd55e9ea4d72b8862cc03420 100644
--- a/net/minecraft/world/entity/LightningBolt.java
+++ b/net/minecraft/world/entity/LightningBolt.java
@@ -283,4 +283,11 @@ public class LightningBolt extends Entity {
public final boolean hurtServer(final ServerLevel level, final DamageSource source, final float damage) {
return false;
}
+
+ // KioCG start
+ @Override
+ public boolean shouldTickHot() {
+ return false;
+ }
+ // KioCG end
}
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
index c6ce88fb63e0d40ed011958a1afd36c645d965c8..3c59325cb82a66a74d6605b51db83ff63e59e089 100644
--- a/net/minecraft/world/entity/Mob.java
+++ b/net/minecraft/world/entity/Mob.java
@@ -1735,4 +1735,11 @@ public abstract class Mob extends LivingEntity implements Targeting, EquipmentUs
public float chargeSpeedModifier() {
return 1.0F;
}
+
+ // KioCG start
+ @Override
+ public boolean shouldTickHot() {
+ return super.shouldTickHot() && (!this.removeWhenFarAway(0.0) || this.isPersistenceRequired() || this.requiresCustomPersistence());
+ }
+ // KioCG end
}
diff --git a/net/minecraft/world/entity/animal/equine/TraderLlama.java b/net/minecraft/world/entity/animal/equine/TraderLlama.java
index 7c92c9335997cee76ff360c51f704ee41a180796..fb4cab83fd23c5561326a58683558e9a4219b0e9 100644
--- a/net/minecraft/world/entity/animal/equine/TraderLlama.java
+++ b/net/minecraft/world/entity/animal/equine/TraderLlama.java
@@ -164,4 +164,11 @@ public class TraderLlama extends Llama {
super.start();
}
}
+
+ // KioCG start
+ @Override
+ public boolean shouldTickHot() {
+ return super.shouldTickHot() && !this.canDespawn();
+ }
+ // KioCG end
}
diff --git a/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java b/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java
index f79353aa58b03d00839e4e95d1fd2480a635a592..0a43947bcc9f505ad9bc4d54c564709c2c3e411a 100644
--- a/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java
+++ b/net/minecraft/world/entity/npc/wanderingtrader/WanderingTrader.java
@@ -271,4 +271,11 @@ public class WanderingTrader extends AbstractVillager implements Consumable.Over
return !pos.closerToCenterThan(this.trader.position(), distance);
}
}
+
+ // KioCG start
+ @Override
+ public boolean shouldTickHot() {
+ return false;
+ }
+ // KioCG end
}
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
index 2eb5fc819e2e17c69de87f8aa1a99e02bc5a62d5..ab0f42c6ed9ba4f920eefba4d1449ded6dda0fe9 100644
--- a/net/minecraft/world/entity/player/Player.java
+++ b/net/minecraft/world/entity/player/Player.java
@@ -170,6 +170,7 @@ public abstract class Player extends Avatar implements ContainerUser {
private ItemStack lastItemInMainHand = ItemStack.EMPTY;
private final ItemCooldowns cooldowns = this.createItemCooldowns();
private Optional<GlobalPos> lastDeathLocation = Optional.empty();
+ public moe.monnairealms.camellia.functions.bars.TickableStatusBarList statusBarList = new moe.monnairealms.camellia.functions.bars.TickableStatusBarList(this); // Shiroha - Add status bars
public @Nullable FishingHook fishing;
public float hurtDir;
public boolean affectsSpawning = true; // Paper - Affects Spawning API
@@ -679,6 +680,7 @@ public abstract class Player extends Avatar implements ContainerUser {
this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(this.abilities.getWalkingSpeed());
this.enderChestInventory.fromSlots(input.listOrEmpty("EnderItems", ItemStackWithSlot.CODEC));
this.setLastDeathLocation(input.read("LastDeathLocation", GlobalPos.CODEC));
+ this.statusBarList.load(input); // Shiroha - Add status bars
}
@Override
@@ -697,6 +699,7 @@ public abstract class Player extends Avatar implements ContainerUser {
output.store("abilities", Abilities.Packed.CODEC, this.abilities.pack());
this.enderChestInventory.storeAsSlots(output.list("EnderItems", ItemStackWithSlot.CODEC));
this.lastDeathLocation.ifPresent(pos -> output.store("LastDeathLocation", GlobalPos.CODEC, pos));
+ this.statusBarList.save(output); // Shiroha - Add status bars
}
@Override
@@ -2255,4 +2258,12 @@ public abstract class Player extends Avatar implements ContainerUser {
public static final Player.BedSleepingProblem NOT_SAFE = new Player.BedSleepingProblem(Component.translatable("block.minecraft.bed.not_safe"));
public static final Player.BedSleepingProblem EXPLOSION = new Player.BedSleepingProblem(null); // Paper - Added to properly handle explosions in bed events
}
+
+ // KioCG start
+ @Override
+ public boolean shouldTickHot() {
+ return false;
+ }
+ // KioCG end
+
}
diff --git a/net/minecraft/world/entity/projectile/Projectile.java b/net/minecraft/world/entity/projectile/Projectile.java
index 67d01bb84cd40a3f67de441e9dbdc2ac7638cada..721e3b083846fd363a31311196bc4c681969215c 100644
--- a/net/minecraft/world/entity/projectile/Projectile.java
+++ b/net/minecraft/world/entity/projectile/Projectile.java
@@ -512,4 +512,11 @@ public abstract class Projectile extends Entity implements TraceableEntity {
public interface ProjectileFactory<T extends Projectile> {
T create(final ServerLevel level, LivingEntity entity, ItemStack itemStack);
}
+
+ // KioCG start
+ @Override
+ public boolean shouldTickHot() {
+ return false;
+ }
+ // KioCG end
}
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
index 64e0c4a60a74cd33f2b99f34fa2a419abf3a0c02..0e84b695a677e71f443a29c78fc5025eec7ae7f4 100644
--- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -112,6 +112,7 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
// Paper start - rewrite chunk system
private boolean postProcessingDone;
private ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder chunkAndHolder;
+ private final com.kiocg.ChunkHot chunkHot = new com.kiocg.ChunkHot(); public com.kiocg.ChunkHot getChunkHot() { return this.chunkHot; } // KioCG
@Override
public final boolean moonrise$isPostProcessingDone() {
@@ -960,6 +961,7 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
ProfilerFiller profiler = Profiler.get();
profiler.push(this::getType);
foliaProfiler.startTimer(timerId); try { // Folia - profiler
+ LevelChunk.this.chunkHot.startTicking(); // KioCG
BlockState blockState = LevelChunk.this.getBlockState(pos);
if (this.blockEntity.getType().isValid(blockState)) {
this.ticker.tick(LevelChunk.this.level, this.blockEntity.getBlockPos(), blockState, this.blockEntity);
@@ -979,7 +981,7 @@ public class LevelChunk extends ChunkAccess implements DebugValueSource, ca.spot
);
} // Paper - Remove the Block Entity if it's invalid
}
- } finally { foliaProfiler.stopTimer(timerId); } // Folia - profiler
+ } finally { foliaProfiler.stopTimer(timerId); LevelChunk.this.chunkHot.stopTickingAndCount(); } // Folia - profiler // KioCG
profiler.pop();
} catch (Throwable t) {
diff --git a/net/minecraft/world/level/redstone/NeighborUpdater.java b/net/minecraft/world/level/redstone/NeighborUpdater.java
index 041ed95948ff6bb4cf3610ce4522a6ba105b6812..44dbe6f83c8593c213132feabc7fe27615cb0049 100644
--- a/net/minecraft/world/level/redstone/NeighborUpdater.java
+++ b/net/minecraft/world/level/redstone/NeighborUpdater.java
@@ -81,7 +81,10 @@ public interface NeighborUpdater {
return;
}
// CraftBukkit end
+ net.minecraft.world.level.chunk.LevelChunk levelChunk = level.getChunkIfLoaded(pos); // KioCG
+ if (levelChunk != null) levelChunk.getChunkHot().startTicking(); try { // KioCG
state.handleNeighborChanged(level, pos, changedBlock, orientation, movedByPiston);
+ } finally { if (levelChunk != null) levelChunk.getChunkHot().stopTickingAndCount(); } // KioCG
// Spigot start
} catch (StackOverflowError ex) {
level.lastPhysicsProblem = pos.immutable();