版本更新至 4.02

调整:部分语言文件地址拼写错误(FAIL写成FALL,我这鸟语算是白学了)
调整:配置文件 tlib.yml 不再监听文件更改(这块不是我写的,监听更改会出死循环不知道为啥)
调整:通过 MysqlUtils 创建的数据库连接会返回已存在的引用,不再重复创建
调整:TagManager 工具现在会根据玩家的前缀进行自动排序(尚未测试)
修复:ListenerPluginDisable 类中语言提示无法更改的问题
新增:几个奇葩数据库工具,我也不知道有啥用写着玩
This commit is contained in:
坏黑 2018-05-18 00:45:32 +08:00
parent 80fe84d0d4
commit 4aabd95c59
25 changed files with 720 additions and 102 deletions

View File

@ -8,23 +8,41 @@
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/libs/ProtocolLib.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="library" name="Maven: org.apache.cassandra:cassandra-all:0.8.1" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:r08" level="project" />
<orderEntry type="library" name="Maven: commons-cli:commons-cli:1.1" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.2" level="project" />
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.1" level="project" />
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.4" level="project" />
<orderEntry type="library" name="Maven: com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.1" level="project" />
<orderEntry type="library" name="Maven: org.antlr:antlr:3.2" level="project" />
<orderEntry type="library" name="Maven: org.antlr:antlr-runtime:3.2" level="project" />
<orderEntry type="library" name="Maven: org.antlr:stringtemplate:3.2" level="project" />
<orderEntry type="library" name="Maven: antlr:antlr:2.7.7" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.6.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.cassandra.deps:avro:1.4.0-cassandra-1" level="project" />
<orderEntry type="library" name="Maven: org.mortbay.jetty:jetty:6.1.22" level="project" />
<orderEntry type="library" name="Maven: org.mortbay.jetty:jetty-util:6.1.22" level="project" />
<orderEntry type="library" name="Maven: org.mortbay.jetty:servlet-api:2.5-20081211" level="project" />
<orderEntry type="library" name="Maven: org.codehaus.jackson:jackson-core-asl:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.codehaus.jackson:jackson-mapper-asl:1.4.0" level="project" />
<orderEntry type="library" name="Maven: jline:jline:0.9.94" level="project" />
<orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1" level="project" />
<orderEntry type="library" name="Maven: com.github.stephenc.high-scale-lib:high-scale-lib:1.1.2" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.6" level="project" />
<orderEntry type="library" name="Maven: org.apache.thrift:libthrift:0.6.1" level="project" />
<orderEntry type="library" name="Maven: junit:junit:4.4" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:servlet-api:2.5" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.0.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.0.1" level="project" />
<orderEntry type="library" name="Maven: commons-logging:commons-logging:1.1.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.cassandra:cassandra-thrift:0.8.1" level="project" />
<orderEntry type="library" name="Maven: com.github.stephenc:jamm:0.2.2" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.1.0" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" />
<orderEntry type="library" name="Maven: org.javalite:activejdbc:2.0" level="project" />
<orderEntry type="library" name="Maven: org.javalite:javalite-common:2.0" level="project" />
<orderEntry type="library" name="Maven: org.codehaus.jackson:jackson-core-asl:1.9.13" level="project" />
<orderEntry type="library" name="Maven: org.codehaus.jackson:jackson-mapper-asl:1.9.13" level="project" />
<orderEntry type="library" name="Maven: org.javalite:app-config:2.0" level="project" />
<orderEntry type="library" name="Maven: com.h2database:h2:1.4.197" level="project" />
<orderEntry type="library" name="Maven: com.ilummc.eagletdl:EagletCore:1.1.2" level="project" />

38
pom.xml
View File

@ -6,10 +6,13 @@
<groupId>me.skymc</groupId>
<artifactId>TabooLib</artifactId>
<version>4.01</version>
<version>4.02</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compile.source>1.5</maven.compile.source>
<maven.compile.target>1.5</maven.compile.target>
<maven.compile.deprecation>off</maven.compile.deprecation>
</properties>
<build>
<defaultGoal>clean install package</defaultGoal>
@ -30,23 +33,9 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<compilerId>eclipse</compilerId>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<source>8</source>
<target>8</target>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-eclipse</artifactId>
<version>2.8.4</version>
</dependency>
<dependency>
<groupId>org.eclipse.jdt</groupId>
<artifactId>ecj</artifactId>
<version>3.13.102</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@ -79,6 +68,21 @@
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.apache.cassandra</groupId>
<artifactId>cassandra-all</artifactId>
<version>0.8.1</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>

View File

@ -9,7 +9,7 @@ import java.util.Map;
* @author sky
* @since 2018-04-22 14:31:11
*/
@TConfig(name = "tlib.yml", listenChanges = true)
@TConfig(name = "tlib.yml")
public class TLibConfig {
private String dataSourceClassName;

View File

@ -23,6 +23,7 @@ import me.skymc.taboolib.javashell.JavaShell;
import me.skymc.taboolib.listener.*;
import me.skymc.taboolib.message.ChatCatcher;
import me.skymc.taboolib.message.MsgUtils;
import me.skymc.taboolib.mysql.hikari.HikariHandler;
import me.skymc.taboolib.mysql.protect.MySQLConnection;
import me.skymc.taboolib.nms.item.DabItemUtils;
import me.skymc.taboolib.other.NumberUtils;
@ -191,7 +192,7 @@ public class Main extends JavaPlugin implements Listener {
}
} else {
// 提示
TLocale.Logger.error("NOTIFY.ERROR-CONNECTION-FALL");
TLocale.Logger.error("NOTIFY.ERROR-CONNECTION-FAIL");
// 关服
Bukkit.shutdown();
}
@ -281,7 +282,7 @@ public class Main extends JavaPlugin implements Listener {
// 如果插件尚未启动完成
if (!started) {
TLocale.Logger.error("NOTIFY.FALL-DISABLE");
TLocale.Logger.error("NOTIFY.FAIL-DISABLE");
return;
}
@ -299,6 +300,8 @@ public class Main extends JavaPlugin implements Listener {
SpecialItem.getInst().unloadItems();
// 注销 TLM 接口
TabooLibraryModule.getInst().unloadModules();
// 注销连接池
HikariHandler.closeDataSourceForce();
// 结束数据库储存方法
if (getStorageType() == StorageType.SQL) {

View File

@ -8,8 +8,24 @@ import org.bukkit.plugin.Plugin;
import java.util.Arrays;
import java.util.UUID;
/**
* @author sky
*/
public class TabooLib {
private static boolean spigot = false;
static {
try {
spigot = Bukkit.getConsoleSender() != null;
} catch (Exception ignored) {
}
}
public static boolean isSpigot() {
return spigot;
}
public static boolean isDebug() {
return Main.getInst().getConfig().getBoolean("DEBUG");
}

View File

@ -82,7 +82,7 @@ public class TabooLibPluginMainCommand extends BaseMainCommand {
break;
}
default: {
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.LOAD.LOAD-FALL", name);
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.LOAD.LOAD-FAIL", name);
}
}
}
@ -123,7 +123,7 @@ public class TabooLibPluginMainCommand extends BaseMainCommand {
break;
}
default: {
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.UNLOAD.UNLOAD-FALL", name);
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.UNLOAD.UNLOAD-FAIL", name);
}
}
}
@ -190,16 +190,20 @@ public class TabooLibPluginMainCommand extends BaseMainCommand {
if (plugin == null) {
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.INFO.INVALID-PLUGIN", name);
} else {
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.INFO.INFO-PLUGIN",
plugin.getName(),
String.valueOf(plugin.getDescription().getDescription()),
String.valueOf(plugin.getDescription().getAuthors()),
String.valueOf(plugin.getDescription().getDepend()),
String.valueOf(plugin.getDescription().getSoftDepend()),
String.valueOf(plugin.getDescription().getMain()),
String.valueOf(plugin.getDescription().getVersion()),
String.valueOf(plugin.getDescription().getWebsite()),
String.valueOf(plugin.getDescription().getCommands().keySet()));
try {
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.INFO.INFO-PLUGIN",
plugin.getName(),
String.valueOf(plugin.getDescription().getDescription()),
String.valueOf(plugin.getDescription().getAuthors()),
String.valueOf(plugin.getDescription().getDepend()),
String.valueOf(plugin.getDescription().getSoftDepend()),
String.valueOf(plugin.getDescription().getMain()),
String.valueOf(plugin.getDescription().getVersion()),
String.valueOf(plugin.getDescription().getWebsite()),
String.valueOf(plugin.getDescription().getCommands().keySet()));
} catch (Exception ignored) {
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.INFO.INVALID-PLUGIN", name);
}
}
}
});

View File

@ -35,7 +35,7 @@ public class ConfigUtils {
@SuppressWarnings("unchecked")
public static Map<String, Object> yamlToMap(String yamlText) {
return YAML.loadAs(yamlText, LinkedHashMap.class);
return (Map<String, Object>) YAML.load(yamlText);
}
public static MemoryConfiguration objToConf(Object object) {
@ -199,7 +199,7 @@ public class ConfigUtils {
configuration.loadFromString(yaml);
return configuration;
} catch (Exception e) {
TLocale.Logger.error("FILE-UTILS.FALL-LOAD-CONFIGURATION", plugin.getName(), file.getName());
TLocale.Logger.error("FILE-UTILS.FAIL-LOAD-CONFIGURATION", plugin.getName(), file.getName());
}
return configuration;
}

View File

@ -100,7 +100,7 @@ public class ItemUtils {
reloadItemCache();
itemdir = YamlConfiguration.loadConfiguration(new File(Main.getInst().getConfig().getString("DATAURL.ITEMDIR")));
} catch (Exception e) {
TLocale.Logger.error("ITEM-UTILS.FALL-LOAD-ITEMS", e.toString());
TLocale.Logger.error("ITEM-UTILS.FAIL-LOAD-ITEMS", e.toString());
}
}
@ -108,7 +108,7 @@ public class ItemUtils {
FileConfiguration conf = ConfigUtils.load(Main.getInst(), file);
for (String name : conf.getConfigurationSection("").getKeys(false)) {
if (isExists(name)) {
TLocale.Logger.error("ITEM-UTILS.FALL-LOAD-ITEMS", name);
TLocale.Logger.error("ITEM-UTILS.FAIL-LOAD-ITEMS", name);
} else if (finalFile) {
itemCachesFinal.put(name, loadItem(conf, name));
} else {
@ -424,7 +424,7 @@ public class ItemUtils {
if (enchant != null) {
meta.addEnchant(enchant, section.getInt("enchants." + preEnchant), true);
} else {
TLocale.Logger.error("ITEM-UTILS.FALL-LOAD-ENCHANTS", preEnchant);
TLocale.Logger.error("ITEM-UTILS.FAIL-LOAD-ENCHANTS", preEnchant);
}
}
}
@ -435,7 +435,7 @@ public class ItemUtils {
if (flag != null) {
meta.addItemFlags(flag);
} else {
TLocale.Logger.error("ITEM-UTILS.FALL-LOAD-FLAG", preFlag);
TLocale.Logger.error("ITEM-UTILS.FAIL-LOAD-FLAG", preFlag);
}
}
}
@ -454,7 +454,7 @@ public class ItemUtils {
NumberUtils.getInteger(section.getString("potions." + prePotionName).split("-")[0]),
NumberUtils.getInteger(section.getString("potions." + prePotionName).split("-")[1]) - 1), true);
} else {
TLocale.Logger.error("ITEM-UTILS.FALL-LOAD-POTION", prePotionName);
TLocale.Logger.error("ITEM-UTILS.FAIL-LOAD-POTION", prePotionName);
}
}
}
@ -505,7 +505,7 @@ public class ItemUtils {
} catch (Exception ignored) {
}
} else {
TLocale.Logger.error("ITEM-UTILS.FALL-LOAD-POTION", name);
TLocale.Logger.error("ITEM-UTILS.FAIL-LOAD-POTION", name);
}
}
}
@ -544,7 +544,7 @@ public class ItemUtils {
} catch (NumberFormatException ignored) {
}
} else {
TLocale.Logger.error("ITEM-UTILS.FALL-LOAD-POTION", name);
TLocale.Logger.error("ITEM-UTILS.FAIL-LOAD-POTION", name);
}
return nbt;
}

View File

@ -1,5 +1,6 @@
package me.skymc.taboolib.listener;
import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.message.MsgUtils;
import me.skymc.taboolib.mysql.MysqlUtils;
@ -41,7 +42,7 @@ public class ListenerPluginDisable implements Listener {
i++;
}
if (i > 0) {
MsgUtils.send("已停止插件 &f" + e.getPlugin().getName() + "&7 的 &f" + i + "&7 条数据库连接");
TLocale.Logger.info("MYSQL-CONNECTION.SUCCESS-CONNECTION-CANCEL", e.getPlugin().getName(), String.valueOf(i));
}
}
};
@ -50,7 +51,7 @@ public class ListenerPluginDisable implements Listener {
try {
runnable.runTaskLater(Main.getInst(), 40);
} catch (Exception err) {
MsgUtils.warn("异步任务失败, 执行方式改为同步执行");
TLocale.Logger.error("MYSQL-CONNECTION.FAIL-EXECUTE-TASK");
runnable.run();
}
}

View File

@ -6,12 +6,14 @@ import me.skymc.taboolib.mysql.protect.MySQLConnection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.Plugin;
import java.sql.Connection;
import java.util.concurrent.CopyOnWriteArrayList;
public class MysqlUtils {
public final static CopyOnWriteArrayList<MySQLConnection> CONNECTIONS = new CopyOnWriteArrayList<>();
@Deprecated
public static MysqlConnection getMysqlConnectionFromConfiguration(FileConfiguration conf, String key) {
return new MysqlConnection(conf.getString(key + ".host"), conf.getString(key + ".port"), conf.getString(key + ".database"), conf.getString(key + ".user"), conf.getString(key + ".pass"));
}
@ -21,17 +23,28 @@ public class MysqlUtils {
}
public static MySQLConnection getMySQLConnectionFromConfiguration(FileConfiguration conf, String key, int recheck, Plugin plugin) {
MySQLConnection conn = new MySQLConnection(
conf.getString(key + ".url"),
conf.getString(key + ".user"),
conf.getString(key + ".port"),
conf.getString(key + ".password"),
conf.getString(key + ".database"), recheck, plugin);
if (conn.isConnection()) {
CONNECTIONS.add(conn);
TLocale.Logger.info("MYSQL-CONNECTION.SUCCESS-REGISTERED", plugin.getName());
MySQLConnection connection = getMySQLConnectionExists(conf, key);
if (connection == null) {
connection = new MySQLConnection(conf.getString(key + ".url"), conf.getString(key + ".user"), conf.getString(key + ".port"), conf.getString(key + ".password"), conf.getString(key + ".database"), recheck, plugin);
if (connection.isConnection()) {
CONNECTIONS.add(connection);
TLocale.Logger.info("MYSQL-CONNECTION.SUCCESS-REGISTERED", plugin.getName());
}
} else {
TLocale.Logger.info("MYSQL-CONNECTION.SUCCESS-REGISTERED-EXISTS", plugin.getName(), connection.getPlugin().getName());
}
return conn;
return connection;
}
private static MySQLConnection getMySQLConnectionExists(FileConfiguration conf, String key) {
return CONNECTIONS.stream().filter(connection -> isSameConnection(conf, key, connection)).findFirst().orElse(null);
}
private static boolean isSameConnection(FileConfiguration conf, String key, MySQLConnection connection) {
return conversionHost(connection.getUrl()).equals(conversionHost(conf.getString(key + ".url", "localhost"))) && connection.getDatabase().equals(conf.getString(key + ".database"));
}
private static String conversionHost(String host) {
return "localhost".equals(host) ? "127.0.0.1" : host;
}
}

View File

@ -0,0 +1,144 @@
package me.skymc.taboolib.mysql.builder;
import com.ilummc.tlib.util.Strings;
import java.util.Arrays;
/**
* @Author sky
* @Since 2018-05-14 19:09
*/
public class SQLColumn {
public static void main(String[] args) {
SQLColumn column2 = new SQLColumn(SQLColumnType.INT, "player_title", "");
System.out.println(column2.convertToCommand());
}
/**
* 类型
*/
private SQLColumnType columnType;
private int m;
private int d;
/**
* 名称
*/
private String columnName;
/**
* 默认值
*/
private Object defaultValue;
/**
* 属性值
*/
private SQLColumnOption[] columnOptions;
/**
* 文本类型常用构造器
* new SQLColumn(SQLColumnType.TEXT, "username");
*/
public SQLColumn(SQLColumnType columnType, String columnName) {
this(columnType, 0, 0, columnName, null);
}
/**
* 主键类型常用构造器
* new SQLColumn(SQLColumnType.TEXT, "username", SQLColumnOption.PRIMARY_KEY, SQLColumnOption.AUTO_INCREMENT);
*/
public SQLColumn(SQLColumnType columnType, String columnName, SQLColumnOption... columnOptions) {
this(columnType, 0, 0, columnName, null, columnOptions);
}
/**
* 数据类型常用构造器
* new SQLColumn(SQLColumnType.TEXT, "player_group", "PLAYER");
*/
public SQLColumn(SQLColumnType columnType, String columnName, Object defaultValue) {
this(columnType, 0, 0, columnName, defaultValue);
}
/**
* 完整构造器
*
* @param columnType 类型
* @param m m值
* @param d d值
* @param columnName 名称
* @param defaultValue 默认值
* @param columnOptions 属性值
*/
public SQLColumn(SQLColumnType columnType, int m, int d, String columnName, Object defaultValue, SQLColumnOption... columnOptions) {
this.columnType = columnType;
this.m = m;
this.d = d;
this.columnName = columnName;
this.defaultValue = defaultValue;
this.columnOptions = columnOptions;
}
public SQLColumn m(int m) {
this.m = m;
return this;
}
public SQLColumn d(int d) {
this.d = d;
return this;
}
public SQLColumn defaultValue(Object defaultValue) {
this.defaultValue = defaultValue;
return this;
}
public SQLColumn columnOptions(SQLColumnOption... columnOptions) {
this.columnOptions = columnOptions;
return this;
}
public String convertToCommand() {
if (this.m == 0 && this.d == 0) {
return Strings.replaceWithOrder("`{0}` {1}{2}", columnName, columnType.name().toLowerCase(), convertToOptions());
} else if (this.d == 0) {
return Strings.replaceWithOrder("`{0}` {1}({2}){3}", columnName, columnType.name().toLowerCase(), m, convertToOptions());
} else {
return Strings.replaceWithOrder("`{0}` {1}({2},{3}){4}", columnName, columnType.name().toLowerCase(), m, d, convertToOptions());
}
}
private String convertToOptions() {
StringBuilder stringBuilder = new StringBuilder();
for (SQLColumnOption options : columnOptions) {
switch (options) {
case NOTNULL:
stringBuilder.append(" not null");
break;
case PRIMARY_KEY:
stringBuilder.append(" primary key");
break;
case AUTO_INCREMENT:
stringBuilder.append(" auto_increment");
break;
case UNIQUE_KEY:
stringBuilder.append(" unique key");
break;
default:
}
}
if (defaultValue instanceof String) {
stringBuilder.append(" default '").append(defaultValue).append("'");
} else {
stringBuilder.append(" default ").append(defaultValue);
}
return stringBuilder.toString();
}
@Override
public String toString() {
return "columnType=" + "SQLColumn{" + columnType + ", m=" + m + ", d=" + d + ", columnName='" + columnName + '\'' + ", defaultValue=" + defaultValue + ", columnOptions=" + Arrays.toString(columnOptions) + '}';
}
}

View File

@ -0,0 +1,29 @@
package me.skymc.taboolib.mysql.builder;
/**
* @Author sky
* @Since 2018-05-14 21:43
*/
public enum SQLColumnOption {
/**
* 不能为空
*/
NOTNULL,
/**
* 唯一
*/
UNIQUE_KEY,
/**
* 主键
*/
PRIMARY_KEY,
/**
* 递增
*/
AUTO_INCREMENT
}

View File

@ -0,0 +1,122 @@
package me.skymc.taboolib.mysql.builder;
/**
* @Author sky
* @Since 2018-05-14 19:13
*/
public enum SQLColumnType {
/**
* 有符号值-128 到127- 27 到27 - 1
* 无符号值0到2550 到28 - 1 1个字节
*/
TINYINT,
/**
* 有符号值-32768 到32767- 215 到215 - 1
* 无符号值0到655350 到21 6 - 1 2个字节
*/
SMALLINT,
/**
* 有符号值-8388608 到8388607- 22 3 到22 3 - 1
* 无符号值0到167772150 到22 4 - 1 3个字节
*/
MEDIUMINT,
/**
* 有符号值-2147683648 到2147683647- 231 到231- 1
* 无符号值0到42949672950 到232 - 1 4个字节
*/
INT,
/**
* 有符号值-9223372036854775808 到9223373036854775807- 263到263-1
* 无符号值0到184467440737095516150到264 1 8个字节
*/
BIGINT,
/**
* 最小非零值±1.175494351e - 38
*/
FLOAT,
/**
* 最小非零值±2.2250738585072014e - 308
*/
DOUBLE,
/**
* 可变其值的范围依赖于m 和d
*/
DECIMAL,
/**
* 定长磁盘空间比较浪费,但是效率高,确定数据长度都一样,就使用定长
* 比如电话号码,身份证号
* 最长可取255
*/
CHAR,
/**
* 边长比较节省空间,但是效率低,数据不能确定长度(不同数据长度有变化)
* 比如地址
* 最长可取65535
*/
VARCHAR,
/**
* 0~255字节值的长度+2字节
*/
TINYTEXT,
/**
* 0~65535字节值的长度+2字节
*/
TEXT,
/**
* 0~167772150字节值的长度+3字节
*/
MEDIUMTEXT,
/**
* 0~4294967295字节值的长度+4字节
*/
LONGTEXT,
/**
* 字节数为M允许长度为0~M的定长二进制字符串
*/
BINARY,
/**
* 允许长度为0~M的变长二进制字符串字节数为值的长度加1
*/
VARBINARY,
/**
* M位二进制数据M最大值为64
*/
BIT,
/**
* 可变长二进制数据最多255个字节
*/
TINYBLOB,
/**
* 可变长二进制数据最多2的16次方-1个字节
*/
BLOB,
/**
* 可变长二进制数据最多2的24次方-1个字节
*/
MEDIUMBLOB,
/**
* 可变长二进制数据最多2的32次方-1个字节
*/
LONGBLOB
}

View File

@ -0,0 +1,89 @@
package me.skymc.taboolib.mysql.builder;
import com.ilummc.tlib.util.Ref;
import com.ilummc.tlib.util.Strings;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.plugin.Plugin;
import java.util.Objects;
/**
* @Author sky
* @Since 2018-05-14 19:01
*/
public class SQLHost {
private String host;
private String user;
private String port;
private String password;
private String database;
private Plugin plugin;
public SQLHost(ConfigurationSection section, Plugin plugin) {
this(section.getString("host", "localhost"), section.getString("user", "root"), section.getString("port", "3306"), section.getString("password", ""), section.getString("database", "test"), plugin);
}
public SQLHost(String host, String user, String port, String password, String database, Plugin plugin) {
this.host = host;
this.user = user;
this.port = port;
this.password = password;
this.database = database;
this.plugin = plugin;
}
public String getHost() {
return host;
}
public String getUser() {
return user;
}
public String getPort() {
return port;
}
public String getPassword() {
return password;
}
public String getDatabase() {
return database;
}
public Plugin getPlugin() {
return plugin;
}
public String getConnectionUrl() {
return Strings.replaceWithOrder("jdbc:mysql://{0}:{1}/{2}?characterEncoding=utf-8&useSSL=false", this.host, this.port, this.database);
}
public String getConnectionUrlSimple() {
return Strings.replaceWithOrder("jdbc:mysql://{0}:{1}/{2}", this.host, this.port, this.database);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof 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());
}
@Override
public int hashCode() {
return Objects.hash(getHost(), getUser(), getPort(), getPassword(), getDatabase());
}
@Override
public String toString() {
return "host='" + "SQLHost{" + host + '\'' + ", user='" + user + '\'' + ", port='" + port + '\'' + ", password='" + password + '\'' + ", database='" + database + '\'' + '}';
}
}

View File

@ -0,0 +1,24 @@
package me.skymc.taboolib.mysql.builder;
/**
* @Author sky
* @Since 2018-05-14 19:07
*/
public class SQLTable {
private final String tableName;
private final SQLColumn[] columns;
public SQLTable(String tableName, SQLColumn... columns) {
this.tableName = tableName;
this.columns = columns;
}
public String getTableName() {
return tableName;
}
public SQLColumn[] getColumns() {
return columns;
}
}

View File

@ -0,0 +1,106 @@
package me.skymc.taboolib.mysql.hikari;
import com.google.common.base.Preconditions;
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.mysql.builder.SQLHost;
import java.util.concurrent.ConcurrentHashMap;
/**
* @Author sky
* @Since 2018-05-16 21:59
*/
public class HikariHandler {
private static ConcurrentHashMap<SQLHost, MapDataSource> dataSource = new ConcurrentHashMap<>();
/**
* 根据数据库地址创建连接池如果已经存在则返回引用
*
* @param host 数据库地址
* @return {@link HikariDataSource}
*/
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();
if (mapDataSource.getActivePlugin().get() == 1) {
TLocale.Logger.info("MYSQL-HIKARI.CREATE-SUCCESS", host.getPlugin().getName(), host.getConnectionUrlSimple());
} else {
TLocale.Logger.info("MYSQL-HIKARI.CREATE-EXISTS", host.getPlugin().getName(), mapDataSource.getSqlHost().getPlugin().getName());
}
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 (dataSource.containsKey(host)) {
MapDataSource mapDataSource = dataSource.get(host);
if (mapDataSource.getActivePlugin().getAndDecrement() <= 1) {
mapDataSource.getHikariDataSource().close();
dataSource.remove(host);
TLocale.Logger.info("MYSQL-HIKARI.CLOSE-SUCCESS", host.getPlugin().getName(), host.getConnectionUrlSimple());
} else {
TLocale.Logger.info("MYSQL-HIKARI.CLOSE-FAIL", host.getPlugin().getName(), String.valueOf(mapDataSource.getActivePlugin().get()));
}
}
}
/**
* 根据数据库地址创建 HikariConfig 对象
*
* @param sqlHost 数据库地址
* @return {@link HikariConfig}
*/
public static HikariConfig createConfig(SQLHost sqlHost) {
HikariConfig config = new HikariConfig();
config.setDriverClassName("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");
return config;
}
}

View File

@ -0,0 +1,35 @@
package me.skymc.taboolib.mysql.hikari;
import com.zaxxer.hikari.HikariDataSource;
import me.skymc.taboolib.mysql.builder.SQLHost;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @Author sky
* @Since 2018-05-17 23:47
*/
public class MapDataSource {
private SQLHost sqlHost;
private AtomicInteger activePlugin;
private HikariDataSource hikariDataSource;
MapDataSource(SQLHost sqlHost, HikariDataSource hikariDataSource) {
this.sqlHost = sqlHost;
this.activePlugin = new AtomicInteger();
this.hikariDataSource = hikariDataSource;
}
public SQLHost getSqlHost() {
return sqlHost;
}
public AtomicInteger getActivePlugin() {
return activePlugin;
}
public HikariDataSource getHikariDataSource() {
return hikariDataSource;
}
}

View File

@ -32,7 +32,7 @@ public class MySQLConnection {
public MySQLConnection(String url, String user, String port, String password, String database, int recheck, Plugin plugin) {
// 检查驱动
if (!loadDriverMySQL()) {
TLocale.Logger.error("MYSQL-CONNECTION.FALL-NOTFOUND-DRIVE");
TLocale.Logger.error("MYSQL-CONNECTION.FAIL-NOTFOUND-DRIVE");
return;
}
@ -58,12 +58,12 @@ public class MySQLConnection {
Thread.sleep(getReCheckSeconds() * 1000);
if (connection == null) {
TLocale.Logger.error("MYSQL-CONNECTION.FALL-NOTFOUND-CONNECTION", plugin.getName());
TLocale.Logger.error("MYSQL-CONNECTION.FAIL-NOTFOUND-CONNECTION", plugin.getName());
} else {
isExists("taboolib");
}
} catch (Exception e) {
TLocale.Logger.error("MYSQL-CONNECTION.FALL-COMMAND-NORMAL", e.toString());
TLocale.Logger.error("MYSQL-CONNECTION.FAIL-COMMAND-NORMAL", e.toString());
}
}
});
@ -657,12 +657,12 @@ public class MySQLConnection {
}
private void printException(Exception e) {
TLocale.Logger.error("MYSQL-CONNECTION.FALL-COMMAND-NORMAL", e.toString());
TLocale.Logger.error("MYSQL-CONNECTION.FAIL-COMMAND-NORMAL", e.toString());
reconnection(e);
}
private void printExceptionDetail(SQLException e) {
TLocale.Logger.error("MYSQL-CONNECTION.FALL-COMMAND-DETAIL", String.valueOf(e.getErrorCode()), e.toString());
TLocale.Logger.error("MYSQL-CONNECTION.FAIL-COMMAND-DETAIL", String.valueOf(e.getErrorCode()), e.toString());
reconnection(e);
}

View File

@ -48,7 +48,7 @@ public class WeightCollection<A> {
return null;
}
class WeightObject<B> {
public static class WeightObject<B> {
private int weightNumber;
private B weightObject;

View File

@ -57,7 +57,7 @@ public class DataUtils implements Listener {
try {
conf.save(file);
} catch (IOException e) {
TLocale.Logger.error("DATA-UTILS.FALL-SAVE-FILE", file.getName(), e.toString());
TLocale.Logger.error("DATA-UTILS.FAIL-SAVE-FILE", file.getName(), e.toString());
}
}

View File

@ -74,7 +74,7 @@ public class Language2 {
languageFile = new File(languageFolder, languageName);
if (!languageFile.exists()) {
if (plugin.getResource("Language2/" + languageName) == null) {
TLocale.Logger.error("LANGUAGE2.FALL-NOTFOUND-FILE", languageName);
TLocale.Logger.error("LANGUAGE2.FAIL-NOTFOUND-FILE", languageName);
} else {
plugin.saveResource("Language2/" + languageName, true);
}

View File

@ -172,9 +172,9 @@ public class TagManager implements Listener {
}
private Team getTeam(Scoreboard scoreboard, PlayerData data) {
Team team = scoreboard.getTeam(data.getName());
Team team = scoreboard.getTeam(String.valueOf(data.getPrefix()));
if (team == null) {
team = scoreboard.registerNewTeam(data.getName());
team = scoreboard.registerNewTeam(String.valueOf(data.getPrefix()));
team.addEntry(data.getName());
}
return team;

View File

@ -59,7 +59,7 @@ public class TimeCycleManager {
if (!cycles.containsKey(cycle.getName())) {
cycles.put(cycle.getName(), cycle);
} else {
TLocale.Logger.error("TIMECYCLE.FALL-CYCLE-EXISTS", cycle.getName());
TLocale.Logger.error("TIMECYCLE.FAIL-CYCLE-EXISTS", cycle.getName());
}
}

View File

@ -93,10 +93,10 @@ public class TLM {
}
public void loadedFall(String moduleName, String result, String location) {
TLocale.Logger.error("TABOOLIB-MODULE.FALL-LOADED", moduleName, result, location);
TLocale.Logger.error("TABOOLIB-MODULE.FAIL-LOADED", moduleName, result, location);
}
public void runtimeFall(String moduleName, String result, String location) {
TLocale.Logger.error("TABOOLIB-MODULE.FALL-RUNTIME", moduleName, result, location);
TLocale.Logger.error("TABOOLIB-MODULE.FAIL-RUNTIME", moduleName, result, location);
}
}

View File

@ -32,7 +32,7 @@ CONFIG:
NOTIFY:
ERROR-SERVER-KEY: '&4检测到本服序列号与其他服务器相同, 已重新生成!'
ERROR-CONNECTION-FALL: '&4数据库连接失败, 请检查配置是否正确!'
ERROR-CONNECTION-FAIL: '&4数据库连接失败, 请检查配置是否正确!'
SUCCESS-LOADED:
- '§7插件载入完成!'
- '§7插件作者: §f{0}'
@ -41,7 +41,7 @@ NOTIFY:
SUCCESS-DISABLE:
- '&c插件已卸载, 感谢您使用&4禁忌书库'
- '&c插件作者: &4坏黑'
FALL-DISABLE:
FAIL-DISABLE:
- '&c插件尚未启动完成, 已跳过卸载代码'
- '&c插件作者: &4坏黑'
@ -72,28 +72,28 @@ ENTITY-UTILS:
NOTFOUND-PROTOCOLLIB: '缺少前置插件 ProtocolLib'
FILE-UTILS:
FALL-LOAD-CONFIGURATION: '&4配置文件载入失败!, 插件: &c{0}&4, 文件: &c{1}'
FAIL-LOAD-CONFIGURATION: '&4配置文件载入失败!, 插件: &c{0}&4, 文件: &c{1}'
DATA-UTILS:
SUCCESS-SAVE-DATA: '&7保存 &f{0} &7条插件数据, 耗时: &f{1} &7(ms)'
FALL-SAVE-FILE: '&4文件 &c{0}&4 保存失败, 原因: &c{1}'
FAIL-SAVE-FILE: '&4文件 &c{0}&4 保存失败, 原因: &c{1}'
ITEM-UTILS:
FALL-LOAD-ITEMS: '物品库载入失败: &4{0}'
FALL-LOAD-ATTRIBUTE: '&c{0} &4不是一个有效的属性名称, 输入 &c/tlib attributes&4 查看所有属性'
FALL-LOAD-ENCHANT: '&c{0} &4不是一个有效的附魔名称, 输入 &c/tlib enchants&4 查看所有附魔'
FALL-LOAD-POTION: '&c{0} &4不是一个有效的药水名称, 输入 &c/tlib potions&4 查看所有药水'
FALL-LOAD-FLAG: '&c{0} &4不是一个有效的标签名称, 输入 &c/tlib flags&4 查看所有标签'
FALL-SAVE-EXISTS: '无法载入载入物品 &4{0}&c, 因为它已经存在了'
FAIL-LOAD-ITEMS: '物品库载入失败: &4{0}'
FAIL-LOAD-ATTRIBUTE: '&c{0} &4不是一个有效的属性名称, 输入 &c/tlib attributes&4 查看所有属性'
FAIL-LOAD-ENCHANT: '&c{0} &4不是一个有效的附魔名称, 输入 &c/tlib enchants&4 查看所有附魔'
FAIL-LOAD-POTION: '&c{0} &4不是一个有效的药水名称, 输入 &c/tlib potions&4 查看所有药水'
FAIL-LOAD-FLAG: '&c{0} &4不是一个有效的标签名称, 输入 &c/tlib flags&4 查看所有标签'
FAIL-SAVE-EXISTS: '无法载入载入物品 &4{0}&c, 因为它已经存在了'
SUCCESS-LOAD-CACHES: '&7载入 &f{0} &7项缓存物品'
SUCCESS-LOAD-NAMES: '&7载入 &f{0} &7项物品名称'
EMPTY-ITEM: '空'
LANGUAGE2:
FALL-NOTFOUND-FILE: '语言文件 {0} 不存在'
FAIL-NOTFOUND-FILE: '语言文件 {0} 不存在'
TIMECYCLE:
FALL-CYCLE-EXISTS: '注册周期管理器 &8{0}&c 失败, 原因: &4名称重复'
FAIL-CYCLE-EXISTS: '注册周期管理器 &8{0}&c 失败, 原因: &4名称重复'
ANVIL-CONTAINER:
NAME-EXAMPLE: '在这里输入文本'
@ -114,19 +114,29 @@ UPDATETASK:
- '&8####################################################'
MYSQL-CONNECTION:
FALL-NOTFOUND-DRIVE: '&7驱动器获取失败, 无法连接到数据库'
FALL-NOTFOUND-CONNECTION: '&7警告! 数据库尚未连接, 请检查配置文件后重启服务器! ({0})'
FALL-COMMAND-NORMAL: '&4数据库命令执行出错, 错误原因: &c{0}'
FALL-COMMAND-DETAIL: '&4数据库命令执行出错, 错误代码: &c{0}&4, 错误原因: &c{1}'
SUCCESS-REGISTERED: '&7已向书库注册插件 &f{0}&7 的数据库连接'
FAIL-CONNECT: '&4数据库 &c{0} &4连接失败, 原因: &c{0}'
FAIL-NOTFOUND-DRIVE: '&7驱动器获取失败, 无法连接到数据库'
FAIL-NOTFOUND-CONNECTION: '&7警告! 数据库尚未连接, 请检查配置文件后重启服务器! ({0})'
FAIL-COMMAND-NORMAL: '&4数据库命令执行出错, 错误原因: &c{0}'
FAIL-COMMAND-DETAIL: '&4数据库命令执行出错, 错误代码: &c{0}&4, 错误原因: &c{1}'
FAIL-EXECUTE-TASK: '异步任务失败, 执行方式改为同步执行'
SUCCESS-REGISTERED: '&7插件 &f{0}&7 注册新的数据库连接'
SUCCESS-REGISTERED-EXISTS: '&7插件 &f{0}&7 引用插件 &f{1}&7 注册的数据库连接'
SUCCESS-REGISTERED-LISTENER: '&7启动数据库连接监控'
SUCCESS-CONNECTION-CANCEL: '已停止插件 &f{0}&7 的 &f{1}&7 条数据库连接'
NOTIFY-CONNECTING: '&7正在连接数据库, 地址: &f{0}'
NOTIFY-CONNECTED: '数据库连接成功 ({0}ms)'
NOTIFY-CONNECTED: '&7数据库连接成功 ({0}ms)'
MYSQL-HIKARI:
CREATE-SUCCESS: '&7插件 &f{0}&7 注册新的数据库连接: &f{1}'
CREATE-EXISTS: '&7插件 &f{0}&7 引用插件 &f{1}&7 注册的数据库连接'
CLOSE-SUCCESS: '&7插件 &f{0} &7注册的数据库连接 &f{1} &7已被注销!'
CLOSE-FAIL: '&7插件 &f{0} &7注册的数据库连接正在被 &f{1} &7个插件使用, 无法注销!'
TABOOLIB-MODULE:
SUCCESS-LOADED: '&7载入 &f{0} &7个 &fTLM &7模块'
FALL-LOADED: '&4模块载入异常: &c{0}&4, 模块: &c{1}&4, 位于: &c{2}'
FALL-RUNTIME: '&4模块运行异常: &c{0}&4, 模块: &c{1}&4, 位于: &c{2}'
FAIL-LOADED: '&4模块载入异常: &c{0}&4, 模块: &c{1}&4, 位于: &c{2}'
FAIL-RUNTIME: '&4模块运行异常: &c{0}&4, 模块: &c{1}&4, 位于: &c{2}'
COMMANDS:
GLOBAL:
@ -459,7 +469,7 @@ COMMANDS:
0: '名称'
INVALID-PLUGIN: '&8[&3&lTabooLib&8] &4插件 &c{0} &4已经载入'
LOAD-SUCCESS: '&8[&3&lTabooLib&8] &7插件已载入'
LOAD-FALL: '&8[&3&lTabooLib&8] &7插件载入失败'
LOAD-FAIL: '&8[&3&lTabooLib&8] &7插件载入失败'
UNLOAD:
DESCRIPTION: '卸载插件'
ARGUMENTS:
@ -467,7 +477,7 @@ COMMANDS:
INVALID-PLUGIN: '&8[&3&lTabooLib&8] &4插件 &c{0} &4不存在'
INVALID-PLUGIN-IGNORED: '&8[&3&lTabooLib&8] &4插件 &c{0} &4无法操作'
UNLOAD-SUCCESS: '&8[&3&lTabooLib&8] &7插件已卸载'
UNLOAD-FALL: '&8[&3&lTabooLib&8] &7插件卸载失败'
UNLOAD-FAIL: '&8[&3&lTabooLib&8] &7插件卸载失败'
RELOAD:
DESCRIPTION: '重载插件'
ARGUMENTS: