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 0e1d737..d3b8e84 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
me.skymc
TabooLib
- 4.325
+ 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
new file mode 100644
index 0000000..4baea78
--- /dev/null
+++ b/src/main/java/me/skymc/taboolib/cloud/TCloudCommand.java
@@ -0,0 +1,244 @@
+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 org.bukkit.Bukkit;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.util.NumberConversions;
+
+import java.util.Arrays;
+import java.util.Map;
+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.getLink());
+ FileUtils.download(expansion.getLink(), expansion.getFile());
+ TLocale.sendTo(sender, "COMMANDS.TCLOUD.DOWNLOAD.DOWNLOAD-SUCCESS", args[0]);
+ });
+ }
+ }
+ };
+
+ @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
new file mode 100644
index 0000000..4ac2f6b
--- /dev/null
+++ b/src/main/java/me/skymc/taboolib/cloud/TCloudLoader.java
@@ -0,0 +1,111 @@
+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;
+ }
+ try {
+ latestJsonObject = new JsonParser().parse(latestJsonOrigin).getAsJsonObject();
+ } catch (Exception e) {
+ TLocale.Logger.info("TCLOUD.LIST-PARSE-FAILED", e.getMessage());
+ return;
+ }
+ 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..0246a80
--- /dev/null
+++ b/src/main/java/me/skymc/taboolib/cloud/expansion/Expansion.java
@@ -0,0 +1,106 @@
+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 org.bukkit.Bukkit;
+import org.bukkit.util.NumberConversions;
+
+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");
+ }
+
+ 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/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/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
new file mode 100644
index 0000000..a8b9623
--- /dev/null
+++ b/src/main/java/me/skymc/taboolib/commands/internal/plugin/TLibLocale.java
@@ -0,0 +1,33 @@
+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));
+ }
+
+ 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/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..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:
@@ -560,6 +560,75 @@ 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尚未获取扩展列表.'
+ INFO:
+ DESCRIPTION: '查看扩展信息'
+ ARGUMENTS:
+ 0: '名称'
+ 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}'
+ - '&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不存在.'
+ 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}'
+ 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}'
+ 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}'
@@ -580,4 +649,10 @@ 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-LOAD-SUCCESS: '载入 &fTCLOUD &7扩展列表完成! 耗时 &f{0} &7毫秒'
+ 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