From e2e8ef0f6a91ee20acbaa771d20a63c712dd27d7 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Mon, 14 Apr 2025 21:14:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=86=92=E9=99=A9=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E6=8C=96=E6=8E=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bukkit/loader/src/main/resources/config.yml | 175 +++++++++++------- .../bukkit/block/BlockEventListener.java | 22 ++- .../item/behavior/BlockItemBehavior.java | 17 +- .../plugin/network/PacketConsumers.java | 12 +- .../plugin/user/BukkitServerPlayer.java | 35 +--- .../core/entity/player/Player.java | 2 - .../core/font/AbstractFontManager.java | 2 +- .../craftengine/core/plugin/CraftEngine.java | 138 +++++++------- .../core/plugin/config/Config.java | 6 + gradle.properties | 4 +- .../craftengine/mod/block/CustomBlocks.java | 2 - 11 files changed, 233 insertions(+), 182 deletions(-) diff --git a/bukkit/loader/src/main/resources/config.yml b/bukkit/loader/src/main/resources/config.yml index e09b121c9..73ef75e8d 100644 --- a/bukkit/loader/src/main/resources/config.yml +++ b/bukkit/loader/src/main/resources/config.yml @@ -130,30 +130,53 @@ item: non-italic-tag: false block: + # Enables the sound system, which prevents the client from hearing some non-custom block sounds and improves the client experience. sound-system: enable: true + # In Adventure Mode, players need the correct tool to break custom blocks. + # Vanilla clients DO NOT recognize custom block IDs (e.g., craftengine:note_block_0). + # + # - When ENABLED: + # - Players can break custom blocks if their tools can mine their VANILLA EQUIVALENTS. + # Example: A tool for "note_block" can break "craftengine:note_block_0". + # + # - When DISABLED: + # ⚠️ WARNING: + # - Server MUST list ACTUAL CUSTOM BLOCK IDs in item's `can_break` component. + # - Sending custom IDs (e.g., craftengine:note_block_0) to vanilla clients WILL CRASH THEM! + # ✅ Solution: + # - Use `client-bound-item-data` to safely sync custom block data to clients. + # Documentation: https://mo-mi.gitbook.io/xiaomomi-plugins/craftengine/plugin-wiki/craftengine/add-new-contents/items/item-data/client-bound-item-data + simplify-adventure-break-check: true furniture: - # Should the plugin remove invalid furniture on chunk load + # Automatically remove outdated furniture entities when a chunk is loaded. remove-invalid-furniture-on-chunk-load: + # Enable/disable the cleanup system enable: false - # If you want to remove all invalid furniture, please set this list to empty, otherwise only furniture in the list will be removed. + # - When EMPTY: Remove ALL invalid furniture entities + # - When POPULATED: Only remove specified furniture types + # Example for targeted removal: + # list: [ "xxx:invalid_furniture", "yyy:broken_sofa" ] list: - "xxx:invalid_furniture" - # Whether to hide the entity containing metadata + # Hide technical entities used for storing furniture metadata. + # NOTE: + # - These are INVISIBLE entities used internally for tracking furniture states + # - Recommended to keep enabled for better performance hide-base-entity: true image: - # Prevent players from using images set in minecraft:default font - # Players with `craftengine.filter.bypass.xxx` would ignore the limitation + # Block image tags using minecraft:default font in these interfaces + # Permission bypass: craftengine.filter.bypass.xxx (replace xxx with context: anvil/book/chat/etc) illegal-characters-filter: anvil: true book: true chat: true command: true sign: true - # By intercepting packets, you are allowed to use in other plugins - # Turning off some unused options would help reduce CPU usage on async threads + # Allow and tags in third-party plugins via packet manipulation + # ⚠️ Disable unused handlers to reduce async thread workload intercept-packets: system-chat: true tab-list: true # Tab list header and footer @@ -168,17 +191,69 @@ image: entity-name: false armor-stand: true # Legacy Holograms text-display: true # Modern Holograms + # Defines Unicode characters used for positioning + # - Must match the font defined in resource packs + # - Do NOT modify unless you understand text rendering mechanics + offset-characters: + font: minecraft:offset_chars + -1: '\uf800' + -2: '\uf801' + -3: '\uf802' + -4: '\uf803' + -5: '\uf804' + -6: '\uf805' + -7: '\uf806' + -8: '\uf807' + -9: '\uf808' + -10: '\uf809' + -11: '\uf80a' + -12: '\uf80b' + -13: '\uf80c' + -14: '\uf80d' + -15: '\uf80e' + -16: '\uf80f' + -24: '\uf810' + -32: '\uf811' + -48: '\uf812' + -64: '\uf813' + -128: '\uf814' + -256: '\uf815' + 1: '\uf830' + 2: '\uf831' + 3: '\uf832' + 4: '\uf833' + 5: '\uf834' + 6: '\uf835' + 7: '\uf836' + 8: '\uf837' + 9: '\uf838' + 10: '\uf839' + 11: '\uf83a' + 12: '\uf83b' + 13: '\uf83c' + 14: '\uf83d' + 15: '\uf83e' + 16: '\uf83f' + 24: '\uf840' + 32: '\uf841' + 48: '\uf842' + 64: '\uf843' + 128: '\uf844' + 256: '\uf845' emoji: {} recipe: - # Enable the plugin's recipe system + # Master switch for custom recipes + # NOTE: When enabled, plugin recipes will OVERRIDE vanilla recipes enable: true - # Disable vanilla recipes + # Manage Minecraft's default recipe behavior disable-vanilla-recipes: - # Disable all vanilla recipes + # ⚠️ WARNING: When true, DISABLES ALL VANILLA RECIPES + # - Conflicts with 'list' option (list will be ignored) all: false - # Disable the recipes in list + # Selective recipe disabling (safer alternative to 'all: true') + # Example: ["minecraft:wooden_sword", "minecraft:stone_hoe"] list: [] gui: @@ -240,12 +315,13 @@ gui: performance: # Maximum chain update depth when fixing client visuals max-block-chain-update-limit: 64 - # Maximum number of emojis to parse per operation + # Prevent lag or oversized packet when processing emoji-heavy content max-emojis-per-parse: 16 light-system: + # Required for custom light-emitting blocks enable: true - # Turning this option on will reduce lighting system issues to some extent, but will increase server bandwidth consumption + # Turning this option on will reduce lighting system issues to some extent, but will increase server bandwidth consumption. force-update-light: false chunk-system: @@ -255,59 +331,28 @@ chunk-system: # 4 = LZ4 | Blazing-Fast Blazing-Fast Low Low | # 5 = ZSTD | Medium-Fast Fast High Medium | compression-method: 4 - # Disabling this option prevents the plugin from converting custom blocks to vanilla states when chunks are unloaded. - # While this can improve performance, custom blocks will turn into air if the plugin is uninstalled. + # Auto-convert custom blocks -> vanilla blocks when unloading chunks + # + # - When ENABLED (true): + # - Prevents custom blocks becoming AIR if plugin is uninstalled + # - Ensures world portability for vanilla environments + # + # - When DISABLED (false): + # ⚠️ IRREVERSIBLE DATA LOSS WARNING: + # - Custom blocks permanently turn to AIR without plugin + # - Recommended for temporary/test worlds only restore-vanilla-blocks-on-chunk-unload: true + # Convert vanilla blocks -> custom blocks when loading chunks + # + # - Performance Mode (false): + # ⚠️ REQUIRED CONDITIONS: + # 1. Must disable restore-vanilla-blocks-on-chunk-unload + # 2. Accept risk of custom block data loss on plugin removal + # + # - Compatibility Mode (true): + # - Full state recovery with minor performance cost + restore-custom-blocks-on-chunk-load: true # When you edit a map locally using CraftEngine fabric mod, the custom block data is not immediately synchronized with the # server's CraftEngine internal data. Enabling this option will synchronize the data when the chunk is loaded. # (This option only slightly impacts performance, which has been fully optimized, so you don't need to worry too much.) - sync-custom-blocks-on-chunk-load: false - # If you disable this, it's a must to disable the above option. - restore-custom-blocks-on-chunk-load: true - -offset-characters: - font: minecraft:offset_chars - -1: '\uf800' - -2: '\uf801' - -3: '\uf802' - -4: '\uf803' - -5: '\uf804' - -6: '\uf805' - -7: '\uf806' - -8: '\uf807' - -9: '\uf808' - -10: '\uf809' - -11: '\uf80a' - -12: '\uf80b' - -13: '\uf80c' - -14: '\uf80d' - -15: '\uf80e' - -16: '\uf80f' - -24: '\uf810' - -32: '\uf811' - -48: '\uf812' - -64: '\uf813' - -128: '\uf814' - -256: '\uf815' - 1: '\uf830' - 2: '\uf831' - 3: '\uf832' - 4: '\uf833' - 5: '\uf834' - 6: '\uf835' - 7: '\uf836' - 8: '\uf837' - 9: '\uf838' - 10: '\uf839' - 11: '\uf83a' - 12: '\uf83b' - 13: '\uf83c' - 14: '\uf83d' - 15: '\uf83e' - 16: '\uf83f' - 24: '\uf840' - 32: '\uf841' - 48: '\uf842' - 64: '\uf843' - 128: '\uf844' - 256: '\uf845' \ No newline at end of file + sync-custom-blocks-on-chunk-load: false \ No newline at end of file diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java index fda52637e..6e8b19e0d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java @@ -105,6 +105,27 @@ public class BlockEventListener implements Listener { ImmutableBlockState state = manager.getImmutableBlockStateUnsafe(stateId); if (!state.isEmpty()) { Location location = block.getLocation(); + BukkitServerPlayer serverPlayer = this.plugin.adapt(player); + // double check to prevent dupe + if (serverPlayer.isAdventureMode()) { + Object itemStack = FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(player.getInventory().getItemInMainHand()); + Object blockPos = LocationUtils.toBlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + try { + Object blockInWorld = Reflections.constructor$BlockInWorld.newInstance(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(location.getWorld()), blockPos, false); + if (VersionHelper.isVersionNewerThan1_20_5()) { + if (Reflections.method$ItemStack$canBreakBlockInAdventureMode != null && !(boolean) Reflections.method$ItemStack$canBreakBlockInAdventureMode.invoke(itemStack, blockInWorld)) { + return; + } + } else { + if (Reflections.method$ItemStack$canDestroy != null && !(boolean) Reflections.method$ItemStack$canDestroy.invoke(itemStack, Reflections.instance$BuiltInRegistries$BLOCK, blockInWorld)) { + return; + } + } + } catch (ReflectiveOperationException e) { + this.plugin.logger().warn("Failed to double check adventure mode", e); + return; + } + } // trigger event CustomBlockBreakEvent customBreakEvent = new CustomBlockBreakEvent(event.getPlayer(), location, block, state); @@ -131,7 +152,6 @@ public class BlockEventListener implements Listener { return; } - BukkitServerPlayer serverPlayer = this.plugin.adapt(player); Item itemInHand = serverPlayer.getItemInHand(InteractionHand.MAIN_HAND); Key itemId = Optional.ofNullable(itemInHand).map(Item::id).orElse(ItemKeys.AIR); // do not drop if it's not the correct tool diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java index 14702bf00..dfcee504b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/behavior/BlockItemBehavior.java @@ -76,22 +76,25 @@ public class BlockItemBehavior extends ItemBehavior { return InteractionResult.FAIL; } Player player = placeContext.getPlayer(); - int gameTicks = player.gameTicks(); - if (!player.updateLastSuccessfulInteractionTick(gameTicks)) { - return InteractionResult.FAIL; - } - BlockPos pos = placeContext.getClickedPos(); BlockPos againstPos = placeContext.getAgainstPos(); World world = (World) placeContext.getLevel().platformWorld(); Location placeLocation = new Location(world, pos.x(), pos.y(), pos.z()); + // todo adventure check + if (player.isAdventureMode()) { + + } + + int gameTicks = player.gameTicks(); + if (!player.updateLastSuccessfulInteractionTick(gameTicks)) { + return InteractionResult.FAIL; + } + Block bukkitBlock = world.getBlockAt(placeLocation); Block againstBlock = world.getBlockAt(againstPos.x(), againstPos.y(), againstPos.z()); org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) player.platformPlayer(); - // todo adventure check - // trigger event CustomBlockAttemptPlaceEvent attemptPlaceEvent = new CustomBlockAttemptPlaceEvent(bukkitPlayer, placeLocation.clone(), blockStateToPlace, DirectionUtils.toBlockFace(context.getClickedFace()), bukkitBlock, context.getHand()); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index 76235e0dd..98a1187b6 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -1127,23 +1127,17 @@ public class PacketConsumers { } return; } - if (player.isAdventureMode()) { + if (player.isAdventureMode() && !Config.simplyAdventureCheck()) { Object itemStack = FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(player.platformPlayer().getInventory().getItemInMainHand()); Object blockPos = LocationUtils.toBlockPos(pos); Object blockInWorld = Reflections.constructor$BlockInWorld.newInstance(serverLevel, blockPos, false); if (VersionHelper.isVersionNewerThan1_20_5()) { - if (Reflections.method$ItemStack$canBreakBlockInAdventureMode != null - && !(boolean) Reflections.method$ItemStack$canBreakBlockInAdventureMode.invoke( - itemStack, blockInWorld - )) { + if (Reflections.method$ItemStack$canBreakBlockInAdventureMode != null && !(boolean) Reflections.method$ItemStack$canBreakBlockInAdventureMode.invoke(itemStack, blockInWorld)) { player.preventMiningBlock(); return; } } else { - if (Reflections.method$ItemStack$canDestroy != null - && !(boolean) Reflections.method$ItemStack$canDestroy.invoke( - itemStack, Reflections.instance$BuiltInRegistries$BLOCK, blockInWorld - )) { + if (Reflections.method$ItemStack$canDestroy != null && !(boolean) Reflections.method$ItemStack$canDestroy.invoke(itemStack, Reflections.instance$BuiltInRegistries$BLOCK, blockInWorld)) { player.preventMiningBlock(); return; } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java index 130b1ec19..ecdf99d2e 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/user/BukkitServerPlayer.java @@ -16,6 +16,7 @@ import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.ItemKeys; import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.plugin.network.ConnectionState; import net.momirealms.craftengine.core.util.Direction; import net.momirealms.craftengine.core.util.Key; @@ -215,31 +216,6 @@ public class BukkitServerPlayer extends Player { platformPlayer().closeInventory(); } - // TODO DO NOT USE BUKKIT API - @Override - public BlockHitResult rayTrace(double distance, FluidCollisionRule collisionRule) { - RayTraceResult result = platformPlayer().rayTraceBlocks(distance, FluidUtils.toCollisionRule(collisionRule)); - if (result == null) { - Location eyeLocation = platformPlayer().getEyeLocation(); - Location targetLocation = eyeLocation.clone(); - targetLocation.add(eyeLocation.getDirection().multiply(distance)); - return BlockHitResult.miss(new Vec3d(eyeLocation.getX(), eyeLocation.getY(), eyeLocation.getZ()), - Direction.getApproximateNearest(eyeLocation.getX() - targetLocation.getX(), eyeLocation.getY() - targetLocation.getY(), eyeLocation.getZ() - targetLocation.getZ()), - new BlockPos(targetLocation.getBlockX(), targetLocation.getBlockY(), targetLocation.getBlockZ()) - ); - } else { - Vector hitPos = result.getHitPosition(); - Block hitBlock = result.getHitBlock(); - Location hitBlockLocation = hitBlock.getLocation(); - return new BlockHitResult( - new Vec3d(hitPos.getX(), hitPos.getY(), hitPos.getZ()), - DirectionUtils.toDirection(result.getHitBlockFace()), - new BlockPos(hitBlockLocation.getBlockX(), hitBlockLocation.getBlockY(), hitBlockLocation.getBlockZ()), - false - ); - } - } - @Override public void sendPacket(Object packet, boolean immediately) { this.plugin.networkManager().sendPacket(this, packet, immediately); @@ -463,8 +439,13 @@ public class BukkitServerPlayer extends Player { } if (this.miningProgress >= 1f) { - //Reflections.method$ServerLevel$levelEvent.invoke(Reflections.field$CraftWorld$ServerLevel.get(player.getWorld()), null, 2001, blockPos, BlockStateUtils.blockStateToId(this.destroyedState)); - Reflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos); + if (isAdventureMode() && Config.simplyAdventureCheck()) { + player.setGameMode(GameMode.SURVIVAL); + Reflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos); + player.setGameMode(GameMode.ADVENTURE); + } else { + Reflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos); + } Object levelEventPacket = Reflections.constructor$ClientboundLevelEventPacket.newInstance(2001, blockPos, id, false); sendPacket(levelEventPacket, false); this.stopMiningBlock(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java b/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java index e23eb0a40..55ce16f34 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java +++ b/core/src/main/java/net/momirealms/craftengine/core/entity/player/Player.java @@ -75,7 +75,5 @@ public abstract class Player extends Entity implements NetWorkUser { public abstract void closeInventory(); - public abstract BlockHitResult rayTrace(double distance, FluidCollisionRule collisionRule); - public abstract void clearView(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java b/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java index 2ccb72aa8..072010f25 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/font/AbstractFontManager.java @@ -51,7 +51,7 @@ public abstract class AbstractFontManager implements FontManager { @Override public void load() { - this.offsetFont = Optional.ofNullable(plugin.config().settings().getSection("offset-characters")) + this.offsetFont = Optional.ofNullable(plugin.config().settings().getSection("image.offset-characters")) .map(OffsetFont::new) .orElse(null); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java index 4c9540d7a..0987a2c35 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/CraftEngine.java @@ -32,6 +32,7 @@ import net.momirealms.craftengine.core.sound.SoundManager; import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.world.WorldManager; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.Logger; import java.util.ArrayList; import java.util.List; @@ -90,8 +91,8 @@ public abstract class CraftEngine implements Plugin { } public void onPluginLoad() { - ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).addFilter(new LogFilter()); - ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).addFilter(new DisconnectLogFilter()); + ((Logger) LogManager.getRootLogger()).addFilter(new LogFilter()); + ((Logger) LogManager.getRootLogger()).addFilter(new DisconnectLogFilter()); this.dependencyManager = new DependencyManagerImpl(this); ArrayList dependenciesToLoad = new ArrayList<>(); dependenciesToLoad.addAll(commonDependencies()); @@ -115,72 +116,77 @@ public abstract class CraftEngine implements Plugin { public CompletableFuture reloadPlugin(Executor asyncExecutor, Executor syncExecutor, boolean reloadRecipe) { CompletableFuture future = new CompletableFuture<>(); asyncExecutor.execute(() -> { - if (this.isReloading) { - future.complete(ReloadResult.failure()); - return; - } - this.isReloading = true; - long time1 = System.currentTimeMillis(); - // firstly reload main config - this.config.load(); - // reset debugger - this.debugger = Config.debug() ? (s) -> logger.info("[Debug] " + s.get()) : (s) -> {}; - // now we reload the translations - this.translationManager.reload(); - // clear the outdated cache by reloading the managers - this.templateManager.reload(); - this.furnitureManager.reload(); - this.fontManager.reload(); - this.itemManager.reload(); - this.soundManager.reload(); - this.itemBrowserManager.reload(); - this.blockManager.reload(); - this.worldManager.reload(); - this.vanillaLootManager.reload(); - this.guiManager.reload(); - this.packManager.reload(); - if (reloadRecipe) { - this.recipeManager.reload(); - } + long asyncTime = -1; try { - // now we load resources - this.packManager.loadResources(reloadRecipe); - } catch (Exception e) { - this.logger().warn("Failed to load resources folder", e); - } - // init suggestions and packet mapper - this.blockManager.delayedLoad(); - // handle some special client lang for instance block_name - this.translationManager.delayedLoad(); - // init suggestions - this.furnitureManager.delayedLoad(); - // sort the categories - this.itemBrowserManager.delayedLoad(); - // collect illegal characters from minecraft:default font - this.fontManager.delayedLoad(); - if (reloadRecipe) { - // convert data pack recipes - this.recipeManager.delayedLoad(); - } - long time2 = System.currentTimeMillis(); - long asyncTime = time2 - time1; - syncExecutor.execute(() -> { - try { - long time3 = System.currentTimeMillis(); - // register songs - this.soundManager.runDelayedSyncTasks(); - // register recipes - if (reloadRecipe) { - this.recipeManager.runDelayedSyncTasks(); - } - long time4 = System.currentTimeMillis(); - long syncTime = time4 - time3; - this.reloadEventDispatcher.accept(this); - future.complete(ReloadResult.success(asyncTime, syncTime)); - } finally { - this.isReloading = false; + if (this.isReloading) { + future.complete(ReloadResult.failure()); + return; } - }); + this.isReloading = true; + long time1 = System.currentTimeMillis(); + // firstly reload main config + this.config.load(); + // reset debugger + this.debugger = Config.debug() ? (s) -> logger.info("[Debug] " + s.get()) : (s) -> {}; + // now we reload the translations + this.translationManager.reload(); + // clear the outdated cache by reloading the managers + this.templateManager.reload(); + this.furnitureManager.reload(); + this.fontManager.reload(); + this.itemManager.reload(); + this.soundManager.reload(); + this.itemBrowserManager.reload(); + this.blockManager.reload(); + this.worldManager.reload(); + this.vanillaLootManager.reload(); + this.guiManager.reload(); + this.packManager.reload(); + if (reloadRecipe) { + this.recipeManager.reload(); + } + try { + // now we load resources + this.packManager.loadResources(reloadRecipe); + } catch (Exception e) { + this.logger().warn("Failed to load resources folder", e); + } + // init suggestions and packet mapper + this.blockManager.delayedLoad(); + // handle some special client lang for instance block_name + this.translationManager.delayedLoad(); + // init suggestions + this.furnitureManager.delayedLoad(); + // sort the categories + this.itemBrowserManager.delayedLoad(); + // collect illegal characters from minecraft:default font + this.fontManager.delayedLoad(); + if (reloadRecipe) { + // convert data pack recipes + this.recipeManager.delayedLoad(); + } + long time2 = System.currentTimeMillis(); + asyncTime = time2 - time1; + } finally { + long finalAsyncTime = asyncTime; + syncExecutor.execute(() -> { + try { + long time3 = System.currentTimeMillis(); + // register songs + this.soundManager.runDelayedSyncTasks(); + // register recipes + if (reloadRecipe) { + this.recipeManager.runDelayedSyncTasks(); + } + long time4 = System.currentTimeMillis(); + long syncTime = time4 - time3; + this.reloadEventDispatcher.accept(this); + future.complete(ReloadResult.success(finalAsyncTime, syncTime)); + } finally { + this.isReloading = false; + } + }); + } }); return future; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java index 13f81cb36..4564e5a26 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java @@ -111,6 +111,7 @@ public class Config { protected boolean furniture$hide_base_entity; protected boolean block$sound_system$enable; + protected boolean block$simply_adventure_break_check; protected boolean recipe$enable; protected boolean recipe$disable_vanilla_recipes$all; @@ -281,6 +282,7 @@ public class Config { // block block$sound_system$enable = config.getBoolean("block.sound-system.enable", true); + block$simply_adventure_break_check = config.getBoolean("block.simplify-adventure-break-check", true); // recipe recipe$enable = config.getBoolean("recipe.enable", true); @@ -390,6 +392,10 @@ public class Config { return instance.block$sound_system$enable; } + public static boolean simplyAdventureCheck() { + return instance.block$simply_adventure_break_check; + } + public static boolean enableRecipeSystem() { return instance.recipe$enable; } diff --git a/gradle.properties b/gradle.properties index d337d0b44..76e0bb555 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,8 +2,8 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.47.4 -config_version=25 +project_version=0.0.47.5 +config_version=26 lang_version=4 project_group=net.momirealms latest_supported_version=1.21.5 diff --git a/server-mod/src/main/java/net/momirealms/craftengine/mod/block/CustomBlocks.java b/server-mod/src/main/java/net/momirealms/craftengine/mod/block/CustomBlocks.java index 789309405..36af40eab 100644 --- a/server-mod/src/main/java/net/momirealms/craftengine/mod/block/CustomBlocks.java +++ b/server-mod/src/main/java/net/momirealms/craftengine/mod/block/CustomBlocks.java @@ -14,14 +14,12 @@ import net.momirealms.craftengine.mod.util.NoteBlockUtils; import net.momirealms.craftengine.mod.util.Reflections; import org.bukkit.configuration.file.YamlConfiguration; -import java.io.StringReader; import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; -import java.util.Objects; public class CustomBlocks {