From a85b94392ee9945c645bc10e2e466467865d26de Mon Sep 17 00:00:00 2001
From: XiaoMoMi <972454774@qq.com>
Date: Tue, 30 Sep 2025 01:14:40 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A4=96=E8=A7=82=E6=96=B9=E5=9D=97=E5=88=86?=
=?UTF-8?q?=E9=85=8D=20=E6=9C=AA=E6=B5=8B=E8=AF=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../bukkit/api/BukkitAdaptors.java | 48 ++-
.../bukkit/api/CraftEngineImages.java | 40 +++
.../bukkit/block/BukkitBlockManager.java | 17 +-
.../bukkit/font/BukkitFontManager.java | 6 +
.../bukkit/plugin/BukkitCraftEngine.java | 5 +
.../plugin/command/BukkitCommandManager.java | 3 +-
.../feature/DebugCleanCacheCommand.java | 84 +++++
common-files/src/main/resources/commands.yml | 7 +
.../configuration/blocks/chessboard_block.yml | 8 +-
.../configuration/blocks/chinese_lantern.yml | 2 +-
.../configuration/blocks/copper_coil.yml | 4 +-
.../blocks/ender_pearl_flower.yml | 6 +-
.../configuration/blocks/fairy_flower.yml | 2 +-
.../configuration/blocks/flame_cane.yml | 2 +-
.../configuration/blocks/gunpowder_block.yml | 4 +-
.../configuration/blocks/palm_tree.yml | 8 +-
.../default/configuration/blocks/pebble.yml | 6 +-
.../default/configuration/blocks/reed.yml | 2 +-
.../configuration/blocks/safe_block.yml | 16 +-
.../configuration/blocks/topaz_ore.yml | 2 +-
.../default/configuration/templates.yml | 246 +------------
.../src/main/resources/translations/en.yml | 2 +
.../core/block/AbstractBlockManager.java | 332 +++++++++++-------
.../core/block/AbstractBlockStateWrapper.java | 12 +
.../core/block/AutoStateGroup.java | 65 +++-
.../craftengine/core/block/BlockKeys.java | 10 +
.../core/block/BlockStateWrapper.java | 8 +-
.../core/font/AbstractFontManager.java | 10 +
.../craftengine/core/font/FontManager.java | 4 +
.../core/item/AbstractItemManager.java | 8 +
.../core/pack/AbstractPackManager.java | 10 +-
.../pack/allocator/BlockStateAllocator.java | 33 --
.../core/pack/allocator/IdAllocator.java | 6 +-
.../allocator/VisualBlockStateAllocator.java | 152 ++++++++
.../allocator/cache/AllocationCacheFile.java | 62 ++++
.../allocator/cache/CacheFileStorage.java | 98 ++++++
.../pack/allocator/cache/CacheFileType.java | 39 ++
.../pack/allocator/cache/CacheSerializer.java | 51 +++
.../pack/allocator/cache/CacheStorage.java | 32 ++
39 files changed, 975 insertions(+), 477 deletions(-)
create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineImages.java
create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/DebugCleanCacheCommand.java
delete mode 100644 core/src/main/java/net/momirealms/craftengine/core/pack/allocator/BlockStateAllocator.java
create mode 100644 core/src/main/java/net/momirealms/craftengine/core/pack/allocator/VisualBlockStateAllocator.java
create mode 100644 core/src/main/java/net/momirealms/craftengine/core/pack/allocator/cache/AllocationCacheFile.java
create mode 100644 core/src/main/java/net/momirealms/craftengine/core/pack/allocator/cache/CacheFileStorage.java
create mode 100644 core/src/main/java/net/momirealms/craftengine/core/pack/allocator/cache/CacheFileType.java
create mode 100644 core/src/main/java/net/momirealms/craftengine/core/pack/allocator/cache/CacheSerializer.java
create mode 100644 core/src/main/java/net/momirealms/craftengine/core/pack/allocator/cache/CacheStorage.java
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/BukkitAdaptors.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/BukkitAdaptors.java
index 6dcd0167a..c667f832e 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/BukkitAdaptors.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/BukkitAdaptors.java
@@ -3,37 +3,63 @@ package net.momirealms.craftengine.bukkit.api;
import net.momirealms.craftengine.bukkit.entity.BukkitEntity;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
-import net.momirealms.craftengine.bukkit.util.LocationUtils;
import net.momirealms.craftengine.bukkit.world.BukkitExistingBlock;
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
-import net.momirealms.craftengine.core.world.WorldPosition;
-import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
public final class BukkitAdaptors {
private BukkitAdaptors() {}
- public static BukkitServerPlayer adapt(final Player player) {
+ /**
+ * Adapts a Bukkit Player to a CraftEngine BukkitServerPlayer.
+ * This provides access to CraftEngine-specific player functionality and data.
+ *
+ * @param player the Bukkit Player to adapt, must not be null
+ * @return a non-null BukkitServerPlayer instance wrapping the provided player
+ */
+ @NotNull
+ public static BukkitServerPlayer adapt(@NotNull final Player player) {
return BukkitCraftEngine.instance().adapt(player);
}
- public static BukkitWorld adapt(final World world) {
+ /**
+ * Adapts a Bukkit World to a CraftEngine BukkitWorld.
+ * This enables CraftEngine world operations on Bukkit world instances.
+ *
+ * @param world the Bukkit World to adapt, must not be null
+ * @return a non-null BukkitWorld instance wrapping the provided world
+ */
+ @NotNull
+ public static BukkitWorld adapt(@NotNull final World world) {
return new BukkitWorld(world);
}
- public static BukkitEntity adapt(final Entity entity) {
+ /**
+ * Adapts a Bukkit Entity to a CraftEngine BukkitEntity.
+ * This provides CraftEngine entity functionality for Bukkit entities.
+ *
+ * @param entity the Bukkit Entity to adapt, must not be null
+ * @return a non-null BukkitEntity instance wrapping the provided entity
+ */
+ @NotNull
+ public static BukkitEntity adapt(@NotNull final Entity entity) {
return new BukkitEntity(entity);
}
- public static BukkitExistingBlock adapt(final Block block) {
+ /**
+ * Adapts a Bukkit Block to a CraftEngine BukkitExistingBlock.
+ * This enables CraftEngine block operations on Bukkit block instances.
+ *
+ * @param block the Bukkit Block to adapt, must not be null
+ * @return a non-null BukkitExistingBlock instance wrapping the provided block
+ */
+ @NotNull
+ public static BukkitExistingBlock adapt(@NotNull final Block block) {
return new BukkitExistingBlock(block);
}
-
- public static Location toLocation(WorldPosition position) {
- return LocationUtils.toLocation(position);
- }
}
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineImages.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineImages.java
new file mode 100644
index 000000000..3a420339f
--- /dev/null
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/CraftEngineImages.java
@@ -0,0 +1,40 @@
+package net.momirealms.craftengine.bukkit.api;
+
+import net.momirealms.craftengine.bukkit.font.BukkitFontManager;
+import net.momirealms.craftengine.core.font.BitmapImage;
+import net.momirealms.craftengine.core.util.Key;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Map;
+
+public final class CraftEngineImages {
+
+ private CraftEngineImages() {}
+
+ /**
+ * Returns an unmodifiable map of all currently loaded custom images.
+ * The map keys represent unique identifiers, and the values are the corresponding BitmapImage instances.
+ *
+ *
Important: Do not attempt to access this method during the onEnable phase
+ * as it will be empty. Instead, listen for the {@code CraftEngineReloadEvent} and use this method
+ * after the event is fired to obtain the complete image list.
+ *
+ * @return a non-null map containing all loaded custom images
+ */
+ @NotNull
+ public static Map loadedImages() {
+ return BukkitFontManager.instance().loadedImages();
+ }
+
+ /**
+ * Gets a custom image by ID
+ *
+ * @param id id
+ * @return the custom image
+ */
+ @Nullable
+ public static BitmapImage byId(@NotNull Key id) {
+ return BukkitFontManager.instance().loadedImages().get(id);
+ }
+}
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java
index 36c421336..abcf5d08f 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java
@@ -44,7 +44,7 @@ public final class BukkitBlockManager extends AbstractBlockManager {
// 事件监听器
private final BlockEventListener blockEventListener;
// 用于缓存string形式的方块状态到原版方块状态
- private final Map blockStateCache = new HashMap<>(1024);
+ private final Map blockStateCache = new HashMap<>(1024);
// 用于临时存储可燃烧自定义方块的列表
private final List burnableBlocks = new ArrayList<>();
// 可燃烧的方块
@@ -169,25 +169,22 @@ public final class BukkitBlockManager extends AbstractBlockManager {
@Override
public BlockStateWrapper createVanillaBlockState(String blockState) {
- Object state = parseBlockState(blockState);
- if (state == null) return null;
- return BlockStateUtils.toBlockStateWrapper(state);
+ return this.blockStateCache.computeIfAbsent(blockState, k -> {
+ Object state = parseBlockState(k);
+ if (state == null) return null;
+ return BlockStateUtils.toBlockStateWrapper(state);
+ });
}
@Nullable
private Object parseBlockState(String state) {
- if (this.blockStateCache.containsKey(state)) {
- return this.blockStateCache.get(state);
- }
try {
Object registryOrLookUp = MBuiltInRegistries.BLOCK;
if (CoreReflections.method$Registry$asLookup != null) {
registryOrLookUp = CoreReflections.method$Registry$asLookup.invoke(registryOrLookUp);
}
Object result = CoreReflections.method$BlockStateParser$parseForBlock.invoke(null, registryOrLookUp, state, false);
- Object resultState = CoreReflections.method$BlockStateParser$BlockResult$blockState.invoke(result);
- this.blockStateCache.put(state, resultState);
- return resultState;
+ return CoreReflections.method$BlockStateParser$BlockResult$blockState.invoke(result);
} catch (Exception e) {
Debugger.BLOCK.warn(() -> "Failed to create block state: " + state, e);
return null;
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java
index f6304a758..637fb20a5 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/font/BukkitFontManager.java
@@ -36,11 +36,17 @@ import java.lang.reflect.InvocationTargetException;
import java.util.*;
public class BukkitFontManager extends AbstractFontManager implements Listener {
+ private static BukkitFontManager instance;
private final BukkitCraftEngine plugin;
public BukkitFontManager(BukkitCraftEngine plugin) {
super(plugin);
this.plugin = plugin;
+ instance = this;
+ }
+
+ public static BukkitFontManager instance() {
+ return instance;
}
@Override
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitCraftEngine.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitCraftEngine.java
index e5a984612..fe991ca7f 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitCraftEngine.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/BukkitCraftEngine.java
@@ -348,6 +348,11 @@ public class BukkitCraftEngine extends CraftEngine {
return (BukkitPackManager) packManager;
}
+ @Override
+ public BukkitFontManager fontManager() {
+ return (BukkitFontManager) fontManager;
+ }
+
@SuppressWarnings("ResultOfMethodCallIgnored")
@Override
public void saveResource(String resourcePath) {
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java
index 024b38db9..14c4d9378 100644
--- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/BukkitCommandManager.java
@@ -56,7 +56,8 @@ public class BukkitCommandManager extends AbstractCommandManager
new ListResourceCommand(this, plugin),
new UploadPackCommand(this, plugin),
new SendResourcePackCommand(this, plugin),
- new DebugSaveDefaultResourcesCommand(this, plugin)
+ new DebugSaveDefaultResourcesCommand(this, plugin),
+ new DebugCleanCacheCommand(this, plugin)
));
final LegacyPaperCommandManager manager = (LegacyPaperCommandManager) getCommandManager();
manager.settings().set(ManagerSetting.ALLOW_UNSAFE_REGISTRATION, true);
diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/DebugCleanCacheCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/DebugCleanCacheCommand.java
new file mode 100644
index 000000000..8337140f6
--- /dev/null
+++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/DebugCleanCacheCommand.java
@@ -0,0 +1,84 @@
+package net.momirealms.craftengine.bukkit.plugin.command.feature;
+
+import net.momirealms.craftengine.bukkit.api.CraftEngineItems;
+import net.momirealms.craftengine.bukkit.font.BukkitFontManager;
+import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
+import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
+import net.momirealms.craftengine.core.pack.allocator.IdAllocator;
+import net.momirealms.craftengine.core.plugin.CraftEngine;
+import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager;
+import net.momirealms.craftengine.core.util.Key;
+import org.bukkit.command.CommandSender;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.incendo.cloud.Command;
+import org.incendo.cloud.context.CommandContext;
+import org.incendo.cloud.context.CommandInput;
+import org.incendo.cloud.parser.standard.StringParser;
+import org.incendo.cloud.suggestion.Suggestion;
+import org.incendo.cloud.suggestion.SuggestionProvider;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+public class DebugCleanCacheCommand extends BukkitCommandFeature {
+
+ public DebugCleanCacheCommand(CraftEngineCommandManager commandManager, CraftEngine plugin) {
+ super(commandManager, plugin);
+ }
+
+ @Override
+ public Command.Builder extends CommandSender> assembleCommand(org.incendo.cloud.CommandManager manager, Command.Builder builder) {
+ return builder
+ .required("type", StringParser.stringComponent().suggestionProvider(new SuggestionProvider<>() {
+ @Override
+ public @NonNull CompletableFuture extends @NonNull Iterable extends @NonNull Suggestion>> suggestionsFuture(@NonNull CommandContext