diff --git a/divinemc-server/minecraft-patches/features/0039-Leaf-Optimize-Connection.flushQueue.patch b/divinemc-server/minecraft-patches/features/0039-Leaf-Optimize-Connection.flushQueue.patch deleted file mode 100644 index aaf0b4e..0000000 --- a/divinemc-server/minecraft-patches/features/0039-Leaf-Optimize-Connection.flushQueue.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> -Date: Mon, 3 Mar 2025 19:57:47 +0300 -Subject: [PATCH] Leaf: Optimize Connection.flushQueue - -Original author - Taiyou06 -Original patch - https://github.com/Winds-Studio/Leaf/pull/235 - -diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java -index 00a82873d226f113278632a53c0faca420dd67d4..332f33dcdd337397c06ce8ace97d048942e321af 100644 ---- a/net/minecraft/network/Connection.java -+++ b/net/minecraft/network/Connection.java -@@ -85,7 +85,11 @@ public class Connection extends SimpleChannelInboundHandler> { - private static final ProtocolInfo INITIAL_PROTOCOL = HandshakeProtocols.SERVERBOUND; - private final PacketFlow receiving; - private volatile boolean sendLoginDisconnect = true; -- private final Queue pendingActions = Queues.newConcurrentLinkedQueue(); // Paper - Optimize network -+ // DivineMC start - Optimize Connection.flushQueue -+ private final Queue pendingActions = org.bxteam.divinemc.DivineConfig.connectionFlushQueueRewrite -+ ? new java.util.ArrayDeque<>() -+ : Queues.newConcurrentLinkedQueue(); // Paper - Optimize network -+ // DivineMC end - Optimize Connection.flushQueue - public Channel channel; - public SocketAddress address; - // Spigot start -@@ -325,6 +329,7 @@ public class Connection extends SimpleChannelInboundHandler> { - - private static void syncAfterConfigurationChange(ChannelFuture future) { - try { -+ if (ca.spottedleaf.moonrise.common.util.TickThread.isTickThread()) net.minecraft.server.MinecraftServer.getServer().managedBlock(future::isDone); // DivineMC - Don't block main thread in Connection#syncAfterConfigurationChange - future.syncUninterruptibly(); - } catch (Exception var2) { - if (var2 instanceof ClosedChannelException) { -@@ -541,10 +546,16 @@ public class Connection extends SimpleChannelInboundHandler> { - if (io.papermc.paper.util.MCUtil.isMainThread()) { - return this.processQueue(); - } else if (this.isPending) { -- // Should only happen during login/status stages -- synchronized (this.pendingActions) { -- return this.processQueue(); -+ // DivineMC start - Leaf: Optimize Connection.flushQueue -+ if (org.bxteam.divinemc.DivineConfig.connectionFlushQueueRewrite) { -+ this.channel.eventLoop().execute(this::processQueue); -+ return false; -+ } else { -+ synchronized (this.pendingActions) { -+ return this.processQueue(); -+ } - } -+ // DivineMC end - Leaf: Optimize Connection.flushQueue - } - return false; - } -@@ -554,33 +565,52 @@ public class Connection extends SimpleChannelInboundHandler> { - return true; - } - -- // If we are on main, we are safe here in that nothing else should be processing queue off main anymore -- // But if we are not on main due to login/status, the parent is synchronized on packetQueue -- final java.util.Iterator iterator = this.pendingActions.iterator(); -- while (iterator.hasNext()) { -- final WrappedConsumer queued = iterator.next(); // poll -> peek -+ // DivineMC start - Leaf: Optimize Connection.flushQueue -+ if (org.bxteam.divinemc.DivineConfig.connectionFlushQueueRewrite) { -+ WrappedConsumer queued; -+ while ((queued = this.pendingActions.poll()) != null) { -+ if (queued instanceof PacketSendAction packetSendAction) { -+ final Packet packet = packetSendAction.packet; -+ if (!packet.isReady()) { -+ this.pendingActions.add(queued); -+ return false; -+ } -+ } - -- // Fix NPE (Spigot bug caused by handleDisconnection()) -- if (queued == null) { -- return true; -+ if (queued.tryMarkConsumed()) { -+ queued.accept(this); -+ } - } -+ } else { -+ // If we are on main, we are safe here in that nothing else should be processing queue off main anymore -+ // But if we are not on main due to login/status, the parent is synchronized on packetQueue -+ final java.util.Iterator iterator = this.pendingActions.iterator(); -+ while (iterator.hasNext()) { -+ final WrappedConsumer queued = iterator.next(); // poll -> peek -+ -+ // Fix NPE (Spigot bug caused by handleDisconnection()) -+ if (queued == null) { -+ return true; -+ } - -- if (queued.isConsumed()) { -- continue; -- } -+ if (queued.isConsumed()) { -+ continue; -+ } - -- if (queued instanceof PacketSendAction packetSendAction) { -- final Packet packet = packetSendAction.packet; -- if (!packet.isReady()) { -- return false; -+ if (queued instanceof PacketSendAction packetSendAction) { -+ final Packet packet = packetSendAction.packet; -+ if (!packet.isReady()) { -+ return false; -+ } - } -- } - -- iterator.remove(); -- if (queued.tryMarkConsumed()) { -- queued.accept(this); -+ iterator.remove(); -+ if (queued.tryMarkConsumed()) { -+ queued.accept(this); -+ } - } - } -+ // DivineMC end - Leaf: Optimize Connection.flushQueue - return true; - } - // Paper end - Optimize network -@@ -913,15 +943,40 @@ public class Connection extends SimpleChannelInboundHandler> { - // Paper start - Optimize network - public void clearPacketQueue() { - final net.minecraft.server.level.ServerPlayer player = getPlayer(); -- for (final Consumer queuedAction : this.pendingActions) { -- if (queuedAction instanceof PacketSendAction packetSendAction) { -- final Packet packet = packetSendAction.packet; -- if (packet.hasFinishListener()) { -- packet.onPacketDispatchFinish(player, null); -+ -+ // DivineMC start - Leaf: Optimize Connection.flushQueue -+ if (org.bxteam.divinemc.DivineConfig.connectionFlushQueueRewrite) { -+ if (this.channel != null && !this.channel.eventLoop().inEventLoop()) { -+ this.channel.eventLoop().execute(this::clearPacketQueue); -+ return; -+ } -+ -+ java.util.List> queueSnapshot = new java.util.ArrayList<>(this.pendingActions); -+ -+ for (Consumer queuedAction : queueSnapshot) { -+ if (queuedAction instanceof PacketSendAction packetSendAction) { -+ final Packet packet = packetSendAction.packet; -+ if (packet.hasFinishListener()) { -+ packet.onPacketDispatchFinish(player, null); -+ } -+ } -+ } -+ -+ this.pendingActions.clear(); -+ } else { -+ synchronized (this.pendingActions) { -+ for (final Consumer queuedAction : this.pendingActions) { -+ if (queuedAction instanceof PacketSendAction packetSendAction) { -+ final Packet packet = packetSendAction.packet; -+ if (packet.hasFinishListener()) { -+ packet.onPacketDispatchFinish(player, null); -+ } -+ } - } -+ this.pendingActions.clear(); - } - } -- this.pendingActions.clear(); -+ // DivineMC end - Leaf: Optimize Connection.flushQueue - } - - private static class InnerUtil { // Attempt to hide these methods from ProtocolLib, so it doesn't accidently pick them up. diff --git a/divinemc-server/minecraft-patches/features/0040-Option-to-disable-disconnect.spam.patch b/divinemc-server/minecraft-patches/features/0039-Option-to-disable-disconnect.spam.patch similarity index 100% rename from divinemc-server/minecraft-patches/features/0040-Option-to-disable-disconnect.spam.patch rename to divinemc-server/minecraft-patches/features/0039-Option-to-disable-disconnect.spam.patch diff --git a/divinemc-server/minecraft-patches/features/0041-Configurable-MC-59471.patch b/divinemc-server/minecraft-patches/features/0040-Configurable-MC-59471.patch similarity index 100% rename from divinemc-server/minecraft-patches/features/0041-Configurable-MC-59471.patch rename to divinemc-server/minecraft-patches/features/0040-Configurable-MC-59471.patch diff --git a/divinemc-server/minecraft-patches/features/0043-ModernFix-compact_bit_storage.patch b/divinemc-server/minecraft-patches/features/0041-ModernFix-compact_bit_storage.patch similarity index 100% rename from divinemc-server/minecraft-patches/features/0043-ModernFix-compact_bit_storage.patch rename to divinemc-server/minecraft-patches/features/0041-ModernFix-compact_bit_storage.patch diff --git a/divinemc-server/minecraft-patches/features/0044-Command-block-parse-results-caching.patch b/divinemc-server/minecraft-patches/features/0042-Command-block-parse-results-caching.patch similarity index 100% rename from divinemc-server/minecraft-patches/features/0044-Command-block-parse-results-caching.patch rename to divinemc-server/minecraft-patches/features/0042-Command-block-parse-results-caching.patch diff --git a/divinemc-server/minecraft-patches/features/0042-lithium-block_entity_ticking.sleeping.patch b/divinemc-server/minecraft-patches/features/0042-lithium-block_entity_ticking.sleeping.patch deleted file mode 100644 index 5e96f86..0000000 --- a/divinemc-server/minecraft-patches/features/0042-lithium-block_entity_ticking.sleeping.patch +++ /dev/null @@ -1,565 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> -Date: Thu, 6 Mar 2025 00:09:54 +0300 -Subject: [PATCH] lithium: block_entity_ticking.sleeping - - -diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index fdaf752b4d39402de504cc8dfb6f0593f9b19d9a..da395fcf672e2c055ea0687d26fa5d31b8fc4640 100644 ---- a/net/minecraft/server/level/ServerLevel.java -+++ b/net/minecraft/server/level/ServerLevel.java -@@ -2398,7 +2398,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - CsvOutput csvOutput = CsvOutput.builder().addColumn("x").addColumn("y").addColumn("z").addColumn("type").build(output); - - for (TickingBlockEntity tickingBlockEntity : this.blockEntityTickers) { -- BlockPos pos = tickingBlockEntity.getPos(); -+ BlockPos pos = getPosOrOrigin(tickingBlockEntity); // DivineMC - lithium: block_entity_ticking.sleeping - csvOutput.writeRow(pos.getX(), pos.getY(), pos.getZ(), tickingBlockEntity.getType()); - } - } -@@ -2453,6 +2453,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - return this; - } - -+ // DivineMC start - lithium: block_entity_ticking.sleeping -+ private BlockPos getPosOrOrigin(TickingBlockEntity instance) { -+ BlockPos pos = instance.getPos(); -+ if (pos == null) { -+ return BlockPos.ZERO; -+ } -+ return pos; -+ } -+ // DivineMC end - lithium: block_entity_ticking.sleeping -+ - @VisibleForTesting - public String getWatchdogStats() { - return String.format( -diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 440d890d32a6705aa5ebc84040c4290634bbae9b..a349f1a74e022a759391b60e820d185f035f2199 100644 ---- a/net/minecraft/world/level/Level.java -+++ b/net/minecraft/world/level/Level.java -@@ -1529,7 +1529,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - // Spigot end - if (tickingBlockEntity.isRemoved()) { - this.blockEntityTickers.markAsRemoved(this.tileTickPosition); // DivineMC - optimize block entity removals - Fix MC-117075 -- } else if (runsNormally && this.shouldTickBlocksAt(tickingBlockEntity.getPos())) { -+ } else if (runsNormally && this.shouldTickBlockPosFilterNull(this, tickingBlockEntity.getPos())) { // DivineMC - lithium: block_entity_ticking.sleeping - tickingBlockEntity.tick(); - // DivineMC start - Parallel world ticking - ++tickedEntities; -@@ -1546,6 +1546,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - this.spigotConfig.currentPrimedTnt = 0; // Spigot - } - -+ // DivineMC start - lithium: block_entity_ticking.sleeping -+ private boolean shouldTickBlockPosFilterNull(Level instance, BlockPos pos) { -+ if (pos == null) { -+ return false; -+ } -+ return instance.shouldTickBlocksAt(pos); -+ } -+ // DivineMC end - lithium: block_entity_ticking.sleeping -+ - public void guardEntityTick(Consumer consumerEntity, T entity) { - try { - consumerEntity.accept(entity); -diff --git a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index 947b2911a71768c43180ca8dcaaacd6ce93b3f55..c8c56a4a8872d4b2a437506322f97ccdc5a9dc87 100644 ---- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -+++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -@@ -39,7 +39,7 @@ import net.minecraft.world.level.block.Blocks; - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.phys.Vec3; - --public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntity implements WorldlyContainer, RecipeCraftingHolder, StackedContentsCompatible { -+public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntity implements WorldlyContainer, RecipeCraftingHolder, StackedContentsCompatible, net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity { // DivineMC - lithium: block_entity_ticking.sleeping - protected static final int SLOT_INPUT = 0; - protected static final int SLOT_FUEL = 1; - protected static final int SLOT_RESULT = 2; -@@ -101,6 +101,38 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit - private final RecipeManager.CachedCheck quickCheck; - public final RecipeType recipeType; // Paper - cook speed multiplier API - public double cookSpeedMultiplier = 1.0; // Paper - cook speed multiplier API -+ // DivineMC start - lithium: block_entity_ticking.sleeping -+ private net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper = null; -+ private TickingBlockEntity sleepingTicker = null; -+ -+ @Override -+ public net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper lithium$getTickWrapper() { -+ return tickWrapper; -+ } -+ -+ @Override -+ public void lithium$setTickWrapper(net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper) { -+ this.tickWrapper = tickWrapper; -+ this.lithium$setSleepingTicker(null); -+ } -+ -+ @Override -+ public TickingBlockEntity lithium$getSleepingTicker() { -+ return sleepingTicker; -+ } -+ -+ @Override -+ public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) { -+ this.sleepingTicker = sleepingTicker; -+ } -+ -+ @Override -+ public void lithium$handleSetChanged() { -+ if (this.isSleeping() && this.level != null && !this.level.isClientSide) { -+ this.wakeUpNow(); -+ } -+ } -+ // DivineMC end - lithium: block_entity_ticking.sleeping - - protected AbstractFurnaceBlockEntity(BlockEntityType type, BlockPos pos, BlockState blockState, RecipeType recipeType) { - super(type, pos, blockState); -@@ -167,6 +199,11 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit - this.cookSpeedMultiplier = tag.getDouble("Paper.CookSpeedMultiplier"); - } - // Paper end - cook speed multiplier API -+ // DivineMC start - lithium: block_entity_ticking.sleeping -+ if (this.isSleeping() && this.level != null && !this.level.isClientSide) { -+ this.wakeUpNow(); -+ } -+ // DivineMC end - lithium: block_entity_ticking.sleeping - } - - @Override -@@ -291,7 +328,16 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit - } - - if (usedLavaFromUnderneath) furnace.items.set(1, ItemStack.EMPTY); // Purpur - Furnace uses lava from underneath -+ furnace.checkSleep(state); // DivineMC - lithium: block_entity_ticking.sleeping -+ } -+ -+ // DivineMC start - lithium: block_entity_ticking.sleeping -+ private void checkSleep(BlockState state) { -+ if (!this.isLit() && this.cookingTimer == 0 && (state.is(Blocks.FURNACE) || state.is(Blocks.BLAST_FURNACE) || state.is(Blocks.SMOKER)) && this.level != null) { -+ this.lithium$startSleeping(); -+ } - } -+ // DivineMC end - lithium: block_entity_ticking.sleeping - - private static boolean canBurn( - RegistryAccess registryAccess, -diff --git a/net/minecraft/world/level/block/entity/BlockEntity.java b/net/minecraft/world/level/block/entity/BlockEntity.java -index 3fd0f42618e5c2c683335d1d3e0bb74c6d32ef66..5e0dbe39c8df0147a067b775455f3b73b2906363 100644 ---- a/net/minecraft/world/level/block/entity/BlockEntity.java -+++ b/net/minecraft/world/level/block/entity/BlockEntity.java -@@ -39,6 +39,7 @@ public abstract class BlockEntity { - protected boolean remove; - private BlockState blockState; - private DataComponentMap components = DataComponentMap.EMPTY; -+ public void lithium$handleSetChanged() { } // DivineMC - lithium: block_entity_ticking.sleeping - - public BlockEntity(BlockEntityType type, BlockPos pos, BlockState blockState) { - this.type = type; -diff --git a/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java b/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java -index 94f9477e78600eded6eecc4c961576501001d187..3c82874cc490bc8e29bb44abcc4b0893cfebf00b 100644 ---- a/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java -+++ b/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java -@@ -24,7 +24,7 @@ import net.minecraft.world.level.Level; - import net.minecraft.world.level.block.BrewingStandBlock; - import net.minecraft.world.level.block.state.BlockState; - --public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements WorldlyContainer { -+public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements WorldlyContainer, net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity { // DivineMC - lithium: block_entity_ticking.sleeping - private static final int INGREDIENT_SLOT = 3; - private static final int FUEL_SLOT = 4; - private static final int[] SLOTS_FOR_UP = new int[]{3}; -@@ -40,6 +40,44 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements - private boolean[] lastPotionCount; - private Item ingredient; - public int fuel; -+ // DivineMC start - lithium: block_entity_ticking.sleeping -+ private net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper = null; -+ private TickingBlockEntity sleepingTicker = null; -+ -+ @Override -+ public net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper lithium$getTickWrapper() { -+ return tickWrapper; -+ } -+ -+ @Override -+ public void lithium$setTickWrapper(net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper) { -+ this.tickWrapper = tickWrapper; -+ this.lithium$setSleepingTicker(null); -+ } -+ -+ @Override -+ public TickingBlockEntity lithium$getSleepingTicker() { -+ return sleepingTicker; -+ } -+ -+ @Override -+ public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) { -+ this.sleepingTicker = sleepingTicker; -+ } -+ -+ private void checkSleep(BlockState state) { -+ if (this.brewTime == 0 && state.is(net.minecraft.world.level.block.Blocks.BREWING_STAND) && this.level != null) { -+ this.lithium$startSleeping(); -+ } -+ } -+ -+ @Override -+ public void lithium$handleSetChanged() { -+ if (this.isSleeping() && this.level != null && !this.level.isClientSide) { -+ this.wakeUpNow(); -+ } -+ } -+ // DivineMC end - lithium: block_entity_ticking.sleeping - protected final ContainerData dataAccess = new ContainerData() { - @Override - public int get(int index) { -@@ -128,6 +166,7 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements - } - - public static void serverTick(Level level, BlockPos pos, BlockState state, BrewingStandBlockEntity blockEntity) { -+ blockEntity.checkSleep(state); // DivineMC - lithium: block_entity_ticking.sleeping - ItemStack itemStack = blockEntity.items.get(4); - if (blockEntity.fuel <= 0 && itemStack.is(ItemTags.BREWING_FUEL)) { - // CraftBukkit start -@@ -145,6 +184,7 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements - itemStack.shrink(1); - } - // CraftBukkit end -+ blockEntity.wakeUpNow(); // DivineMC - lithium: block_entity_ticking.sleeping - setChanged(level, pos, state); - } - -@@ -160,6 +200,7 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements - blockEntity.brewTime = 0; - } - -+ blockEntity.wakeUpNow(); // DivineMC - lithium: block_entity_ticking.sleeping - setChanged(level, pos, state); - } else if (isBrewable && blockEntity.fuel > 0) { - blockEntity.fuel--; -@@ -172,6 +213,7 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements - blockEntity.brewTime = event.getBrewingTime(); // 400 -> event.getTotalBrewTime() // Paper - use brewing time from event - // CraftBukkit end - blockEntity.ingredient = itemStack1.getItem(); -+ blockEntity.wakeUpNow(); // DivineMC - lithium: block_entity_ticking.sleeping - setChanged(level, pos, state); - } - -@@ -278,6 +320,11 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements - } - - this.fuel = tag.getByte("Fuel"); -+ // DivineMC start - lithium: block_entity_ticking.sleeping -+ if (this.isSleeping() && this.level != null && !this.level.isClientSide()) { -+ this.wakeUpNow(); -+ } -+ // DivineMC end - lithium: block_entity_ticking.sleeping - } - - @Override -diff --git a/net/minecraft/world/level/block/entity/CampfireBlockEntity.java b/net/minecraft/world/level/block/entity/CampfireBlockEntity.java -index 2811ecb7624877b6b04896811f1d1626d716dad6..dcf92ac304c0d54c8371ce63eeb4942a67e3796e 100644 ---- a/net/minecraft/world/level/block/entity/CampfireBlockEntity.java -+++ b/net/minecraft/world/level/block/entity/CampfireBlockEntity.java -@@ -30,13 +30,50 @@ import net.minecraft.world.level.block.CampfireBlock; - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.level.gameevent.GameEvent; - --public class CampfireBlockEntity extends BlockEntity implements Clearable { -+public class CampfireBlockEntity extends BlockEntity implements Clearable, net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity { // DivineMC - lithium: block_entity_ticking.sleeping - private static final int BURN_COOL_SPEED = 2; - private static final int NUM_SLOTS = 4; - private final NonNullList items = NonNullList.withSize(4, ItemStack.EMPTY); - public final int[] cookingProgress = new int[4]; - public final int[] cookingTime = new int[4]; - public final boolean[] stopCooking = new boolean[4]; // Paper - Add more Campfire API -+ // DivineMC start - lithium: block_entity_ticking.sleeping -+ private net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper = null; -+ private TickingBlockEntity sleepingTicker = null; -+ -+ @Override -+ public net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper lithium$getTickWrapper() { -+ return tickWrapper; -+ } -+ -+ @Override -+ public void lithium$setTickWrapper(net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper) { -+ this.tickWrapper = tickWrapper; -+ this.lithium$setSleepingTicker(null); -+ } -+ -+ @Override -+ public TickingBlockEntity lithium$getSleepingTicker() { -+ return sleepingTicker; -+ } -+ -+ @Override -+ public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) { -+ this.sleepingTicker = sleepingTicker; -+ } -+ -+ private static void trySleepLit(CampfireBlockEntity campfireBlockEntity, boolean bl) { -+ if (!bl) { -+ campfireBlockEntity.lithium$startSleeping(); -+ } -+ } -+ -+ private static void trySleepUnlit(CampfireBlockEntity campfire, boolean hadProgress) { -+ if (!hadProgress) { -+ campfire.lithium$startSleeping(); -+ } -+ } -+ // DivineMC end - lithium: block_entity_ticking.sleeping - - public CampfireBlockEntity(BlockPos pos, BlockState blockState) { - super(BlockEntityType.CAMPFIRE, pos, blockState); -@@ -62,8 +99,14 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { - SingleRecipeInput singleRecipeInput = new SingleRecipeInput(itemStack); - // Paper start - add recipe to cook events - final var optionalCookingRecipe = check.getRecipeFor(singleRecipeInput, level); -+ // DivineMC start - lithium: block_entity_ticking.sleeping -+ final boolean finalFlag = flag; - ItemStack itemStack1 = optionalCookingRecipe -- .map(recipe -> recipe.value().assemble(singleRecipeInput, level.registryAccess())) -+ .map(recipe -> { -+ trySleepLit(campfire, finalFlag); // Canvas -+ return recipe.value().assemble(singleRecipeInput, level.registryAccess()); -+ }) -+ // DivineMC end - lithium: block_entity_ticking.sleeping - .orElse(itemStack); - // Paper end - add recipe to cook events - if (itemStack1.isItemEnabled(level.enabledFeatures())) { -@@ -79,6 +122,7 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { - ); - - if (!blockCookEvent.callEvent()) { -+ trySleepLit(campfire, flag); // DivineMC - lithium: block_entity_ticking.sleeping - return; - } - -@@ -104,6 +148,8 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { - if (flag) { - setChanged(level, pos, state); - } -+ -+ trySleepLit(campfire, flag); // DivineMC - lithium: block_entity_ticking.sleeping - } - - public static void cooldownTick(Level level, BlockPos pos, BlockState state, CampfireBlockEntity blockEntity) { -@@ -119,6 +165,8 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { - if (flag) { - setChanged(level, pos, state); - } -+ -+ trySleepUnlit(blockEntity, flag); // DivineMC - lithium: block_entity_ticking.sleeping - } - - public static void particleTick(Level level, BlockPos pos, BlockState state, CampfireBlockEntity blockEntity) { -@@ -175,6 +223,8 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { - System.arraycopy(cookingState, 0, this.stopCooking, 0, Math.min(this.stopCooking.length, abyte.length)); - } - // Paper end - Add more Campfire API -+ -+ this.wakeUpNow(); // DivineMC - lithium: block_entity_ticking.sleeping - } - - @Override -@@ -224,6 +274,7 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { - this.cookingTime[i] = event.getTotalCookTime(); // i -> event.getTotalCookTime() - // CraftBukkit end - this.cookingProgress[i] = 0; -+ this.wakeUpNow(); // DivineMC - lithium: block_entity_ticking.sleeping - this.items.set(i, stack.consumeAndReturn(1, entity)); - level.gameEvent(GameEvent.BLOCK_CHANGE, this.getBlockPos(), GameEvent.Context.of(entity, this.getBlockState())); - this.markUpdated(); -diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index a0ee6ad6e7a6791605191d20d742e16cc9857a60..627af05bbfc3ed60fb22bfeb1b7c79c09cf4f442 100644 ---- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java -+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java -@@ -28,7 +28,7 @@ import net.minecraft.world.level.block.HopperBlock; - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.phys.AABB; - --public class HopperBlockEntity extends RandomizableContainerBlockEntity implements Hopper { -+public class HopperBlockEntity extends RandomizableContainerBlockEntity implements Hopper, net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity { // DivineMC - lithium: block_entity_ticking.sleeping - public static final int MOVE_ITEM_SPEED = 8; - public static final int HOPPER_CONTAINER_SIZE = 5; - private static final int[][] CACHED_SLOTS = new int[54][]; -@@ -36,6 +36,51 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - public int cooldownTime = -1; - private long tickedGameTime; - private Direction facing; -+ // DivineMC start - lithium: block_entity_ticking.sleeping -+ private net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper = null; -+ private TickingBlockEntity sleepingTicker = null; -+ -+ @Override -+ public net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper lithium$getTickWrapper() { -+ return tickWrapper; -+ } -+ -+ @Override -+ public void lithium$setTickWrapper(net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper) { -+ this.tickWrapper = tickWrapper; -+ this.lithium$setSleepingTicker(null); -+ } -+ -+ @Override -+ public TickingBlockEntity lithium$getSleepingTicker() { -+ return sleepingTicker; -+ } -+ -+ @Override -+ public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) { -+ this.sleepingTicker = sleepingTicker; -+ } -+ -+ @Override -+ public boolean lithium$startSleeping() { -+ if (this.isSleeping()) { -+ return false; -+ } -+ -+ net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper = this.lithium$getTickWrapper(); -+ if (tickWrapper != null) { -+ this.lithium$setSleepingTicker(tickWrapper.ticker); -+ tickWrapper.rebind(net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity.SLEEPING_BLOCK_ENTITY_TICKER); -+ -+ // Set the last tick time to max value, so other hoppers transferring into this hopper will set it to 7gt -+ // cooldown. Then when waking up, we make sure to not tick this hopper in the same gametick. -+ // This makes the observable hopper cooldown not be different from vanilla. -+ this.tickedGameTime = Long.MAX_VALUE; -+ return true; -+ } -+ return false; -+ } -+ // DivineMC end - lithium: block_entity_ticking.sleeping - - // CraftBukkit start - add fields and methods - public List transaction = new java.util.ArrayList<>(); -@@ -160,6 +205,14 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - } - } - -+ // DivineMC start - lithium: block_entity_ticking.sleeping -+ if (!(blockEntity).isOnCooldown() && -+ !(blockEntity).isSleeping() && -+ !state.getValue(HopperBlock.ENABLED)) { -+ (blockEntity).lithium$startSleeping(); -+ } -+ // DivineMC end - lithium: block_entity_ticking.sleeping -+ - return false; - } - } -@@ -586,6 +639,17 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - } - - public void setCooldown(int cooldownTime) { -+ // DivineMC start - lithium: block_entity_ticking.sleeping -+ if (cooldownTime == 7) { -+ if (this.tickedGameTime == Long.MAX_VALUE) { -+ this.sleepOnlyCurrentTick(); -+ } else { -+ this.wakeUpNow(); -+ } -+ } else if (cooldownTime > 0 && this.sleepingTicker != null) { -+ this.wakeUpNow(); -+ } -+ // DivineMC end - lithium: block_entity_ticking.sleeping - this.cooldownTime = cooldownTime; - } - -diff --git a/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java b/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java -index a2ae4b47d742e7fb9809cfc4575517c06400ec61..e92863af578bb472a692482be3dddc1cc658f930 100644 ---- a/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java -+++ b/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java -@@ -32,7 +32,7 @@ import net.minecraft.world.level.material.PushReaction; - import net.minecraft.world.phys.AABB; - import net.minecraft.world.phys.Vec3; - --public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity implements WorldlyContainer { -+public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity implements WorldlyContainer, net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity { // DivineMC - lithium: block_entity_ticking.sleeping - public static final int COLUMNS = 9; - public static final int ROWS = 3; - public static final int CONTAINER_SIZE = 27; -@@ -48,6 +48,30 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl - private float progressOld; - @Nullable - private final DyeColor color; -+ // DivineMC start - lithium: block_entity_ticking.sleeping -+ private net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper = null; -+ private TickingBlockEntity sleepingTicker = null; -+ -+ @Override -+ public net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper lithium$getTickWrapper() { -+ return tickWrapper; -+ } -+ -+ @Override -+ public void lithium$setTickWrapper(net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper) { -+ this.tickWrapper = tickWrapper; -+ } -+ -+ @Override -+ public TickingBlockEntity lithium$getSleepingTicker() { -+ return sleepingTicker; -+ } -+ -+ @Override -+ public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) { -+ this.sleepingTicker = sleepingTicker; -+ } -+ // DivineMC end - lithium: block_entity_ticking.sleeping - - // CraftBukkit start - add fields and methods - public List transaction = new java.util.ArrayList<>(); -@@ -129,6 +153,12 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl - doNeighborUpdates(level, pos, state); - } - } -+ -+ // DivineMC start - lithium: block_entity_ticking.sleeping -+ if (this.animationStatus == ShulkerBoxBlockEntity.AnimationStatus.CLOSED && this.progressOld == 0.0f && this.progress == 0.0f) { -+ this.lithium$startSleeping(); -+ } -+ // DivineMC end - lithium: block_entity_ticking.sleeping - } - - public ShulkerBoxBlockEntity.AnimationStatus getAnimationStatus() { -@@ -169,6 +199,7 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl - - @Override - public boolean triggerEvent(int id, int type) { -+ if (this.sleepingTicker != null) this.wakeUpNow(); // DivineMC - lithium: block_entity_ticking.sleeping - if (id == 1) { - this.openCount = type; - if (type == 0) { -diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java -index 0337f4b9ca3c9c9a1e2a7cf19fcbad5e78b949dc..7491c062172e26d2ae5a5deedb7185bc5da3aa83 100644 ---- a/net/minecraft/world/level/chunk/LevelChunk.java -+++ b/net/minecraft/world/level/chunk/LevelChunk.java -@@ -877,12 +877,22 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p - (pos, ticker1) -> { - TickingBlockEntity tickingBlockEntity = this.createTicker(blockEntity, ticker); - if (ticker1 != null) { -+ // DivineMC start - lithium: block_entity_ticking.sleeping -+ if (blockEntity instanceof net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity sleepingBlockEntity) { -+ sleepingBlockEntity.lithium$setTickWrapper(ticker1); -+ } -+ // DivineMC end - lithium: block_entity_ticking.sleeping - ticker1.rebind(tickingBlockEntity); - return (LevelChunk.RebindableTickingBlockEntityWrapper)ticker1; - } else if (this.isInLevel()) { - LevelChunk.RebindableTickingBlockEntityWrapper rebindableTickingBlockEntityWrapper = new LevelChunk.RebindableTickingBlockEntityWrapper( - tickingBlockEntity - ); -+ // DivineMC start - lithium: block_entity_ticking.sleeping -+ if (blockEntity instanceof net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity sleepingBlockEntity) { -+ sleepingBlockEntity.lithium$setTickWrapper(rebindableTickingBlockEntityWrapper); -+ } -+ // DivineMC end - lithium: block_entity_ticking.sleeping - this.level.addBlockEntityTicker(rebindableTickingBlockEntityWrapper); - return rebindableTickingBlockEntityWrapper; - } else { diff --git a/divinemc-server/minecraft-patches/features/0045-Linear-region-file-format.patch b/divinemc-server/minecraft-patches/features/0043-Linear-region-file-format.patch similarity index 99% rename from divinemc-server/minecraft-patches/features/0045-Linear-region-file-format.patch rename to divinemc-server/minecraft-patches/features/0043-Linear-region-file-format.patch index afbb1ad..c00a8f6 100644 --- a/divinemc-server/minecraft-patches/features/0045-Linear-region-file-format.patch +++ b/divinemc-server/minecraft-patches/features/0043-Linear-region-file-format.patch @@ -54,7 +54,7 @@ index 51c126735ace8fdde89ad97b5cab62f244212db0..c466ce5c669e4b5ed835b13584a5ae5a + public void moonrise$write(final org.stupidcraft.linearpaper.region.IRegionFile regionFile) throws IOException; // DivineMC - Linear region file format } diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 19ebcc9a175fa1bcd3bb4f954bdda00664a86f19..761f648df387e49750eac9000f7f46d1ae22e257 100644 +index daf6141a6aed6baf7b8de4030324703a0fe872d3..6182c6f7cc6f5199897a5e227dabe9f9738733a5 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -947,10 +947,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop= this.sleepUntilTickExclusive) { - ((SleepingBlockEntity) this.sleepingBlockEntity).setTicker(this.delegate); - this.delegate.tick(); - } - } - - @Override - public boolean isRemoved() { - return this.sleepingBlockEntity.isRemoved(); - } - - @Override - public @NotNull BlockPos getPos() { - return this.sleepingBlockEntity.getBlockPos(); - } - - @Override - public @NotNull String getType() { - return BlockEntityType.getKey(this.sleepingBlockEntity.getType()).toString(); - } -} diff --git a/divinemc-server/src/main/java/net/caffeinemc/mods/lithium/common/block/entity/SleepingBlockEntity.java b/divinemc-server/src/main/java/net/caffeinemc/mods/lithium/common/block/entity/SleepingBlockEntity.java deleted file mode 100644 index a0f54f8..0000000 --- a/divinemc-server/src/main/java/net/caffeinemc/mods/lithium/common/block/entity/SleepingBlockEntity.java +++ /dev/null @@ -1,82 +0,0 @@ -package net.caffeinemc.mods.lithium.common.block.entity; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.TickingBlockEntity; -import net.minecraft.world.level.chunk.LevelChunk; -import org.jetbrains.annotations.NotNull; -import org.jspecify.annotations.Nullable; - -public interface SleepingBlockEntity { - TickingBlockEntity SLEEPING_BLOCK_ENTITY_TICKER = new TickingBlockEntity() { - public void tick() { - } - - public boolean isRemoved() { - return false; - } - - public @Nullable BlockPos getPos() { - return null; - } - - public @NotNull String getType() { - return ""; - } - }; - - LevelChunk.RebindableTickingBlockEntityWrapper lithium$getTickWrapper(); - - void lithium$setTickWrapper(LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper); - - TickingBlockEntity lithium$getSleepingTicker(); - - void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker); - - default boolean lithium$startSleeping() { - if (this.isSleeping()) { - return false; - } - - LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper = this.lithium$getTickWrapper(); - if (tickWrapper == null) { - return false; - } - this.lithium$setSleepingTicker(tickWrapper.ticker); - tickWrapper.rebind(SleepingBlockEntity.SLEEPING_BLOCK_ENTITY_TICKER); - return true; - } - - default void sleepOnlyCurrentTick() { - TickingBlockEntity sleepingTicker = this.lithium$getSleepingTicker(); - LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper = this.lithium$getTickWrapper(); - if (sleepingTicker == null) { - sleepingTicker = tickWrapper.ticker; - } - Level world = ((BlockEntity) this).getLevel(); - tickWrapper.rebind(new SleepUntilTimeBlockEntityTickInvoker((BlockEntity) this, world.getGameTime() + 1, sleepingTicker)); - this.lithium$setSleepingTicker(null); - } - - default void wakeUpNow() { - TickingBlockEntity sleepingTicker = this.lithium$getSleepingTicker(); - if (sleepingTicker == null) { - return; - } - this.setTicker(sleepingTicker); - this.lithium$setSleepingTicker(null); - } - - default void setTicker(TickingBlockEntity delegate) { - LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper = this.lithium$getTickWrapper(); - if (tickWrapper == null) { - return; - } - tickWrapper.rebind(delegate); - } - - default boolean isSleeping() { - return this.lithium$getSleepingTicker() != null; - } -} diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java b/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java index 0adfc9c..8cf2ad4 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java @@ -320,17 +320,11 @@ public class DivineConfig { } public static boolean disableDisconnectSpam = false; - public static boolean connectionFlushQueueRewrite = false; public static boolean gracefulTeleportHandling = false; public static boolean dontRespondPingBeforeStart = true; private static void networkSettings() { disableDisconnectSpam = getBoolean("settings.network.disable-disconnect-spam", disableDisconnectSpam, "Prevents players being disconnected by 'disconnect.spam' when sending too many chat packets"); - connectionFlushQueueRewrite = getBoolean("settings.network.connection-flush-queue-rewrite", connectionFlushQueueRewrite, - "Replaces ConcurrentLinkedQueue with ArrayDeque in Connection for better performance", - "and also uses the Netty event loop to ensure thread safety.", - "", - "Note: May increase the Netty thread usage"); gracefulTeleportHandling = getBoolean("settings.network.graceful-teleport-handling", gracefulTeleportHandling , "Disables being disconnected from 'multiplayer.disconnect.invalid_player_movement' (also declines the packet handling)."); dontRespondPingBeforeStart = getBoolean("settings.network.dont-respond-ping-before-start", dontRespondPingBeforeStart,