diff --git a/gradle.properties b/gradle.properties index e0726f1..e0f07fa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ mcVersion=1.21.8 release=2 # 0 for skip release, 1 for pre-release, 2 for release -luminolRef=ab525054c73906ef8120333387b1602dd3376229 +luminolRef=fe2b7d2f1b19cb752f50ac63c102c27271a2b73d org.gradle.configuration-cache=true org.gradle.caching=true diff --git a/lophine-server/minecraft-patches/features/0010-Leaves-Item-overstack-util.patch b/lophine-server/minecraft-patches/features/0010-Leaves-Item-overstack-util.patch index 69ecb5f..3e749d1 100644 --- a/lophine-server/minecraft-patches/features/0010-Leaves-Item-overstack-util.patch +++ b/lophine-server/minecraft-patches/features/0010-Leaves-Item-overstack-util.patch @@ -446,10 +446,10 @@ index 10b2cc20bbf3b70e4e09dbbe14b90506e6366158..1535bb8cec8692e8d26eaff090288f1b } diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index d353b15401e629c5f367786111d5227236968d4a..e660eef2508023eef87eb6cb8f2ef0d0110f5449 100644 +index 1ddc320ab18fbd2793eb10a178cf77e0c55cf880..f871712cbca93ac4b3e1f0d3ebed6a815b8b6b59 100644 --- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java -@@ -163,7 +163,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -145,7 +145,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen public void setItem(int index, ItemStack stack) { this.unpackLootTable(null); this.getItems().set(index, stack); @@ -458,7 +458,7 @@ index d353b15401e629c5f367786111d5227236968d4a..e660eef2508023eef87eb6cb8f2ef0d0 } @Override -@@ -788,9 +788,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen +@@ -770,9 +770,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen if (item.isEmpty()) { // Spigot start - SPIGOT-6693, SimpleContainer#setItem ItemStack leftover = ItemStack.EMPTY; // Paper - Make hoppers respect inventory max stack size diff --git a/lophine-server/src/main/java/fun/bm/lophine/config/modules/function/SurvuxProtocolConfig.java b/lophine-server/src/main/java/fun/bm/lophine/config/modules/function/SurvuxProtocolConfig.java index 18ae6d6..22d990b 100644 --- a/lophine-server/src/main/java/fun/bm/lophine/config/modules/function/SurvuxProtocolConfig.java +++ b/lophine-server/src/main/java/fun/bm/lophine/config/modules/function/SurvuxProtocolConfig.java @@ -47,4 +47,7 @@ public class SurvuxProtocolConfig implements IConfigModule { @CommandSuggestions(suggest = {"-1", "2097152"}) @ConfigInfo(baseName = "litematics-max-nbt-size") public static int litematicsMaxNbtSize = 2097152; + + @ConfigInfo(baseName = "litematics-print-max-delay-ticks", comments = "The max delay ticks for printing litematics, -1 to disable") + public static int maxDelay = 1200; } diff --git a/lophine-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/ServuxLitematicsProtocol.java b/lophine-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/ServuxLitematicsProtocol.java index 80bcc9f..ec1b4a2 100644 --- a/lophine-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/ServuxLitematicsProtocol.java +++ b/lophine-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/ServuxLitematicsProtocol.java @@ -269,23 +269,7 @@ public class ServuxLitematicsProtocol implements LeavesProtocol { long timeStart = System.currentTimeMillis(); SchematicPlacement placement = SchematicPlacement.createFromNbt(tags); ReplaceBehavior replaceMode = ReplaceBehavior.fromStringStatic(tags.getStringOr("ReplaceMode", ReplaceBehavior.NONE.name())); - io.papermc.paper.threadedregions.RegionizedServer.getInstance().taskQueue.queueTickTaskQueue( - player.level(), - ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkX(player.position()), - ca.spottedleaf.moonrise.common.util.CoordinateUtils.getChunkZ(player.position()), - () -> { - placement.pasteTo(serverLevel, replaceMode); - long timeElapsed = System.currentTimeMillis() - timeStart; - player.getBukkitEntity().sendActionBar( - Component.text("Pasted ") - .append(Component.text(placement.getName(), NamedTextColor.AQUA)) - .append(Component.text(" to world ")) - .append(Component.text(serverLevel.serverLevelData.getLevelName(), NamedTextColor.LIGHT_PURPLE)) - .append(Component.text(" in ")) - .append(Component.text(timeElapsed, NamedTextColor.GREEN)) - .append(Component.text("ms")) - ); - }); + placement.pasteTo(serverLevel, replaceMode, player, timeStart); } } diff --git a/lophine-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/placement/SchematicPlacement.java b/lophine-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/placement/SchematicPlacement.java index e08b9ab..0528abc 100644 --- a/lophine-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/placement/SchematicPlacement.java +++ b/lophine-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/placement/SchematicPlacement.java @@ -18,15 +18,23 @@ package org.leavesmc.leaves.protocol.servux.litematics.placement; import com.google.common.collect.ImmutableMap; +import fun.bm.lophine.config.modules.function.SurvuxProtocolConfig; +import io.papermc.paper.threadedregions.RegionizedServer; +import me.earthme.luminol.utils.NullPlugin; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; import net.minecraft.core.BlockBox; import net.minecraft.core.BlockPos; import net.minecraft.core.SectionPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.block.Rotation; import net.minecraft.world.phys.AABB; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import org.leavesmc.leaves.protocol.servux.ServuxProtocol; import org.leavesmc.leaves.protocol.servux.litematics.LitematicaSchematic; @@ -35,6 +43,7 @@ import org.leavesmc.leaves.protocol.servux.litematics.utils.*; import javax.annotation.Nullable; import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Stream; public class SchematicPlacement { @@ -283,14 +292,52 @@ public class SchematicPlacement { return ChunkPos.rangeClosed(new ChunkPos(i, j), new ChunkPos(k, l)); } - public void pasteTo(ServerLevel serverWorld, ReplaceBehavior replaceBehavior) { + public void pasteTo(ServerLevel serverWorld, ReplaceBehavior replaceBehavior, ServerPlayer player, long timeStart) { Box enclosingBox = this.getEnclosingBox(); if (enclosingBox == null || enclosingBox.pos1() == null || enclosingBox.pos2() == null) { ServuxProtocol.LOGGER.error("receiver a null enclosing box"); return; } - streamChunkPos(Objects.requireNonNull(enclosingBox.toVanilla())).forEach(chunkPos -> - SchematicPlacingUtils.placeToWorldWithinChunk(serverWorld, chunkPos, this, replaceBehavior, false) + + AtomicInteger count_full = new AtomicInteger(); + AtomicInteger count = new AtomicInteger(); + + streamChunkPos(Objects.requireNonNull(enclosingBox.toVanilla())).forEach(chunkPos -> { + RegionizedServer.getInstance().taskQueue.queueTickTaskQueue( + serverWorld, + chunkPos.x, + chunkPos.z, + () -> { + SchematicPlacingUtils.placeToWorldWithinChunk(serverWorld, chunkPos, this, replaceBehavior, false); + count.getAndIncrement(); + }); + count_full.getAndIncrement(); + } ); + + final NullPlugin nullPlugin = new NullPlugin(); + scheduleTask(nullPlugin, serverWorld, count, count_full, player, timeStart, SurvuxProtocolConfig.maxDelay); + } + + private void scheduleTask(Plugin plugin, ServerLevel serverWorld, AtomicInteger count1, AtomicInteger count2, ServerPlayer player, long timeStart, int retryCount) { + Bukkit.getGlobalRegionScheduler().runDelayed(plugin, + (unused) -> { + if (count1.get() >= count2.get()) { + long timeElapsed = System.currentTimeMillis() - timeStart; + player.getBukkitEntity().sendActionBar( + Component.text("Pasted ") + .append(Component.text(this.getName(), NamedTextColor.AQUA)) + .append(Component.text(" to world ")) + .append(Component.text(serverWorld.serverLevelData.getLevelName(), NamedTextColor.LIGHT_PURPLE)) + .append(Component.text(" in ")) + .append(Component.text(timeElapsed, NamedTextColor.GREEN)) + .append(Component.text("ms")) + ); + } else { + if (retryCount >= 0 || retryCount == -1) { + scheduleTask(plugin, serverWorld, count1, count2, player, timeStart, retryCount - 1); + } + } + }, 1); } }