9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2026-01-04 15:41:38 +00:00

修复已知问题

This commit is contained in:
XiaoMoMi
2025-09-30 18:27:58 +08:00
parent 26cf53ffb0
commit db07951974
5 changed files with 141 additions and 111 deletions

View File

@@ -41,10 +41,10 @@ public class DebugCleanCacheCommand extends BukkitCommandFeature<CommandSender>
@Override
public Command.Builder<? extends CommandSender> assembleCommand(org.incendo.cloud.CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) {
return builder
.required("type", StringParser.stringComponent().suggestionProvider(new SuggestionProvider<>() {
.optional("type", StringParser.stringComponent().suggestionProvider(new SuggestionProvider<>() {
@Override
public @NonNull CompletableFuture<? extends @NonNull Iterable<? extends @NonNull Suggestion>> suggestionsFuture(@NonNull CommandContext<Object> context, @NonNull CommandInput input) {
return CompletableFuture.completedFuture(List.of(Suggestion.suggestion("custom-model-data"), Suggestion.suggestion("custom-block-states"), Suggestion.suggestion("visual-block-states"), Suggestion.suggestion("font")));
return CompletableFuture.completedFuture(List.of(Suggestion.suggestion("custom-model-data"), Suggestion.suggestion("custom-block-states"), Suggestion.suggestion("visual-block-states"), Suggestion.suggestion("font"), Suggestion.suggestion("all")));
}
}))
.handler(context -> {
@@ -52,103 +52,17 @@ public class DebugCleanCacheCommand extends BukkitCommandFeature<CommandSender>
context.sender().sendMessage("The plugin is reloading. Please wait until the process is complete.");
return;
}
String type = context.get("type");
String type = context.getOrDefault("type", "all");
switch (type) {
case "custom-model-data" -> {
BukkitItemManager instance = BukkitItemManager.instance();
Map<Key, Set<String>> idsMap = new HashMap<>();
for (CustomItem<ItemStack> item : instance.loadedItems().values()) {
Set<String> ids = idsMap.computeIfAbsent(item.clientBoundMaterial(), k -> new HashSet<>());
ids.add(item.id().asString());
}
int total = 0;
for (Map.Entry<Key, IdAllocator> entry : getAllCachedCustomModelData().entrySet()) {
Set<String> ids = idsMap.getOrDefault(entry.getKey(), Collections.emptySet());
List<String> removed = entry.getValue().cleanupUnusedIds(i -> !ids.contains(i));
total += removed.size();
try {
entry.getValue().saveToCache();
} catch (IOException e) {
this.plugin().logger().warn("Error while saving custom model data allocation for material " + entry.getKey().asString(), e);
return;
}
for (String id : removed) {
this.plugin().logger().info("Cleaned unsued item: " + id);
}
}
context.sender().sendMessage("Cleaned " + total + " unused custom model data");
}
case "font", "images" -> {
BukkitFontManager instance = this.plugin().fontManager();
Map<Key, Set<String>> idsMap = new HashMap<>();
for (BitmapImage image : instance.loadedImages().values()) {
Set<String> ids = idsMap.computeIfAbsent(image.font(), k -> new HashSet<>());
String id = image.id().toString();
ids.add(id);
for (int i = 0; i < image.rows(); i++) {
for (int j = 0; j < image.columns(); j++) {
String imageArgs = id + ":" + i + ":" + j;
ids.add(imageArgs);
}
}
}
int total = 0;
for (Map.Entry<Key, IdAllocator> entry : getAllCachedFont().entrySet()) {
Key font = entry.getKey();
Set<String> ids = idsMap.getOrDefault(font, Collections.emptySet());
List<String> removed = entry.getValue().cleanupUnusedIds(i -> !ids.contains(i));
try {
entry.getValue().saveToCache();
} catch (IOException e) {
this.plugin().logger().warn("Error while saving codepoint allocation for font " + font.asString(), e);
return;
}
for (String id : removed) {
this.plugin().logger().info("Cleaned unsued image: " + id);
}
total += removed.size();
}
context.sender().sendMessage("Cleaned " + total + " unused codepoints");
}
case "custom-block-states" -> {
BukkitBlockManager instance = BukkitBlockManager.instance();
Set<String> ids = new HashSet<>();
for (CustomBlock customBlock : instance.loadedBlocks().values()) {
for (ImmutableBlockState state : customBlock.variantProvider().states()) {
ids.add(state.toString());
}
}
IdAllocator idAllocator = instance.blockParser().internalIdAllocator();
List<String> removed = idAllocator.cleanupUnusedIds(i -> !ids.contains(i));
try {
idAllocator.saveToCache();
} catch (IOException e) {
this.plugin().logger().warn("Error while saving custom block states allocation", e);
}
for (String id : removed) {
this.plugin().logger().info("Cleaned unsued block state: " + id);
}
context.sender().sendMessage("Cleaned " + removed.size() + " unused custom block states");
}
case "visual-block-states" -> {
BukkitBlockManager instance = BukkitBlockManager.instance();
Set<BlockStateWrapper> ids = new HashSet<>();
for (CustomBlock customBlock : instance.loadedBlocks().values()) {
for (ImmutableBlockState state : customBlock.variantProvider().states()) {
ids.add(state.vanillaBlockState());
}
}
VisualBlockStateAllocator visualBlockStateAllocator = instance.blockParser().visualBlockStateAllocator();
List<String> removed = visualBlockStateAllocator.cleanupUnusedIds(i -> !ids.contains(i));
try {
visualBlockStateAllocator.saveToCache();
} catch (IOException e) {
this.plugin().logger().warn("Error while saving visual block states allocation", e);
}
for (String id : removed) {
this.plugin().logger().info("Cleaned unsued block appearance: " + id);
}
context.sender().sendMessage("Cleaned " + removed.size() + " unused block state appearances");
case "custom-model-data" -> handleCustomModelData(context);
case "font", "images" -> handleFont(context);
case "custom-block-states" -> handleCustomBlockState(context);
case "visual-block-states" -> handleVisualBlockState(context);
case "all" -> {
handleCustomModelData(context);
handleFont(context);
handleCustomBlockState(context);
handleVisualBlockState(context);
}
}
});
@@ -159,6 +73,106 @@ public class DebugCleanCacheCommand extends BukkitCommandFeature<CommandSender>
return "debug_clean_cache";
}
private void handleVisualBlockState(CommandContext<CommandSender> context) {
BukkitBlockManager instance = BukkitBlockManager.instance();
Set<BlockStateWrapper> ids = new HashSet<>();
for (CustomBlock customBlock : instance.loadedBlocks().values()) {
for (ImmutableBlockState state : customBlock.variantProvider().states()) {
ids.add(state.vanillaBlockState());
}
}
VisualBlockStateAllocator visualBlockStateAllocator = instance.blockParser().visualBlockStateAllocator();
List<String> removed = visualBlockStateAllocator.cleanupUnusedIds(i -> !ids.contains(i));
try {
visualBlockStateAllocator.saveToCache();
} catch (IOException e) {
this.plugin().logger().warn("Error while saving visual block states allocation", e);
}
for (String id : removed) {
this.plugin().logger().info("Cleaned unsued block appearance: " + id);
}
context.sender().sendMessage("Cleaned " + removed.size() + " unused block state appearances");
}
private void handleCustomBlockState(CommandContext<CommandSender> context) {
BukkitBlockManager instance = BukkitBlockManager.instance();
Set<String> ids = new HashSet<>();
for (CustomBlock customBlock : instance.loadedBlocks().values()) {
for (ImmutableBlockState state : customBlock.variantProvider().states()) {
ids.add(state.toString());
}
}
IdAllocator idAllocator = instance.blockParser().internalIdAllocator();
List<String> removed = idAllocator.cleanupUnusedIds(i -> !ids.contains(i));
try {
idAllocator.saveToCache();
} catch (IOException e) {
this.plugin().logger().warn("Error while saving custom block states allocation", e);
}
for (String id : removed) {
this.plugin().logger().info("Cleaned unsued block state: " + id);
}
context.sender().sendMessage("Cleaned " + removed.size() + " unused custom block states");
}
private void handleFont(CommandContext<CommandSender> context) {
BukkitFontManager instance = this.plugin().fontManager();
Map<Key, Set<String>> idsMap = new HashMap<>();
for (BitmapImage image : instance.loadedImages().values()) {
Set<String> ids = idsMap.computeIfAbsent(image.font(), k -> new HashSet<>());
String id = image.id().toString();
ids.add(id);
for (int i = 0; i < image.rows(); i++) {
for (int j = 0; j < image.columns(); j++) {
String imageArgs = id + ":" + i + ":" + j;
ids.add(imageArgs);
}
}
}
int total = 0;
for (Map.Entry<Key, IdAllocator> entry : getAllCachedFont().entrySet()) {
Key font = entry.getKey();
Set<String> ids = idsMap.getOrDefault(font, Collections.emptySet());
List<String> removed = entry.getValue().cleanupUnusedIds(i -> !ids.contains(i));
try {
entry.getValue().saveToCache();
} catch (IOException e) {
this.plugin().logger().warn("Error while saving codepoint allocation for font " + font.asString(), e);
return;
}
for (String id : removed) {
this.plugin().logger().info("Cleaned unsued image: " + id);
}
total += removed.size();
}
context.sender().sendMessage("Cleaned " + total + " unused codepoints");
}
private void handleCustomModelData(CommandContext<CommandSender> context) {
BukkitItemManager instance = BukkitItemManager.instance();
Map<Key, Set<String>> idsMap = new HashMap<>();
for (CustomItem<ItemStack> item : instance.loadedItems().values()) {
Set<String> ids = idsMap.computeIfAbsent(item.clientBoundMaterial(), k -> new HashSet<>());
ids.add(item.id().asString());
}
int total = 0;
for (Map.Entry<Key, IdAllocator> entry : getAllCachedCustomModelData().entrySet()) {
Set<String> ids = idsMap.getOrDefault(entry.getKey(), Collections.emptySet());
List<String> removed = entry.getValue().cleanupUnusedIds(i -> !ids.contains(i));
total += removed.size();
try {
entry.getValue().saveToCache();
} catch (IOException e) {
this.plugin().logger().warn("Error while saving custom model data allocation for material " + entry.getKey().asString(), e);
return;
}
for (String id : removed) {
this.plugin().logger().info("Cleaned unsued item: " + id);
}
}
context.sender().sendMessage("Cleaned " + total + " unused custom model data");
}
public Map<Key, IdAllocator> getAllCachedCustomModelData() {
Path cacheDir = CraftEngine.instance().dataFolderPath().resolve("cache").resolve("custom-model-data");

View File

@@ -2,6 +2,7 @@ package net.momirealms.craftengine.bukkit.plugin.command.feature;
import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
@@ -10,6 +11,7 @@ import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager;
import net.momirealms.craftengine.core.plugin.command.sender.Sender;
import net.momirealms.craftengine.core.plugin.config.Config;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.command.CommandSender;
@@ -44,15 +46,14 @@ public class DebugTargetBlockCommand extends BukkitCommandFeature<CommandSender>
Sender sender = plugin().senderFactory().wrap(context.sender());
sender.sendMessage(Component.text(bData));
int id = BlockStateUtils.blockStateToId(blockState);
Object holder = BukkitBlockManager.instance().getMinecraftBlockHolder(id);
if (holder != null) {
if (!BlockStateUtils.isVanillaBlock(id)) {
Object holder = BukkitBlockManager.instance().getMinecraftBlockHolder(id);
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockState(id);
if (immutableBlockState != null) {
sender.sendMessage(Component.text(immutableBlockState.toString()));
}
ImmutableBlockState dataInCache = plugin().worldManager().getWorld(block.getWorld().getUID()).getBlockStateAtIfLoaded(LocationUtils.toBlockPos(block.getLocation()));
sender.sendMessage(Component.text("cache-state: " + !dataInCache.isEmpty()));
sender.sendMessage(Component.text("cache-state: " + (dataInCache != null && !dataInCache.isEmpty())));
try {
@SuppressWarnings("unchecked")
Set<Object> tags = (Set<Object>) CoreReflections.field$Holder$Reference$tags.get(holder);