diff --git a/bukkit/loader/src/main/resources/config.yml b/bukkit/loader/src/main/resources/config.yml index e4aa5638c..2a1105a77 100644 --- a/bukkit/loader/src/main/resources/config.yml +++ b/bukkit/loader/src/main/resources/config.yml @@ -136,6 +136,8 @@ furniture: # If you want to remove all invalid furniture, please set this list to empty, otherwise only furniture in the list will be removed. list: - "xxx:invalid_furniture" + # Whether to hide the entity containing metadata + hide-base-entity: true image: # Prevent players from using images set in minecraft:default font @@ -209,20 +211,22 @@ gui: performance: # Maximum chain update depth when fixing client visuals max-block-chain-update-limit: 64 - light-system: - enable: true - # Turning this option on will reduce lighting system issues to some extent, but will increase server bandwidth consumption - force-update-light: false - chunk-system: - # 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. - restore-vanilla-blocks-on-chunk-unload: 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 + +light-system: + enable: true + # Turning this option on will reduce lighting system issues to some extent, but will increase server bandwidth consumption + force-update-light: false + +chunk-system: + # 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. + restore-vanilla-blocks-on-chunk-unload: 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:default diff --git a/bukkit/loader/src/main/resources/resources/internal/configuration/gui.yml b/bukkit/loader/src/main/resources/resources/internal/configuration/gui.yml index 827a861ed..9c32bd009 100644 --- a/bukkit/loader/src/main/resources/resources/internal/configuration/gui.yml +++ b/bukkit/loader/src/main/resources/resources/internal/configuration/gui.yml @@ -74,9 +74,16 @@ templates: item-name: "{name}" lore: "{lore}" model: - template: "default:model/simplified_generated" + template: "internal:model/simplified_generated" arguments: path: "minecraft:item/custom/gui/{texture}" + internal:model/simplified_generated: + type: "minecraft:model" + path: "{path}" + generation: + parent: "minecraft:item/generated" + textures: + "layer0": "{path}" items: internal:next_page_0: 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 3eae94443..46b5e204e 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 @@ -7,6 +7,8 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import dev.dejvokep.boostedyaml.YamlDocument; +import net.momirealms.craftengine.bukkit.block.worldedit.WorldEditCommandHelper; +import net.momirealms.craftengine.bukkit.block.worldedit.WorldEditBlockRegister; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.injector.BukkitInjector; import net.momirealms.craftengine.bukkit.plugin.network.PacketConsumers; @@ -84,10 +86,14 @@ public class BukkitBlockManager extends AbstractBlockManager { private final Map modBlockStates = new HashMap<>(); // Cached command suggestions private final List cachedSuggestions = new ArrayList<>(); + // Cached Namespace + private final Set namespacesInUse = new HashSet<>(); // Event listeners private final BlockEventListener blockEventListener; private final FallingBlockRemoveListener fallingBlockRemoveListener; + private WorldEditCommandHelper weCommandHelper; + public BukkitBlockManager(BukkitCraftEngine plugin) { super(plugin); this.plugin = plugin; @@ -125,6 +131,19 @@ public class BukkitBlockManager extends AbstractBlockManager { if (this.fallingBlockRemoveListener != null) { Bukkit.getPluginManager().registerEvents(this.fallingBlockRemoveListener, plugin.bootstrap()); } + boolean hasWE = false; + // WorldEdit + if (this.plugin.isPluginEnabled("FastAsyncWorldEdit")) { + this.initFastAsyncWorldEditHook(); + hasWE = true; + } else if (this.plugin.isPluginEnabled("WorldEdit")) { + this.initWorldEditHook(); + hasWE = true; + } + if (hasWE) { + this.weCommandHelper = new WorldEditCommandHelper(this.plugin, this); + this.weCommandHelper.enable(); + } } @Override @@ -145,6 +164,7 @@ public class BukkitBlockManager extends AbstractBlockManager { this.unload(); HandlerList.unregisterAll(this.blockEventListener); if (this.fallingBlockRemoveListener != null) HandlerList.unregisterAll(this.fallingBlockRemoveListener); + if (this.weCommandHelper != null) this.weCommandHelper.disable(); } @Override @@ -172,7 +192,7 @@ public class BukkitBlockManager extends AbstractBlockManager { public void initWorldEditHook() { try { for (Key newBlockId : this.blockRegisterOrder) { - WorldEditHook.register(newBlockId); + WorldEditBlockRegister.register(newBlockId); } } catch (Exception e) { this.plugin.logger().warn("Failed to initialize world edit hook", e); @@ -225,9 +245,11 @@ public class BukkitBlockManager extends AbstractBlockManager { @Override public void initSuggestions() { this.cachedSuggestions.clear(); + this.namespacesInUse.clear(); Set states = new HashSet<>(); for (CustomBlock block : this.id2CraftEngineBlocks.values()) { states.add(block.id().toString()); + this.namespacesInUse.add(block.id().namespace()); for (ImmutableBlockState state : block.variantProvider().states()) { states.add(state.toString()); } @@ -237,6 +259,10 @@ public class BukkitBlockManager extends AbstractBlockManager { } } + public Set namespacesInUse() { + return Collections.unmodifiableSet(namespacesInUse); + } + public ImmutableMap> blockAppearanceArranger() { return blockAppearanceArranger; } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/WorldEditHook.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/worldedit/WorldEditBlockRegister.java similarity index 90% rename from bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/WorldEditHook.java rename to bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/worldedit/WorldEditBlockRegister.java index f4992949e..279ada1c2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/WorldEditHook.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/worldedit/WorldEditBlockRegister.java @@ -1,4 +1,4 @@ -package net.momirealms.craftengine.bukkit.block; +package net.momirealms.craftengine.bukkit.block.worldedit; import com.sk89q.worldedit.bukkit.BukkitBlockRegistry; import com.sk89q.worldedit.util.concurrency.LazyReference; @@ -9,7 +9,7 @@ import org.bukkit.Material; import java.lang.reflect.Field; -public class WorldEditHook { +public class WorldEditBlockRegister { private static final Field field$BlockType$blockMaterial; static { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/worldedit/WorldEditCommandHelper.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/worldedit/WorldEditCommandHelper.java new file mode 100644 index 000000000..31d3f331d --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/worldedit/WorldEditCommandHelper.java @@ -0,0 +1,84 @@ +package net.momirealms.craftengine.bukkit.block.worldedit; + +import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; +import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; +import net.momirealms.craftengine.bukkit.util.BlockStateUtils; +import net.momirealms.craftengine.core.block.BlockStateParser; +import net.momirealms.craftengine.core.block.ImmutableBlockState; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; + +import java.util.*; + +// TODO A better command suggestion system +public class WorldEditCommandHelper implements Listener { + private final BukkitBlockManager manager; + private final BukkitCraftEngine plugin; + + public WorldEditCommandHelper(BukkitCraftEngine plugin, BukkitBlockManager manager) { + this.plugin = plugin; + this.manager = manager; + } + + public void enable() { + Bukkit.getPluginManager().registerEvents(this, plugin.bootstrap()); + } + + public void disable() { + HandlerList.unregisterAll(this); + } + + @EventHandler(priority = EventPriority.HIGH) + public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) { + String message = event.getMessage(); + if (!message.startsWith("//")) return; + + Set cachedNamespaces = manager.namespacesInUse(); + String[] args = message.split(" "); + boolean modified = false; + + for (int i = 1; i < args.length; i++) { + String[] parts = args[i].split(","); + List processedParts = new ArrayList<>(parts.length); + boolean partModified = false; + + for (String part : parts) { + String processed = processIdentifier(part, cachedNamespaces); + partModified |= !part.equals(processed); + processedParts.add(processed); + } + + if (partModified) { + args[i] = String.join(",", processedParts); + modified = true; + } + } + + if (modified) { + event.setMessage(String.join(" ", args)); + } + } + + private String processIdentifier(String identifier, Set cachedNamespaces) { + int colonIndex = identifier.indexOf(':'); + if (colonIndex == -1) return identifier; + + String namespace = identifier.substring(0, colonIndex); + if (!cachedNamespaces.contains(namespace)) return identifier; + + ImmutableBlockState state = BlockStateParser.deserialize(identifier); + if (state == null) return identifier; + + try { + return BlockStateUtils.getBlockOwnerIdFromState( + state.customBlockState().handle() + ).toString(); + } catch (NullPointerException e) { + return identifier; + } + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java index 16a7458ad..0f965dbc8 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java @@ -111,16 +111,6 @@ public class BukkitItemManager extends AbstractItemManager { return getCustomItem(id).map(it -> it.settings().fuelTime()).orElse(0); } - @Override - public void load() { - super.load(); - } - - @Override - public void unload() { - super.unload(); - } - @Override public void disable() { this.unload(); 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 423bdd269..fc5b6b2a5 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 @@ -4,6 +4,7 @@ import net.momirealms.antigrieflib.AntiGriefLib; import net.momirealms.craftengine.bukkit.api.event.CraftEngineReloadEvent; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.block.behavior.BukkitBlockBehaviors; +import net.momirealms.craftengine.bukkit.block.worldedit.WorldEditCommandHelper; import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; import net.momirealms.craftengine.bukkit.font.BukkitImageManager; import net.momirealms.craftengine.bukkit.item.BukkitItemManager; @@ -178,12 +179,6 @@ public class BukkitCraftEngine extends CraftEngine { new ImageExpansion(this).register(); this.hasPlaceholderAPI = true; } - // WorldEdit - if (this.isPluginEnabled("FastAsyncWorldEdit")) { - this.blockManager().initFastAsyncWorldEditHook(); - } else if (this.isPluginEnabled("WorldEdit")) { - this.blockManager().initWorldEditHook(); - } } @Override 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 1ff40f0f5..aa2dbd8f2 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 @@ -619,6 +619,9 @@ public class PacketConsumers { if (furniture != null) { user.furnitureView().computeIfAbsent(furniture.baseEntityId(), k -> new ArrayList<>()).addAll(furniture.subEntityIds()); user.sendPacket(furniture.spawnPacket(), false); + if (ConfigManager.hideBaseEntity()) { + event.setCancelled(true); + } } } } catch (Exception e) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigManager.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigManager.java index 746769d83..1914dbb78 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/ConfigManager.java @@ -90,15 +90,18 @@ public class ConfigManager implements Reloadable { protected String resource_pack$external_host$sha1; protected UUID resource_pack$external_host$uuid; - protected boolean performance$light_system$force_update_light; - protected boolean performance$light_system$enable; protected int performance$max_block_chain_update_limit; - protected boolean performance$chunk_system$restore_vanilla_blocks_on_chunk_unload; - protected boolean performance$chunk_system$restore_custom_blocks_on_chunk_load; - protected boolean performance$chunk_system$sync_custom_blocks_on_chunk_load; + + protected boolean light_system$force_update_light; + protected boolean light_system$enable; + + protected boolean chunk_system$restore_vanilla_blocks_on_chunk_unload; + protected boolean chunk_system$restore_custom_blocks_on_chunk_load; + protected boolean chunk_system$sync_custom_blocks_on_chunk_load; protected boolean furniture$remove_invalid_furniture_on_chunk_load$enable; protected Set furniture$remove_invalid_furniture_on_chunk_load$list; + protected boolean furniture$hide_base_entity; protected boolean block$sound_system$enable; protected boolean recipe$enable; @@ -239,15 +242,20 @@ public class ConfigManager implements Reloadable { // performance performance$max_block_chain_update_limit = config.getInt("performance.max-block-chain-update-limit", 64); - performance$light_system$force_update_light = config.getBoolean("performance.light-system.force-update-light", false); - performance$light_system$enable = config.getBoolean("performance.light-system.enable", true); - performance$chunk_system$restore_vanilla_blocks_on_chunk_unload = config.getBoolean("performance.chunk-system.restore-vanilla-blocks-on-chunk-unload", true); - performance$chunk_system$restore_custom_blocks_on_chunk_load = config.getBoolean("performance.chunk-system.restore-custom-blocks-on-chunk-load", true); - performance$chunk_system$sync_custom_blocks_on_chunk_load = config.getBoolean("performance.chunk-system.sync-custom-blocks-on-chunk-load", false); + + // light + light_system$force_update_light = config.getBoolean("light-system.force-update-light", false); + light_system$enable = config.getBoolean("light-system.enable", true); + + // chunk + chunk_system$restore_vanilla_blocks_on_chunk_unload = config.getBoolean("chunk-system.restore-vanilla-blocks-on-chunk-unload", true); + chunk_system$restore_custom_blocks_on_chunk_load = config.getBoolean("chunk-system.restore-custom-blocks-on-chunk-load", true); + chunk_system$sync_custom_blocks_on_chunk_load = config.getBoolean("chunk-system.sync-custom-blocks-on-chunk-load", false); // furniture furniture$remove_invalid_furniture_on_chunk_load$enable = config.getBoolean("furniture.remove-invalid-furniture-on-chunk-load.enable", false); furniture$remove_invalid_furniture_on_chunk_load$list = new HashSet<>(config.getStringList("furniture.remove-invalid-furniture-on-chunk-load.list")); + furniture$hide_base_entity = config.getBoolean("furniture.hide-base-entity", true); // block block$sound_system$enable = config.getBoolean("block.sound-system.enable", true); @@ -318,11 +326,11 @@ public class ConfigManager implements Reloadable { } public static boolean forceUpdateLight() { - return instance.performance$light_system$force_update_light; + return instance.light_system$force_update_light; } public static boolean enableLightSystem() { - return instance.performance$light_system$enable; + return instance.light_system$enable; } public static float packMinVersion() { @@ -346,7 +354,7 @@ public class ConfigManager implements Reloadable { } public static boolean restoreVanillaBlocks() { - return instance.performance$chunk_system$restore_vanilla_blocks_on_chunk_unload && instance.performance$chunk_system$restore_custom_blocks_on_chunk_load; + return instance.chunk_system$restore_vanilla_blocks_on_chunk_unload && instance.chunk_system$restore_custom_blocks_on_chunk_load; } public static boolean denyNonMinecraftRequest() { @@ -354,11 +362,11 @@ public class ConfigManager implements Reloadable { } public static boolean restoreCustomBlocks() { - return instance.performance$chunk_system$restore_custom_blocks_on_chunk_load; + return instance.chunk_system$restore_custom_blocks_on_chunk_load; } public static boolean syncCustomBlocks() { - return instance.performance$chunk_system$sync_custom_blocks_on_chunk_load; + return instance.chunk_system$sync_custom_blocks_on_chunk_load; } public static List foldersToMerge() { @@ -533,6 +541,10 @@ public class ConfigManager implements Reloadable { return instance().image$illegal_characters_filter$sign; } + public static boolean hideBaseEntity() { + return instance().furniture$hide_base_entity; + } + public YamlDocument loadOrCreateYamlData(String fileName) { File file = new File(this.plugin.dataFolderFile(), fileName); if (!file.exists()) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java index e50fe5837..7afd0daf1 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/template/TemplateManagerImpl.java @@ -76,7 +76,9 @@ public class TemplateManagerImpl implements TemplateManager { for (Object template : templates) { processUnknownTypeMember(template, processingResult.arguments(), processedTemplates::add); } - + if (processedTemplates.isEmpty()) { + return; + } Object firstTemplate = processedTemplates.get(0); // 对于map和list,应当对多模板合并 if (firstTemplate instanceof Map) { @@ -187,7 +189,7 @@ public class TemplateManagerImpl implements TemplateManager { // 合并参数 private Map mergeArguments(@NotNull Map rawChildArguments, @NotNull Map parentArguments) { - Map result = new HashMap<>(); + Map result = new HashMap<>(parentArguments); // 我们遍历一下当前节点下的所有参数,这些参数可能含有内嵌参数。所以需要对参数map先处理一次后再合并 // arguments: // argument_1: "{parent_argument}" diff --git a/gradle.properties b/gradle.properties index 3375f61ce..3f90eae1f 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.38 -config_version=16 +project_version=0.0.39 +config_version=17 lang_version=3 project_group=net.momirealms latest_minecraft_version=1.21.4