diff --git a/bukkit/loader/src/main/resources/commands.yml b/bukkit/loader/src/main/resources/commands.yml index 125d3e971..81f4a1076 100644 --- a/bukkit/loader/src/main/resources/commands.yml +++ b/bukkit/loader/src/main/resources/commands.yml @@ -76,6 +76,27 @@ totem_animation: - /craftengine feature totem-animation - /ce feature totem-animation +enable_resource: + enable: true + permission: ce.command.admin.resource + usage: + - /craftengine resource enable + - /ce resource enable + +disable_resource: + enable: true + permission: ce.command.admin.resource + usage: + - /craftengine resource disable + - /ce resource disable + +list_resource: + enable: true + permission: ce.command.admin.resource + usage: + - /craftengine resource list + - /ce resource list + # Debug commands debug_set_block: enable: true diff --git a/bukkit/loader/src/main/resources/translations/en.yml b/bukkit/loader/src/main/resources/translations/en.yml index 007676fe9..eee50f283 100644 --- a/bukkit/loader/src/main/resources/translations/en.yml +++ b/bukkit/loader/src/main/resources/translations/en.yml @@ -54,6 +54,11 @@ command.search_usage.not_found: "No usage found for this item" command.search_recipe.no_item: "Please hold an item before running this command" command.search_usage.no_item: "Please hold an item before running this command" command.totem_animation.failure.not_totem: "Item '' is not minecraft:totem_of_undying" +command.resource.enable.success: "Enabled resource . Run /ce reload all to apply changes" +command.resource.enable.failure.unknown: "Unknown resource " +command.resource.disable.success: "Disabled resource . Run /ce reload all to apply changes" +command.resource.disable.failure.unknown: "Unknown resource " +command.resource.list: "Enabled resources(): Disabled resources(): " warning.config.image.duplicated: "Issue found in file - Duplicated image ''." warning.config.image.lack_height: "Issue found in file - The image '' is missing the required 'height' argument." warning.config.image.height_smaller_than_ascent: "Issue found in file - The image '' violates the bitmap image rule: 'height' should be no lower than 'ascent'." diff --git a/bukkit/loader/src/main/resources/translations/zh_cn.yml b/bukkit/loader/src/main/resources/translations/zh_cn.yml index 66acc8f30..0f03c5226 100644 --- a/bukkit/loader/src/main/resources/translations/zh_cn.yml +++ b/bukkit/loader/src/main/resources/translations/zh_cn.yml @@ -54,6 +54,11 @@ command.search_usage.not_found: "找不到此物品的用途" command.search_recipe.no_item: "请手持物品后再执行此命令" command.search_usage.no_item: "请手持物品后再执行此命令" command.totem_animation.failure.not_totem: "'' 不是 totem_of_undying 类型" +command.resource.enable.success: "已启用 . 执行 /ce reload all 以应用更改" +command.resource.enable.failure.unknown: "未知资源 " +command.resource.disable.success: "已禁用 . 执行 /ce reload all 以应用更改" +command.resource.disable.failure.unknown: "未知资源 " +command.resource.list: "启用的资源(): 禁用的资源(): " warning.config.image.duplicated: "在文件 中发现问题 - 图片 '' 重复定义" warning.config.image.lack_height: "在文件 中发现问题 - 图片 '' 缺少必要的 'height' 高度参数" warning.config.image.height_smaller_than_ascent: "在文件 中发现问题 - 图片 '' 违反位图规则:'height' 高度值不应小于 'ascent' 基准线高度" 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 515ac12ec..556ceaf64 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 @@ -46,7 +46,10 @@ public class BukkitCommandManager extends AbstractCommandManager new DebugSetBlockCommand(this, plugin), new DebugSpawnFurnitureCommand(this, plugin), new DebugTargetBlockCommand(this, plugin), - new TotemAnimationCommand(this, plugin) + new TotemAnimationCommand(this, plugin), + new EnableResourceCommand(this, plugin), + new DisableResourceCommand(this, plugin), + new ListResourceCommand(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/DisableResourceCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/DisableResourceCommand.java new file mode 100644 index 000000000..c92513366 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/DisableResourceCommand.java @@ -0,0 +1,72 @@ +package net.momirealms.craftengine.bukkit.plugin.command.feature; + +import dev.dejvokep.boostedyaml.YamlDocument; +import net.kyori.adventure.text.Component; +import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; +import net.momirealms.craftengine.core.pack.Pack; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; +import net.momirealms.craftengine.core.plugin.locale.MessageConstants; +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.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.CompletableFuture; + +public class DisableResourceCommand extends BukkitCommandFeature { + + public DisableResourceCommand(CraftEngineCommandManager commandManager, CraftEngine plugin) { + super(commandManager, plugin); + } + + @Override + public Command.Builder assembleCommand(org.incendo.cloud.CommandManager manager, Command.Builder builder) { + return builder + .flag(manager.flagBuilder("silent").withAliases("s")) + .required("pack", StringParser.stringComponent(StringParser.StringMode.GREEDY).suggestionProvider(new SuggestionProvider<>() { + @Override + public @NonNull CompletableFuture> suggestionsFuture(@NonNull CommandContext context, @NonNull CommandInput input) { + return CompletableFuture.completedFuture(plugin().packManager().loadedPacks().stream().filter(Pack::enabled).map(pack -> Suggestion.suggestion(pack.name())).toList()); + } + })) + .handler(context -> { + String packFolder = context.get("pack"); + Path path = plugin().dataFolderPath().resolve("resources").resolve(packFolder); + if (!Files.exists(path)) { + handleFeedback(context, MessageConstants.COMMAND_RESOURCE_DISABLE_FAILURE, Component.text(packFolder)); + return; + } + Path packMetaPath = path.resolve("pack.yml"); + if (!Files.exists(packMetaPath)) { + try { + Files.createFile(packMetaPath); + } catch (IOException e) { + plugin().logger().warn("Could not create pack.yml file: " + packMetaPath); + return; + } + } + YamlDocument document = plugin().config().loadYamlData(packMetaPath.toFile()); + document.set("enable", false); + try { + document.save(packMetaPath.toFile()); + } catch (IOException e) { + plugin().logger().warn("Could not save pack.yml file: " + packMetaPath); + return; + } + handleFeedback(context, MessageConstants.COMMAND_RESOURCE_DISABLE_SUCCESS, Component.text(packFolder)); + }); + } + + @Override + public String getFeatureID() { + return "disable_resource"; + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/EnableResourceCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/EnableResourceCommand.java new file mode 100644 index 000000000..e565f9935 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/EnableResourceCommand.java @@ -0,0 +1,71 @@ +package net.momirealms.craftengine.bukkit.plugin.command.feature; + +import dev.dejvokep.boostedyaml.YamlDocument; +import net.kyori.adventure.text.Component; +import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; +import net.momirealms.craftengine.core.plugin.locale.MessageConstants; +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.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.CompletableFuture; + +public class EnableResourceCommand extends BukkitCommandFeature { + + public EnableResourceCommand(CraftEngineCommandManager commandManager, CraftEngine plugin) { + super(commandManager, plugin); + } + + @Override + public Command.Builder assembleCommand(org.incendo.cloud.CommandManager manager, Command.Builder builder) { + return builder + .flag(manager.flagBuilder("silent").withAliases("s")) + .required("pack", StringParser.stringComponent(StringParser.StringMode.GREEDY).suggestionProvider(new SuggestionProvider<>() { + @Override + public @NonNull CompletableFuture> suggestionsFuture(@NonNull CommandContext context, @NonNull CommandInput input) { + return CompletableFuture.completedFuture(plugin().packManager().loadedPacks().stream().filter(pack -> !pack.enabled()).map(pack -> Suggestion.suggestion(pack.name())).toList()); + } + })) + .handler(context -> { + String packFolder = context.get("pack"); + Path path = plugin().dataFolderPath().resolve("resources").resolve(packFolder); + if (!Files.exists(path)) { + handleFeedback(context, MessageConstants.COMMAND_RESOURCE_ENABLE_FAILURE, Component.text(packFolder)); + return; + } + Path packMetaPath = path.resolve("pack.yml"); + if (!Files.exists(packMetaPath)) { + try { + Files.createFile(packMetaPath); + } catch (IOException e) { + plugin().logger().warn("Could not create pack.yml file: " + packMetaPath); + return; + } + } + YamlDocument document = plugin().config().loadYamlData(packMetaPath.toFile()); + document.set("enable", true); + try { + document.save(packMetaPath.toFile()); + } catch (IOException e) { + plugin().logger().warn("Could not save pack.yml file: " + packMetaPath); + return; + } + handleFeedback(context, MessageConstants.COMMAND_RESOURCE_ENABLE_SUCCESS, Component.text(packFolder)); + }); + } + + @Override + public String getFeatureID() { + return "enable_resource"; + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/ListResourceCommand.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/ListResourceCommand.java new file mode 100644 index 000000000..48a14bb3e --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/command/feature/ListResourceCommand.java @@ -0,0 +1,80 @@ +package net.momirealms.craftengine.bukkit.plugin.command.feature; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.HoverEvent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature; +import net.momirealms.craftengine.core.pack.Pack; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager; +import net.momirealms.craftengine.core.plugin.locale.MessageConstants; +import net.momirealms.craftengine.core.util.AdventureHelper; +import org.bukkit.command.CommandSender; +import org.incendo.cloud.Command; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class ListResourceCommand extends BukkitCommandFeature { + + public ListResourceCommand(CraftEngineCommandManager commandManager, CraftEngine plugin) { + super(commandManager, plugin); + } + + @Override + public Command.Builder assembleCommand(org.incendo.cloud.CommandManager manager, Command.Builder builder) { + return builder + .handler(context -> { + Collection packs = plugin().packManager().loadedPacks(); + List enabled = new ArrayList<>(); + List disabled = new ArrayList<>(); + for (Pack pack : packs) { + if (pack.enabled()) { + enabled.add(pack); + } else { + disabled.add(pack); + } + } + handleFeedback(context, MessageConstants.COMMAND_RESOURCE_LIST, Component.text(enabled.size()), Component.empty().children(getChildComponents(enabled)), Component.text(disabled.size()), Component.empty().children(getChildComponents(disabled))); + }); + } + + private List getChildComponents(List disabled) { + List components = new ArrayList<>(); + for (int i = 0; i < disabled.size(); i++) { + Pack pack = disabled.get(i); + components.add(getPackComponent(pack)); + if (i != disabled.size() - 1) { + components.add(Component.text(", ")); + } + } + if (components.isEmpty()) { + return List.of(Component.text("[]")); + } + return components; + } + + private Component getPackComponent(Pack pack) { + String description = pack.meta().description(); + String version = pack.meta().version(); + String author = pack.meta().author(); + String text = version == null ? pack.name() : pack.name() + " v" + version; + Component base = Component.text("[" + text + "]"); + if (author != null || description != null) { + if (author != null && description != null) { + base = base.hoverEvent(HoverEvent.showText(Component.empty().children(List.of(Component.text("by: " + author).color(NamedTextColor.YELLOW), Component.newline(), AdventureHelper.miniMessage().deserialize(description))))); + } else if (author != null) { + base = base.hoverEvent(HoverEvent.showText(Component.text("by: " + author))); + } else { + base = base.hoverEvent(HoverEvent.showText(AdventureHelper.miniMessage().deserialize(description))); + } + } + return base; + } + + @Override + public String getFeatureID() { + return "list_resource"; + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java index 07f36dfdd..b8ff6f265 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java @@ -52,17 +52,7 @@ public abstract class AbstractPackManager implements PackManager { public static final Set VANILLA_ITEM_TEXTURES = new HashSet<>(); public static final Set VANILLA_BLOCK_TEXTURES = new HashSet<>(); public static final Set VANILLA_FONT_TEXTURES = new HashSet<>(); - - private final CraftEngine plugin; - private final BiConsumer eventDispatcher; - private final Map loadedPacks = new HashMap<>(); - private final Map sectionParsers = new HashMap<>(); - private final TreeMap> cachedConfigs = new TreeMap<>(); - private static final byte[] emptyImage; - protected BiConsumer zipGenerator; - protected String packHash; - protected UUID packUUID; - + private static final byte[] EMPTY_IMAGE; static { var stream = new ByteArrayOutputStream(); try { @@ -70,9 +60,19 @@ public abstract class AbstractPackManager implements PackManager { } catch (IOException e) { throw new RuntimeException(e); } - emptyImage = stream.toByteArray(); + EMPTY_IMAGE = stream.toByteArray(); } + private final CraftEngine plugin; + private final BiConsumer eventDispatcher; + private final Map loadedPacks = new HashMap<>(); + private final Map sectionParsers = new HashMap<>(); + private final TreeMap> cachedConfigs = new TreeMap<>(); + + protected BiConsumer zipGenerator; + protected String packHash; + protected UUID packUUID; + public AbstractPackManager(CraftEngine plugin, BiConsumer eventDispatcher) { this.plugin = plugin; this.eventDispatcher = eventDispatcher; @@ -244,17 +244,16 @@ public abstract class AbstractPackManager implements PackManager { String description = null; String version = null; String author = null; + boolean enable = true; if (Files.exists(metaFile) && Files.isRegularFile(metaFile)) { YamlDocument metaYML = Config.instance().loadYamlData(metaFile.toFile()); - if (!metaYML.getBoolean("enable", true)) { - continue; - } + enable = metaYML.getBoolean("enable", true); namespace = metaYML.getString("namespace", namespace); description = metaYML.getString("description"); version = metaYML.getString("version"); author = metaYML.getString("author"); } - Pack pack = new Pack(path, new PackMeta(author, description, version, namespace)); + Pack pack = new Pack(path, new PackMeta(author, description, version, namespace), enable); this.loadedPacks.put(path.getFileName().toString(), pack); this.plugin.logger().info("Loaded pack: " + pack.folder().getFileName() + ". Default namespace: " + namespace); } @@ -398,6 +397,7 @@ public abstract class AbstractPackManager implements PackManager { private void loadResourceConfigs(Predicate predicate) { long o1 = System.nanoTime(); for (Pack pack : loadedPacks()) { + if (!pack.enabled()) continue; Pair, List> files = FileUtils.getConfigsDeeply(pack.configurationFolder()); for (Path path : files.left()) { try (InputStreamReader inputStream = new InputStreamReader(new FileInputStream(path.toFile()), StandardCharsets.UTF_8)) { @@ -573,7 +573,7 @@ public abstract class AbstractPackManager implements PackManager { } try { GsonHelper.writeJsonFile(json, jsonPath); - Files.write(pngPath, emptyImage); + Files.write(pngPath, EMPTY_IMAGE); } catch (IOException e) { this.plugin.logger().severe("Error writing particles file", e); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/Pack.java b/core/src/main/java/net/momirealms/craftengine/core/pack/Pack.java index 09b70fffe..3953b2076 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/Pack.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/Pack.java @@ -15,16 +15,26 @@ import java.nio.file.Path; public class Pack { private final Path folder; private final PackMeta meta; + private final boolean enabled; - public Pack(Path folder, PackMeta meta) { + public Pack(Path folder, PackMeta meta, boolean enabled) { this.folder = folder; this.meta = meta; + this.enabled = enabled; + } + + public String name() { + return folder.getFileName().toString(); } public String namespace() { return meta.namespace(); } + public boolean enabled() { + return enabled; + } + public PackMeta meta() { return meta; } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/MessageConstants.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/MessageConstants.java index 1151d1fe2..3d61517ab 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/MessageConstants.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/MessageConstants.java @@ -21,4 +21,9 @@ public interface MessageConstants { TranslatableComponent.Builder COMMAND_SEARCH_USAGE_NOT_FOUND = Component.translatable().key("command.search_usage.not_found"); TranslatableComponent.Builder COMMAND_SEARCH_USAGE_NO_ITEM = Component.translatable().key("command.search_usage.no_item"); TranslatableComponent.Builder COMMAND_TOTEM_NOT_TOTEM = Component.translatable().key("command.totem_animation.failure.not_totem"); + TranslatableComponent.Builder COMMAND_RESOURCE_ENABLE_SUCCESS = Component.translatable().key("command.resource.enable.success"); + TranslatableComponent.Builder COMMAND_RESOURCE_ENABLE_FAILURE = Component.translatable().key("command.resource.enable.failure.unknown"); + TranslatableComponent.Builder COMMAND_RESOURCE_DISABLE_SUCCESS = Component.translatable().key("command.resource.disable.success"); + TranslatableComponent.Builder COMMAND_RESOURCE_DISABLE_FAILURE = Component.translatable().key("command.resource.disable.failure.unknown"); + TranslatableComponent.Builder COMMAND_RESOURCE_LIST = Component.translatable().key("command.resource.list"); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/IndexedArgumentTag.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/IndexedArgumentTag.java index 5b8c768dc..098b4f6e0 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/IndexedArgumentTag.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/IndexedArgumentTag.java @@ -34,7 +34,7 @@ public class IndexedArgumentTag implements TagResolver { throw ctx.newException("Invalid argument number", arguments); } - return Tag.inserting(argumentComponents.get(index)); + return Tag.selfClosingInserting(argumentComponents.get(index)); } @Override diff --git a/gradle.properties b/gradle.properties index 4014d46db..56793b92e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -65,9 +65,9 @@ modmenu_version=13.0.3 cloth_version=17.0.144 # Proxy settings -#systemProp.socks.proxyHost=127.0.0.1 -#systemProp.socks.proxyPort=7890 -#systemProp.http.proxyHost=127.0.0.1 -#systemProp.http.proxyPort=7890 -#systemProp.https.proxyHost=127.0.0.1 -#systemProp.https.proxyPort=7890 \ No newline at end of file +systemProp.socks.proxyHost=127.0.0.1 +systemProp.socks.proxyPort=7890 +systemProp.http.proxyHost=127.0.0.1 +systemProp.http.proxyPort=7890 +systemProp.https.proxyHost=127.0.0.1 +systemProp.https.proxyPort=7890 \ No newline at end of file