diff --git a/README.md b/README.md index 5ff24bb..3d39de1 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # TabooLib -> Bukkit 开发工具库 +> Bukkit 开发工具库集合 -[![](http://ci.pcd.ac.cn/job/TabooLibDev/badge/icon)](http://ci.pcd.ac.cn/job/TabooLibDev) +[![](http://ci.pcd.ac.cn/job/TabooLib/badge/icon)](http://ci.pcd.ac.cn/job/TabooLib) [![](https://img.shields.io/github/downloads/Bkm016/TabooLib/total.svg)](https://github.com/Bkm016/TabooLib/releases) [![](https://img.shields.io/github/release/Bkm016/TabooLib.svg)](https://github.com/Bkm016/TabooLib/tags) [![](https://img.shields.io/github/stars/Bkm016/TabooLib.svg?style=flat-square&label=Stars)](https://github.com/Bkm016/TabooLib) diff --git a/pom.xml b/pom.xml index 0b6faf7..b22d8db 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.skymc TabooLib - 4.10 + 4.12 UTF-8 diff --git a/src/main/java/com/ilummc/tlib/TLib.java b/src/main/java/com/ilummc/tlib/TLib.java index 2b0e2b4..3857f35 100644 --- a/src/main/java/com/ilummc/tlib/TLib.java +++ b/src/main/java/com/ilummc/tlib/TLib.java @@ -102,7 +102,9 @@ public class TLib { } catch (NoSuchFieldException | IllegalAccessException | IllegalArgumentException ignored) { TLocale.Logger.fatal("TLIB.INJECTION-FAILED"); for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { - if (plugin != Main.getInst()) TDependencyInjector.inject(plugin, plugin); + if (plugin != Main.getInst()) { + TDependencyInjector.inject(plugin, plugin); + } } } } diff --git a/src/main/java/com/ilummc/tlib/inject/TPluginManager.java b/src/main/java/com/ilummc/tlib/inject/TPluginManager.java index ae5d1ca..f9ead8d 100644 --- a/src/main/java/com/ilummc/tlib/inject/TPluginManager.java +++ b/src/main/java/com/ilummc/tlib/inject/TPluginManager.java @@ -37,8 +37,9 @@ public class TPluginManager implements PluginManager { private List delayedDisable = new ArrayList<>(); public static void delayDisable(Plugin plugin) { - if (!singleton.delayedDisable.contains(plugin)) + if (!singleton.delayedDisable.contains(plugin)) { singleton.delayedDisable.add(plugin); + } } public TPluginManager() { diff --git a/src/main/java/com/ilummc/tlib/resources/type/TLocaleActionBar.java b/src/main/java/com/ilummc/tlib/resources/type/TLocaleActionBar.java index 614efae..70f3f3d 100644 --- a/src/main/java/com/ilummc/tlib/resources/type/TLocaleActionBar.java +++ b/src/main/java/com/ilummc/tlib/resources/type/TLocaleActionBar.java @@ -2,10 +2,9 @@ package com.ilummc.tlib.resources.type; import com.google.common.collect.Maps; import com.ilummc.tlib.compat.PlaceholderHook; -import com.ilummc.tlib.nms.ActionBar; import com.ilummc.tlib.resources.TLocaleSerialize; import com.ilummc.tlib.util.Strings; -import me.skymc.taboolib.Main; +import me.skymc.taboolib.display.ActionUtils; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.configuration.serialization.SerializableAs; @@ -34,7 +33,7 @@ public class TLocaleActionBar extends TLocaleSerialize { @Override public void sendTo(CommandSender sender, String... args) { if (sender instanceof Player) { - ActionBar.sendActionBar(((Player) sender), replace(sender, text, args)); + ActionUtils.send(((Player) sender), replace(sender, text, args)); } } diff --git a/src/main/java/com/ilummc/tlib/resources/type/TLocaleBook.java b/src/main/java/com/ilummc/tlib/resources/type/TLocaleBook.java index 978eb27..24c8008 100644 --- a/src/main/java/com/ilummc/tlib/resources/type/TLocaleBook.java +++ b/src/main/java/com/ilummc/tlib/resources/type/TLocaleBook.java @@ -71,7 +71,7 @@ public class TLocaleBook extends TLocaleSerialize { @Override public void run() { BookBuilder bookBuilder = BookFormatter.writtenBook(); - pages.stream().map(jsonPage -> papi ? TLocale.Translate.setPlaceholders(sender, Strings.replaceWithOrder(jsonPage.toRawMessage(), args)) : TLocale.Translate.setColored(Strings.replaceWithOrder(jsonPage.toRawMessage(), args))).map(ComponentSerializer::parse).forEach(bookBuilder::addPages); + pages.stream().map(jsonPage -> format(jsonPage, sender, args)).map(ComponentSerializer::parse).forEach(bookBuilder::addPages); new BukkitRunnable() { @Override public void run() { @@ -82,6 +82,10 @@ public class TLocaleBook extends TLocaleSerialize { }.runTaskAsynchronously(Main.getInst()); } + private String format(TellrawJson jsonPage, CommandSender sender, String[] args) { + return papi ? TLocale.Translate.setPlaceholders(sender, Strings.replaceWithOrder(jsonPage.toRawMessage(), args)) : Strings.replaceWithOrder(jsonPage.toRawMessage(), args); + } + public static TLocaleBook valueOf(Map map) { Map pages = map.containsKey("pages") ? (Map) map.get("pages") : new HashMap<>(); Map section = map.containsKey("args") ? (Map) map.get("args") : new HashMap<>(); diff --git a/src/main/java/com/ilummc/tlib/resources/type/TLocaleJson.java b/src/main/java/com/ilummc/tlib/resources/type/TLocaleJson.java index 2a14974..456f862 100644 --- a/src/main/java/com/ilummc/tlib/resources/type/TLocaleJson.java +++ b/src/main/java/com/ilummc/tlib/resources/type/TLocaleJson.java @@ -171,7 +171,7 @@ public class TLocaleJson extends TLocaleSerialize { // 遍历本页文本 for (int i = 0; i < textList.size(); i++) { // 捕捉变量 - for (VariableFormatter.Variable variable : new VariableFormatter(textList.get(i), pattern).find().getVariableList()) { + for (VariableFormatter.Variable variable : new VariableFormatter(TLocale.Translate.setColored(textList.get(i)), pattern).find().getVariableList()) { // 如果是变量 if (variable.isVariable()) { String[] split = variable.getText().split("@"); diff --git a/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java b/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java index 59fcf6e..fb90a40 100644 --- a/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java +++ b/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java @@ -42,13 +42,7 @@ public class TLocaleTitle extends TLocaleSerialize { public static TLocaleTitle valueOf(Map map) { TLocaleTitle title; try { - title = new TLocaleTitle( - getStringOrDefault(map, "title", ""), - getStringOrDefault(map, "subtitle", ""), - getIntegerOrDefault(map, "fadein", 10), - getIntegerOrDefault(map, "fadeout", 10), - getIntegerOrDefault(map, "stay", 10), - isPlaceholderEnabled(map)); + title = new TLocaleTitle(getStringOrDefault(map, "title", ""), getStringOrDefault(map, "subtitle", ""), getIntegerOrDefault(map, "fadein", 10), getIntegerOrDefault(map, "fadeout", 10), getIntegerOrDefault(map, "stay", 10), isPlaceholderEnabled(map)); } catch (Exception e) { title = new TLocaleTitle("Empty Title message.", e.getMessage(), 10, 20, 10, false); } @@ -58,7 +52,7 @@ public class TLocaleTitle extends TLocaleSerialize { @Override public void sendTo(CommandSender sender, String... args) { if (sender instanceof Player) { - TitleUtils.sendTitle((Player) sender, replaceText(sender, title), replaceText(sender, subtitle), fadein, stay, fadeout); + TitleUtils.sendTitle((Player) sender, replaceText(sender, Strings.replaceWithOrder(title, args)), replaceText(sender, Strings.replaceWithOrder(subtitle, args)), fadein, stay, fadeout); } else { TLocale.Logger.error("LOCALE.TITLE-SEND-TO-NON-PLAYER", asString(args)); } @@ -86,7 +80,7 @@ public class TLocaleTitle extends TLocaleSerialize { return map; } - private String replaceText(CommandSender sender, String args) { - return usePlaceholder ? TLocale.Translate.setPlaceholders(sender, args) : TLocale.Translate.setColored(args); + private String replaceText(CommandSender sender, String text, String... args) { + return usePlaceholder ? TLocale.Translate.setPlaceholders(sender, text) : TLocale.Translate.setColored(text); } } diff --git a/src/main/java/me/skymc/taboolib/Main.java b/src/main/java/me/skymc/taboolib/Main.java index 20f0dd5..53aacd2 100644 --- a/src/main/java/me/skymc/taboolib/Main.java +++ b/src/main/java/me/skymc/taboolib/Main.java @@ -8,11 +8,12 @@ import com.ilummc.tlib.util.IO; import com.ilummc.tlib.util.Strings; import me.skymc.taboolib.anvil.AnvilContainerAPI; import me.skymc.taboolib.bstats.Metrics; +import me.skymc.taboolib.commands.TabooLibExecuteCommand; import me.skymc.taboolib.commands.TabooLibMainCommand; import me.skymc.taboolib.commands.internal.TBaseCommand; import me.skymc.taboolib.commands.language.Language2Command; import me.skymc.taboolib.commands.locale.TabooLibLocaleCommand; -import me.skymc.taboolib.commands.plugin.TabooLibPluginMainCommand; +import me.skymc.taboolib.commands.plugin.TabooLibPluginCommand; import me.skymc.taboolib.commands.taboolib.listener.ListenerItemListCommand; import me.skymc.taboolib.commands.taboolib.listener.ListenerSoundsCommand; import me.skymc.taboolib.database.GlobalDataManager; @@ -45,6 +46,7 @@ import me.skymc.taboolib.update.UpdateTask; import me.skymc.tlm.TLM; import me.skymc.tlm.command.TLMCommands; import me.skymc.tlm.module.TabooLibraryModule; +import net.milkbowl.vault.economy.Economy; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.event.Listener; @@ -74,25 +76,15 @@ public class Main extends JavaPlugin implements Listener { } private static Plugin inst; - - private static net.milkbowl.vault.economy.Economy Economy; - + private static Economy economy; private static File playerDataFolder; - private static File serverDataFolder; - private static StorageType storageType = StorageType.LOCAL; - - private static boolean disable = false; - private static MySQLConnection connection = null; - private static Language2 exampleLanguage2; - - private static boolean started; - + private static boolean disable = false; + private static boolean started = false; private static boolean isInternetOnline = false; - private FileConfiguration config = null; @Override @@ -132,6 +124,8 @@ public class Main extends JavaPlugin implements Listener { setupLibraries(); // 载入牛逼玩意儿 TLib.initPost(); + // 注册连接池 + HikariHandler.init(); } @Override @@ -348,7 +342,8 @@ public class Main extends JavaPlugin implements Listener { getCommand("taboolibrarymodule").setExecutor(new TLMCommands()); TBaseCommand.registerCommand("taboolib", new TabooLibMainCommand()); TBaseCommand.registerCommand("tabooliblocale", new TabooLibLocaleCommand()); - TBaseCommand.registerCommand("taboolibplugin", new TabooLibPluginMainCommand()); + TBaseCommand.registerCommand("taboolibplugin", new TabooLibPluginCommand()); + TBaseCommand.registerCommand("taboolibexecute", new TabooLibExecuteCommand()); TBaseCommand.registerCommand("translateuuid", new TranslateUUIDCommand()); } @@ -390,11 +385,11 @@ public class Main extends JavaPlugin implements Listener { } public static net.milkbowl.vault.economy.Economy getEconomy() { - return Economy; + return economy; } - public static void setEconomy(net.milkbowl.vault.economy.Economy economy) { - Economy = economy; + public static void setEconomy(Economy economy) { + Main.economy = economy; } public static File getPlayerDataFolder() { diff --git a/src/main/java/me/skymc/taboolib/commands/TabooLibExecuteCommand.java b/src/main/java/me/skymc/taboolib/commands/TabooLibExecuteCommand.java new file mode 100644 index 0000000..f83d847 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/commands/TabooLibExecuteCommand.java @@ -0,0 +1,116 @@ +package me.skymc.taboolib.commands; + +import com.ilummc.tlib.resources.TLocale; +import com.ilummc.tlib.util.Strings; +import me.skymc.taboolib.commands.internal.BaseMainCommand; +import me.skymc.taboolib.commands.internal.BaseSubCommand; +import me.skymc.taboolib.commands.internal.type.CommandArgument; +import me.skymc.taboolib.commands.internal.type.CommandRegister; +import me.skymc.taboolib.string.ArrayUtils; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.server.ServerCommandEvent; + +/** + * @Author sky + * @Since 2018-07-04 21:32 + */ +public class TabooLibExecuteCommand extends BaseMainCommand { + + @Override + public String getCommandTitle() { + return TLocale.asString("COMMANDS.TEXECUTE.COMMAND-TITLE"); + } + + @CommandRegister(priority = 1) + BaseSubCommand chat = new BaseSubCommand() { + @Override + public String getLabel() { + return "chat"; + } + + @Override + public String getDescription() { + return TLocale.asString("COMMANDS.TEXECUTE.CHAT.DESCRIPTION"); + } + + @Override + public CommandArgument[] getArguments() { + return new CommandArgument[] { + new CommandArgument(TLocale.asString("COMMANDS.TEXECUTE.CHAT.ARGUMENTS.0")), + new CommandArgument(TLocale.asString("COMMANDS.TEXECUTE.CHAT.ARGUMENTS.1")) + }; + } + + @Override + public void onCommand(CommandSender sender, Command command, String label, String[] args) { + Player player = Bukkit.getPlayerExact(args[0]); + if (player == null) { + TLocale.sendTo(sender, "INVALID-PLAYER-OFFLINE", args[0]); + return; + } + player.chat(ArrayUtils.arrayJoin(args, 1)); + } + }; + + @CommandRegister(priority = 1) + BaseSubCommand command = new BaseSubCommand() { + @Override + public String getLabel() { + return "command"; + } + + @Override + public String getDescription() { + return TLocale.asString("COMMANDS.TEXECUTE.COMMAND.DESCRIPTION"); + } + + @Override + public CommandArgument[] getArguments() { + return new CommandArgument[] { + new CommandArgument(TLocale.asString("COMMANDS.TEXECUTE.COMMAND.ARGUMENTS.0")), + new CommandArgument(TLocale.asString("COMMANDS.TEXECUTE.COMMAND.ARGUMENTS.1")) + }; + } + + @Override + public void onCommand(CommandSender sender, Command command, String label, String[] args) { + if (args[0].equalsIgnoreCase("console")) { + dispatchCommand(Bukkit.getConsoleSender(), ArrayUtils.arrayJoin(args, 1)); + return; + } + Player player = Bukkit.getPlayerExact(args[0]); + if (player == null) { + TLocale.sendTo(sender, "INVALID-TARGET-NOT-FOUND", args[0]); + return; + } + dispatchCommand(player, ArrayUtils.arrayJoin(args, 1)); + } + }; + + public static boolean dispatchCommand(CommandSender sender, String command) { + try { + if ((sender instanceof Player)) { + PlayerCommandPreprocessEvent e = new PlayerCommandPreprocessEvent((Player) sender, "/" + command); + Bukkit.getPluginManager().callEvent(e); + if (e.isCancelled() || Strings.isBlank(e.getMessage()) || !e.getMessage().startsWith("/")) { + return false; + } + return Bukkit.dispatchCommand(e.getPlayer(), e.getMessage().substring(1)); + } else { + ServerCommandEvent e = new ServerCommandEvent(sender, command); + Bukkit.getPluginManager().callEvent(e); + if (e.isCancelled() || Strings.isBlank(e.getCommand())) { + return false; + } + return Bukkit.dispatchCommand(e.getSender(), e.getCommand()); + } + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } +} diff --git a/src/main/java/me/skymc/taboolib/commands/TabooLibMainCommand.java b/src/main/java/me/skymc/taboolib/commands/TabooLibMainCommand.java index 9b120a0..705133c 100644 --- a/src/main/java/me/skymc/taboolib/commands/TabooLibMainCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/TabooLibMainCommand.java @@ -12,6 +12,7 @@ import me.skymc.taboolib.commands.taboolib.*; import me.skymc.taboolib.fileutils.FileUtils; import me.skymc.taboolib.inventory.ItemUtils; import me.skymc.taboolib.other.NumberUtils; +import me.skymc.taboolib.player.PlayerUtils; import me.skymc.taboolib.plugin.PluginUtils; import me.skymc.taboolib.update.UpdateTask; import org.bukkit.Bukkit; @@ -807,6 +808,11 @@ public class TabooLibMainCommand extends BaseMainCommand { @Override public void run() { + if (PlayerUtils.getOnlinePlayers().size() > 0) { + TLocale.sendTo(sender, "COMMANDS.TABOOLIB.UPDATEPLUGIN.PLAYER-ONLINE"); + return; + } + String url = Strings.replaceWithOrder("https://github.com/Bkm016/TabooLib/releases/download/{0}/TabooLib-{0}.jar", UpdateTask.getNewVersion()); TLocale.sendTo(sender, "COMMANDS.TABOOLIB.UPDATEPLUGIN.UPDATE-START", url); diff --git a/src/main/java/me/skymc/taboolib/commands/plugin/TabooLibPluginMainCommand.java b/src/main/java/me/skymc/taboolib/commands/plugin/TabooLibPluginCommand.java similarity index 99% rename from src/main/java/me/skymc/taboolib/commands/plugin/TabooLibPluginMainCommand.java rename to src/main/java/me/skymc/taboolib/commands/plugin/TabooLibPluginCommand.java index 42a0a86..2cc8b40 100644 --- a/src/main/java/me/skymc/taboolib/commands/plugin/TabooLibPluginMainCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/plugin/TabooLibPluginCommand.java @@ -25,7 +25,7 @@ import java.util.stream.Collectors; * @Author sky * @Since 2018-05-07 20:14 */ -public class TabooLibPluginMainCommand extends BaseMainCommand { +public class TabooLibPluginCommand extends BaseMainCommand { @Override public String getCommandTitle() { diff --git a/src/main/java/me/skymc/taboolib/commands/taboolib/InfoCommand.java b/src/main/java/me/skymc/taboolib/commands/taboolib/InfoCommand.java index 31b880d..1eae955 100644 --- a/src/main/java/me/skymc/taboolib/commands/taboolib/InfoCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/taboolib/InfoCommand.java @@ -4,6 +4,7 @@ import com.ilummc.tlib.resources.TLocale; import me.skymc.taboolib.commands.SubCommand; import me.skymc.taboolib.inventory.ItemUtils; import me.skymc.taboolib.itemnbtapi.NBTItem; +import me.skymc.taboolib.json.JSONReader; import org.bukkit.Material; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -23,7 +24,7 @@ public class InfoCommand extends SubCommand { player.getItemInHand().getType().name(), ItemUtils.getCustomName(player.getItemInHand()), player.getItemInHand().getTypeId() + ":" + player.getItemInHand().getDurability(), - nbt.toString()); + JSONReader.formatJson(nbt.asNBTString())); } } } diff --git a/src/main/java/me/skymc/taboolib/csvutils/CsvReader.java b/src/main/java/me/skymc/taboolib/csvutils/CsvReader.java index cfc3477..fda2878 100644 --- a/src/main/java/me/skymc/taboolib/csvutils/CsvReader.java +++ b/src/main/java/me/skymc/taboolib/csvutils/CsvReader.java @@ -500,7 +500,7 @@ public class CsvReader { ++dataBuffer2.Position; if (this.userSettings.SafetySwitch && this.dataBuffer.Position - this.dataBuffer.ColumnStart + this.columnBuffer.Position > 100000) { this.close(); - throw new IOException("Maximum addColumn length of 100,000 exceeded in addColumn " + NumberFormat.getIntegerInstance().format(this.columnsCount) + " in record " + NumberFormat.getIntegerInstance().format(this.currentRecord) + ". Set the SafetySwitch property to false" + " if you're expecting addColumn lengths greater than 100,000 characters to" + " avoid this error."); + throw new IOException("Maximum column length of 100,000 exceeded in column " + NumberFormat.getIntegerInstance().format(this.columnsCount) + " in record " + NumberFormat.getIntegerInstance().format(this.currentRecord) + ". Set the SafetySwitch property to false" + " if you're expecting column lengths greater than 100,000 characters to" + " avoid this error."); } } } while (this.hasMoreData && this.startedColumn); @@ -695,7 +695,7 @@ public class CsvReader { ++dataBuffer3.Position; if (this.userSettings.SafetySwitch && this.dataBuffer.Position - this.dataBuffer.ColumnStart + this.columnBuffer.Position > 100000) { this.close(); - throw new IOException("Maximum addColumn length of 100,000 exceeded in addColumn " + NumberFormat.getIntegerInstance().format(this.columnsCount) + " in record " + NumberFormat.getIntegerInstance().format(this.currentRecord) + ". Set the SafetySwitch property to false" + " if you're expecting addColumn lengths greater than 100,000 characters to" + " avoid this error."); + throw new IOException("Maximum column length of 100,000 exceeded in column " + NumberFormat.getIntegerInstance().format(this.columnsCount) + " in record " + NumberFormat.getIntegerInstance().format(this.currentRecord) + ". Set the SafetySwitch property to false" + " if you're expecting column lengths greater than 100,000 characters to" + " avoid this error."); } } } while (this.hasMoreData && this.startedColumn); @@ -868,7 +868,7 @@ public class CsvReader { this.startedColumn = false; if (this.columnsCount >= 100000 && this.userSettings.SafetySwitch) { this.close(); - throw new IOException("Maximum addColumn count of 100,000 exceeded in record " + NumberFormat.getIntegerInstance().format(this.currentRecord) + ". Set the SafetySwitch property to false" + " if you're expecting more than 100,000 columns per record to" + " avoid this error."); + throw new IOException("Maximum column count of 100,000 exceeded in record " + NumberFormat.getIntegerInstance().format(this.currentRecord) + ". Set the SafetySwitch property to false" + " if you're expecting more than 100,000 columns per record to" + " avoid this error."); } if (this.columnsCount == this.values.length) { final int n3 = this.values.length * 2; diff --git a/src/main/java/me/skymc/taboolib/entity/EntityUtils.java b/src/main/java/me/skymc/taboolib/entity/EntityUtils.java index 43a5a06..549d52f 100644 --- a/src/main/java/me/skymc/taboolib/entity/EntityUtils.java +++ b/src/main/java/me/skymc/taboolib/entity/EntityUtils.java @@ -32,14 +32,7 @@ public class EntityUtils implements Listener { * @return */ public static Entity getEntityWithUUID(UUID u) { - for (World w : Bukkit.getWorlds()) { - for (Entity e : w.getLivingEntities()) { - if (e.getUniqueId().equals(u)) { - return e; - } - } - } - return null; + return Bukkit.getWorlds().stream().flatMap(w -> w.getLivingEntities().stream()).filter(e -> e.getUniqueId().equals(u)).findFirst().orElse(null); } /** @@ -50,12 +43,7 @@ public class EntityUtils implements Listener { * @return */ public static Entity getEntityWithUUID_World(UUID u, World world) { - for (Entity e : world.getLivingEntities()) { - if (e.getUniqueId().equals(u)) { - return e; - } - } - return null; + return world.getLivingEntities().stream().filter(e -> e.getUniqueId().equals(u)).findFirst().orElse(null); } /** @@ -66,11 +54,7 @@ public class EntityUtils implements Listener { */ public static void addGlow(Player player, Entity entity) { if (Bukkit.getPluginManager().getPlugin("ProtocolLib") == null) { - try { - throw new PluginNotFoundException(TLocale.asString("ENTITY-UTILS.NOTFOUND-PROTOCOLLIB")); - } catch (Exception e) { - // - } + TLocale.sendToConsole("ENTITY-UTILS.NOTFOUND-PROTOCOLLIB"); } PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); packet.getIntegers().write(0, entity.getEntityId()); @@ -94,11 +78,7 @@ public class EntityUtils implements Listener { */ public static void delGlow(Player player, Entity entity) { if (Bukkit.getPluginManager().getPlugin("ProtocolLib") == null) { - try { - throw new PluginNotFoundException(TLocale.asString("ENTITY-UTILS.NOTFOUND-PROTOCOLLIB")); - } catch (Exception e) { - // - } + TLocale.sendToConsole("ENTITY-UTILS.NOTFOUND-PROTOCOLLIB"); } PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); packet.getIntegers().write(0, entity.getEntityId()); diff --git a/src/main/java/me/skymc/taboolib/entity/VectorUtils.java b/src/main/java/me/skymc/taboolib/entity/VectorUtils.java new file mode 100644 index 0000000..2428757 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/entity/VectorUtils.java @@ -0,0 +1,122 @@ +package me.skymc.taboolib.entity; + +import me.skymc.taboolib.other.NumberUtils; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +import java.util.stream.IntStream; + +/** + * @Author sky + * @Since 2018-06-24 16:32 + */ +public class VectorUtils { + + /** + * 物品丢弃 + * + * 常用参数: + * itemDrop(player, itemStack, 0.2, 0.5) + * + * @param player 玩家 + * @param itemStack 丢弃物品 + * @param bulletSpread 视角偏移 + * @param radius 距离 + * @return {@link Item} + */ + public static Item itemDrop(Player player, ItemStack itemStack, double bulletSpread, double radius) { + Location location = player.getLocation().add(0, 1.5, 0); + Item item = player.getWorld().dropItem(location, itemStack); + + double yaw = Math.toRadians(-player.getLocation().getYaw() - 90.0F); + double pitch = Math.toRadians(-player.getLocation().getPitch()); + double x; + double y; + double z; + + if (bulletSpread > 0) { + double[] spread = {1.0D, 1.0D, 1.0D}; + IntStream.range(0, 3).forEach(t -> spread[t] = ((NumberUtils.getRandom().nextDouble() - NumberUtils.getRandom().nextDouble()) * bulletSpread * 0.1D)); + x = Math.cos(pitch) * Math.cos(yaw) + spread[0]; + y = Math.sin(pitch) + spread[1]; + z = -Math.sin(yaw) * Math.cos(pitch) + spread[2]; + } else { + x = Math.cos(pitch) * Math.cos(yaw); + y = Math.sin(pitch); + z = -Math.sin(yaw) * Math.cos(pitch); + } + + Vector dirVel = new Vector(x, y, z); + item.setVelocity(dirVel.normalize().multiply(radius)); + return item; + } + + /** + * 生物抛射 + * + * 常用参数: + * entityPush(entity, location, 15) + * + * @param entity 目标生物 + * @param to 目标坐标 + * @param velocity 力量 + */ + public static void entityPush(Entity entity, Location to, double velocity) { + Location from = entity.getLocation(); + + Vector test = to.clone().subtract(from).toVector(); + Double elevation = test.getY(); + + Double launchAngle = calculateLaunchAngle(from, to, velocity, elevation, 20.0D); + Double distance = Math.sqrt(Math.pow(test.getX(), 2.0D) + Math.pow(test.getZ(), 2.0D)); + if (distance == 0.0D) { + return; + } + if (launchAngle == null) { + launchAngle = Math.atan((40.0D * elevation + Math.pow(velocity, 2.0D)) / (40.0D * elevation + 2.0D * Math.pow(velocity, 2.0D))); + } + Double hangTime = calculateHangTime(launchAngle, velocity, elevation, 20.0D); + + test.setY(Math.tan(launchAngle) * distance); + test = normalizeVector(test); + + Vector noise = Vector.getRandom(); + noise = noise.multiply(1 / 10.0D); + test.add(noise); + + velocity = velocity + 1.188D * Math.pow(hangTime, 2.0D) + (NumberUtils.getRandom().nextDouble() - 0.8D) / 2.0D; + test = test.multiply(velocity / 20.0D); + + entity.setVelocity(test); + } + + // ********************************* + // + // Private Methods + // + // ********************************* + + private static double calculateHangTime(double launchAngle, double v, double elev, double g) { + double a = v * Math.sin(launchAngle); + double b = -2.0D * g * elev; + return Math.pow(a, 2.0D) + b < 0.0D ? 0.0D : (a + Math.sqrt(Math.pow(a, 2.0D) + b)) / g; + } + + private static Vector normalizeVector(Vector victor) { + double mag = Math.sqrt(Math.pow(victor.getX(), 2.0D) + Math.pow(victor.getY(), 2.0D) + Math.pow(victor.getZ(), 2.0D)); + return mag != 0.0D ? victor.multiply(1.0D / mag) : victor.multiply(0); + } + + private static Double calculateLaunchAngle(Location from, Location to, double v, double elevation, double g) { + Vector vector = from.clone().subtract(to).toVector(); + Double distance = Math.sqrt(Math.pow(vector.getX(), 2.0D) + Math.pow(vector.getZ(), 2.0D)); + double v2 = Math.pow(v, 2.0D); + double v4 = Math.pow(v, 4.0D); + double check = g * (g * Math.pow(distance, 2.0D) + 2.0D * elevation * v2); + return v4 < check ? null : Math.atan((v2 - Math.sqrt(v4 - check)) / (g * distance)); + } +} diff --git a/src/main/java/me/skymc/taboolib/inventory/DropUtils.java b/src/main/java/me/skymc/taboolib/inventory/DropUtils.java index 1ff941f..0da14da 100644 --- a/src/main/java/me/skymc/taboolib/inventory/DropUtils.java +++ b/src/main/java/me/skymc/taboolib/inventory/DropUtils.java @@ -1,5 +1,6 @@ package me.skymc.taboolib.inventory; +import me.skymc.taboolib.entity.VectorUtils; import me.skymc.taboolib.other.NumberUtils; import org.bukkit.Location; import org.bukkit.entity.Item; @@ -9,35 +10,11 @@ import org.bukkit.util.Vector; import java.util.stream.IntStream; +@Deprecated public class DropUtils { public static Item drop(Player player, ItemStack itemStack, double bulletSpread, double radius) { - Location location = player.getLocation(); - location.setY(location.getY() + 1.5); - Item item = player.getWorld().dropItem(location, itemStack); - - double yaw = Math.toRadians(-player.getLocation().getYaw() - 90.0F); - double pitch = Math.toRadians(-player.getLocation().getPitch()); - double x; - double y; - double z; - - if (bulletSpread > 0) { - double[] spread = {1.0D, 1.0D, 1.0D}; - IntStream.range(0, 3).forEach(t -> spread[t] = ((NumberUtils.getRandom().nextDouble() - NumberUtils.getRandom().nextDouble()) * bulletSpread * 0.1D)); - x = Math.cos(pitch) * Math.cos(yaw) + spread[0]; - y = Math.sin(pitch) + spread[1]; - z = -Math.sin(yaw) * Math.cos(pitch) + spread[2]; - } else { - x = Math.cos(pitch) * Math.cos(yaw); - y = Math.sin(pitch); - z = -Math.sin(yaw) * Math.cos(pitch); - } - - Vector dirVel = new Vector(x, y, z); - dirVel.normalize().multiply(radius); - item.setVelocity(dirVel); - return item; + return VectorUtils.itemDrop(player, itemStack, bulletSpread, radius); } } diff --git a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTCompound.java b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTCompound.java index a5b9887..d02e435 100644 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTCompound.java +++ b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTCompound.java @@ -190,7 +190,7 @@ public class NBTCompound { } public String asNBTString(){ - return getCompound().toString(); + return getCompound() == null ? "" : getCompound().toString(); } } diff --git a/src/main/java/me/skymc/taboolib/json/JSONReader.java b/src/main/java/me/skymc/taboolib/json/JSONReader.java new file mode 100644 index 0000000..393cdd0 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/json/JSONReader.java @@ -0,0 +1,50 @@ +package me.skymc.taboolib.json; + +import java.util.regex.Pattern; + +/** + * @Author sky + * @Since 2018-07-01 11:10 + */ +public class JSONReader { + + private static Pattern pattern = Pattern.compile("[\t\n]"); + + public static String formatJson(String content) { + StringBuilder builder = new StringBuilder(); + int index = 0; + int count = 0; + while (index < content.length()) { + char ch = content.charAt(index); + if (ch == '{' || ch == '[') { + builder.append(ch); + builder.append('\n'); + count++; + for (int i = 0; i < count; i++) { + builder.append('\t'); + } + } else if (ch == '}' || ch == ']') { + builder.append('\n'); + count--; + for (int i = 0; i < count; i++) { + builder.append('\t'); + } + builder.append(ch); + } else if (ch == ',') { + builder.append(ch); + builder.append('\n'); + for (int i = 0; i < count; i++) { + builder.append('\t'); + } + } else { + builder.append(ch); + } + index++; + } + return compactJson(builder.toString()); + } + + private static String compactJson(String content) { + return pattern.matcher(content).replaceAll("").trim(); + } +} diff --git a/src/main/java/me/skymc/taboolib/mysql/builder/SQLExample.java b/src/main/java/me/skymc/taboolib/mysql/builder/SQLExample.java new file mode 100644 index 0000000..e6dc79a --- /dev/null +++ b/src/main/java/me/skymc/taboolib/mysql/builder/SQLExample.java @@ -0,0 +1,31 @@ +package me.skymc.taboolib.mysql.builder; + +import com.zaxxer.hikari.HikariDataSource; +import org.bukkit.plugin.java.JavaPlugin; + +/** + * @Author sky + * @Since 2018-07-02 23:43 + */ +public class SQLExample extends JavaPlugin { + + private SQLHost sqlHost; + private SQLTable sqlTable; + private HikariDataSource dataSource; + + @Override + public void onEnable() { + int value = sqlTable.executeQuery("select * from table where username = ?") + .dataSource(dataSource) + .statement(statement -> statement.setString(1, "BlackSKY")) + .resultNext(result -> result.getInt("value")) + .run(0, 0); + + sqlTable.executeUpdate("statement table set value = ? where username = ?") + .dataSource(dataSource) + .statement(statement -> { + statement.setInt(1, 999); + statement.setString(2, "BlackSKY"); + }).run(); + } +} diff --git a/src/main/java/me/skymc/taboolib/mysql/builder/SQLHost.java b/src/main/java/me/skymc/taboolib/mysql/builder/SQLHost.java index 185a59b..13e9c15 100644 --- a/src/main/java/me/skymc/taboolib/mysql/builder/SQLHost.java +++ b/src/main/java/me/skymc/taboolib/mysql/builder/SQLHost.java @@ -74,7 +74,11 @@ public class SQLHost { return false; } SQLHost sqlHost = (SQLHost) o; - return Objects.equals(getHost(), sqlHost.getHost()) && Objects.equals(getPort(), sqlHost.getPort()) && Objects.equals(getUser(), sqlHost.getUser()) && Objects.equals(getPassword(), sqlHost.getPassword()) && Objects.equals(getDatabase(), sqlHost.getDatabase()); + return Objects.equals(getHost(), sqlHost.getHost()) && + Objects.equals(getUser(), sqlHost.getUser()) && + Objects.equals(getPort(), sqlHost.getPort()) && + Objects.equals(getPassword(), sqlHost.getPassword()) && + Objects.equals(getDatabase(), sqlHost.getDatabase()); } @Override @@ -84,6 +88,13 @@ public class SQLHost { @Override public String toString() { - return MessageFormat.format("SQLHost'{'host=''{0}'', user=''{1}'', port=''{2}'', password=''{3}'', database=''{4}'', plugin={5}'}'", host, user, port, password, database, plugin); + return "SQLHost{" + + "host='" + host + '\'' + + ", user='" + user + '\'' + + ", port='" + port + '\'' + + ", password='" + password + '\'' + + ", database='" + database + '\'' + + ", plugin=" + plugin + + '}'; } } 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 9e88b9f..ed2e5f5 100644 --- a/src/main/java/me/skymc/taboolib/mysql/builder/SQLTable.java +++ b/src/main/java/me/skymc/taboolib/mysql/builder/SQLTable.java @@ -1,9 +1,12 @@ package me.skymc.taboolib.mysql.builder; -import com.google.common.base.Preconditions; import com.ilummc.tlib.util.Strings; +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; + /** * @Author sky * @Since 2018-05-14 19:07 @@ -24,19 +27,16 @@ public class SQLTable { public SQLTable addColumn(SQLColumn sqlColumn) { if (columns == null) { - columns = new SQLColumn[]{sqlColumn}; + columns = new SQLColumn[] {sqlColumn}; } else { - ArrayUtils.arrayAppend(columns, sqlColumn); + columns = ArrayUtils.arrayAppend(columns, sqlColumn); } return this; } public String createQuery() { - Preconditions.checkNotNull(columns); StringBuilder builder = new StringBuilder(); - for (SQLColumn sqlColumn : columns) { - builder.append(sqlColumn.convertToCommand()).append(", "); - } + Arrays.stream(columns).forEach(sqlColumn -> builder.append(sqlColumn.convertToCommand()).append(", ")); return Strings.replaceWithOrder("create table if not exists `{0}` ({1})", tableName, builder.substring(0, builder.length() - 2)); } @@ -52,6 +52,14 @@ public class SQLTable { return Strings.replaceWithOrder("truncate table `{0}`", tableName); } + public RunnableUpdate executeUpdate(String query) { + return new RunnableUpdate(query); + } + + public RunnableQuery executeQuery(String query) { + return new RunnableQuery(query); + } + // ********************************* // // Getter and Setter diff --git a/src/main/java/me/skymc/taboolib/mysql/builder/query/RunnableQuery.java b/src/main/java/me/skymc/taboolib/mysql/builder/query/RunnableQuery.java new file mode 100644 index 0000000..e76479f --- /dev/null +++ b/src/main/java/me/skymc/taboolib/mysql/builder/query/RunnableQuery.java @@ -0,0 +1,120 @@ +package me.skymc.taboolib.mysql.builder.query; + +import com.ilummc.tlib.logger.TLogger; +import me.skymc.taboolib.mysql.builder.SQLExecutor; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * @Author sky + * @Since 2018-07-03 21:29 + */ +public class RunnableQuery { + + private DataSource dataSource; + private TaskStatement statement; + private TaskResult result; + private TaskResult resultNext; + private Connection connection; + private boolean autoClose; + private String query; + + public RunnableQuery(String query) { + this.query = query; + } + + public RunnableQuery dataSource(DataSource dataSource) { + this.dataSource = dataSource; + return this; + } + + public RunnableQuery statement(TaskStatement statement) { + this.statement = statement; + return this; + } + + public RunnableQuery result(TaskResult result) { + this.result = result; + return this; + } + + public RunnableQuery resultNext(TaskResult result) { + this.resultNext = result; + return this; + } + + public RunnableQuery connection(Connection connection) { + return connection(connection, false); + } + + public RunnableQuery connection(Connection connection, boolean autoClose) { + this.connection = connection; + this.autoClose = autoClose; + return this; + } + + public T run(Object def, T translate) { + Object object = run(def); + return object == null ? def == null ? null : (T) def : (T) object; + } + + public Object run() { + return run(null); + } + + public Object run(Object def) { + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + if (dataSource != null) { + try (Connection connection = dataSource.getConnection()) { + preparedStatement = connection.prepareStatement(query); + if (statement != null) { + statement.execute(preparedStatement); + } + resultSet = preparedStatement.executeQuery(); + return getResult(resultSet); + } catch (Exception e) { + printException(e); + } finally { + SQLExecutor.freeStatement(preparedStatement, resultSet); + } + } else if (connection != null) { + try { + preparedStatement = connection.prepareStatement(query); + if (statement != null) { + statement.execute(preparedStatement); + } + resultSet = preparedStatement.executeQuery(); + return getResult(resultSet); + } catch (Exception e) { + printException(e); + } finally { + SQLExecutor.freeStatement(preparedStatement, resultSet); + if (autoClose) { + SQLExecutor.freeConnection(connection); + } + } + } + return def; + } + + private void printException(Exception e) { + TLogger.getGlobalLogger().error("An exception occurred in the database. (" + query + ")"); + TLogger.getGlobalLogger().error("Reason: " + e.toString()); + e.printStackTrace(); + } + + private Object getResult(ResultSet resultSet) throws SQLException { + if (resultNext != null && resultSet.next()) { + return resultNext.execute(resultSet); + } else if (result != null) { + return result.execute(resultSet); + } else { + return null; + } + } +} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/mysql/builder/query/RunnableUpdate.java b/src/main/java/me/skymc/taboolib/mysql/builder/query/RunnableUpdate.java new file mode 100644 index 0000000..91cdb50 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/mysql/builder/query/RunnableUpdate.java @@ -0,0 +1,85 @@ +package me.skymc.taboolib.mysql.builder.query; + +import com.ilummc.tlib.logger.TLogger; +import me.skymc.taboolib.mysql.builder.SQLExecutor; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.PreparedStatement; + +/** + * F + * + * @Author sky + * @Since 2018-07-03 21:29 + */ +public class RunnableUpdate { + + private DataSource dataSource; + private TaskStatement statement; + private Connection connection; + private boolean autoClose; + private String query; + + public RunnableUpdate(String query) { + this.query = query; + } + + public RunnableUpdate dataSource(DataSource dataSource) { + this.dataSource = dataSource; + return this; + } + + public RunnableUpdate statement(TaskStatement task) { + this.statement = task; + return this; + } + + public RunnableUpdate connection(Connection connection) { + return connection(connection, false); + } + + public RunnableUpdate connection(Connection connection, boolean autoClose) { + this.connection = connection; + this.autoClose = autoClose; + return this; + } + + public void run() { + PreparedStatement preparedStatement = null; + if (dataSource != null) { + try (Connection connection = dataSource.getConnection()) { + preparedStatement = connection.prepareStatement(query); + if (statement != null) { + statement.execute(preparedStatement); + } + preparedStatement.executeUpdate(); + } catch (Exception e) { + printException(e); + } finally { + SQLExecutor.freeStatement(preparedStatement, null); + } + } else if (connection != null) { + try { + preparedStatement = connection.prepareStatement(query); + if (statement != null) { + statement.execute(preparedStatement); + } + preparedStatement.executeUpdate(); + } catch (Exception e) { + printException(e); + } finally { + SQLExecutor.freeStatement(preparedStatement, null); + if (autoClose) { + SQLExecutor.freeConnection(connection); + } + } + } + } + + private void printException(Exception e) { + TLogger.getGlobalLogger().error("An exception occurred in the database. (" + query + ")"); + TLogger.getGlobalLogger().error("Reason: " + e.toString()); + e.printStackTrace(); + } +} diff --git a/src/main/java/me/skymc/taboolib/mysql/builder/query/TaskResult.java b/src/main/java/me/skymc/taboolib/mysql/builder/query/TaskResult.java new file mode 100644 index 0000000..21acd8d --- /dev/null +++ b/src/main/java/me/skymc/taboolib/mysql/builder/query/TaskResult.java @@ -0,0 +1,14 @@ +package me.skymc.taboolib.mysql.builder.query; + +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * @Author sky + * @Since 2018-07-03 22:02 + */ +public interface TaskResult { + + Object execute(ResultSet resultSet) throws SQLException; + +} diff --git a/src/main/java/me/skymc/taboolib/mysql/builder/query/TaskStatement.java b/src/main/java/me/skymc/taboolib/mysql/builder/query/TaskStatement.java new file mode 100644 index 0000000..58d1707 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/mysql/builder/query/TaskStatement.java @@ -0,0 +1,14 @@ +package me.skymc.taboolib.mysql.builder.query; + +import java.sql.PreparedStatement; +import java.sql.SQLException; + +/** + * @Author sky + * @Since 2018-07-03 22:02 + */ +public interface TaskStatement { + + void execute(PreparedStatement preparedStatement) throws SQLException; + +} diff --git a/src/main/java/me/skymc/taboolib/mysql/hikari/HikariHandler.java b/src/main/java/me/skymc/taboolib/mysql/hikari/HikariHandler.java index 4a65e96..410c3f5 100644 --- a/src/main/java/me/skymc/taboolib/mysql/hikari/HikariHandler.java +++ b/src/main/java/me/skymc/taboolib/mysql/hikari/HikariHandler.java @@ -5,8 +5,13 @@ import com.ilummc.tlib.resources.TLocale; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import me.skymc.taboolib.Main; +import me.skymc.taboolib.fileutils.ConfigUtils; +import me.skymc.taboolib.fileutils.FileUtils; import me.skymc.taboolib.mysql.builder.SQLHost; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import javax.sql.DataSource; import java.util.concurrent.ConcurrentHashMap; /** @@ -16,14 +21,16 @@ import java.util.concurrent.ConcurrentHashMap; public class HikariHandler { private static ConcurrentHashMap dataSource = new ConcurrentHashMap<>(); + private static FileConfiguration settings; + + public static void init() { + settings = ConfigUtils.saveDefaultConfig(Main.getInst(), "hikarisettings.yml"); + } + + public static DataSource createDataSource(SQLHost host) { + return createDataSource(host, null); + } - /** - * 根据数据库地址创建连接池,如果已经存在则返回引用 - * - * @param host 数据库地址 - * @return {@link HikariDataSource} - * @throws java.sql.SQLException 数据库连接失败异常 - */ public static HikariDataSource createDataSource(SQLHost host, HikariConfig hikariConfig) { MapDataSource mapDataSource = dataSource.computeIfAbsent(host, x -> new MapDataSource(x, new HikariDataSource(hikariConfig == null ? createConfig(host) : hikariConfig))); mapDataSource.getActivePlugin().getAndIncrement(); @@ -35,21 +42,11 @@ public class HikariHandler { return mapDataSource.getHikariDataSource(); } - /** - * 强制注销所有已注册的连接池 - * 只能在 TabooLib 卸载后调用 - */ public static void closeDataSourceForce() { Preconditions.checkArgument(Main.isDisable(), "Cannot be invoked when the server is running."); dataSource.values().forEach(x -> x.getHikariDataSource().close()); } - /** - * 注销连接池 - * 如果连接池有 1 个以上的插件正在使用则跳过,反之则注销并从缓存中移除 - * - * @param host 地址 - */ public static void closeDataSource(SQLHost host) { if (host != null && dataSource.containsKey(host)) { MapDataSource mapDataSource = dataSource.get(host); @@ -63,45 +60,35 @@ public class HikariHandler { } } - /** - * 根据数据库地址创建 HikariConfig 对象 - * - * @param sqlHost 数据库地址 - * @return {@link HikariConfig} - */ public static HikariConfig createConfig(SQLHost sqlHost) { HikariConfig config = new HikariConfig(); - config.setDriverClassName("com.mysql.jdbc.Driver"); + config.setDriverClassName(settings.getString("DefaultSettings.DriverClassName", "com.mysql.jdbc.Driver")); config.setJdbcUrl(sqlHost.getConnectionUrl()); config.setUsername(sqlHost.getUser()); config.setPassword(sqlHost.getPassword()); config.setConnectionTestQuery("SELECT 1"); - config.setAutoCommit(true); - config.setMinimumIdle(1); - config.setMaximumPoolSize(10); - // 用来指定验证连接有效性的超时时间(毫秒/默认: 5秒) - config.setValidationTimeout(3000); - // 等待连接池分配连接的最大时长(毫秒/默认: 30秒),超过这个时长还没可用的连接则发生 SQLException - config.setConnectionTimeout(10000); - // 一个连接idle状态的最大时长(毫秒/默认: 10分钟),超时则被释放 - config.setIdleTimeout(60000); - // 一个连接的生命时长(毫秒/默认: 30分钟),超时而且没被使用则被释放 - config.setMaxLifetime(60000); - // 是否自定义配置,为true时下面两个参数才生效 - config.addDataSourceProperty("cachePrepStmts", "true"); - // 连接池大小默认25,官方推荐250-500 - config.addDataSourceProperty("prepStmtCacheSize", "250"); - // 单条语句最大长度默认256,官方推荐2048 - config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); - // 新版本MySQL支持服务器端准备,开启能够得到显著性能提升 - config.addDataSourceProperty("useServerPrepStmts", "true"); - config.addDataSourceProperty("useLocalSessionState", "true"); - config.addDataSourceProperty("useLocalTransactionState", "true"); - config.addDataSourceProperty("rewriteBatchedStatements", "true"); - config.addDataSourceProperty("cacheResultSetMetadata", "true"); - config.addDataSourceProperty("cacheServerConfiguration", "true"); - config.addDataSourceProperty("elideSetAutoCommits", "true"); - config.addDataSourceProperty("maintainTimeStats", "false"); + config.setAutoCommit(settings.getBoolean("DefaultSettings.AutoCommit", true)); + config.setMinimumIdle(settings.getInt("DefaultSettings.MinimumIdle", 1)); + config.setMaximumPoolSize(settings.getInt("DefaultSettings.MaximumPoolSize", 10)); + config.setValidationTimeout(settings.getInt("DefaultSettings.ValidationTimeout", 3000)); + config.setConnectionTimeout(settings.getInt("DefaultSettings.ConnectionTimeout", 10000)); + config.setIdleTimeout(settings.getInt("DefaultSettings.IdleTimeout", 60000)); + config.setMaxLifetime(settings.getInt("DefaultSettings.MaxLifetime", 60000)); + if (settings.contains("DefaultSettings.DataSourceProperty")) { + settings.getConfigurationSection("DefaultSettings.DataSourceProperty").getKeys(false).forEach(key -> config.addDataSourceProperty(key, settings.getString("DefaultSettings.DataSourceProperty." + key))); + } else { + config.addDataSourceProperty("cachePrepStmts", "true"); + config.addDataSourceProperty("prepStmtCacheSize", "250"); + config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); + config.addDataSourceProperty("useServerPrepStmts", "true"); + config.addDataSourceProperty("useLocalSessionState", "true"); + config.addDataSourceProperty("useLocalTransactionState", "true"); + config.addDataSourceProperty("rewriteBatchedStatements", "true"); + config.addDataSourceProperty("cacheResultSetMetadata", "true"); + config.addDataSourceProperty("cacheServerConfiguration", "true"); + config.addDataSourceProperty("elideSetAutoCommits", "true"); + config.addDataSourceProperty("maintainTimeStats", "false"); + } return config; } } diff --git a/src/main/java/me/skymc/taboolib/player/PlayerUtils.java b/src/main/java/me/skymc/taboolib/player/PlayerUtils.java index bc2a665..3fd1b95 100644 --- a/src/main/java/me/skymc/taboolib/player/PlayerUtils.java +++ b/src/main/java/me/skymc/taboolib/player/PlayerUtils.java @@ -1,11 +1,15 @@ package me.skymc.taboolib.player; +import com.google.common.collect.ImmutableList; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Collections; import java.util.HashSet; /** @@ -13,6 +17,30 @@ import java.util.HashSet; */ public class PlayerUtils { + private static boolean setup; + private static boolean useReflection; + private static Method oldGetOnlinePlayersMethod; + + public static Collection getOnlinePlayers() { + try { + if (!setup) { + oldGetOnlinePlayersMethod = Bukkit.class.getDeclaredMethod("getOnlinePlayers"); + if (oldGetOnlinePlayersMethod.getReturnType() == Player[].class) { + useReflection = true; + } + setup = true; + } + if (!useReflection) { + return Bukkit.getOnlinePlayers(); + } else { + Player[] playersArray = (Player[]) oldGetOnlinePlayersMethod.invoke(null); + return ImmutableList.copyOf(playersArray); + } + } catch (Exception e) { + return Collections.emptyList(); + } + } + /** * 获取目标方块 * diff --git a/src/main/java/me/skymc/taboolib/translateuuid/TranslateUUID.java b/src/main/java/me/skymc/taboolib/translateuuid/TranslateUUID.java index 4e008fc..25a8732 100644 --- a/src/main/java/me/skymc/taboolib/translateuuid/TranslateUUID.java +++ b/src/main/java/me/skymc/taboolib/translateuuid/TranslateUUID.java @@ -159,15 +159,7 @@ public class TranslateUUID { // ********************************* private static void createTable() { - PreparedStatement preparedStatement = null; - try (Connection connection = dataSource.getConnection()) { - preparedStatement = connection.prepareStatement(sqlTable.createQuery()); - preparedStatement.executeUpdate(); - } catch (SQLException e) { - TLogger.getGlobalLogger().error("Database error: " + e.toString()); - } finally { - SQLExecutor.freeStatement(preparedStatement, null); - } + sqlTable.executeUpdate(sqlTable.createQuery()).dataSource(dataSource).run(); } private static String getDefaultWorldName() { @@ -194,21 +186,11 @@ public class TranslateUUID { } private static String translateInternal(Connection connection, String input, String output, String command) { - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - try { - preparedStatement = connection.prepareStatement(Strings.replaceWithOrder(command, sqlTable.getTableName())); - preparedStatement.setString(1, input); - resultSet = preparedStatement.executeQuery(); - while (resultSet.next()) { - return resultSet.getString(output); - } - } catch (SQLException e) { - TLogger.getGlobalLogger().error("Database error: " + e.toString()); - } finally { - SQLExecutor.freeStatement(preparedStatement, resultSet); - } - return null; + return sqlTable.executeQuery(Strings.replaceWithOrder(command, sqlTable.getTableName())) + .connection(connection) + .statement(statement -> statement.setString(1, input)) + .resultNext(result -> result.getString(output)) + .run(null, ""); } // ********************************* diff --git a/src/main/java/me/skymc/taboolib/update/UpdateTask.java b/src/main/java/me/skymc/taboolib/update/UpdateTask.java index 790e709..0bb475f 100644 --- a/src/main/java/me/skymc/taboolib/update/UpdateTask.java +++ b/src/main/java/me/skymc/taboolib/update/UpdateTask.java @@ -6,7 +6,6 @@ import com.google.gson.JsonParser; import com.ilummc.tlib.resources.TLocale; import me.skymc.taboolib.Main; import me.skymc.taboolib.TabooLib; -import me.skymc.taboolib.commands.plugin.TabooLibPluginMainCommand; import me.skymc.taboolib.fileutils.FileUtils; import org.bukkit.Bukkit; import org.bukkit.scheduler.BukkitRunnable; diff --git a/src/main/java/org/javalite/activejdbc/MetaModel.java b/src/main/java/org/javalite/activejdbc/MetaModel.java index 3613a89..55657bf 100644 --- a/src/main/java/org/javalite/activejdbc/MetaModel.java +++ b/src/main/java/org/javalite/activejdbc/MetaModel.java @@ -163,7 +163,7 @@ public class MetaModel implements Serializable { } /** - * @return name of the addColumn for optimistic locking record version + * @return name of the column for optimistic locking record version */ public String getVersionColumn() { return versionColumn; @@ -401,11 +401,11 @@ public class MetaModel implements Serializable { } /** - * FK name is a foreign key name used in relationships as a foreign key addColumn in a child table (table represented by this + * FK name is a foreign key name used in relationships as a foreign key column in a child table (table represented by this * instance is a parent table). * The FK name is derived using {@link org.javalite.common.Inflector}: It is a singular version of this table name plus "_id". * - * @return foreign key name used in relationships as a foreign key addColumn in a child table. + * @return foreign key name used in relationships as a foreign key column in a child table. */ public String getFKName() { return singularize(getTableName()).toLowerCase() + "_id"; @@ -469,10 +469,10 @@ public class MetaModel implements Serializable { } /** - * Provides addColumn metadata map, keyed by attribute names. + * Provides column metadata map, keyed by attribute names. * Table columns correspond to ActiveJDBC model attributes. * - * @return Provides addColumn metadata map, keyed by attribute names. + * @return Provides column metadata map, keyed by attribute names. */ public Map getColumnMetadata() { if (columnMetadata == null || columnMetadata.isEmpty()) { diff --git a/src/main/resources/hikarisettings.yml b/src/main/resources/hikarisettings.yml new file mode 100644 index 0000000..81b6f5b --- /dev/null +++ b/src/main/resources/hikarisettings.yml @@ -0,0 +1,32 @@ +# 默认连接池配置 +DefaultSettings: + DriverClassName: 'com.mysql.jdbc.Driver' + AutoCommit: true + MinimumIdle: 1 + # 连接池大小 + MaximumPoolSize: 10 + # 用来指定验证连接有效性的超时时间(毫秒/默认: 5秒) + ValidationTimeout: 3000 + # 等待连接池分配连接的最大时长(毫秒/默认: 30秒) + # 超过这个时长还没可用的连接则发生 SQLException + ConnectionTimeout: 10000 + # 一个连接idle状态的最大时长(毫秒/默认: 10分钟),超时则被释放 + IdleTimeout: 60000 + # 一个连接的生命时长(毫秒/默认: 30分钟),超时而且没被使用则被释放 + MaxLifetime: 60000 + # 是否自定义配置,为true时下面两个参数才生效 + DataSourceProperty: + cachePrepStmts: true + # 连接池大小默认25,官方推荐250-500 + prepStmtCacheSize: 250 + # 单条语句最大长度默认256,官方推荐2048 + prepStmtCacheSqlLimit: 2048 + # 新版本MySQL支持服务器端准备,开启能够得到显著性能提升 + useServerPrepStmts: true + useLocalSessionState: true + useLocalTransactionState: true + rewriteBatchedStatements: true + cacheResultSetMetadata: true + cacheServerConfiguration: true + elideSetAutoCommits: true + maintainTimeStats: false \ No newline at end of file diff --git a/src/main/resources/lang/zh_CN.yml b/src/main/resources/lang/zh_CN.yml index e1f72cd..fbf0b08 100644 --- a/src/main/resources/lang/zh_CN.yml +++ b/src/main/resources/lang/zh_CN.yml @@ -239,6 +239,7 @@ COMMANDS: UPDATE-NOT-FOUND: '&8[&3&lTabooLib&8] &7插件已是最新版, 无需更新!' UPDATE-NOT-SUPPORT: '&8[&3&lTabooLib&8] &4您的服务器不支持在线更新!' FILE-NOT-FOUND: '&8[&3&lTabooLib&8] &4尚未寻找到插件文件' + PLAYER-ONLINE: '&8[&3&lTabooLib&8] &4服务器有玩家在线无法更新插件.' UPDATE-START: '&8[&3&lTabooLib&8] &7开始下载:&f {0}' UPDATE-SUCCESS: '&8[&3&lTabooLib&8] &7最新版下载完成, 服务器即将重启!' JAVASHELL: @@ -533,6 +534,20 @@ COMMANDS: RELOAD: DESCRIPTION: '重载配置及数据库' SUCCESS: '&8[&3&lTabooLib&8] &7请求已发送, 详细信息请查看控制台' + TEXECUTE: + COMMAND-TITLE: '&e&l----- &6&lTabooLibExecute Commands &e&l-----' + CHAT: + DESCRIPTION: '使玩家输入聊天内容' + ARGUMENTS: + 0: '玩家' + 1: '内容' + INVALID-PLAYER-OFFLINE: '&8[&3&lTabooLib&8] &4玩家 &c{0} &4不在线.' + COMMAND: + DESCRIPTION: '使目标输入执行指令' + ARGUMENTS: + 0: '目标' + 1: '内容' + INVALID-TARGET-NOT-FOUND: '&8[&3&lTabooLib&8] &4目标 &c{0} &4不存在.' DATABASE: CONNECTION-ESTABLISHED: '成功连接到 {0} 数据库,连接池大小 {1}' diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index ccf4e28..2a0c06d 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -21,6 +21,9 @@ commands: taboolibplugin: aliases: [tabooplugin, tplugin] permission: taboolib.admin + taboolibexecute: + aliases: [texecute] + permission: taboolib.admin taboolibrarymodule: aliases: [tlm] translateuuid: