diff --git a/.examples/depositories/README.md b/.examples/depositories/README.md index 1f9d4a9..29bab90 100644 --- a/.examples/depositories/README.md +++ b/.examples/depositories/README.md @@ -2,7 +2,7 @@ ## 详细示例 -您可以 [点击这里](full-example.yml) 查看一份详细的示例。 +您可以 [点击这里](../../src/main/resources/depositories/.example-depository.yml) 查看一份详细的示例。 ## 使用须知 diff --git a/README.md b/README.md index 8d819f2..5a9fdf3 100644 --- a/README.md +++ b/README.md @@ -211,15 +211,15 @@ 详见代码文件中默认值,相关文件将在首次运行时创建。 -### 仓库配置文件 ([depositories/<仓库ID>.yml](.examples/depositories/full-example.yml)) +### 仓库配置文件 ([depositories/<仓库ID>.yml](src/main/resources/depositories/.example-depository.yml)) 所有仓库配置均为单独的配置文件,存放于 `插件配置目录/depositories` 下,便于管理。 -文件名即仓库的ID,**强烈推荐使用纯英文**,部分符号可能会影响正常读取,请避免使用。 +文件名即仓库的ID,**强烈推荐使用纯英文**。以`.`开头的仓库配置不会被加载。部分符号可能会影响正常读取,请避免使用。 随本项目预设了几个常用的仓库类型,可以 [在这里](.examples/depositories) 找到您需要的仓库配置加以修改后使用。 -您也可以 [点击这里](.examples/depositories/full-example.yml) 查看一份*详细的仓库配置示例*,以制作您自己的仓库。 +您也可以 [点击这里](src/main/resources/depositories/.example-depository.yml) 查看一份*详细的仓库配置示例*,以制作您自己的仓库。 ## 开发 diff --git a/src/main/java/cc/carm/plugin/ultradepository/manager/ConfigManager.java b/src/main/java/cc/carm/plugin/ultradepository/manager/ConfigManager.java index f9d3d7f..39232d9 100644 --- a/src/main/java/cc/carm/plugin/ultradepository/manager/ConfigManager.java +++ b/src/main/java/cc/carm/plugin/ultradepository/manager/ConfigManager.java @@ -6,6 +6,7 @@ import cc.carm.lib.easyplugin.configuration.language.MessagesConfig; import cc.carm.lib.easyplugin.configuration.language.MessagesInitializer; import cc.carm.plugin.ultradepository.UltraDepository; import cc.carm.plugin.ultradepository.configuration.PluginMessages; +import cc.carm.plugin.ultradepository.util.JarUtil; import java.io.File; @@ -16,15 +17,21 @@ public class ConfigManager { public static boolean initialize() { UltraDepository udPlugin = UltraDepository.getInstance(); - File configFile = new File(udPlugin.getDataFolder(), "config.yml"); - if (!configFile.exists()) { - //没找到配置文件,可能是第一次加载此插件 - //把一些英文版的东西复制出来,方便英文用户使用。 - udPlugin.saveResource("i18n/en_US/config.yml", false); - udPlugin.saveResource("i18n/ko_KR/config.yml", false); - } + try { + File configFile = new File(udPlugin.getDataFolder(), "config.yml"); + if (!configFile.exists()) { + //没找到配置文件,可能是第一次加载此插件 + //把一些英文版的东西复制出来,方便英文用户使用。 + UltraDepository.getInstance().log(" 未找到配置文件,生成默认配置..."); + JarUtil.copyFolderFromJar( + "i18n", udPlugin.getDataFolder(), + JarUtil.CopyOption.COPY_IF_NOT_EXIST + ); + + } + pluginConfiguration = new FileConfig(udPlugin, "config.yml"); messageConfiguration = new MessagesConfig(udPlugin, "messages.yml"); diff --git a/src/main/java/cc/carm/plugin/ultradepository/manager/DepositoryManager.java b/src/main/java/cc/carm/plugin/ultradepository/manager/DepositoryManager.java index dc5a919..2429789 100644 --- a/src/main/java/cc/carm/plugin/ultradepository/manager/DepositoryManager.java +++ b/src/main/java/cc/carm/plugin/ultradepository/manager/DepositoryManager.java @@ -45,6 +45,11 @@ public class DepositoryManager { File folder = new File(UltraDepository.getInstance().getDataFolder(), "depositories"); if (!folder.exists()) { folder.mkdir(); + + UltraDepository.getInstance().saveResource( + "depositories/.example-depository.yml", false + ); + } else if (folder.isDirectory()) { folder.delete(); folder.mkdir(); @@ -56,7 +61,8 @@ public class DepositoryManager { HashMap<@NotNull String, @NotNull Depository> data = new HashMap<>(); for (File file : files) { String fileName = file.getName(); - if (!file.isFile() || !fileName.toLowerCase().endsWith(".yml")) continue; + if (!file.isFile() || fileName.startsWith(".")) continue; + if (!fileName.toLowerCase().endsWith(".yml")) continue; String identifier = fileName.substring(0, fileName.lastIndexOf(".")); FileConfiguration configuration = YamlConfiguration.loadConfiguration(file); Depository depository = Depository.loadFrom(identifier, configuration); @@ -101,6 +107,7 @@ public class DepositoryManager { return getDepositories().get(depositoryID); } + @SuppressWarnings("deprecation") public Set getItemDepositories(ItemStack itemStack) { return getItemDepositories(itemStack.getType(), itemStack.getDurability()); } @@ -124,6 +131,7 @@ public class DepositoryManager { else return material.name() + ":" + data; } + @SuppressWarnings("deprecation") public @NotNull String getItemTypeID(ItemStack itemStack) { return getItemTypeID(itemStack.getType(), itemStack.getDurability()); } diff --git a/src/main/java/cc/carm/plugin/ultradepository/util/JarUtil.java b/src/main/java/cc/carm/plugin/ultradepository/util/JarUtil.java new file mode 100644 index 0000000..af26776 --- /dev/null +++ b/src/main/java/cc/carm/plugin/ultradepository/util/JarUtil.java @@ -0,0 +1,90 @@ +package cc.carm.plugin.ultradepository.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +@SuppressWarnings("ResultOfMethodCallIgnored") +public class JarUtil { + public static final char JAR_SEPARATOR = '/'; + + public static void copyFolderFromJar(String folderName, File destFolder, CopyOption option) + throws IOException { + copyFolderFromJar(folderName, destFolder, option, null); + } + + public static void copyFolderFromJar(String folderName, File destFolder, + CopyOption option, PathTrimmer trimmer) throws IOException { + if (!destFolder.exists()) + destFolder.mkdirs(); + + byte[] buffer = new byte[1024]; + + File fullPath; + String path = JarUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath(); + if (trimmer != null) + path = trimmer.trim(path); + try { + if (!path.startsWith("file")) + path = "file://" + path; + + fullPath = new File(new URI(path)); + } catch (URISyntaxException e) { + e.printStackTrace(); + return; + } + + ZipInputStream zis = new ZipInputStream(new FileInputStream(fullPath)); + + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + if (!entry.getName().startsWith(folderName + JAR_SEPARATOR)) + continue; + + String fileName = entry.getName(); + + if (fileName.charAt(fileName.length() - 1) == JAR_SEPARATOR) { + File file = new File(destFolder + File.separator + fileName); + if (file.isFile()) { + file.delete(); + } + file.mkdirs(); + continue; + } + + File file = new File(destFolder + File.separator + fileName); + if (option == CopyOption.COPY_IF_NOT_EXIST && file.exists()) + continue; + + if (!file.getParentFile().exists()) + file.getParentFile().mkdirs(); + + if (!file.exists()) + file.createNewFile(); + FileOutputStream fos = new FileOutputStream(file); + + int len; + while ((len = zis.read(buffer)) > 0) { + fos.write(buffer, 0, len); + } + fos.close(); + } + + zis.closeEntry(); + zis.close(); + } + + public enum CopyOption { + COPY_IF_NOT_EXIST, REPLACE_IF_EXIST + } + + @FunctionalInterface + public interface PathTrimmer { + String trim(String original); + } +} \ No newline at end of file diff --git a/.examples/depositories/full-example.yml b/src/main/resources/depositories/.example-depository.yml similarity index 100% rename from .examples/depositories/full-example.yml rename to src/main/resources/depositories/.example-depository.yml diff --git a/src/main/resources/i18n/en_US/.example-depository.yml b/src/main/resources/i18n/en_US/.example-depository.yml new file mode 100644 index 0000000..89e5714 --- /dev/null +++ b/src/main/resources/i18n/en_US/.example-depository.yml @@ -0,0 +1,47 @@ +name: "&b&lExample Depository" # 仓库名,用于消息显示 + +capacity: # 容量配置 + default: 500 # 若为0则默认不可以使用该仓库 + permissions: # 特殊权限对应的仓库容量,格式为 "权限:容量 + - "UltraDepository.vip:1000" + - "UltraDepository.mvp:1500" + +gui: # GUI额外配置 + title: "&b&l示例仓库 &7| 界面" #示例仓库的GUI标题 + lines: 4 # GUI的行数,支持 1-6行。 + items: + "TEST": + material: CHEST # 物品图标的类型 + data: 0 # 物品图标的数据值 + slot: 31 # 在GUI中显示的格子 + name: "&9&l测试图标" + lore: + # 支持使用变量 + - "你好 %player_name% !" + actions: # 物品点击操作 + - "[CHAT] Hello!" #以玩家身份发送Hello,支持PlaceholderAPI变量 + - "[CHAT] /help" #若内容以"/"开头,则会以玩家身份执行指令,支持PlaceholderAPI变量 + - "[CONSOLE] say HELLO WORLD" #以后台身份执行指令,不需要加"/",支持PlaceholderAPI变量 + - "[MESSAGE] &(#FFBBBBB)Test %player_name%" # 向玩家发送消息,支持PlaceholderAPI变量和RGB颜色 + - "[SOUND] ENTITY_EXPERIENCE_ORB_PICKUP:0.5" # 向玩家发送声音,可以规定音量大小和音调,格式为 <声音>:[音量]:[音调] + - "[CLOSE]" # 为玩家关闭界面 + + - "[LEFT:CLOSE]" #限制只有 鼠标左键 才触发CLOSE + - "[SHIFT_LEFT:CLOSE]" #限制只有 按住Shift+鼠标左键 才触发CLOSE + - "[RIGHT:CLOSE]" #限制只有 鼠标右键 才触发CLOSE + - "[SHIFT_RIGHT:CLOSE]" #限制只有 按住Shift+鼠标右键 才触发CLOSE + - "[MIDDLE:CLOSE]" #限制只有 鼠标中键 才触发CLOSE + - "[DROP:CLOSE]" #限制只有 丢弃建 才触发CLOSE + - "[CONTROL_DROP:CLOSE]" #限制只有 按住Ctrl+丢弃键 才触发CLOSE + - "[DOUBLE_CLICK:CLOSE]" #限制只有 鼠标双击物品 才触发CLOSE + - "[NUMBER_KEY:CLOSE]" #限制只有 数字键切换 才触发CLOSE + +items: + "INK_SAC": #物品ID,若需要限制数据ID则可以加“:”,如 "INK_SANK:4" + slot: 11 # 物品在GUI中显示的槽位 + price: 0.1 # 物品单价 + limit: 500 # 物品每日售出限制 + name: "&8&l墨囊" # 物品显示的名字 + lore: # 物品的lore + - " " + - "&f抓住墨鱼!" \ No newline at end of file diff --git a/src/main/resources/i18n/ko_KR/.example-depository.yml b/src/main/resources/i18n/ko_KR/.example-depository.yml new file mode 100644 index 0000000..1806f33 --- /dev/null +++ b/src/main/resources/i18n/ko_KR/.example-depository.yml @@ -0,0 +1,48 @@ + +name: "&b&l示例仓库" # 仓库名,用于消息显示 + +capacity: # 容量配置 + default: 500 # 若为0则默认不可以使用该仓库 + permissions: # 特殊权限对应的仓库容量,格式为 "权限:容量 + - "UltraDepository.vip:1000" + - "UltraDepository.mvp:1500" + +gui: # GUI额外配置 + title: "&b&l示例仓库 &7| 界面" #示例仓库的GUI标题 + lines: 4 # GUI的行数,支持 1-6行。 + items: + "TEST": + material: CHEST # 物品图标的类型 + data: 0 # 物品图标的数据值 + slot: 31 # 在GUI中显示的格子 + name: "&9&l测试图标" + lore: + # 支持使用变量 + - "你好 %player_name% !" + actions: # 物品点击操作 + - "[CHAT] Hello!" #以玩家身份发送Hello,支持PlaceholderAPI变量 + - "[CHAT] /help" #若内容以"/"开头,则会以玩家身份执行指令,支持PlaceholderAPI变量 + - "[CONSOLE] say HELLO WORLD" #以后台身份执行指令,不需要加"/",支持PlaceholderAPI变量 + - "[MESSAGE] &(#FFBBBBB)Test %player_name%" # 向玩家发送消息,支持PlaceholderAPI变量和RGB颜色 + - "[SOUND] ENTITY_EXPERIENCE_ORB_PICKUP:0.5" # 向玩家发送声音,可以规定音量大小和音调,格式为 <声音>:[音量]:[音调] + - "[CLOSE]" # 为玩家关闭界面 + + - "[LEFT:CLOSE]" #限制只有 鼠标左键 才触发CLOSE + - "[SHIFT_LEFT:CLOSE]" #限制只有 按住Shift+鼠标左键 才触发CLOSE + - "[RIGHT:CLOSE]" #限制只有 鼠标右键 才触发CLOSE + - "[SHIFT_RIGHT:CLOSE]" #限制只有 按住Shift+鼠标右键 才触发CLOSE + - "[MIDDLE:CLOSE]" #限制只有 鼠标中键 才触发CLOSE + - "[DROP:CLOSE]" #限制只有 丢弃建 才触发CLOSE + - "[CONTROL_DROP:CLOSE]" #限制只有 按住Ctrl+丢弃键 才触发CLOSE + - "[DOUBLE_CLICK:CLOSE]" #限制只有 鼠标双击物品 才触发CLOSE + - "[NUMBER_KEY:CLOSE]" #限制只有 数字键切换 才触发CLOSE + +items: + "INK_SAC": #物品ID,若需要限制数据ID则可以加“:”,如 "INK_SANK:4" + slot: 11 # 物品在GUI中显示的槽位 + price: 0.1 # 物品单价 + limit: 500 # 物品每日售出限制 + name: "&8&l墨囊" # 物品显示的名字 + lore: # 物品的lore + - " " + - "&f抓住墨鱼!" \ No newline at end of file