diff --git a/pom.xml b/pom.xml index 8b7e150..e1cb2c3 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.skymc TabooLib - 4.64 + 4.65 UTF-8 diff --git a/src/main/java/com/ilummc/tlib/filter/impl/FilterExceptionMirror.java b/src/main/java/com/ilummc/tlib/filter/impl/FilterExceptionMirror.java index b315ccf..db01569 100644 --- a/src/main/java/com/ilummc/tlib/filter/impl/FilterExceptionMirror.java +++ b/src/main/java/com/ilummc/tlib/filter/impl/FilterExceptionMirror.java @@ -1,6 +1,7 @@ package com.ilummc.tlib.filter.impl; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import com.ilummc.tlib.filter.TLoggerFilterHandler; import com.ilummc.tlib.resources.TLocale; import me.skymc.taboolib.Main; @@ -11,6 +12,7 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import java.util.List; +import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import java.util.logging.LogRecord; import java.util.regex.Matcher; @@ -53,17 +55,17 @@ public class FilterExceptionMirror extends TLoggerFilterHandler { * @return 是否成功捕捉并打印 */ public boolean printException(AtomicReference plugin, StackTraceElement[] stackTraceElements, String message, ArgumentsCallback args) { + Set plugins = Sets.newHashSet(); List stackTraces = Lists.newLinkedList(); for (StackTraceElement stack : stackTraceElements) { try { - plugin.set(JavaPlugin.getProvidingPlugin(Class.forName(stack.getClassName()))); - if (TabooLib.isTabooLib(plugin.get()) || TabooLib.isDependTabooLib(plugin.get())) { - stackTraces.add(stack); - } + plugins.add(JavaPlugin.getProvidingPlugin(Class.forName(stack.getClassName()))); + stackTraces.add(stack); } catch (Exception ignored) { } } - if (plugin.get() != null && (TabooLib.isTabooLib(plugin.get()) || TabooLib.isDependTabooLib(plugin.get()))) { + if (!plugins.isEmpty() && plugins.stream().allMatch(p -> TabooLib.isTabooLib(p) || TabooLib.isDependTabooLib(p))) { + plugin.set(plugins.iterator().next()); TLocale.Logger.error("TFILTER.EXCEPTION-MIRROR." + message + ".HEAD", args.run()); for (int i = 0; i < stackTraces.size(); i++) { StackTraceElement stack = stackTraces.get(i); diff --git a/src/main/java/me/skymc/taboolib/common/inject/TInjectLoader.java b/src/main/java/me/skymc/taboolib/common/inject/TInjectLoader.java index 802de72..41d58bf 100644 --- a/src/main/java/me/skymc/taboolib/common/inject/TInjectLoader.java +++ b/src/main/java/me/skymc/taboolib/common/inject/TInjectLoader.java @@ -24,45 +24,45 @@ public class TInjectLoader implements TabooLibLoader.Loader { static { // Instance Inject - injectTypes.put(Plugin.class, (plugin, field, args) -> { + injectTypes.put(Plugin.class, (plugin, field, args, instance) -> { try { - field.set(null, plugin); + field.set(instance, plugin); } catch (Exception e) { e.printStackTrace(); } }); // TLogger Inject - injectTypes.put(TLogger.class, (plugin, field, args) -> { + injectTypes.put(TLogger.class, (plugin, field, args, instance) -> { try { - field.set(null, args.length == 0 ? TLogger.getUnformatted(plugin) : TLogger.getUnformatted(args[0])); + field.set(instance, args.length == 0 ? TLogger.getUnformatted(plugin) : TLogger.getUnformatted(args[0])); } catch (Exception e) { e.printStackTrace(); } }); // TPacketListener Inject - injectTypes.put(TPacketListener.class, (plugin, field, args) -> { + injectTypes.put(TPacketListener.class, (plugin, field, args, instance) -> { try { - TPacketHandler.addListener(plugin, ((TPacketListener) field.get(null))); + TPacketHandler.addListener(plugin, ((TPacketListener) field.get(instance))); } catch (Exception e) { e.printStackTrace(); } }); // TConfiguration Inject - injectTypes.put(TConfiguration.class, (plugin, field, args) -> { + injectTypes.put(TConfiguration.class, (plugin, field, args, instance) -> { try { if (args.length == 0) { TLogger.getGlobalLogger().error("Invalid inject arguments: " + field.getName() + " (" + field.getType().getName() + ")"); } else { - field.set(null, TConfiguration.createInResource(plugin, args[0])); + field.set(instance, TConfiguration.createInResource(plugin, args[0])); } } catch (Exception e) { e.printStackTrace(); } }); // SimpleCommandBuilder Inject - injectTypes.put(SimpleCommandBuilder.class, (plugin, field, args) -> { + injectTypes.put(SimpleCommandBuilder.class, (plugin, field, args, instance) -> { try { - SimpleCommandBuilder builder = (SimpleCommandBuilder) field.get(null); + SimpleCommandBuilder builder = (SimpleCommandBuilder) field.get(instance); if (builder.isBuild()) { TLogger.getGlobalLogger().error("Command was registered. (" + field.getType().getName() + ")"); } else { @@ -84,14 +84,21 @@ public class TInjectLoader implements TabooLibLoader.Loader { if (annotation == null) { continue; } + Object instance = null; + // 如果是非静态类型 if (!Modifier.isStatic(declaredField.getModifiers())) { - TLogger.getGlobalLogger().error(declaredField.getName() + " is not a static field. (" + declaredField.getType().getName() + ")"); - continue; + // 是否为主类 + if (pluginClass.equals(plugin.getClass())) { + instance = plugin; + } else { + TLogger.getGlobalLogger().error(declaredField.getName() + " is not a static field. (" + declaredField.getType().getName() + ")"); + continue; + } } if (declaredField.getType().equals(plugin.getClass())) { try { declaredField.setAccessible(true); - injectTypes.get(Plugin.class).run(plugin, declaredField, annotation.value()); + injectTypes.get(Plugin.class).run(plugin, declaredField, annotation.value(), instance); TabooLib.debug(declaredField.getName() + " injected. (" + declaredField.getType().getName() + ")"); } catch (Throwable e) { TLogger.getGlobalLogger().error(declaredField.getName() + " inject failed: " + e.getMessage() + " (" + declaredField.getType().getName() + ")"); @@ -110,9 +117,16 @@ public class TInjectLoader implements TabooLibLoader.Loader { if (annotation == null || declaredField.getType().equals(plugin.getClass())) { continue; } + Object instance = null; + // 如果是非静态类型 if (!Modifier.isStatic(declaredField.getModifiers())) { - TLogger.getGlobalLogger().error(declaredField.getName() + " is not a static field. (" + declaredField.getType().getName() + ")"); - continue; + // 是否为主类 + if (pluginClass.equals(plugin.getClass())) { + instance = plugin; + } else { + TLogger.getGlobalLogger().error(declaredField.getName() + " is not a static field. (" + declaredField.getType().getName() + ")"); + continue; + } } TInjectTask tInjectTask = injectTypes.get(declaredField.getType()); if (tInjectTask == null) { @@ -121,7 +135,7 @@ public class TInjectLoader implements TabooLibLoader.Loader { } try { declaredField.setAccessible(true); - tInjectTask.run(plugin, declaredField, annotation.value()); + tInjectTask.run(plugin, declaredField, annotation.value(), instance); TabooLib.debug(declaredField.getName() + " injected. (" + declaredField.getType().getName() + ")"); } catch (Throwable e) { TLogger.getGlobalLogger().error(declaredField.getName() + " inject failed: " + e.getMessage() + " (" + declaredField.getType().getName() + ")"); diff --git a/src/main/java/me/skymc/taboolib/common/inject/TInjectTask.java b/src/main/java/me/skymc/taboolib/common/inject/TInjectTask.java index bdd06da..8dc7b76 100644 --- a/src/main/java/me/skymc/taboolib/common/inject/TInjectTask.java +++ b/src/main/java/me/skymc/taboolib/common/inject/TInjectTask.java @@ -10,6 +10,6 @@ import java.lang.reflect.Field; */ public interface TInjectTask { - void run(Plugin plugin, Field field, String[] args); + void run(Plugin plugin, Field field, String[] args, Object instance); } diff --git a/src/main/java/me/skymc/taboolib/fileutils/FileUtils.java b/src/main/java/me/skymc/taboolib/fileutils/FileUtils.java index c40b855..859abc9 100644 --- a/src/main/java/me/skymc/taboolib/fileutils/FileUtils.java +++ b/src/main/java/me/skymc/taboolib/fileutils/FileUtils.java @@ -4,7 +4,6 @@ import ch.njol.util.Closeable; import com.ilummc.eagletdl.EagletTask; import com.ilummc.eagletdl.ProgressEvent; import com.ilummc.tlib.resources.TLocale; -import com.ilummc.tlib.util.IO; import me.skymc.taboolib.Main; import org.apache.commons.io.IOUtils; import org.bukkit.plugin.Plugin; @@ -14,7 +13,6 @@ import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; import java.nio.channels.FileChannel; -import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import java.util.Objects; diff --git a/src/main/java/me/skymc/taboolib/mysql/builder/SQLTable.java b/src/main/java/me/skymc/taboolib/mysql/builder/SQLTable.java index d61e5fd..fb52e5e 100644 --- a/src/main/java/me/skymc/taboolib/mysql/builder/SQLTable.java +++ b/src/main/java/me/skymc/taboolib/mysql/builder/SQLTable.java @@ -1,11 +1,14 @@ package me.skymc.taboolib.mysql.builder; import com.ilummc.tlib.util.Strings; +import me.skymc.taboolib.mysql.builder.data.Insert; +import me.skymc.taboolib.mysql.builder.data.Select; import me.skymc.taboolib.mysql.builder.query.RunnableQuery; import me.skymc.taboolib.mysql.builder.query.RunnableUpdate; import me.skymc.taboolib.string.ArrayUtils; import java.util.Arrays; +import java.util.stream.Collectors; /** * @Author sky @@ -48,28 +51,40 @@ public class SQLTable { return Strings.replaceWithOrder("truncate table `{0}`", tableName); } - public RunnableUpdate executeInsert(String values) { - return executeUpdate("insert into " + tableName + " values(" + values + ")"); + public RunnableQuery select(Select where) { + return executeSelect(Arrays.stream(where.getColumn()).map(s -> s + " = ?").collect(Collectors.joining(", "))); } - public RunnableQuery executeSelect(String where) { - return executeQuery("select * from " + tableName + " where " + where); + public RunnableUpdate insert(Insert... inserts) { + return executeInsert(Arrays.stream(inserts).map(Insert::getText).collect(Collectors.joining(", "))); + } + + public RunnableUpdate update(Select update, Select where) { + return executeUpdate(Arrays.stream(update.getColumn()).map(s -> s + " = ?").collect(Collectors.joining(", ")), Arrays.stream(where.getColumn()).map(s -> s + " = ?").collect(Collectors.joining(", "))); + } + + public RunnableQuery executeQuery(String query) { + return new RunnableQuery(query); } public RunnableQuery executeSelect() { return executeQuery("select * from " + tableName); } - public RunnableUpdate executeUpdate(String update, String where) { - return executeUpdate("update " + tableName + " set " + update + " where " + where); + public RunnableQuery executeSelect(String queryWhere) { + return executeQuery("select * from " + tableName + " where " + queryWhere); + } + + public RunnableUpdate executeInsert(String queryValues) { + return executeUpdate("insert into " + tableName + " values(" + queryValues + ")"); } public RunnableUpdate executeUpdate(String query) { return new RunnableUpdate(query); } - public RunnableQuery executeQuery(String query) { - return new RunnableQuery(query); + public RunnableUpdate executeUpdate(String update, String where) { + return executeUpdate("update " + tableName + " set " + update + " where " + where); } // ********************************* diff --git a/src/main/java/me/skymc/taboolib/mysql/builder/data/Insert.java b/src/main/java/me/skymc/taboolib/mysql/builder/data/Insert.java new file mode 100644 index 0000000..a8cc7af --- /dev/null +++ b/src/main/java/me/skymc/taboolib/mysql/builder/data/Insert.java @@ -0,0 +1,22 @@ +package me.skymc.taboolib.mysql.builder.data; + +/** + * @Author 坏黑 + * @Since 2018-12-01 23:32 + */ +public enum Insert { + + NULL("null"), + + VARIABLE("?"); + + private String text; + + Insert(String text) { + this.text = text; + } + + public String getText() { + return text; + } +} diff --git a/src/main/java/me/skymc/taboolib/mysql/builder/data/Select.java b/src/main/java/me/skymc/taboolib/mysql/builder/data/Select.java new file mode 100644 index 0000000..22afe2b --- /dev/null +++ b/src/main/java/me/skymc/taboolib/mysql/builder/data/Select.java @@ -0,0 +1,22 @@ +package me.skymc.taboolib.mysql.builder.data; + +/** + * @Author 坏黑 + * @Since 2018-12-02 11:12 + */ +public class Select { + + private String[] column; + + public Select(String... column) { + this.column = column; + } + + public String[] getColumn() { + return column; + } + + public static Select of(String... column) { + return new Select(column); + } +} diff --git a/src/main/java/me/skymc/taboolib/update/UpdateTask.java b/src/main/java/me/skymc/taboolib/update/UpdateTask.java index 7214cbd..ad3c22b 100644 --- a/src/main/java/me/skymc/taboolib/update/UpdateTask.java +++ b/src/main/java/me/skymc/taboolib/update/UpdateTask.java @@ -1,6 +1,7 @@ package me.skymc.taboolib.update; 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.Main; @@ -11,7 +12,7 @@ import me.skymc.taboolib.plugin.PluginUtils; import org.bukkit.Bukkit; import org.bukkit.scheduler.BukkitRunnable; -import java.io.File; +import java.io.*; /** * @author sky @@ -20,6 +21,7 @@ import java.io.File; public class UpdateTask { private static double newVersion = 0; + private static double length = -1; private static int updateLocationUsing; private static String[][] updateLocation = { { @@ -37,10 +39,9 @@ public class UpdateTask { @Override public void run() { - if (!Main.getInst().getConfig().getBoolean("UPDATE-CHECK")) { + if (!Main.getInst().getConfig().getBoolean("UPDATE-CHECK", true)) { return; } - boolean success = false; for (int i = 0; i < updateLocation.length; i++) { String[] location = updateLocation[i]; String value = FileUtils.getStringFromURL(location[0], null); @@ -49,20 +50,28 @@ public class UpdateTask { } JsonElement json = new JsonParser().parse(value); if (json.isJsonArray()) { + JsonObject releaseData = json.getAsJsonArray().get(0).getAsJsonObject(); updateLocationUsing = i; - newVersion = json.getAsJsonArray().get(0).getAsJsonObject().get("tag_name").getAsDouble(); + newVersion = releaseData.get("tag_name").getAsDouble(); + // 获取文件长度 + for (JsonElement assetData : releaseData.getAsJsonArray("assets")) { + if (assetData instanceof JsonObject && ((JsonObject) assetData).get("name").getAsString().equals("TabooLib-" + newVersion + ".jar")) { + length = ((JsonObject) assetData).get("size").getAsInt(); + } + } if (TabooLib.getPluginVersion() >= newVersion) { TLocale.Logger.info("UPDATETASK.VERSION-LATEST"); } else { TLocale.Logger.info("UPDATETASK.VERSION-OUTDATED", String.valueOf(TabooLib.getPluginVersion()), String.valueOf(newVersion)); - Bukkit.getScheduler().runTask(TabooLib.instance(), () -> updatePlugin(true, false)); + // 是否启用启动下载 + if (Main.getInst().getConfig().getBoolean("UPDATE-DOWNLOAD", false)) { + Bukkit.getScheduler().runTask(TabooLib.instance(), () -> updatePlugin(true, false)); + } } return; } } - if (!success) { - TLocale.Logger.error("UPDATETASK.VERSION-FAIL"); - } + TLocale.Logger.error("UPDATETASK.VERSION-FAIL"); } }.runTaskTimerAsynchronously(Main.getInst(), 100, 20 * 60 * 60 * 6); } @@ -84,24 +93,48 @@ public class UpdateTask { } public static void updatePlugin(boolean shutdown, boolean force) { + File pluginFile = PluginUtils.getPluginFile(Main.getInst()); + if (pluginFile == null) { + TLocale.Logger.info("COMMANDS.TABOOLIB.UPDATEPLUGIN.FILE-NOT-FOUND"); + return; + } if (!UpdateTask.isHaveUpdate() && (newVersion == 0 || !force)) { TLocale.Logger.info("COMMANDS.TABOOLIB.UPDATEPLUGIN.UPDATE-NOT-FOUND"); return; } + if (length < 0) { + TLocale.Logger.error("COMMANDS.TABOOLIB.UPDATEPLUGIN.UPDATE-NOT-FOUND-SIZE"); + return; + } if (PlayerUtils.getOnlinePlayers().size() > 0) { TLocale.Logger.info("COMMANDS.TABOOLIB.UPDATEPLUGIN.PLAYER-ONLINE"); return; } - File pluginFile = PluginUtils.getPluginFile(Main.getInst()); - if (pluginFile == null) { - TLocale.Logger.info("COMMANDS.TABOOLIB.UPDATEPLUGIN.FILE-NOT-FOUND"); - return; - } + // 创建临时文件 + File tempFile = new File(Main.getInst().getDataFolder(), "update" + File.separator + "TabooLib-" + newVersion + ".jar"); + FileUtils.createNewFileAndPath(tempFile); Bukkit.getScheduler().runTaskAsynchronously(TabooLib.instance(), () -> { - FileUtils.download(updateLocation[updateLocationUsing][1].replace("?", String.valueOf(newVersion)), pluginFile); - TLocale.Logger.info("COMMANDS.TABOOLIB.UPDATEPLUGIN.UPDATE-SUCCESS"); - if (shutdown) { - Bukkit.shutdown(); + FileUtils.download(updateLocation[updateLocationUsing][1].replace("?", String.valueOf(newVersion)), tempFile); + // 判断文件长度是否与标准长度相同 + if (tempFile.length() != length) { + TLocale.Logger.error("COMMANDS.TABOOLIB.UPDATEPLUGIN.UPDATE-FAILED"); + } else { + // 覆盖插件文件 + byte[] buf = new byte[1024]; + int len; + try (BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(tempFile)); BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(pluginFile))) { + while ((len = inputStream.read(buf)) > 0) { + outputStream.write(buf, 0, len); + } + outputStream.flush(); + } catch (Throwable t) { + t.printStackTrace(); + return; + } + TLocale.Logger.info("COMMANDS.TABOOLIB.UPDATEPLUGIN.UPDATE-SUCCESS"); + if (shutdown) { + Bukkit.shutdown(); + } } }); } diff --git a/src/main/resources/Addons/TabooLibDeprecated.jar b/src/main/resources/Addons/TabooLibDeprecated.jar index b7f2371..4bdc3c5 100644 Binary files a/src/main/resources/Addons/TabooLibDeprecated.jar and b/src/main/resources/Addons/TabooLibDeprecated.jar differ diff --git a/src/main/resources/lang/zh_CN.yml b/src/main/resources/lang/zh_CN.yml index 96fbd3c..80915b3 100644 --- a/src/main/resources/lang/zh_CN.yml +++ b/src/main/resources/lang/zh_CN.yml @@ -236,9 +236,11 @@ COMMANDS: UPDATEPLUGIN: DESCRIPTION: '&4更新插件 &8(谨防非正规途径的插件获取方式)' UPDATE-NOT-FOUND: '&8[&3&lTabooLib&8] &7插件已是最新版, 无需更新!' + UPDATE-NOT-FOUND-SIZE: '&8[&3&lTabooLib&8] &4文件长度获取失败.' UPDATE-NOT-SUPPORT: '&8[&3&lTabooLib&8] &4您的服务器不支持在线更新!' UPDATE-SUCCESS: '&8[&3&lTabooLib&8] &7最新版下载完成, 服务器即将重启!' - FILE-NOT-FOUND: '&8[&3&lTabooLib&8] &4尚未寻找到插件文件' + UPDATE-FAILED: '&8[&3&lTabooLib&8] &4最新版下载失败.' + FILE-NOT-FOUND: '&8[&3&lTabooLib&8] &4尚未寻找到插件文件.' PLAYER-ONLINE: '&8[&3&lTabooLib&8] &4服务器有玩家在线无法更新插件.' ARGUMENTS: 0: '-f'