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 extends Player> 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: