From aa913c36ec715edf76ddf87054d81540d569bbe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9D=8F=E9=BB=91?= Date: Mon, 1 Oct 2018 12:59:48 +0800 Subject: [PATCH 1/2] =?UTF-8?q?+=20=E5=8D=8A=E6=88=90=E5=93=81=20tcloud?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../skymc/taboolib/cloud/TCloudCommand.java | 151 ++++++++++++++++++ .../me/skymc/taboolib/cloud/TCloudLoader.java | 115 +++++++++++++ .../taboolib/cloud/expansion/Expansion.java | 97 +++++++++++ .../cloud/expansion/ExpansionType.java | 10 ++ .../commands/internal/plugin/TLibLocale.java | 29 ++++ .../me/skymc/taboolib/update/UpdateTask.java | 2 +- src/main/resources/lang/zh_CN.yml | 48 +++++- 8 files changed, 451 insertions(+), 3 deletions(-) create mode 100644 src/main/java/me/skymc/taboolib/cloud/TCloudCommand.java create mode 100644 src/main/java/me/skymc/taboolib/cloud/TCloudLoader.java create mode 100644 src/main/java/me/skymc/taboolib/cloud/expansion/Expansion.java create mode 100644 src/main/java/me/skymc/taboolib/cloud/expansion/ExpansionType.java create mode 100644 src/main/java/me/skymc/taboolib/commands/internal/plugin/TLibLocale.java diff --git a/pom.xml b/pom.xml index f9b19a9..ad2417d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.skymc TabooLib - 4.325 + 4.4 UTF-8 diff --git a/src/main/java/me/skymc/taboolib/cloud/TCloudCommand.java b/src/main/java/me/skymc/taboolib/cloud/TCloudCommand.java new file mode 100644 index 0000000..695d65b --- /dev/null +++ b/src/main/java/me/skymc/taboolib/cloud/TCloudCommand.java @@ -0,0 +1,151 @@ +package me.skymc.taboolib.cloud; + +import com.ilummc.tlib.resources.TLocale; +import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.cloud.expansion.Expansion; +import me.skymc.taboolib.commands.internal.BaseMainCommand; +import me.skymc.taboolib.commands.internal.BaseSubCommand; +import me.skymc.taboolib.commands.internal.TCommand; +import me.skymc.taboolib.commands.internal.plugin.TLibLocale; +import me.skymc.taboolib.commands.internal.type.CommandArgument; +import me.skymc.taboolib.commands.internal.type.CommandRegister; +import me.skymc.taboolib.fileutils.FileUtils; +import me.skymc.taboolib.plugin.PluginUtils; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +import java.io.File; +import java.util.Arrays; +import java.util.stream.Collectors; + +/** + * @Author sky + * @Since 2018-09-30 19:17 + */ +@TCommand( + name = "taboolibcloud", + permission = "taboolib.admin", + aliases = "tcloud" +) +public class TCloudCommand extends BaseMainCommand { + + @CommandRegister + BaseSubCommand refresh = new BaseSubCommand() { + @Override + public String getLabel() { + return "refresh"; + } + + @Override + public String getDescription() { + return TLibLocale.description("TCLOUD", "REFRESH"); + } + + @Override + public CommandArgument[] getArguments() { + return new CommandArgument[0]; + } + + @Override + public void onCommand(CommandSender sender, Command command, String label, String[] args) { + TLocale.sendTo(sender, "COMMANDS.TCLOUD.REFRESH.SUCCESS"); + TCloudLoader.refresh(); + } + }; + @CommandRegister(priority = 1) + BaseSubCommand status = new BaseSubCommand() { + @Override + public String getLabel() { + return "status"; + } + + @Override + public String getDescription() { + return TLibLocale.description("TCLOUD", "STATUS"); + } + + @Override + public CommandArgument[] getArguments() { + return new CommandArgument[0]; + } + + @Override + public void onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!TCloudLoader.isConnected()) { + TLocale.sendTo(sender, "COMMANDS.TCLOUD.STATUS.CONNECT-FAILED"); + } else { + TLocale.sendTo(sender, "COMMANDS.TCLOUD.STATUS.STATUS", String.valueOf(TCloudLoader.getExpansionInternal().size() + TCloudLoader.getExpansionPlugins().size()), String.valueOf(TCloudLoader.getExpansionInternal().size()), String.valueOf(TCloudLoader.getExpansionPlugins().size())); + } + } + }; + @CommandRegister(priority = 2) + BaseSubCommand info = new BaseSubCommand() { + @Override + public String getLabel() { + return "info"; + } + + @Override + public String getDescription() { + return TLibLocale.description("TCLOUD", "INFO"); + } + + @Override + public CommandArgument[] getArguments() { + return TLibLocale.arguments("TCLOUD", "INFO", 1); + } + + @Override + public void onCommand(CommandSender sender, Command command, String label, String[] args) { + Expansion expansion = TCloudLoader.getExpansion(args[0]); + if (expansion == null) { + TLocale.sendTo(sender, "COMMANDS.TCLOUD.INFO.EXPANSION-NOT-FOUND", args[0]); + } else { + String builder = Arrays.stream(expansion.getAuthor()).map(author -> author + ", ").collect(Collectors.joining()); + TLocale.sendTo(sender, "COMMANDS.TCLOUD.INFO.EXPANSION-INFO", expansion.getName(), builder.substring(0, builder.length() - 2), expansion.getVersion(), expansion.getDescription(), expansion.getLastUpdate(), expansion.getLastUpdateNote()); + TLocale.sendTo(sender, "COMMANDS.TCLOUD.INFO.EXPANSION-INFO-DETAIL.0"); + Arrays.stream(expansion.getDetail()).forEach(detail -> TLocale.sendTo(sender, "COMMANDS.TCLOUD.INFO.EXPANSION-INFO-DETAIL.1", detail)); + } + } + }; + @CommandRegister(priority = 3) + BaseSubCommand download = new BaseSubCommand() { + @Override + public String getLabel() { + return "download"; + } + + @Override + public String getDescription() { + return TLibLocale.description("TCLOUD", "DOWNLOAD"); + } + + @Override + public CommandArgument[] getArguments() { + return TLibLocale.arguments("TCLOUD", "DOWNLOAD", 1); + } + + @Override + public void onCommand(CommandSender sender, Command command, String label, String[] args) { + Expansion expansion = TCloudLoader.getExpansion(args[0]); + if (expansion == null) { + TLocale.sendTo(sender, "COMMANDS.TCLOUD.DOWNLOAD.EXPANSION-NOT-FOUND", args[0]); + } else if (TCloudLoader.isExpansionExists(expansion)) { + TLocale.sendTo(sender, "COMMANDS.TCLOUD.DOWNLOAD.EXPANSION-EXISTS", args[0]); + } else { + Bukkit.getScheduler().runTaskAsynchronously(TabooLib.instance(), () -> { + TLocale.sendTo(sender, "COMMANDS.TCLOUD.DOWNLOAD.DOWNLOAD-START", args[0], expansion.getFile().getPath(), expansion.getLink()); + FileUtils.download(expansion.getLink(), expansion.getFile()); + TLocale.sendTo(sender, "COMMANDS.TCLOUD.DOWNLOAD.DOWNLOAD-SUCCESS", args[0]); + Bukkit.getScheduler().runTask(TabooLib.instance(), () -> PluginUtils.load(expansion.getName())); + }); + } + } + }; + + @Override + public String getCommandTitle() { + return TLocale.asString("COMMANDS.TCLOUD.COMMAND-TITLE"); + } +} diff --git a/src/main/java/me/skymc/taboolib/cloud/TCloudLoader.java b/src/main/java/me/skymc/taboolib/cloud/TCloudLoader.java new file mode 100644 index 0000000..1aa1671 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/cloud/TCloudLoader.java @@ -0,0 +1,115 @@ +package me.skymc.taboolib.cloud; + +import com.google.common.collect.Maps; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.ilummc.tlib.resources.TLocale; +import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.cloud.expansion.Expansion; +import me.skymc.taboolib.cloud.expansion.ExpansionType; +import me.skymc.taboolib.common.function.TFunction; +import me.skymc.taboolib.fileutils.FileUtils; +import me.skymc.taboolib.plugin.PluginUtils; +import org.bukkit.Bukkit; + +import java.io.File; +import java.util.Map; + +/** + * @Author sky + * @Since 2018-09-30 17:30 + */ +@TFunction +public class TCloudLoader { + + private static String url = "https://gitee.com/bkm016/TabooLibCloud/raw/master/cloud.json"; + private static String latestJsonOrigin; + private static JsonObject latestJsonObject; + private static Map expansionPlugins = Maps.newHashMap(); + private static Map expansionInternal = Maps.newHashMap(); + private static File expansionInternalFolder; + + public void onEnable() { + createFolder(); + refresh(); + } + + public static void createFolder() { + if (!(expansionInternalFolder = new File(TabooLib.instance().getDataFolder(), "TCloud")).exists()) { + expansionInternalFolder.mkdirs(); + } + } + + public static void refresh() { + Bukkit.getScheduler().runTaskAsynchronously(TabooLib.instance(), () -> { + long time = System.currentTimeMillis(); + latestJsonOrigin = FileUtils.getStringFromURL(url, 1024); + if (latestJsonOrigin == null) { + TLocale.Logger.error("TCLOUD.LIST-CONNECT-FAILED"); + return; + } + TLocale.Logger.info("TCLOUD.LIST-CONNECT-SUCCESS", String.valueOf(System.currentTimeMillis() - time)); + time = System.currentTimeMillis(); + try { + latestJsonObject = new JsonParser().parse(latestJsonOrigin).getAsJsonObject(); + } catch (Exception e) { + TLocale.Logger.info("TCLOUD.LIST-PARSE-FAILED", e.getMessage()); + return; + } + TLocale.Logger.info("TCLOUD.LIST-PARSE-SUCCESS", String.valueOf(System.currentTimeMillis() - time)); + time = System.currentTimeMillis(); + if (latestJsonObject.has("plugins")) { + for (Map.Entry pluginEntry : latestJsonObject.getAsJsonObject("plugins").entrySet()) { + try { + expansionPlugins.put(pluginEntry.getKey(), Expansion.unSerialize(ExpansionType.PLUGIN, pluginEntry.getKey(), pluginEntry.getValue().getAsJsonObject())); + } catch (Exception e) { + TLocale.Logger.info("TCLOUD.LIST-LOAD-FAILED", pluginEntry.getKey(), e.getMessage()); + } + } + } + if (latestJsonObject.has("internal")) { + for (Map.Entry pluginEntry : latestJsonObject.getAsJsonObject("internal").entrySet()) { + try { + expansionInternal.put(pluginEntry.getKey(), Expansion.unSerialize(ExpansionType.INTERNAL, pluginEntry.getKey(), pluginEntry.getValue().getAsJsonObject())); + } catch (Exception e) { + TLocale.Logger.info("TCLOUD.LIST-LOAD-FAILED", pluginEntry.getKey(), e.getMessage()); + } + } + } + TLocale.Logger.info("TCLOUD.LIST-LOAD-SUCCESS", String.valueOf(System.currentTimeMillis() - time)); + }); + } + + public static boolean isConnected() { + return latestJsonOrigin != null; + } + + public static String getLatestJsonOrigin() { + return latestJsonOrigin; + } + + public static JsonObject getLatestJsonObject() { + return latestJsonObject; + } + + public static Map getExpansionPlugins() { + return expansionPlugins; + } + + public static Map getExpansionInternal() { + return expansionInternal; + } + + public static File getExpansionInternalFolder() { + return expansionInternalFolder; + } + + public static Expansion getExpansion(String name) { + return expansionPlugins.getOrDefault(name, expansionInternal.get(name)); + } + + public static boolean isExpansionExists(Expansion expansion) { + return expansion.getType() == ExpansionType.PLUGIN && PluginUtils.isPluginExists(expansion.getName()); + } +} diff --git a/src/main/java/me/skymc/taboolib/cloud/expansion/Expansion.java b/src/main/java/me/skymc/taboolib/cloud/expansion/Expansion.java new file mode 100644 index 0000000..ff99b76 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/cloud/expansion/Expansion.java @@ -0,0 +1,97 @@ +package me.skymc.taboolib.cloud.expansion; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.ilummc.eagletdl.EagletTask; +import com.ilummc.eagletdl.ProgressEvent; +import com.ilummc.tlib.resources.TLocale; +import me.skymc.taboolib.cloud.TCloudLoader; +import me.skymc.taboolib.fileutils.FileUtils; +import me.skymc.taboolib.string.ArrayUtils; + +import java.io.File; +import java.util.stream.IntStream; + +/** + * @Author sky + * @Since 2018-09-30 16:39 + */ +public class Expansion { + + private final String name; + private final String[] author; + private final String description; + private final String[] detail; + private final String version; + private final String lastUpdate; + private final String lastUpdateNote; + private final String link; + private final ExpansionType type; + + public Expansion(String name, String[] author, String description, String[] detail, String version, String lastUpdate, String lastUpdateNote, String link, ExpansionType type) { + this.name = name; + this.author = author; + this.description = description; + this.detail = detail; + this.version = version; + this.lastUpdate = lastUpdate; + this.lastUpdateNote = lastUpdateNote; + this.link = link; + this.type = type; + } + + public static Expansion unSerialize(ExpansionType type, String name, JsonObject object) { + String[] author = object.get("author").isJsonArray() ? toArray(object.get("author").getAsJsonArray()) : ArrayUtils.asArray(object.get("author").getAsString()); + String description = object.get("description").getAsString(); + String[] detail = object.get("detail").isJsonArray() ? toArray(object.get("detail").getAsJsonArray()) : ArrayUtils.asArray(object.get("detail").getAsString()); + String version = object.get("version").getAsString(); + String lastUpdate = object.get("last_update").getAsString(); + String lastUpdateNote = object.get("last_update_note").getAsString(); + String link = object.get("link").getAsString(); + return new Expansion(name, author, description, detail, version, lastUpdate, lastUpdateNote, link, type); + } + + public static String[] toArray(JsonArray json) { + return IntStream.range(0, json.size()).mapToObj(i -> json.get(i).getAsString()).toArray(String[]::new); + } + + public String getName() { + return name; + } + + public String[] getAuthor() { + return author; + } + + public String getDescription() { + return description; + } + + public String[] getDetail() { + return detail; + } + + public String getVersion() { + return version; + } + + public String getLastUpdate() { + return lastUpdate; + } + + public String getLastUpdateNote() { + return lastUpdateNote; + } + + public String getLink() { + return link; + } + + public ExpansionType getType() { + return type; + } + + public File getFile() { + return type == ExpansionType.INTERNAL ? new File(TCloudLoader.getExpansionInternalFolder(), "[TCLOUD] " + name + ".jar") : new File("plugins/[TCLOUD] " + name + ".jar"); + } +} diff --git a/src/main/java/me/skymc/taboolib/cloud/expansion/ExpansionType.java b/src/main/java/me/skymc/taboolib/cloud/expansion/ExpansionType.java new file mode 100644 index 0000000..a59b388 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/cloud/expansion/ExpansionType.java @@ -0,0 +1,10 @@ +package me.skymc.taboolib.cloud.expansion; + +/** + * @Author sky + * @Since 2018-09-30 16:39 + */ +public enum ExpansionType { + + INTERNAL, PLUGIN +} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/commands/internal/plugin/TLibLocale.java b/src/main/java/me/skymc/taboolib/commands/internal/plugin/TLibLocale.java new file mode 100644 index 0000000..426e663 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/commands/internal/plugin/TLibLocale.java @@ -0,0 +1,29 @@ +package me.skymc.taboolib.commands.internal.plugin; + +import com.ilummc.tlib.resources.TLocale; +import me.skymc.taboolib.commands.internal.type.CommandArgument; + +import java.util.stream.IntStream; + +/** + * @Author sky + * @Since 2018-09-30 19:26 + */ +public class TLibLocale { + + public static String title(String name) { + return TLocale.asString("COMMANDS." + name + ".COMMAND-TITLE"); + } + + public static String description(String name, String label) { + return TLocale.asString("COMMANDS." + name + "." + label + ".DESCRIPTION"); + } + + public static CommandArgument[] arguments(String name, String label, int size) { + return IntStream.range(0, size).mapToObj(i -> new CommandArgument(TLocale.asString("COMMANDS." + name + "." + label + ".ARGUMENTS." + i))).toArray(CommandArgument[]::new); + } + + public static CommandArgument argument(String name, String label, int index) { + return new CommandArgument(TLocale.asString("COMMANDS." + name + "." + label + ".ARGUMENTS." + index)); + } +} diff --git a/src/main/java/me/skymc/taboolib/update/UpdateTask.java b/src/main/java/me/skymc/taboolib/update/UpdateTask.java index 0536cef..14e5bb4 100644 --- a/src/main/java/me/skymc/taboolib/update/UpdateTask.java +++ b/src/main/java/me/skymc/taboolib/update/UpdateTask.java @@ -49,7 +49,7 @@ public class UpdateTask { } public static boolean isHaveUpdate() { - return newVersion > 0; + return newVersion > TabooLib.getPluginVersion(); } public static double getNewVersion() { diff --git a/src/main/resources/lang/zh_CN.yml b/src/main/resources/lang/zh_CN.yml index 8fc0a19..e085359 100644 --- a/src/main/resources/lang/zh_CN.yml +++ b/src/main/resources/lang/zh_CN.yml @@ -560,6 +560,44 @@ COMMANDS: 0: '目录' 1: '内容' SUCCESS: '&8[&3&lTabooLib&8] &7写入完成.' + TCLOUD: + COMMAND-TITLE: '&e&l----- &6&lTabooLibCloud Commands &e&l-----' + REFRESH: + DESCRIPTION: '刷新扩展列表' + SUCCESS: '&8[&3&lTabooLib&8] &7请求已发送. &8(详细信息请在控制台查看)' + STATUS: + DESCRIPTION: '查看扩展统计' + STATUS: + - '&8[&3&lTabooLib&8] &7当前总共 &f{0} &7项扩展被 &fTCLOUD &7录入, 其中包含:' + - '&8[&3&lTabooLib&8] &7内置扩展 &f{1} &7项' + - '&8[&3&lTabooLib&8] &7插件扩展 &f{2} &7项' + CONNECT-FAILED: '&8[&3&lTabooLib&8] &c尚未获取扩展列表, 输入 &4/tcloud refresh &c刷新.' + INFO: + DESCRIPTION: '查看扩展信息' + ARGUMENTS: + 0: '名称' + EXPANSION-NOT-FOUND: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c不存在, 输入 &4/tcloud refresh &c刷新.' + EXPANSION-INFO: + - '&8[&3&lTabooLib&8] &7扩展 &f{0} &7信息:' + - '&8[&3&lTabooLib&8] &7作者 &f{1}' + - '&8[&3&lTabooLib&8] &7版本 &f{2}' + - '&8[&3&lTabooLib&8] &7描述 &f{3}' + - '&8[&3&lTabooLib&8] &7最后更新时间 &f{4}' + - '&8[&3&lTabooLib&8] &7最后更新内容 &f{5}' + EXPANSION-INFO-DETAIL: + 0: '&8[&3&lTabooLib&8] &7详细描述' + 1: '&8[&3&lTabooLib&8] &7- &f{0}' + DOWNLOAD: + DESCRIPTION: '下载扩展' + ARGUMENTS: + 0: '名称' + EXPANSION-NOT-FOUND: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c不存在, 输入 &4/tcloud refresh &c刷新.' + EXPANSION-EXISTS: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c已存在, 输入 &4/tcloud update &c更新.' + DOWNLOAD-START: + - '&8[&3&lTabooLib&8] &7扩展 &f{0} &7开始下载:' + - '&8[&3&lTabooLib&8] &7目标 &f{1}' + - '&8[&3&lTabooLib&8] &7地址 &f{2}' + DOWNLOAD-SUCCESS: '&8[&3&lTabooLib&8] &7扩展 &f{0} &7下载完成. &8(详细信息请在控制台查看)' DATABASE: CONNECTION-ESTABLISHED: '成功连接到 {0} 数据库,连接池大小 {1}' @@ -580,4 +618,12 @@ UTIL: DOWNLOAD-CONNECTED: '开始下载文件 {0} 大小 {1}' DOWNLOAD-PROGRESS: ' 下载速度 {0} 进度 {1}' DOWNLOAD-SUCCESS: '下载 {0} 完成!' - DOWNLOAD-FAILED: '下载 {0} 失败!' \ No newline at end of file + DOWNLOAD-FAILED: '下载 {0} 失败!' + +TCLOUD: + LIST-CONNECT-SUCCESS: '获取 &fTCLOUD &7扩展列表完成! 耗时 &f{0} &7毫秒.' + LIST-CONNECT-FAILED: '获取 &4TCLOUD &c扩展列表失败!' + LIST-PARSE-SUCCESS: '读取 &fTCLOUD &7扩展列表完成! 耗时 &f{0} &7毫秒' + LIST-PARSE-FAILED: '读取 &4TCLOUD &c扩展列表失败: &4{0}' + LIST-LOAD-SUCCESS: '载入 &fTCLOUD &7扩展列表完成! 耗时 &f{0} &7毫秒' + LIST-LOAD-FAILED: '载入 &4{0} &c扩展数据失败: &4{1}' \ No newline at end of file From 16f8312a8f3f3ea677b6a180cf74f2ae2a933f2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9D=8F=E9=BB=91?= Date: Mon, 1 Oct 2018 22:52:48 +0800 Subject: [PATCH 2/2] =?UTF-8?q?+=20tcloud=20=E5=88=9D=E6=AD=A5=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E6=88=90=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + cloud.json | 76 +++++++++++++ pom.xml | 24 ++--- .../java/com/ilummc/eagletdl/EagletTask.java | 77 +++++++------ .../skymc/taboolib/cloud/TCloudCommand.java | 101 +++++++++++++++++- .../me/skymc/taboolib/cloud/TCloudLoader.java | 4 - .../taboolib/cloud/expansion/Expansion.java | 9 ++ .../commands/internal/BaseSubCommand.java | 3 +- .../commands/internal/plugin/TLibLocale.java | 4 + .../taboolib/common/util/SimpleIterator.java | 51 +++++++++ src/main/resources/lang/zh_CN.yml | 53 ++++++--- 11 files changed, 340 insertions(+), 64 deletions(-) create mode 100644 cloud.json create mode 100644 src/main/java/me/skymc/taboolib/common/util/SimpleIterator.java diff --git a/README.md b/README.md index 115619a..c068479 100644 --- a/README.md +++ b/README.md @@ -43,10 +43,12 @@ | /taboolibplugin | TPlugin 工具主命令 | taboolib.admin | | /taboolibexecute | TExecute 工具主命令 | taboolib.admin | | /tabooliblogs | TLogs 工具主命令 | taboolib.admin | +| /taboolibcloud | TCLOUD 模块主命令 | taboolib.admin | | /taboolibrarymodule | TLM 模块主命令 | tlm.use | | /language2 | Language2 工具主命令 | taboolib.admin | | /translateuuid | TranslateUUID 工具主命令 | taboolib.admin | +
diff --git a/cloud.json b/cloud.json new file mode 100644 index 0000000..9e71283 --- /dev/null +++ b/cloud.json @@ -0,0 +1,76 @@ +{ + "plugins": { + "TabooMenu": { + "author": [ + "Bkm016", + "filoghost" + ], + "description": "一款高自由,高效率,功能丰富的菜单插件。", + "detail": [ + "独创忽略大小写式节点判断", + "保留 ChestCommands 载入格式,更换插件直接复制文件", + "保留 ChestCommands 的大部分节点", + "保留 ChestCommands 的 51 项物品别名", + "保留 ChestCommands 的 cc 指令,直接更换也不会影响其他插件", + "更简单的物品坐标写法", + "更强大的指令功能,多达 7 种触发方式,17 种执行方式", + "更强大的物品扣除功能,多达 6 种检测方式", + "更直观的物品条件写法", + "更智能的菜单刷新方式", + "物品 ID 容错,智能匹配", + "关闭菜单时自动打开其他菜单", + "点击/查看物品时执行自定义脚本", + "PlaceholderAPI 支持。", + "独立权限控制", + "在线模板编辑", + "冷却时间", + "..." + ], + "version": "1.73", + "last_update": "2018-7-4", + "last_update_note": "修复优先级问题", + "link": "https://gitee.com/bkm016/TabooLibCloud/raw/master/plugins/TabooMenu.jar" + }, + "TabooScript": { + "author": [ + "lzzelAliz", + "Bkm016" + ], + "description": "告别 Java 开启奔放脚本时代。", + "detail": [ + "快速上手,写法自由,功能强大", + "超强 Bukkit 脚本拓展" + ], + "version": "1.3", + "last_update": "2018-10-1", + "last_update_note": "-", + "link": "https://gitee.com/bkm016/TabooLibCloud/raw/master/plugins/TabooScript.jar" + }, + "TabooLibBungeeSuite": { + "author": [ + "Bkm016" + ], + "description": "用于 BungeeCord 与 Bukkit 之间的快速交流工具。", + "detail": [ + "本插件为前置依赖无详细介绍" + ], + "version": "1.3", + "last_update": "2018-6-21", + "last_update_note": "-", + "link": "https://gitee.com/bkm016/TabooLibCloud/raw/master/plugins/TabooLibBungeeSuite.jar" + }, + "TabooSK": { + "author": [ + "Bkm016" + ], + "description": "Skript 扩展插件。", + "detail": [ + "计分板、配置文件、时间戳等高性能语法。" + ], + "version": "2.2", + "last_update": "2018-8-14", + "last_update_note": "更新了MythicMobs的物品获取语法", + "link": "https://gitee.com/bkm016/TabooLibCloud/raw/master/plugins/TabooSK.jar" + } + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 2f19b81..d3b8e84 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.skymc TabooLib - 4.4 + 4.5 UTF-8 @@ -59,17 +59,6 @@ - - org.apache.maven.plugins - maven-jar-plugin - - - - me.skymc.taboolib.socket.TabooLibServer - - - - net.alchim31.maven scala-maven-plugin @@ -82,6 +71,17 @@ + + org.apache.maven.plugins + maven-jar-plugin + + + + me.skymc.taboolib.socket.TabooLibServer + + + + diff --git a/src/main/java/com/ilummc/eagletdl/EagletTask.java b/src/main/java/com/ilummc/eagletdl/EagletTask.java index fb85bdb..a37d6b7 100644 --- a/src/main/java/com/ilummc/eagletdl/EagletTask.java +++ b/src/main/java/com/ilummc/eagletdl/EagletTask.java @@ -71,15 +71,21 @@ public class EagletTask { // create thread pool for download executorService = Executors.newFixedThreadPool(threadAmount); // check if is already running - if (running) throw new AlreadyStartException(); + if (running) { + throw new AlreadyStartException(); + } // start the monitor thread monitor = new Thread(() -> { lock.lock(); // fire a new start event - if (onStart != null) onStart.handle(new StartEvent(this)); + if (onStart != null) { + onStart.handle(new StartEvent(this)); + } try { // create the target file - if (!dest.exists()) dest.createNewFile(); + if (!dest.exists()) { + dest.createNewFile(); + } HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // set the connection properties httpHeader.forEach(connection::addRequestProperty); @@ -90,27 +96,26 @@ public class EagletTask { contentLength = connection.getContentLengthLong(); // fire a new connected event // contains connection properties - if (onConnected != null) onConnected.handle(new ConnectedEvent(contentLength, this)); + if (onConnected != null) { + onConnected.handle(new ConnectedEvent(contentLength, this)); + } // if this is an unknown length task if (contentLength == -1 || threadAmount == 1) { // pass the connection instance to this new thread SingleThreadDownload download = new SingleThreadDownload(connection, dest, this); executorService.execute(download); long last = 0; - while (true) { + do { Thread.sleep(1000); // check the progress long progress = download.getCurrentProgress(); // fire a new progress event - if (onProgress != null) - onProgress.handle(new ProgressEvent(progress - last, this, - ((double) progress) / Math.max((double) contentLength, 0D))); + if (onProgress != null) { + onProgress.handle(new ProgressEvent(progress - last, this, ((double) progress) / Math.max((double) contentLength, 0D))); + } last = progress; // check complete - if (last == contentLength || download.isComplete()) { - break; - } - } + } while (last != contentLength && !download.isComplete()); // close the thread pool, release resources executorService.shutdown(); // change the running flag to false @@ -131,48 +136,54 @@ public class EagletTask { splitDownloads.add(download); } long last = 0; - while (true) { + do { Thread.sleep(1000); long progress = 0; // Collect download progress for (SplitDownload splitDownload : splitDownloads) { progress += splitDownload.getCurrentIndex() - splitDownload.startIndex; // blocked then restart from current index - if (!splitDownload.isComplete() && - System.currentTimeMillis() - splitDownload.getLastUpdateTime() > maxBlockingTime) { + if (!splitDownload.isComplete() && System.currentTimeMillis() - splitDownload.getLastUpdateTime() > maxBlockingTime) { splitDownload.setStartIndex(splitDownload.getCurrentIndex()); - if (splitDownload.getRetry() <= maxRetry) + if (splitDownload.getRetry() <= maxRetry) { executorService.execute(splitDownload); - else throw new RetryFailedException(this); + } else { + throw new RetryFailedException(this); + } } } // Fire a progress event - if (onProgress != null) + if (onProgress != null) { onProgress.handle(new ProgressEvent(progress - last, this, ((double) progress) / ((double) contentLength))); + } last = progress; // check complete - if (last >= contentLength) { - break; - } - } + } while (last < contentLength); // close the thread pool, release resources executorService.shutdown(); // change the running flag to false running = false; } // check hash - if (md5 != null && !md5.equalsIgnoreCase(HashUtil.md5(dest))) + if (md5 != null && !md5.equalsIgnoreCase(HashUtil.md5(dest))) { throw new HashNotMatchException(); - if (sha1 != null && !sha1.equalsIgnoreCase(HashUtil.sha1(dest))) + } + if (sha1 != null && !sha1.equalsIgnoreCase(HashUtil.sha1(dest))) { throw new HashNotMatchException(); - if (sha256 != null && !sha256.equalsIgnoreCase(HashUtil.sha256(dest))) + } + if (sha256 != null && !sha256.equalsIgnoreCase(HashUtil.sha256(dest))) { throw new HashNotMatchException(); - if (onComplete != null) onComplete.handle(new CompleteEvent(this, true)); + } + if (onComplete != null) { + onComplete.handle(new CompleteEvent(this, true)); + } } catch (Exception e) { onError.handle(new ErrorEvent(e, this)); executorService.shutdown(); - if (onComplete != null) onComplete.handle(new CompleteEvent(this, false)); + if (onComplete != null) { + onComplete.handle(new CompleteEvent(this, false)); + } } finally { lock.unlock(); } @@ -182,14 +193,18 @@ public class EagletTask { } public EagletTask waitUntil() { - while (lock.tryLock()) lock.unlock(); + while (lock.tryLock()) { + lock.unlock(); + } lock.lock(); lock.unlock(); return this; } public EagletTask waitFor(long timeout, TimeUnit unit) { - while (lock.tryLock()) lock.unlock(); + while (lock.tryLock()) { + lock.unlock(); + } try { lock.tryLock(timeout, unit); } catch (InterruptedException e) { @@ -404,7 +419,9 @@ public class EagletTask { * @return task instance */ public EagletTask setThreads(int i) { - if (i < 1) throw new RuntimeException("Thread amount cannot be zero or negative!"); + if (i < 1) { + throw new RuntimeException("Thread amount cannot be zero or negative!"); + } threadAmount = i; return this; } diff --git a/src/main/java/me/skymc/taboolib/cloud/TCloudCommand.java b/src/main/java/me/skymc/taboolib/cloud/TCloudCommand.java index 695d65b..4baea78 100644 --- a/src/main/java/me/skymc/taboolib/cloud/TCloudCommand.java +++ b/src/main/java/me/skymc/taboolib/cloud/TCloudCommand.java @@ -3,20 +3,22 @@ package me.skymc.taboolib.cloud; import com.ilummc.tlib.resources.TLocale; import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.cloud.expansion.Expansion; +import me.skymc.taboolib.cloud.expansion.ExpansionType; import me.skymc.taboolib.commands.internal.BaseMainCommand; import me.skymc.taboolib.commands.internal.BaseSubCommand; import me.skymc.taboolib.commands.internal.TCommand; import me.skymc.taboolib.commands.internal.plugin.TLibLocale; import me.skymc.taboolib.commands.internal.type.CommandArgument; import me.skymc.taboolib.commands.internal.type.CommandRegister; +import me.skymc.taboolib.common.util.SimpleIterator; import me.skymc.taboolib.fileutils.FileUtils; -import me.skymc.taboolib.plugin.PluginUtils; import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; +import org.bukkit.util.NumberConversions; -import java.io.File; import java.util.Arrays; +import java.util.Map; import java.util.stream.Collectors; /** @@ -109,6 +111,7 @@ public class TCloudCommand extends BaseMainCommand { } } }; + @CommandRegister(priority = 3) BaseSubCommand download = new BaseSubCommand() { @Override @@ -135,15 +138,105 @@ public class TCloudCommand extends BaseMainCommand { TLocale.sendTo(sender, "COMMANDS.TCLOUD.DOWNLOAD.EXPANSION-EXISTS", args[0]); } else { Bukkit.getScheduler().runTaskAsynchronously(TabooLib.instance(), () -> { - TLocale.sendTo(sender, "COMMANDS.TCLOUD.DOWNLOAD.DOWNLOAD-START", args[0], expansion.getFile().getPath(), expansion.getLink()); + TLocale.sendTo(sender, "COMMANDS.TCLOUD.DOWNLOAD.DOWNLOAD-START", args[0], expansion.getLink()); FileUtils.download(expansion.getLink(), expansion.getFile()); TLocale.sendTo(sender, "COMMANDS.TCLOUD.DOWNLOAD.DOWNLOAD-SUCCESS", args[0]); - Bukkit.getScheduler().runTask(TabooLib.instance(), () -> PluginUtils.load(expansion.getName())); }); } } }; + @CommandRegister(priority = 4) + BaseSubCommand update = new BaseSubCommand() { + @Override + public String getLabel() { + return "update"; + } + + @Override + public String getDescription() { + return TLibLocale.description("TCLOUD", "UPDATE"); + } + + @Override + public CommandArgument[] getArguments() { + return TLibLocale.arguments("TCLOUD", "UPDATE", 1); + } + + @Override + public void onCommand(CommandSender sender, Command command, String label, String[] args) { + Expansion expansion = TCloudLoader.getExpansion(args[0]); + if (expansion == null) { + TLocale.sendTo(sender, "COMMANDS.TCLOUD.UPDATE.EXPANSION-NOT-FOUND", args[0]); + } else if (!TCloudLoader.isExpansionExists(expansion)) { + TLocale.sendTo(sender, "COMMANDS.TCLOUD.UPDATE.EXPANSION-NOT-EXISTS", args[0]); + } else if (!expansion.canUpdate()) { + TLocale.sendTo(sender, "COMMANDS.TCLOUD.UPDATE.EXPANSION-NO-UPDATE", args[0]); + } else { + Bukkit.getScheduler().runTaskAsynchronously(TabooLib.instance(), () -> { + TLocale.sendTo(sender, "COMMANDS.TCLOUD.UPDATE.UPDATE-START", args[0], expansion.getVersion(), expansion.getLink()); + FileUtils.download(expansion.getLink(), expansion.getFile()); + TLocale.sendTo(sender, "COMMANDS.TCLOUD.UPDATE.UPDATE-SUCCESS", args[0]); + }); + } + } + }; + + @CommandRegister(priority = 5) + BaseSubCommand list = new BaseSubCommand() { + @Override + public String getLabel() { + return "list"; + } + + @Override + public String getDescription() { + return TLibLocale.description("TCLOUD", "LIST"); + } + + @Override + public CommandArgument[] getArguments() { + return new CommandArgument[] { + TLibLocale.argument("TCLOUD", "LIST", 0), + TLibLocale.argument("TCLOUD", "LIST", 1, false) + }; + } + + @Override + public void onCommand(CommandSender sender, Command command, String label, String[] args) { + ExpansionType type; + switch (args[0].toLowerCase()) { + case "plugins": + type = ExpansionType.PLUGIN; + break; + case "internal": + type = ExpansionType.INTERNAL; + break; + default: + TLocale.sendTo(sender, "COMMANDS.TCLOUD.LIST.INVALID-TYPE.0"); + return; + } + Map expansions = type == ExpansionType.PLUGIN ? TCloudLoader.getExpansionPlugins() : TCloudLoader.getExpansionInternal(); + int page = args.length < 2 ? 1 : NumberConversions.toInt(args[1]); + if (page < 1 || page > (expansions.size() / 5) + 1) { + TLocale.sendTo(sender, "COMMANDS.TCLOUD.LIST.INVALID-TYPE.1"); + return; + } + TLocale.sendTo(sender, "COMMANDS.TCLOUD.LIST.LIST-HEAD", type.name(), String.valueOf(page), String.valueOf((expansions.size() / 5) + 1)); + int i = (page - 1) * 5; + for (Map.Entry entry : new SimpleIterator(expansions).mapIterator((page - 1) * 5, page * 5)) { + if (!TCloudLoader.isExpansionExists(entry.getValue())) { + TLocale.sendTo(sender, "COMMANDS.TCLOUD.LIST.LIST-EXPANSION.0", String.valueOf(++i), entry.getValue().getName(), entry.getValue().getDescription()); + } else if (entry.getValue().canUpdate()) { + TLocale.sendTo(sender, "COMMANDS.TCLOUD.LIST.LIST-EXPANSION.1", String.valueOf(++i), entry.getValue().getName(), entry.getValue().getDescription()); + } else { + TLocale.sendTo(sender, "COMMANDS.TCLOUD.LIST.LIST-EXPANSION.2", String.valueOf(++i), entry.getValue().getName(), entry.getValue().getDescription()); + } + } + TLocale.sendTo(sender, "COMMANDS.TCLOUD.LIST.LIST-BOTTOM"); + } + }; + @Override public String getCommandTitle() { return TLocale.asString("COMMANDS.TCLOUD.COMMAND-TITLE"); diff --git a/src/main/java/me/skymc/taboolib/cloud/TCloudLoader.java b/src/main/java/me/skymc/taboolib/cloud/TCloudLoader.java index 1aa1671..4ac2f6b 100644 --- a/src/main/java/me/skymc/taboolib/cloud/TCloudLoader.java +++ b/src/main/java/me/skymc/taboolib/cloud/TCloudLoader.java @@ -49,16 +49,12 @@ public class TCloudLoader { TLocale.Logger.error("TCLOUD.LIST-CONNECT-FAILED"); return; } - TLocale.Logger.info("TCLOUD.LIST-CONNECT-SUCCESS", String.valueOf(System.currentTimeMillis() - time)); - time = System.currentTimeMillis(); try { latestJsonObject = new JsonParser().parse(latestJsonOrigin).getAsJsonObject(); } catch (Exception e) { TLocale.Logger.info("TCLOUD.LIST-PARSE-FAILED", e.getMessage()); return; } - TLocale.Logger.info("TCLOUD.LIST-PARSE-SUCCESS", String.valueOf(System.currentTimeMillis() - time)); - time = System.currentTimeMillis(); if (latestJsonObject.has("plugins")) { for (Map.Entry pluginEntry : latestJsonObject.getAsJsonObject("plugins").entrySet()) { try { diff --git a/src/main/java/me/skymc/taboolib/cloud/expansion/Expansion.java b/src/main/java/me/skymc/taboolib/cloud/expansion/Expansion.java index ff99b76..0246a80 100644 --- a/src/main/java/me/skymc/taboolib/cloud/expansion/Expansion.java +++ b/src/main/java/me/skymc/taboolib/cloud/expansion/Expansion.java @@ -8,6 +8,8 @@ import com.ilummc.tlib.resources.TLocale; import me.skymc.taboolib.cloud.TCloudLoader; import me.skymc.taboolib.fileutils.FileUtils; import me.skymc.taboolib.string.ArrayUtils; +import org.bukkit.Bukkit; +import org.bukkit.util.NumberConversions; import java.io.File; import java.util.stream.IntStream; @@ -94,4 +96,11 @@ public class Expansion { public File getFile() { return type == ExpansionType.INTERNAL ? new File(TCloudLoader.getExpansionInternalFolder(), "[TCLOUD] " + name + ".jar") : new File("plugins/[TCLOUD] " + name + ".jar"); } + + public boolean canUpdate() { + if (!TCloudLoader.isExpansionExists(this)) { + return false; + } + return type == ExpansionType.PLUGIN && NumberConversions.toDouble(Bukkit.getPluginManager().getPlugin(name).getDescription().getVersion()) < NumberConversions.toDouble(version); + } } diff --git a/src/main/java/me/skymc/taboolib/commands/internal/BaseSubCommand.java b/src/main/java/me/skymc/taboolib/commands/internal/BaseSubCommand.java index 37a8dd8..e690197 100644 --- a/src/main/java/me/skymc/taboolib/commands/internal/BaseSubCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/internal/BaseSubCommand.java @@ -100,7 +100,6 @@ public abstract class BaseSubCommand { * @return String */ public String getCommandString(String label) { - String stringBuilder = Arrays.stream(getArguments()).map(parameter -> parameter.toString() + " ").collect(Collectors.joining()); - return TLocale.asString("COMMANDS.INTERNAL.COMMAND-HELP", label, getLabel(), stringBuilder.trim(), getDescription()); + return TLocale.asString("COMMANDS.INTERNAL.COMMAND-HELP", label, getLabel(), Arrays.stream(getArguments()).map(parameter -> parameter.toString() + " ").collect(Collectors.joining()), getDescription()); } } \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/commands/internal/plugin/TLibLocale.java b/src/main/java/me/skymc/taboolib/commands/internal/plugin/TLibLocale.java index 426e663..a8b9623 100644 --- a/src/main/java/me/skymc/taboolib/commands/internal/plugin/TLibLocale.java +++ b/src/main/java/me/skymc/taboolib/commands/internal/plugin/TLibLocale.java @@ -26,4 +26,8 @@ public class TLibLocale { public static CommandArgument argument(String name, String label, int index) { return new CommandArgument(TLocale.asString("COMMANDS." + name + "." + label + ".ARGUMENTS." + index)); } + + public static CommandArgument argument(String name, String label, int index, boolean required) { + return new CommandArgument(TLocale.asString("COMMANDS." + name + "." + label + ".ARGUMENTS." + index), required); + } } diff --git a/src/main/java/me/skymc/taboolib/common/util/SimpleIterator.java b/src/main/java/me/skymc/taboolib/common/util/SimpleIterator.java new file mode 100644 index 0000000..88ce0be --- /dev/null +++ b/src/main/java/me/skymc/taboolib/common/util/SimpleIterator.java @@ -0,0 +1,51 @@ +package me.skymc.taboolib.common.util; + +import com.google.common.collect.Lists; + +import java.util.List; +import java.util.Map; + +/** + * @Author sky + * @Since 2018-10-01 16:19 + */ +public class SimpleIterator { + + private final Object container; + + public SimpleIterator(Object container) { + this.container = container; + } + + public List mapIterator(int start, int end) { + List iterator = Lists.newArrayList(); + Map container = (Map) this.container; + int loop = 0; + for (Object entry : container.entrySet()) { + if (loop++ >= start) { + if (loop <= end) { + iterator.add((Map.Entry) entry); + } else { + break; + } + } + } + return iterator; + } + + public List listIterator(int start, int end) { + List iterator = Lists.newArrayList(); + List container = (List) this.container; + int loop = 0; + for (Object entry : container) { + if (loop++ >= start) { + if (loop <= end) { + iterator.add(entry); + } else { + break; + } + } + } + return iterator; + } +} diff --git a/src/main/resources/lang/zh_CN.yml b/src/main/resources/lang/zh_CN.yml index e085359..7be8925 100644 --- a/src/main/resources/lang/zh_CN.yml +++ b/src/main/resources/lang/zh_CN.yml @@ -172,7 +172,7 @@ COMMANDS: COMMAND-CREATE: '&7自动为插件 &f{0} &7的 &f{1} &7命令注册到服务器' COMMAND-CREATE-FAILED: '&7插件 &f{0} &7的 &f{1} &7命令注册失败: &c{2}' COMMAND-REGISTER: '&7自动为插件 &f{0} &7的 &f{1} &7命令注册 &f{2} &7条子命令' - COMMAND-HELP: ' §f/{0} {1} {2} §6- §e{3}' + COMMAND-HELP: ' §f/{0} {1} {2}§6- §e{3}' COMMAND-ARGUMENT: '§7<§8{0}§7>' COMMAND-ARGUMENT-REQUIRE: '§7[§8{0}§7]' PARAMETER: @@ -571,12 +571,12 @@ COMMANDS: - '&8[&3&lTabooLib&8] &7当前总共 &f{0} &7项扩展被 &fTCLOUD &7录入, 其中包含:' - '&8[&3&lTabooLib&8] &7内置扩展 &f{1} &7项' - '&8[&3&lTabooLib&8] &7插件扩展 &f{2} &7项' - CONNECT-FAILED: '&8[&3&lTabooLib&8] &c尚未获取扩展列表, 输入 &4/tcloud refresh &c刷新.' + CONNECT-FAILED: '&8[&3&lTabooLib&8] &c尚未获取扩展列表.' INFO: DESCRIPTION: '查看扩展信息' ARGUMENTS: 0: '名称' - EXPANSION-NOT-FOUND: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c不存在, 输入 &4/tcloud refresh &c刷新.' + EXPANSION-NOT-FOUND: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c不存在.' EXPANSION-INFO: - '&8[&3&lTabooLib&8] &7扩展 &f{0} &7信息:' - '&8[&3&lTabooLib&8] &7作者 &f{1}' @@ -591,13 +591,44 @@ COMMANDS: DESCRIPTION: '下载扩展' ARGUMENTS: 0: '名称' - EXPANSION-NOT-FOUND: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c不存在, 输入 &4/tcloud refresh &c刷新.' - EXPANSION-EXISTS: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c已存在, 输入 &4/tcloud update &c更新.' + EXPANSION-NOT-FOUND: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c不存在.' + EXPANSION-EXISTS: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c已存在.' DOWNLOAD-START: - '&8[&3&lTabooLib&8] &7扩展 &f{0} &7开始下载:' - - '&8[&3&lTabooLib&8] &7目标 &f{1}' + - '&8[&3&lTabooLib&8] &7地址 &f{1}' + DOWNLOAD-SUCCESS: '&8[&3&lTabooLib&8] &7扩展 &f{0} &7下载完成, 请重启服务器.' + UPDATE: + DESCRIPTION: '更新扩展' + ARGUMENTS: + 0: '名称' + EXPANSION-NOT-FOUND: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c不存在.' + EXPANSION-NOT-EXISTS: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c尚未下载.' + EXPANSION-NO-UPDATE: '&8[&3&lTabooLib&8] &7扩展 &f{0} &7已是最新版本.' + UPDATE-START: + - '&8[&3&lTabooLib&8] &7扩展 &f{0} &7开始更新:' + - '&8[&3&lTabooLib&8] &7版本 &f{1}' - '&8[&3&lTabooLib&8] &7地址 &f{2}' - DOWNLOAD-SUCCESS: '&8[&3&lTabooLib&8] &7扩展 &f{0} &7下载完成. &8(详细信息请在控制台查看)' + UPDATE-SUCCESS: '&8[&3&lTabooLib&8] &7扩展 &f{0} &7更新完成, 请重启服务器.' + LIST: + DESCRIPTION: '查看扩展列表' + ARGUMENTS: + 0: 'PLUGINS/INTERNAL' + 1: '页数' + INVALID-TYPE: + 0: '&8[&3&lTabooLib&8] &c错误的扩展类型. &4(PLUGINS、INTERNAL)' + 1: '&8[&3&lTabooLib&8] &c错误的页数.' + LIST-HEAD: + - '' + - '&e&l----- &6&lTabooLibCloud Expansions : &f{0} &6&l: &f{1}/{2} &e&l-----' + - '' + LIST-EXPANSION: + 0: ' &f{0}. &8{1} &f- &7{2}' + 1: ' &f{0}. &c{1} &f- &7{2}' + 2: ' &f{0}. &a{1} &f- &7{2}' + LIST-BOTTOM: + - '' + - ' &f> &8[未安装] &a[已安装] &c[可更新]' + - '' DATABASE: CONNECTION-ESTABLISHED: '成功连接到 {0} 数据库,连接池大小 {1}' @@ -621,9 +652,7 @@ UTIL: DOWNLOAD-FAILED: '下载 {0} 失败!' TCLOUD: - LIST-CONNECT-SUCCESS: '获取 &fTCLOUD &7扩展列表完成! 耗时 &f{0} &7毫秒.' - LIST-CONNECT-FAILED: '获取 &4TCLOUD &c扩展列表失败!' - LIST-PARSE-SUCCESS: '读取 &fTCLOUD &7扩展列表完成! 耗时 &f{0} &7毫秒' - LIST-PARSE-FAILED: '读取 &4TCLOUD &c扩展列表失败: &4{0}' LIST-LOAD-SUCCESS: '载入 &fTCLOUD &7扩展列表完成! 耗时 &f{0} &7毫秒' - LIST-LOAD-FAILED: '载入 &4{0} &c扩展数据失败: &4{1}' \ No newline at end of file + LIST-LOAD-FAILED: '载入 &4{0} &c扩展数据失败: &4{1}' + LIST-PARSE-FAILED: '读取 &4TCLOUD &c扩展列表失败: &4{0}' + LIST-CONNECT-FAILED: '获取 &4TCLOUD &c扩展列表失败!' \ No newline at end of file