更换至 Gradle
This commit is contained in:
283
src/main/scala/me/skymc/taboolib/Main.java
Normal file
283
src/main/scala/me/skymc/taboolib/Main.java
Normal file
@@ -0,0 +1,283 @@
|
||||
package me.skymc.taboolib;
|
||||
|
||||
import com.ilummc.tlib.TLib;
|
||||
import com.ilummc.tlib.filter.TLoggerFilter;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import com.ilummc.tlib.util.IO;
|
||||
import com.ilummc.tlib.util.Strings;
|
||||
import me.skymc.taboolib.database.GlobalDataManager;
|
||||
import me.skymc.taboolib.database.PlayerDataManager;
|
||||
import me.skymc.taboolib.fileutils.ConfigUtils;
|
||||
import me.skymc.taboolib.fileutils.FileUtils;
|
||||
import me.skymc.taboolib.listener.TListenerHandler;
|
||||
import me.skymc.taboolib.mysql.hikari.HikariHandler;
|
||||
import me.skymc.taboolib.mysql.protect.MySQLConnection;
|
||||
import me.skymc.taboolib.other.NumberUtils;
|
||||
import me.skymc.taboolib.playerdata.DataUtils;
|
||||
import me.skymc.taboolib.socket.TabooLibClient;
|
||||
import me.skymc.taboolib.socket.TabooLibServer;
|
||||
import me.skymc.taboolib.string.language2.Language2;
|
||||
import me.skymc.taboolib.update.UpdateTask;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
*/
|
||||
public class Main extends JavaPlugin {
|
||||
|
||||
public Main() {
|
||||
inst = this;
|
||||
}
|
||||
|
||||
public enum StorageType {
|
||||
LOCAL, SQL
|
||||
}
|
||||
|
||||
private static Plugin inst;
|
||||
private static Economy economy;
|
||||
private static File playerDataFolder;
|
||||
private static File serverDataFolder;
|
||||
private static StorageType storageType = StorageType.LOCAL;
|
||||
private static Language2 exampleLanguage2;
|
||||
private static boolean disable = false;
|
||||
private static boolean started = false;
|
||||
private static boolean isInternetOnline = false;
|
||||
private FileConfiguration config = null;
|
||||
|
||||
@Override
|
||||
public FileConfiguration getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveDefaultConfig() {
|
||||
reloadConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadConfig() {
|
||||
File file = new File(getDataFolder(), "config.yml");
|
||||
if (!file.exists()) {
|
||||
saveResource("config.yml", true);
|
||||
}
|
||||
config = ConfigUtils.load(this, file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
disable = false;
|
||||
// 载入配置文件
|
||||
saveDefaultConfig();
|
||||
// 载入日志过滤
|
||||
TLoggerFilter.preInit();
|
||||
// 载入扩展
|
||||
TabooLibLoader.setupAddons();
|
||||
// 载入牛逼东西
|
||||
TLib.init();
|
||||
TLib.injectPluginManager();
|
||||
// 载入插件设置
|
||||
TabooLibLoader.setup();
|
||||
// 载入大饼
|
||||
TLib.initPost();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
// 载入日志过滤
|
||||
TLoggerFilter.postInit();
|
||||
// 注册插件配置
|
||||
TabooLibLoader.register();
|
||||
// 启动数据库储存方法
|
||||
if (getStorageType() == StorageType.SQL) {
|
||||
GlobalDataManager.SQLMethod.startSQLMethod();
|
||||
}
|
||||
// 载入完成
|
||||
TLocale.Logger.info("NOTIFY.SUCCESS-LOADED", getDescription().getAuthors().toString(), getDescription().getVersion(), String.valueOf(TabooLib.getVersion()));
|
||||
// 文件保存
|
||||
Bukkit.getScheduler().runTaskTimerAsynchronously(this, DataUtils::saveAllCaches, 20, 20 * 120);
|
||||
Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> PlayerDataManager.saveAllCaches(true, false), 20, 20 * 60);
|
||||
// 文件监控
|
||||
TLib.getTLib().getConfigWatcher().addSimpleListener(new File(getDataFolder(), "config.yml"), () -> {
|
||||
reloadConfig();
|
||||
TLocale.Logger.info("CONFIG.RELOAD-SUCCESS", inst.getName(), "config.yml");
|
||||
});
|
||||
// 插件联动
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// 面子工程
|
||||
if (!TabooLib.isSilent()) {
|
||||
InputStream inputStream = FileUtils.getResource("motd.txt");
|
||||
try {
|
||||
String text = new String(IO.readFully(inputStream), Charset.forName("utf-8"));
|
||||
if (text != null) {
|
||||
Arrays.stream(text.split("\n")).forEach(line -> Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(line, getDescription().getVersion())));
|
||||
}
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
// 本地通讯网络终端
|
||||
if (getConfig().getBoolean("SERVER")) {
|
||||
TabooLibServer.main(new String[0]);
|
||||
}
|
||||
// 本地通讯网络
|
||||
TabooLibClient.init();
|
||||
}
|
||||
}.runTask(this);
|
||||
// 启动
|
||||
started = true;
|
||||
// 载入语言文件
|
||||
exampleLanguage2 = new Language2("Language2", this);
|
||||
// 更新检测
|
||||
if (!TabooLib.isSilent()) {
|
||||
new UpdateTask();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
disable = true;
|
||||
// 如果插件尚未启动完成
|
||||
if (!started) {
|
||||
TLocale.Logger.error("NOTIFY.FAIL-DISABLE");
|
||||
return;
|
||||
}
|
||||
// 注销插件
|
||||
TabooLibLoader.unregister();
|
||||
// 保存数据
|
||||
Bukkit.getOnlinePlayers().forEach(x -> DataUtils.saveOnline(x.getName()));
|
||||
// 结束线程
|
||||
Bukkit.getScheduler().cancelTasks(this);
|
||||
// 保存插件数据
|
||||
DataUtils.saveAllCaches();
|
||||
// 保存玩家数据
|
||||
PlayerDataManager.saveAllPlayers(false, true);
|
||||
// 注销连接池
|
||||
HikariHandler.closeDataSourceForce();
|
||||
// 注销监听器
|
||||
TListenerHandler.cancelListeners();
|
||||
// 结束数据库储存方法
|
||||
if (getStorageType() == StorageType.SQL) {
|
||||
GlobalDataManager.SQLMethod.cancelSQLMethod();
|
||||
}
|
||||
// 清理数据
|
||||
if (getStorageType() == StorageType.LOCAL && getConfig().getBoolean("DELETE-DATA")) {
|
||||
getPlayerDataFolder().delete();
|
||||
}
|
||||
// 清理数据
|
||||
if (getStorageType() == StorageType.SQL && getConfig().getBoolean("DELETE-VARIABLE")) {
|
||||
GlobalDataManager.clearInvalidVariables();
|
||||
}
|
||||
// 提示信息
|
||||
TLocale.Logger.info("NOTIFY.SUCCESS-DISABLE");
|
||||
// 卸载牛逼玩意儿
|
||||
TLib.unload();
|
||||
// 关闭服务器
|
||||
Bukkit.shutdown();
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Getter and Setter
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public static Plugin getInst() {
|
||||
return inst;
|
||||
}
|
||||
|
||||
public static String getPrefix() {
|
||||
return "§8[§3§lTabooLib§8] §7";
|
||||
}
|
||||
|
||||
public static net.milkbowl.vault.economy.Economy getEconomy() {
|
||||
return economy;
|
||||
}
|
||||
|
||||
public static void setEconomy(Economy economy) {
|
||||
Main.economy = economy;
|
||||
}
|
||||
|
||||
public static File getPlayerDataFolder() {
|
||||
return playerDataFolder;
|
||||
}
|
||||
|
||||
public static File getServerDataFolder() {
|
||||
return serverDataFolder;
|
||||
}
|
||||
|
||||
public static StorageType getStorageType() {
|
||||
return storageType;
|
||||
}
|
||||
|
||||
public static boolean isDisable() {
|
||||
return disable;
|
||||
}
|
||||
|
||||
public static MySQLConnection getConnection() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Language2 getExampleLanguage2() {
|
||||
return exampleLanguage2;
|
||||
}
|
||||
|
||||
public static boolean isStarted() {
|
||||
return started;
|
||||
}
|
||||
|
||||
public static Random getRandom() {
|
||||
return NumberUtils.getRandom();
|
||||
}
|
||||
|
||||
public static String getTablePrefix() {
|
||||
return inst.getConfig().getString("MYSQL.PREFIX");
|
||||
}
|
||||
|
||||
public static boolean isInternetOnline() {
|
||||
return isInternetOnline;
|
||||
}
|
||||
|
||||
public static boolean isOfflineVersion() {
|
||||
return inst.getResource("libs") != null;
|
||||
}
|
||||
|
||||
public static boolean isLibrariesExists() {
|
||||
return TLib.getTLib().getLibsFolder().listFiles().length > 0;
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Private Setter
|
||||
//
|
||||
// *********************************
|
||||
|
||||
static void setIsInternetOnline(boolean isInternetOnline) {
|
||||
Main.isInternetOnline = isInternetOnline;
|
||||
}
|
||||
|
||||
static void setPlayerDataFolder(File playerDataFolder) {
|
||||
Main.playerDataFolder = playerDataFolder;
|
||||
}
|
||||
|
||||
static void setServerDataFolder(File serverDataFolder) {
|
||||
Main.serverDataFolder = serverDataFolder;
|
||||
}
|
||||
|
||||
static void setStorageType(StorageType storageType) {
|
||||
Main.storageType = storageType;
|
||||
}
|
||||
}
|
||||
167
src/main/scala/me/skymc/taboolib/TabooLib.java
Normal file
167
src/main/scala/me/skymc/taboolib/TabooLib.java
Normal file
@@ -0,0 +1,167 @@
|
||||
package me.skymc.taboolib;
|
||||
|
||||
import me.skymc.taboolib.common.nms.NMSHandler;
|
||||
import me.skymc.taboolib.other.NumberUtils;
|
||||
import me.skymc.taboolib.playerdata.DataUtils;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
*/
|
||||
public class TabooLib {
|
||||
|
||||
private static boolean spigot = false;
|
||||
private static boolean silent = false;
|
||||
|
||||
static {
|
||||
try {
|
||||
// 判断是否为独立客户端运行,不是判断 Bukkit 与 Spigot
|
||||
Class.forName("org.bukkit.Bukkit");
|
||||
spigot = true;
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取主类对象,因 Main 名称容易造成混淆所以转移至此
|
||||
*/
|
||||
public static Main instance() {
|
||||
return (Main) Main.getInst();
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件是否为 TabooLib(沙雕方法)
|
||||
*/
|
||||
public static boolean isTabooLib(Plugin plugin) {
|
||||
return plugin.equals(instance()) || plugin.getName().equals("TabooLib");
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件是否依赖于 TabooLib(依赖或软兼容)
|
||||
*/
|
||||
public static boolean isDependTabooLib(Plugin plugin) {
|
||||
return plugin.getDescription().getDepend().contains("TabooLib") || plugin.getDescription().getSoftDepend().contains("TabooLib");
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为 Spigot 核心,因 TabooLib 可在 BungeeCord 上运行所以添加此方法
|
||||
*/
|
||||
public static boolean isSpigot() {
|
||||
return spigot;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为静默模式
|
||||
*/
|
||||
public static boolean isSilent() {
|
||||
return silent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置静默模式,启用后将关闭部分提示
|
||||
*/
|
||||
public static void setSilent(boolean silent) {
|
||||
TabooLib.silent = silent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 TabooLib 插件版本
|
||||
*/
|
||||
public static double getPluginVersion() {
|
||||
return NumberUtils.getDouble(Main.getInst().getDescription().getVersion());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务端版本
|
||||
*/
|
||||
public static String getVersion() {
|
||||
return Bukkit.getServer().getClass().getName().split("\\.")[3];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务端版本数字
|
||||
*/
|
||||
public static int getVersionNumber() {
|
||||
return getVerint();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置服务器序列号
|
||||
*/
|
||||
public static void resetServerUID() {
|
||||
DataUtils.getPluginData("TabooLibrary", null).set("serverUID", UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为调试模式
|
||||
*/
|
||||
public static boolean isDebug() {
|
||||
return DataUtils.getPluginData("TabooLibrary", instance()).getBoolean("debug");
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换调试模式
|
||||
*/
|
||||
public static void setDebug(boolean debug) {
|
||||
DataUtils.getPluginData("TabooLibrary", instance()).set("debug", debug);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送调试信息
|
||||
*/
|
||||
public static void debug(String... args) {
|
||||
debug(instance(), args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送调试信息
|
||||
*/
|
||||
public static void debug(Plugin plugin, String... args) {
|
||||
if (TabooLib.isDebug()) {
|
||||
Arrays.stream(args).forEach(var -> Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "[TabooLib - DEBUG][" + plugin.getName() + "] " + ChatColor.RED + var));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务器序列号
|
||||
*/
|
||||
public static String getServerUID() {
|
||||
if (!DataUtils.getPluginData("TabooLibrary", null).contains("serverUID")) {
|
||||
DataUtils.getPluginData("TabooLibrary", null).set("serverUID", UUID.randomUUID().toString());
|
||||
}
|
||||
return DataUtils.getPluginData("TabooLibrary", null).getString("serverUID");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务器 TPS
|
||||
*/
|
||||
public static double[] getTPS() {
|
||||
return NMSHandler.getHandler().getTPS();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static int getVerint() {
|
||||
String version = getVersion();
|
||||
if (version.startsWith("v1_7")) {
|
||||
return 10700;
|
||||
} else if (version.startsWith("v1_8")) {
|
||||
return 10800;
|
||||
} else if (version.startsWith("v1_9")) {
|
||||
return 10900;
|
||||
} else if (version.startsWith("v1_10")) {
|
||||
return 11000;
|
||||
} else if (version.startsWith("v1_11")) {
|
||||
return 11100;
|
||||
} else if (version.startsWith("v1_12")) {
|
||||
return 11200;
|
||||
} else if (version.startsWith("v1_13")) {
|
||||
return 11300;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
128
src/main/scala/me/skymc/taboolib/TabooLibDatabase.java
Normal file
128
src/main/scala/me/skymc/taboolib/TabooLibDatabase.java
Normal file
@@ -0,0 +1,128 @@
|
||||
package me.skymc.taboolib;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.mysql.builder.SQLColumn;
|
||||
import me.skymc.taboolib.mysql.builder.SQLColumnType;
|
||||
import me.skymc.taboolib.mysql.builder.SQLHost;
|
||||
import me.skymc.taboolib.mysql.builder.SQLTable;
|
||||
import me.skymc.taboolib.mysql.hikari.HikariHandler;
|
||||
import me.skymc.taboolib.string.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-08-23 17:15
|
||||
*/
|
||||
public class TabooLibDatabase {
|
||||
|
||||
private static SQLHost host;
|
||||
private static DataSource dataSource;
|
||||
private static HashMap<String, SQLTable> tables = new HashMap<>();
|
||||
|
||||
static void init() {
|
||||
if (Main.getStorageType() != Main.StorageType.SQL) {
|
||||
return;
|
||||
}
|
||||
// 数据库地址
|
||||
host = new SQLHost(
|
||||
// 地址
|
||||
Main.getInst().getConfig().getString("MYSQL.HOST"),
|
||||
// 用户
|
||||
Main.getInst().getConfig().getString("MYSQL.USER"),
|
||||
// 端口
|
||||
Main.getInst().getConfig().getString("MYSQL.POST"),
|
||||
// 密码
|
||||
Main.getInst().getConfig().getString("MYSQL.PASSWORD"),
|
||||
// 数据库
|
||||
Main.getInst().getConfig().getString("MYSQL.DATABASE"), TabooLib.instance());
|
||||
// 连接数据库
|
||||
try {
|
||||
dataSource = HikariHandler.createDataSource(host);
|
||||
} catch (Exception ignored) {
|
||||
TLocale.Logger.error("NOTIFY.ERROR-CONNECTION-FAIL");
|
||||
return;
|
||||
}
|
||||
// 创建各项数据表
|
||||
createTableWithPlayerData();
|
||||
createTableWithPluginData();
|
||||
createTableWithServerUUID();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建玩家数据表
|
||||
*/
|
||||
static void createTableWithPlayerData() {
|
||||
SQLTable table = new SQLTable(Main.getTablePrefix() + "_playerdata", SQLColumn.PRIMARY_KEY_ID, new SQLColumn(SQLColumnType.TEXT, "username"), new SQLColumn(SQLColumnType.TEXT, "configuration"));
|
||||
table.executeUpdate(table.createQuery()).dataSource(dataSource).run();
|
||||
tables.put("playerdata", table);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建插件数据表
|
||||
*/
|
||||
static void createTableWithPluginData() {
|
||||
SQLTable table = new SQLTable(Main.getTablePrefix() + "_plugindata", SQLColumn.PRIMARY_KEY_ID, new SQLColumn(SQLColumnType.TEXT, "name"), new SQLColumn(SQLColumnType.TEXT, "variable"), new SQLColumn(SQLColumnType.TEXT, "upgrade"));
|
||||
table.executeUpdate(table.createQuery()).dataSource(dataSource).run();
|
||||
tables.put("plugindata", table);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建服务器数据表
|
||||
*/
|
||||
static void createTableWithServerUUID() {
|
||||
SQLTable table = new SQLTable(Main.getTablePrefix() + "_serveruuid", SQLColumn.PRIMARY_KEY_ID, new SQLColumn(SQLColumnType.TEXT, "uuid"), new SQLColumn(SQLColumnType.TEXT, "hash"));
|
||||
table.executeUpdate(table.createQuery()).dataSource(dataSource).run();
|
||||
tables.put("serveruuid", table);
|
||||
// 获取当前服务器信息
|
||||
String hash = getServerHash(TabooLib.getServerUID());
|
||||
if (hash == null) {
|
||||
// 写入序列号
|
||||
table.executeUpdate("insert into " + table.getTableName() + " values(null, ?, ?)")
|
||||
.dataSource(dataSource)
|
||||
.statement(s -> {
|
||||
s.setString(1, TabooLib.getServerUID());
|
||||
s.setString(2, StringUtils.hashKeyForDisk(Main.getInst().getDataFolder().getPath()));
|
||||
}).run();
|
||||
} else if (!hash.equals(StringUtils.hashKeyForDisk(Main.getInst().getDataFolder().getPath()))) {
|
||||
TLocale.Logger.error("NOTIFY.ERROR-SERVER-KEY");
|
||||
TabooLib.resetServerUID();
|
||||
Bukkit.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务器序列号对应的目录哈希值
|
||||
*
|
||||
* @param uuid 服务器序列号
|
||||
* @return 目录哈希值
|
||||
*/
|
||||
public static String getServerHash(String uuid) {
|
||||
SQLTable table = tables.get("serveruuid");
|
||||
return table.executeQuery("select * from " + table.getTableName() + " where uuid = ?")
|
||||
.dataSource(dataSource)
|
||||
.statement(s -> s.setString(1, uuid))
|
||||
.resultNext(r -> r.getString("hash"))
|
||||
.run(null, "");
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Getter and Setter
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public static SQLHost getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public static HashMap<String, SQLTable> getTables() {
|
||||
return tables;
|
||||
}
|
||||
|
||||
public static DataSource getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
}
|
||||
300
src/main/scala/me/skymc/taboolib/TabooLibLoader.java
Normal file
300
src/main/scala/me/skymc/taboolib/TabooLibLoader.java
Normal file
@@ -0,0 +1,300 @@
|
||||
package me.skymc.taboolib;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.ilummc.tlib.TLib;
|
||||
import com.ilummc.tlib.annotations.Dependency;
|
||||
import com.ilummc.tlib.dependency.TDependencyLoader;
|
||||
import com.ilummc.tlib.inject.TDependencyInjector;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.bstats.Metrics;
|
||||
import me.skymc.taboolib.deprecated.TabooLibDeprecated;
|
||||
import me.skymc.taboolib.events.TPluginEnableEvent;
|
||||
import me.skymc.taboolib.fileutils.FileUtils;
|
||||
import me.skymc.taboolib.listener.TListener;
|
||||
import me.skymc.taboolib.listener.TListenerHandler;
|
||||
import me.skymc.taboolib.methods.ReflectionUtils;
|
||||
import me.skymc.taboolib.playerdata.DataUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.net.InetAddress;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-08-23 17:04
|
||||
*/
|
||||
@TListener
|
||||
public class TabooLibLoader implements Listener {
|
||||
|
||||
/*
|
||||
关于 TabooLib 各项自动化接口的执行顺序
|
||||
|
||||
[ENABLING]
|
||||
第一阶段:运行 @TInject(Instance Inject)
|
||||
第二阶段(先后):实例化 @TListener -> 实例化 @Instantiable
|
||||
第三阶段(并行):运行 @TFunction & 运行 @TInject
|
||||
|
||||
[ENABLED]
|
||||
第三阶段:注册 @TListener
|
||||
*/
|
||||
|
||||
static TabooLibDeprecated tabooLibDeprecated;
|
||||
static Map<String, List<Class>> pluginClasses = Maps.newHashMap();
|
||||
static List<Loader> loaders = Lists.newArrayList();
|
||||
static List<Runnable> tasks = Lists.newArrayList();
|
||||
static boolean started;
|
||||
|
||||
static void setup() {
|
||||
testInternet();
|
||||
setupDataFolder();
|
||||
setupDatabase();
|
||||
setupLibraries();
|
||||
}
|
||||
|
||||
static void register() {
|
||||
setupClasses();
|
||||
preLoadClasses();
|
||||
registerListener();
|
||||
registerMetrics();
|
||||
postLoadClasses();
|
||||
try {
|
||||
tabooLibDeprecated = new TabooLibDeprecated();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Bukkit.getScheduler().runTask(TabooLib.instance(), () -> {
|
||||
for (Runnable task : tasks) {
|
||||
try {
|
||||
task.run();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void unregister() {
|
||||
unloadClasses();
|
||||
try {
|
||||
tabooLibDeprecated.unregister();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static TabooLibDeprecated getTabooLibDeprecated() {
|
||||
return tabooLibDeprecated;
|
||||
}
|
||||
|
||||
public static Optional<List<Class>> getPluginClasses(Plugin plugin) {
|
||||
return Optional.ofNullable(pluginClasses.get(plugin.getName()));
|
||||
}
|
||||
|
||||
public static List<Class> getPluginClassSafely(Plugin plugin) {
|
||||
List<Class> classes = pluginClasses.get(plugin.getName());
|
||||
return classes == null ? new ArrayList<>() : new ArrayList<>(classes);
|
||||
}
|
||||
|
||||
public static void runTaskOnEnabled(Runnable runnable) {
|
||||
if (Main.isStarted()) {
|
||||
Bukkit.getScheduler().runTask(TabooLib.instance(), () -> {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
tasks.add(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isLoader(Class pluginClass) {
|
||||
return !Loader.class.equals(pluginClass) && Loader.class.isAssignableFrom(pluginClass);
|
||||
}
|
||||
|
||||
static void preLoadClasses() {
|
||||
pluginClasses.forEach((key, classes) -> classes.forEach(pluginClass -> preLoadClass(Bukkit.getPluginManager().getPlugin(key), pluginClass)));
|
||||
}
|
||||
|
||||
static void postLoadClasses() {
|
||||
pluginClasses.forEach((key, classes) -> classes.forEach(pluginClass -> postLoadClass(Bukkit.getPluginManager().getPlugin(key), pluginClass)));
|
||||
}
|
||||
|
||||
static void unloadClasses() {
|
||||
pluginClasses.forEach((key, classes) -> classes.forEach(pluginClass -> unloadClass(Bukkit.getPluginManager().getPlugin(key), pluginClass)));
|
||||
}
|
||||
|
||||
static void registerListener() {
|
||||
TListenerHandler.setupListeners();
|
||||
Bukkit.getScheduler().runTask(TabooLib.instance(), TListenerHandler::registerListeners);
|
||||
}
|
||||
|
||||
static void registerMetrics() {
|
||||
Metrics metrics = new Metrics(TabooLib.instance());
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("plugins_using_taboolib", () -> Math.toIntExact(Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin.getDescription().getDepend().contains("TabooLib")).count())));
|
||||
}
|
||||
|
||||
static void setupDataFolder() {
|
||||
Main.setPlayerDataFolder(FileUtils.folder(Main.getInst().getConfig().getString("DATAURL.PLAYER-DATA")));
|
||||
Main.setServerDataFolder(FileUtils.folder(Main.getInst().getConfig().getString("DATAURL.SERVER-DATA")));
|
||||
}
|
||||
|
||||
static void setupDatabase() {
|
||||
DataUtils.addPluginData("TabooLibrary", null);
|
||||
Main.setStorageType(Main.getInst().getConfig().getBoolean("MYSQL.ENABLE") ? Main.StorageType.SQL : Main.StorageType.LOCAL);
|
||||
TabooLibDatabase.init();
|
||||
}
|
||||
|
||||
static void setupAddons() {
|
||||
TabooLib.instance().saveResource("Addons/TabooLibDeprecated", true);
|
||||
// 傻逼 Gradle 的 shadow 插件会将所有 jar 排除
|
||||
// https://github.com/johnrengelman/shadow/issues/276
|
||||
new File(TabooLib.instance().getDataFolder(), "Addons/TabooLibDeprecated").renameTo(new File(TabooLib.instance().getDataFolder(), "Addons/TabooLibDeprecated.jar"));
|
||||
File file = new File(TabooLib.instance().getDataFolder(), "Addons");
|
||||
if (file.exists()) {
|
||||
Arrays.stream(file.listFiles()).forEach(listFile -> TDependencyLoader.addToPath(TabooLib.instance(), listFile));
|
||||
}
|
||||
}
|
||||
|
||||
static void setupLibraries() {
|
||||
if (Main.isOfflineVersion()) {
|
||||
Arrays.stream(TDependencyInjector.getDependencies(TLib.getTLib())).filter(dependency -> dependency.type() == Dependency.Type.LIBRARY && dependency.maven().matches(".*:.*:.*")).map(dependency -> String.join("-", dependency.maven().split(":")) + ".jar").forEach(fileName -> {
|
||||
File targetFile = FileUtils.file(TLib.getTLib().getLibsFolder(), fileName);
|
||||
InputStream inputStream = FileUtils.getResource("libs/" + fileName);
|
||||
if (!targetFile.exists() && inputStream != null) {
|
||||
FileUtils.inputStreamToFile(inputStream, FileUtils.file(TLib.getTLib().getLibsFolder(), fileName));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void testInternet() {
|
||||
try {
|
||||
InetAddress inetAddress = InetAddress.getByName(Main.getInst().getConfig().getString("TEST-URL", "aliyun.com"));
|
||||
Main.setIsInternetOnline(inetAddress.isReachable(10000));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
if (!Main.isInternetOnline() && !Main.isOfflineVersion() && !Main.isLibrariesExists()) {
|
||||
TLocale.Logger.error("TLIB.LOAD-FAIL-OFFLINE", Main.getInst().getDescription().getVersion());
|
||||
for (; ; ) {
|
||||
// 停止主线程
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setupClasses(Plugin plugin) {
|
||||
if (TabooLib.isTabooLib(plugin) || TabooLib.isDependTabooLib(plugin)) {
|
||||
try {
|
||||
long time = System.currentTimeMillis();
|
||||
List<Class> classes;
|
||||
IgnoreClasses annotation = plugin.getClass().getAnnotation(IgnoreClasses.class);
|
||||
if (annotation != null) {
|
||||
classes = FileUtils.getClasses(plugin, annotation.value());
|
||||
} else {
|
||||
classes = FileUtils.getClasses(plugin);
|
||||
}
|
||||
TabooLib.debug("Saved " + classes.size() + " classes (" + plugin.getName() + ") (" + (System.currentTimeMillis() - time) + "ms)");
|
||||
pluginClasses.put(plugin.getName(), classes);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setupClasses() {
|
||||
Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(TabooLibLoader::setupClasses);
|
||||
pluginClasses.get("TabooLib").stream().filter(TabooLibLoader::isLoader).forEach(pluginClass -> {
|
||||
try {
|
||||
loaders.add((Loader) ReflectionUtils.instantiateObject(pluginClass));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
loaders.sort(Comparator.comparingInt(Loader::priority));
|
||||
});
|
||||
}
|
||||
|
||||
static void preLoadClass(Plugin plugin, Class<?> loadClass) {
|
||||
loaders.forEach(loader -> {
|
||||
try {
|
||||
loader.preLoad(plugin, loadClass);
|
||||
} catch (NoClassDefFoundError ignore) {
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void postLoadClass(Plugin plugin, Class<?> loadClass) {
|
||||
loaders.forEach(loader -> {
|
||||
try {
|
||||
loader.postLoad(plugin, loadClass);
|
||||
} catch (NoClassDefFoundError ignore) {
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void unloadClass(Plugin plugin, Class<?> loadClass) {
|
||||
loaders.forEach(loader -> {
|
||||
try {
|
||||
loader.unload(plugin, loadClass);
|
||||
} catch (NoClassDefFoundError ignore) {
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onEnablePre(TPluginEnableEvent e) {
|
||||
setupClasses(e.getPlugin());
|
||||
Optional.ofNullable(pluginClasses.get(e.getPlugin().getName())).ifPresent(classes -> classes.forEach(pluginClass -> preLoadClass(e.getPlugin(), pluginClass)));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEnablePost(TPluginEnableEvent e) {
|
||||
Optional.ofNullable(pluginClasses.get(e.getPlugin().getName())).ifPresent(classes -> classes.forEach(pluginClass -> postLoadClass(e.getPlugin(), pluginClass)));
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onDisable(PluginDisableEvent e) {
|
||||
Optional.ofNullable(pluginClasses.remove(e.getPlugin().getName())).ifPresent(classes -> classes.forEach(pluginClass -> unloadClass(e.getPlugin(), pluginClass)));
|
||||
}
|
||||
|
||||
public interface Loader {
|
||||
|
||||
default void preLoad(Plugin plugin, Class<?> loadClass) {
|
||||
}
|
||||
|
||||
default void postLoad(Plugin plugin, Class<?> loadClass) {
|
||||
}
|
||||
|
||||
default void unload(Plugin plugin, Class<?> cancelClass) {
|
||||
}
|
||||
|
||||
default int priority() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface IgnoreClasses {
|
||||
|
||||
String[] value();
|
||||
|
||||
}
|
||||
}
|
||||
29
src/main/scala/me/skymc/taboolib/anvil/AnvilContainer.java
Normal file
29
src/main/scala/me/skymc/taboolib/anvil/AnvilContainer.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package me.skymc.taboolib.anvil;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-08 15:47
|
||||
*/
|
||||
public class AnvilContainer extends net.minecraft.server.v1_12_R1.ContainerAnvil {
|
||||
|
||||
public AnvilContainer(net.minecraft.server.v1_12_R1.EntityHuman player) {
|
||||
super(player.inventory, player.world, new net.minecraft.server.v1_12_R1.BlockPosition(0, 0, 0), player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean a(net.minecraft.server.v1_12_R1.EntityHuman player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void openAnvil(Player p) {
|
||||
net.minecraft.server.v1_12_R1.EntityPlayer player = ((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) p).getHandle();
|
||||
AnvilContainer container = new AnvilContainer(player);
|
||||
int c = player.nextContainerCounter();
|
||||
player.playerConnection.sendPacket(new net.minecraft.server.v1_12_R1.PacketPlayOutOpenWindow(c, "minecraft:anvil", new net.minecraft.server.v1_12_R1.ChatMessage("Repairing"), 0));
|
||||
player.activeContainer = container;
|
||||
player.activeContainer.windowId = c;
|
||||
player.activeContainer.addSlotListener(player);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package me.skymc.taboolib.anvil;
|
||||
|
||||
import com.ilummc.tlib.util.asm.AsmClassLoader;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.common.loader.Instantiable;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
*/
|
||||
@Instantiable("AnvilContainerAPI")
|
||||
public class AnvilContainerAPI implements Listener {
|
||||
|
||||
private static Class<?> impl;
|
||||
|
||||
public AnvilContainerAPI() {
|
||||
try {
|
||||
impl = AsmClassLoader.createNewClass("me.skymc.taboolib.anvil.AnvilContainer", AnvilContainerGenerator.generate());
|
||||
Bukkit.getPluginManager().registerEvents(this, TabooLib.instance());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void openAnvil(Player player) {
|
||||
try {
|
||||
impl.getMethod("openAnvil", Player.class).invoke(impl, player);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void example(PlayerCommandPreprocessEvent e) {
|
||||
if (e.getMessage().equalsIgnoreCase("/anvilExample") && e.getPlayer().hasPermission("taboolib.admin")) {
|
||||
e.setCancelled(true);
|
||||
openAnvil(e.getPlayer());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package me.skymc.taboolib.anvil;
|
||||
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
/**
|
||||
* @author idea
|
||||
*/
|
||||
public class AnvilContainerGenerator {
|
||||
|
||||
public static byte[] generate() {
|
||||
String version = TabooLib.getVersion();
|
||||
ClassWriter cw = new ClassWriter(0);
|
||||
FieldVisitor fv;
|
||||
MethodVisitor mv;
|
||||
AnnotationVisitor av0;
|
||||
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, "me/skymc/taboolib/anvil/AnvilContainer", null, "net/minecraft/server/" + version + "/ContainerAnvil", null);
|
||||
cw.visitSource("AnvilContainer.java", null);
|
||||
{
|
||||
mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(Lnet/minecraft/server/" + version + "/EntityHuman;)V", null, null);
|
||||
mv.visitCode();
|
||||
Label l0 = new Label();
|
||||
mv.visitLabel(l0);
|
||||
mv.visitLineNumber(12, l0);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 1);
|
||||
mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/server/" + version + "/EntityHuman", "inventory", "Lnet/minecraft/server/" + version + "/PlayerInventory;");
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 1);
|
||||
mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/server/" + version + "/EntityHuman", "world", "Lnet/minecraft/server/" + version + "/World;");
|
||||
mv.visitTypeInsn(Opcodes.NEW, "net/minecraft/server/" + version + "/BlockPosition");
|
||||
mv.visitInsn(Opcodes.DUP);
|
||||
mv.visitInsn(Opcodes.ICONST_0);
|
||||
mv.visitInsn(Opcodes.ICONST_0);
|
||||
mv.visitInsn(Opcodes.ICONST_0);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "net/minecraft/server/" + version + "/BlockPosition", "<init>", "(III)V", false);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 1);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "net/minecraft/server/" + version + "/ContainerAnvil", "<init>", "(Lnet/minecraft/server/" + version + "/PlayerInventory;Lnet/minecraft/server/" + version + "/World;Lnet/minecraft/server/" + version + "/BlockPosition;Lnet/minecraft/server/" + version + "/EntityHuman;)V", false);
|
||||
Label l1 = new Label();
|
||||
mv.visitLabel(l1);
|
||||
mv.visitLineNumber(13, l1);
|
||||
mv.visitInsn(Opcodes.RETURN);
|
||||
Label l2 = new Label();
|
||||
mv.visitLabel(l2);
|
||||
mv.visitLocalVariable("this", "Lme/skymc/taboolib/anvil/AnvilContainer;", null, l0, l2, 0);
|
||||
mv.visitLocalVariable("player", "Lnet/minecraft/server/" + version + "/EntityHuman;", null, l0, l2, 1);
|
||||
mv.visitMaxs(8, 2);
|
||||
mv.visitEnd();
|
||||
}
|
||||
{
|
||||
mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "a", "(Lnet/minecraft/server/" + version + "/EntityHuman;)Z", null, null);
|
||||
mv.visitCode();
|
||||
Label l0 = new Label();
|
||||
mv.visitLabel(l0);
|
||||
mv.visitLineNumber(17, l0);
|
||||
mv.visitInsn(Opcodes.ICONST_1);
|
||||
mv.visitInsn(Opcodes.IRETURN);
|
||||
Label l1 = new Label();
|
||||
mv.visitLabel(l1);
|
||||
mv.visitLocalVariable("this", "Lme/skymc/taboolib/anvil/AnvilContainer;", null, l0, l1, 0);
|
||||
mv.visitLocalVariable("player", "Lnet/minecraft/server/" + version + "/EntityHuman;", null, l0, l1, 1);
|
||||
mv.visitMaxs(1, 2);
|
||||
mv.visitEnd();
|
||||
}
|
||||
{
|
||||
mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "openAnvil", "(Lorg/bukkit/entity/Player;)V", null, null);
|
||||
mv.visitCode();
|
||||
Label l0 = new Label();
|
||||
mv.visitLabel(l0);
|
||||
mv.visitLineNumber(21, l0);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
||||
mv.visitTypeInsn(Opcodes.CHECKCAST, "org/bukkit/craftbukkit/" + version + "/entity/CraftPlayer");
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/bukkit/craftbukkit/" + version + "/entity/CraftPlayer", "getHandle", "()Lnet/minecraft/server/" + version + "/EntityPlayer;", false);
|
||||
mv.visitVarInsn(Opcodes.ASTORE, 1);
|
||||
Label l1 = new Label();
|
||||
mv.visitLabel(l1);
|
||||
mv.visitLineNumber(22, l1);
|
||||
mv.visitTypeInsn(Opcodes.NEW, "me/skymc/taboolib/anvil/AnvilContainer");
|
||||
mv.visitInsn(Opcodes.DUP);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 1);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "me/skymc/taboolib/anvil/AnvilContainer", "<init>", "(Lnet/minecraft/server/" + version + "/EntityHuman;)V", false);
|
||||
mv.visitVarInsn(Opcodes.ASTORE, 2);
|
||||
Label l2 = new Label();
|
||||
mv.visitLabel(l2);
|
||||
mv.visitLineNumber(23, l2);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 1);
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "net/minecraft/server/" + version + "/EntityPlayer", "nextContainerCounter", "()I", false);
|
||||
mv.visitVarInsn(Opcodes.ISTORE, 3);
|
||||
Label l3 = new Label();
|
||||
mv.visitLabel(l3);
|
||||
mv.visitLineNumber(24, l3);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 1);
|
||||
mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/server/" + version + "/EntityPlayer", "playerConnection", "Lnet/minecraft/server/" + version + "/PlayerConnection;");
|
||||
mv.visitTypeInsn(Opcodes.NEW, "net/minecraft/server/" + version + "/PacketPlayOutOpenWindow");
|
||||
mv.visitInsn(Opcodes.DUP);
|
||||
mv.visitVarInsn(Opcodes.ILOAD, 3);
|
||||
mv.visitLdcInsn("minecraft:anvil");
|
||||
mv.visitTypeInsn(Opcodes.NEW, "net/minecraft/server/" + version + "/ChatMessage");
|
||||
mv.visitInsn(Opcodes.DUP);
|
||||
mv.visitLdcInsn("Repairing");
|
||||
mv.visitInsn(Opcodes.ICONST_0);
|
||||
mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
|
||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "net/minecraft/server/" + version + "/ChatMessage", "<init>", "(Ljava/lang/String;[Ljava/lang/Object;)V", false);
|
||||
mv.visitInsn(Opcodes.ICONST_0);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "net/minecraft/server/" + version + "/PacketPlayOutOpenWindow", "<init>", "(ILjava/lang/String;Lnet/minecraft/server/" + version + "/IChatBaseComponent;I)V", false);
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "net/minecraft/server/" + version + "/PlayerConnection", "sendPacket", "(Lnet/minecraft/server/" + version + "/Packet;)V", false);
|
||||
Label l4 = new Label();
|
||||
mv.visitLabel(l4);
|
||||
mv.visitLineNumber(25, l4);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 1);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 2);
|
||||
mv.visitFieldInsn(Opcodes.PUTFIELD, "net/minecraft/server/" + version + "/EntityPlayer", "activeContainer", "Lnet/minecraft/server/" + version + "/Container;");
|
||||
Label l5 = new Label();
|
||||
mv.visitLabel(l5);
|
||||
mv.visitLineNumber(26, l5);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 1);
|
||||
mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/server/" + version + "/EntityPlayer", "activeContainer", "Lnet/minecraft/server/" + version + "/Container;");
|
||||
mv.visitVarInsn(Opcodes.ILOAD, 3);
|
||||
mv.visitFieldInsn(Opcodes.PUTFIELD, "net/minecraft/server/" + version + "/Container", "windowId", "I");
|
||||
Label l6 = new Label();
|
||||
mv.visitLabel(l6);
|
||||
mv.visitLineNumber(27, l6);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 1);
|
||||
mv.visitFieldInsn(Opcodes.GETFIELD, "net/minecraft/server/" + version + "/EntityPlayer", "activeContainer", "Lnet/minecraft/server/" + version + "/Container;");
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 1);
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "net/minecraft/server/" + version + "/Container", "addSlotListener", "(Lnet/minecraft/server/" + version + "/ICrafting;)V", false);
|
||||
Label l7 = new Label();
|
||||
mv.visitLabel(l7);
|
||||
mv.visitLineNumber(28, l7);
|
||||
mv.visitInsn(Opcodes.RETURN);
|
||||
Label l8 = new Label();
|
||||
mv.visitLabel(l8);
|
||||
mv.visitLocalVariable("p", "Lorg/bukkit/entity/Player;", null, l0, l8, 0);
|
||||
mv.visitLocalVariable("player", "Lnet/minecraft/server/" + version + "/EntityPlayer;", null, l1, l8, 1);
|
||||
mv.visitLocalVariable("container", "Lme/skymc/taboolib/anvil/AnvilContainer;", null, l2, l8, 2);
|
||||
mv.visitLocalVariable("c", "I", null, l3, l8, 3);
|
||||
mv.visitMaxs(9, 4);
|
||||
mv.visitEnd();
|
||||
}
|
||||
cw.visitEnd();
|
||||
return cw.toByteArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package me.skymc.taboolib.bookformatter;
|
||||
|
||||
import org.bukkit.Achievement;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import static org.bukkit.Achievement.*;
|
||||
|
||||
public final class BookAchievement {
|
||||
|
||||
private static final HashMap<Achievement, String> achievements = new HashMap<>();
|
||||
|
||||
static {
|
||||
achievements.put(OPEN_INVENTORY, "openInventory");
|
||||
achievements.put(MINE_WOOD, "mineWood");
|
||||
achievements.put(BUILD_WORKBENCH, "buildWorkBench");
|
||||
achievements.put(BUILD_PICKAXE, "buildPickaxe");
|
||||
achievements.put(BUILD_FURNACE, "buildFurnace");
|
||||
achievements.put(ACQUIRE_IRON, "aquireIron");
|
||||
achievements.put(BUILD_HOE, "buildHoe");
|
||||
achievements.put(MAKE_BREAD, "makeBread");
|
||||
achievements.put(BAKE_CAKE, "bakeCake");
|
||||
achievements.put(BUILD_BETTER_PICKAXE, "buildBetterPickaxe");
|
||||
achievements.put(COOK_FISH, "cookFish");
|
||||
achievements.put(ON_A_RAIL, "onARail");
|
||||
achievements.put(BUILD_SWORD, "buildSword");
|
||||
achievements.put(KILL_ENEMY, "killEnemy");
|
||||
achievements.put(KILL_COW, "killCow");
|
||||
achievements.put(FLY_PIG, "flyPig");
|
||||
achievements.put(SNIPE_SKELETON, "snipeSkeleton");
|
||||
achievements.put(GET_DIAMONDS, "diamonds");
|
||||
achievements.put(NETHER_PORTAL, "portal");
|
||||
achievements.put(GHAST_RETURN, "ghast");
|
||||
achievements.put(GET_BLAZE_ROD, "blazerod");
|
||||
achievements.put(BREW_POTION, "potion");
|
||||
achievements.put(END_PORTAL, "thEnd");
|
||||
achievements.put(THE_END, "theEnd2");
|
||||
achievements.put(ENCHANTMENTS, "enchantments");
|
||||
achievements.put(OVERKILL, "overkill");
|
||||
achievements.put(BOOKCASE, "bookacase");
|
||||
achievements.put(EXPLORE_ALL_BIOMES, "exploreAllBiomes");
|
||||
achievements.put(SPAWN_WITHER, "spawnWither");
|
||||
achievements.put(KILL_WITHER, "killWither");
|
||||
achievements.put(FULL_BEACON, "fullBeacon");
|
||||
achievements.put(BREED_COW, "breedCow");
|
||||
achievements.put(DIAMONDS_TO_YOU, "diamondsToYou");
|
||||
achievements.put(OVERPOWERED, "overpowered");
|
||||
}
|
||||
|
||||
private BookAchievement() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the json id from the bukkit achievement passed as argument
|
||||
*
|
||||
* @param achievement the achievement
|
||||
* @return the achievement's id or null if not found
|
||||
*/
|
||||
public static String toId(Achievement achievement) {
|
||||
return achievements.get(achievement);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package me.skymc.taboolib.bookformatter;
|
||||
|
||||
import me.skymc.taboolib.bookformatter.builder.BookBuilder;
|
||||
import me.skymc.taboolib.events.CustomBookOpenEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public final class BookFormatter {
|
||||
|
||||
/**
|
||||
* Opens a book GUI to the player
|
||||
* @param p the player
|
||||
* @param book the book to be opened
|
||||
*/
|
||||
public static void openPlayer(Player p, ItemStack book) {
|
||||
CustomBookOpenEvent event = new CustomBookOpenEvent(p, book, false);
|
||||
//Call the CustomBookOpenEvent
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
//Check if it's cancelled
|
||||
if(event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Close inventory currently
|
||||
p.closeInventory();
|
||||
//Store the previous item
|
||||
ItemStack hand = p.getItemInHand();
|
||||
p.setItemInHand(event.getBook());
|
||||
|
||||
//Opening the GUI
|
||||
BookReflection.openBook(p, event.getBook(), event.getHand() == CustomBookOpenEvent.Hand.OFF_HAND);
|
||||
|
||||
//Returning whatever was on hand.
|
||||
p.setItemInHand(hand);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a book GUI to the player, Bypass the {@link CustomBookOpenEvent}
|
||||
* @param p the player
|
||||
* @param book the book to be opened
|
||||
*/
|
||||
public static void forceOpen(Player p, ItemStack book) {
|
||||
//Close inventory currently
|
||||
p.closeInventory();
|
||||
//Store the previous item
|
||||
ItemStack hand = p.getItemInHand();
|
||||
p.setItemInHand(book);
|
||||
|
||||
//Opening the GUI
|
||||
BookReflection.openBook(p, book, false);
|
||||
|
||||
//Returning whatever was on hand.
|
||||
p.setItemInHand(hand);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BookBuilder instance with a written book as the Itemstack's type
|
||||
* @return
|
||||
*/
|
||||
public static BookBuilder writtenBook() {
|
||||
return new BookBuilder(new ItemStack(Material.WRITTEN_BOOK));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BookBuilder instance with a written book as the Itemstack's type
|
||||
* @return
|
||||
*/
|
||||
public static BookBuilder writtenBook(String title, String author) {
|
||||
return new BookBuilder(new ItemStack(Material.WRITTEN_BOOK), title, author);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,324 @@
|
||||
package me.skymc.taboolib.bookformatter;
|
||||
|
||||
import com.ilummc.tlib.bungee.api.chat.BaseComponent;
|
||||
import com.ilummc.tlib.bungee.api.chat.TextComponent;
|
||||
import com.ilummc.tlib.bungee.chat.ComponentSerializer;
|
||||
import com.ilummc.tlib.logger.TLogger;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.BookMeta;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* The NMS helper for all the Book-API
|
||||
*/
|
||||
@SuppressWarnings({"ALL", "AliControlFlowStatementWithoutBraces"})
|
||||
public final class BookReflection {
|
||||
|
||||
private static final String version;
|
||||
private static final boolean doubleHands;
|
||||
|
||||
private static final Class<?> craftMetaBookClass;
|
||||
private static final Field craftMetaBookField;
|
||||
private static final Method chatSerializerA;
|
||||
|
||||
private static final Method craftPlayerGetHandle;
|
||||
|
||||
/*
|
||||
This method takes an enum that represents the player's hand only in versions >= 1.9
|
||||
In the other versions it only takes the nms item
|
||||
*/
|
||||
private static final Method entityPlayerOpenBook;
|
||||
|
||||
// only version >= 1.9
|
||||
private static final Object[] hands;
|
||||
|
||||
//Older versions
|
||||
/*private static final Field entityHumanPlayerConnection;
|
||||
private static final Method playerConnectionSendPacket;
|
||||
|
||||
private static final Constructor<?> packetPlayOutCustomPayloadConstructor;
|
||||
private static final Constructor<?> packetDataSerializerConstructor;*/
|
||||
|
||||
private static final Method nmsItemStackSave;
|
||||
private static final Constructor<?> nbtTagCompoundConstructor;
|
||||
|
||||
private static final Method craftItemStackAsNMSCopy;
|
||||
|
||||
static {
|
||||
version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
|
||||
final int major, minor;
|
||||
Pattern pattern = Pattern.compile("v([0-9]+)_([0-9]+)");
|
||||
Matcher m = pattern.matcher(version);
|
||||
if (m.find()) {
|
||||
major = Integer.parseInt(m.group(1));
|
||||
minor = Integer.parseInt(m.group(2));
|
||||
} else {
|
||||
throw new IllegalStateException("Cannot parse version \"" + version + "\", make sure it follows \"v<major>_<minor>...\"");
|
||||
}
|
||||
doubleHands = major <= 1 && minor >= 9;
|
||||
try {
|
||||
craftMetaBookClass = getCraftClass("inventory.CraftMetaBook");
|
||||
craftMetaBookField = craftMetaBookClass.getDeclaredField("pages");
|
||||
craftMetaBookField.setAccessible(true);
|
||||
Class<?> chatSerializer = getNmsClass("IChatBaseComponent$ChatSerializer", false);
|
||||
//noinspection AliControlFlowStatementWithoutBraces
|
||||
if (chatSerializer == null) {
|
||||
chatSerializer = getNmsClass("ChatSerializer");
|
||||
}
|
||||
|
||||
chatSerializerA = chatSerializer.getDeclaredMethod("a", String.class);
|
||||
|
||||
final Class<?> craftPlayerClass = getCraftClass("entity.CraftPlayer");
|
||||
craftPlayerGetHandle = craftPlayerClass.getMethod("getHandle");
|
||||
|
||||
final Class<?> entityPlayerClass = getNmsClass("EntityPlayer");
|
||||
final Class<?> itemStackClass = getNmsClass("ItemStack");
|
||||
if (doubleHands) {
|
||||
final Class<?> enumHandClass = getNmsClass("EnumHand");
|
||||
entityPlayerOpenBook = entityPlayerClass.getMethod("a", itemStackClass, enumHandClass);
|
||||
hands = enumHandClass.getEnumConstants();
|
||||
} else {
|
||||
entityPlayerOpenBook = entityPlayerClass.getMethod("openBook", itemStackClass);
|
||||
hands = null;
|
||||
}
|
||||
//Older versions
|
||||
/*entityHumanPlayerConnection = entityPlayerClass.getField("playerConnection");
|
||||
final Class<?> playerConnectionClass = getNmsClass("PlayerConnection");
|
||||
playerConnectionSendPacket = playerConnectionClass.getMethod("sendPacket", getNmsClass("Packet"));
|
||||
|
||||
final Class<?> packetDataSerializerClasss = getNmsClass("PacketDataSerializer");
|
||||
packetPlayOutCustomPayloadConstructor = getNmsClass("PacketPlayOutCustomPayload").getConstructor(String.class, packetDataSerializerClasss);
|
||||
packetDataSerializerConstructor = packetDataSerializerClasss.getConstructor(ByteBuf.class);*/
|
||||
|
||||
final Class<?> craftItemStackClass = getCraftClass("inventory.CraftItemStack");
|
||||
craftItemStackAsNMSCopy = craftItemStackClass.getMethod("asNMSCopy", ItemStack.class);
|
||||
Class<?> nmsItemStackClazz = getNmsClass("ItemStack");
|
||||
Class<?> nbtTagCompoundClazz = getNmsClass("NBTTagCompound");
|
||||
nmsItemStackSave = nmsItemStackClazz.getMethod("save", nbtTagCompoundClazz);
|
||||
nbtTagCompoundConstructor = nbtTagCompoundClazz.getConstructor();
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Cannot initiate reflections for " + version, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the pages of the book to the components json equivalent
|
||||
*
|
||||
* @param meta the book meta to change
|
||||
* @param components the pages of the book
|
||||
*/
|
||||
public static void setPages(BookMeta meta, BaseComponent[]... components) {
|
||||
List<Object> pages = null;
|
||||
try {
|
||||
pages = (List<Object>) craftMetaBookField.get(meta);
|
||||
} catch (Exception e) {
|
||||
TLogger.getGlobalLogger().error("Error while executing reflections, failed to get bookmeta (version: " + BookReflection.version + ")");
|
||||
return;
|
||||
}
|
||||
pages.clear();
|
||||
for (BaseComponent[] c : components) {
|
||||
try {
|
||||
pages.add(chatSerializerA.invoke(null, ComponentSerializer.toString(c)));
|
||||
} catch (Exception e) {
|
||||
TLogger.getGlobalLogger().error("Error while executing reflections, submit to developers the following log (version: " + BookReflection.version + ")");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the pages of the book to the components json equivalent
|
||||
*
|
||||
* @param meta the book meta to change
|
||||
* @param components the pages of the book
|
||||
*/
|
||||
public static void addPages(BookMeta meta, BaseComponent[]... components) {
|
||||
List<Object> pages = null;
|
||||
try {
|
||||
pages = (List<Object>) craftMetaBookField.get(meta);
|
||||
} catch (Exception e) {
|
||||
TLogger.getGlobalLogger().error("Error while executing reflections, failed to get bookmeta (version: " + BookReflection.version + ")");
|
||||
return;
|
||||
}
|
||||
for (BaseComponent[] c : components) {
|
||||
try {
|
||||
pages.add(chatSerializerA.invoke(null, ComponentSerializer.toString(c)));
|
||||
} catch (Exception e) {
|
||||
TLogger.getGlobalLogger().error("Error while executing reflections, submit to developers the following log (version: " + BookReflection.version + ")");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the book to a player (the player needs to have the book in one of his hands)
|
||||
*
|
||||
* @param player the player
|
||||
* @param book the book to open
|
||||
* @param offHand false if the book is in the right hand, true otherwise
|
||||
*/
|
||||
public static void openBook(Player player, ItemStack book, boolean offHand) {
|
||||
//nms(player).openBook(nms(player), nms(book), hand);
|
||||
try {
|
||||
//Older versions:
|
||||
/*playerConnectionSendPacket.invoke(
|
||||
entityHumanPlayerConnection.get(toNms(player)),
|
||||
createBookOpenPacket()
|
||||
);*/
|
||||
if (doubleHands) {
|
||||
entityPlayerOpenBook.invoke(
|
||||
toNms(player),
|
||||
nmsCopy(book),
|
||||
hands[offHand ? 1 : 0]
|
||||
);
|
||||
} else {
|
||||
entityPlayerOpenBook.invoke(
|
||||
toNms(player),
|
||||
nmsCopy(book)
|
||||
);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new UnsupportedVersionException(e);
|
||||
}
|
||||
}
|
||||
|
||||
//Older versions
|
||||
/*public static Object createBookOpenPacket() {
|
||||
//new PacketPlayOutCustomPayload("MC|BOpen", new PacketDataSerializer(Unpooled.buffer())));
|
||||
try {
|
||||
return packetPlayOutCustomPayloadConstructor.newInstance(
|
||||
"MC|BOpen",
|
||||
packetDataSerializerConstructor.newInstance(Unpooled.buffer())
|
||||
);
|
||||
} catch (Exception e) {
|
||||
throw new UnsupportedVersionException(e);
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Translates an ItemStack to his Chat-Component equivalent
|
||||
*
|
||||
* @param item the item to be converted
|
||||
* @return a Chat-Component equivalent of the parameter
|
||||
*/
|
||||
public static BaseComponent[] itemToComponents(ItemStack item) {
|
||||
return jsonToComponents(itemToJson(item));
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a json string to his Chat-Component equivalent
|
||||
*
|
||||
* @param json the json string to be converted
|
||||
* @return a Chat-Component equivalent of the parameter
|
||||
*/
|
||||
public static BaseComponent[] jsonToComponents(String json) {
|
||||
return new BaseComponent[]{new TextComponent(json)};
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates an ItemStack to his json equivalent
|
||||
*
|
||||
* @param item the item to be converted
|
||||
* @return a json equivalent of the parameter
|
||||
*/
|
||||
private static String itemToJson(ItemStack item) {
|
||||
try {
|
||||
//net.minecraft.server.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
|
||||
Object nmsItemStack = nmsCopy(item);
|
||||
|
||||
//net.minecraft.server.NBTTagCompound compound = new NBTTagCompound();
|
||||
//compound = nmsItemStack.save(compound);
|
||||
Object emptyTag = nbtTagCompoundConstructor.newInstance();
|
||||
Object json = nmsItemStackSave.invoke(nmsItemStack, emptyTag);
|
||||
return json.toString();
|
||||
} catch (Exception e) {
|
||||
throw new UnsupportedVersionException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the EntityPlayer handled by the argument
|
||||
*
|
||||
* @param player the Player handler
|
||||
* @return the handled class
|
||||
* @throws InvocationTargetException when some problems are found with the reflection
|
||||
* @throws IllegalAccessException when some problems are found with the reflection
|
||||
*/
|
||||
public static Object toNms(Player player) throws InvocationTargetException, IllegalAccessException {
|
||||
return craftPlayerGetHandle.invoke(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a NMS copy of the parameter
|
||||
*
|
||||
* @param item the ItemStack to be nms-copied
|
||||
* @return a NMS-ItemStack that is the equivalent of the one passed as argument
|
||||
* @throws InvocationTargetException when some problems are found with the reflection
|
||||
* @throws IllegalAccessException when some problems are found with the reflection
|
||||
*/
|
||||
public static Object nmsCopy(ItemStack item) throws InvocationTargetException, IllegalAccessException {
|
||||
return craftItemStackAsNMSCopy.invoke(null, item);
|
||||
}
|
||||
|
||||
@SuppressWarnings("AliControlFlowStatementWithoutBraces")
|
||||
public static Class<?> getNmsClass(String className, boolean log) {
|
||||
try {
|
||||
return Class.forName("net.minecraft.server." + version + "." + className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
//noinspection AliControlFlowStatementWithoutBraces
|
||||
if (log) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Class<?> getCraftClass(String path) {
|
||||
try {
|
||||
return Class.forName("org.bukkit.craftbukkit." + version + "." + path);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> getNmsClass(String className) {
|
||||
return getNmsClass(className, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* An error thrown when this NMS-helper class doesn't support the running MC version
|
||||
*/
|
||||
public static class UnsupportedVersionException extends RuntimeException {
|
||||
/**
|
||||
* serialVersionUID
|
||||
*/
|
||||
private static final long serialVersionUID = 6835583513394319946L;
|
||||
|
||||
/**
|
||||
* The current running version
|
||||
*/
|
||||
private final String version = BookReflection.version;
|
||||
|
||||
public UnsupportedVersionException(Exception e) {
|
||||
super("Error while executing reflections, submit to developers the following log (version: " + BookReflection.version + ")", e);
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package me.skymc.taboolib.bookformatter.action;
|
||||
|
||||
import com.ilummc.tlib.bungee.api.chat.ClickEvent;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018-03-08 22:38:04
|
||||
*/
|
||||
public interface ClickAction {
|
||||
|
||||
/**
|
||||
* Creates a command action: when the player clicks, the command passed as parameter gets executed with the clicker as sender
|
||||
*
|
||||
* @param command the command to be executed
|
||||
* @return a new ClickAction
|
||||
*/
|
||||
static ClickAction runCommand(String command) {
|
||||
return new SimpleClickAction(ClickEvent.Action.RUN_COMMAND, command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a suggest_command action: when the player clicks, the book closes and the chat opens with the parameter written into it
|
||||
*
|
||||
* @param command the command to be suggested
|
||||
* @return a new ClickAction
|
||||
*/
|
||||
static ClickAction suggestCommand(String command) {
|
||||
return new SimpleClickAction(ClickEvent.Action.SUGGEST_COMMAND, command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a open_utl action: when the player clicks the url passed as argument will open in the browser
|
||||
*
|
||||
* @param url the url to be opened
|
||||
* @return a new ClickAction
|
||||
*/
|
||||
static ClickAction openUrl(String url) {
|
||||
if (url.startsWith("http://") || url.startsWith("https://")) {
|
||||
return new SimpleClickAction(ClickEvent.Action.OPEN_URL, url);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid url: \"" + url + "\", it should start with http:// or https://");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a change_page action: when the player clicks the book page will be set at the value passed as argument
|
||||
*
|
||||
* @param page the new page
|
||||
* @return a new ClickAction
|
||||
*/
|
||||
static ClickAction changePage(int page) {
|
||||
return new SimpleClickAction(ClickEvent.Action.CHANGE_PAGE, Integer.toString(page));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Chat-Component action
|
||||
*
|
||||
* @return the Chat-Component action
|
||||
*/
|
||||
ClickEvent.Action action();
|
||||
|
||||
/**
|
||||
* The value paired to the action
|
||||
*
|
||||
* @return the value paired tot the action
|
||||
*/
|
||||
String value();
|
||||
|
||||
class SimpleClickAction implements ClickAction {
|
||||
|
||||
private final ClickEvent.Action action;
|
||||
private final String value;
|
||||
|
||||
public SimpleClickAction(ClickEvent.Action action, String value) {
|
||||
this.action = action;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public ClickEvent.Action getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClickEvent.Action action() {
|
||||
return action;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String value() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package me.skymc.taboolib.bookformatter.action;
|
||||
|
||||
import com.ilummc.tlib.bungee.api.chat.BaseComponent;
|
||||
import com.ilummc.tlib.bungee.api.chat.HoverEvent;
|
||||
import com.ilummc.tlib.bungee.api.chat.TextComponent;
|
||||
import me.skymc.taboolib.bookformatter.BookAchievement;
|
||||
import me.skymc.taboolib.bookformatter.BookReflection;
|
||||
import org.bukkit.Achievement;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018-03-08 22:38:51
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public interface HoverAction {
|
||||
|
||||
/**
|
||||
* Creates a show_text action: when the component is hovered the text used as parameter will be displayed
|
||||
*
|
||||
* @param text the text to display
|
||||
* @return a new HoverAction instance
|
||||
*/
|
||||
static HoverAction showText(BaseComponent... text) {
|
||||
return new SimpleHoverAction(HoverEvent.Action.SHOW_TEXT, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a show_text action: when the component is hovered the text used as parameter will be displayed
|
||||
*
|
||||
* @param text the text to display
|
||||
* @return a new HoverAction instance
|
||||
*/
|
||||
static HoverAction showText(String text) {
|
||||
return new SimpleHoverAction(HoverEvent.Action.SHOW_TEXT, new TextComponent(text));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a show_item action: when the component is hovered some item information will be displayed
|
||||
*
|
||||
* @param item a component array representing item to display
|
||||
* @return a new HoverAction instance
|
||||
*/
|
||||
static HoverAction showItem(BaseComponent... item) {
|
||||
return new SimpleHoverAction(HoverEvent.Action.SHOW_ITEM, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a show_item action: when the component is hovered some item information will be displayed
|
||||
*
|
||||
* @param item the item to display
|
||||
* @return a new HoverAction instance
|
||||
*/
|
||||
static HoverAction showItem(ItemStack item) {
|
||||
return new SimpleHoverAction(HoverEvent.Action.SHOW_ITEM, BookReflection.itemToComponents(item));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a show_entity action: when the component is hovered some entity information will be displayed
|
||||
*
|
||||
* @param entity a component array representing the item to display
|
||||
* @return a new HoverAction instance
|
||||
*/
|
||||
static HoverAction showEntity(BaseComponent... entity) {
|
||||
return new SimpleHoverAction(HoverEvent.Action.SHOW_ENTITY, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a show_entity action: when the component is hovered some entity information will be displayed
|
||||
*
|
||||
* @param uuid the entity's UniqueId
|
||||
* @param type the entity's type
|
||||
* @param name the entity's name
|
||||
* @return a new HoverAction instance
|
||||
*/
|
||||
static HoverAction showEntity(UUID uuid, String type, String name) {
|
||||
return new SimpleHoverAction(HoverEvent.Action.SHOW_ENTITY,
|
||||
BookReflection.jsonToComponents(
|
||||
"{id:\"" + uuid + "\",type:\"" + type + "\"name:\"" + name + "\"}"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a show_entity action: when the component is hovered some entity information will be displayed
|
||||
*
|
||||
* @param entity the item to display
|
||||
* @return a new HoverAction instance
|
||||
*/
|
||||
static HoverAction showEntity(Entity entity) {
|
||||
return showEntity(entity.getUniqueId(), entity.getType().getName(), entity.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a show_achievement action: when the component is hovered the achievement information will be displayed
|
||||
*
|
||||
* @param achievementId the id of the achievement to display
|
||||
* @return a new HoverAction instance
|
||||
*/
|
||||
static HoverAction showAchievement(String achievementId) {
|
||||
return new SimpleHoverAction(HoverEvent.Action.SHOW_ACHIEVEMENT, new TextComponent("achievement." + achievementId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a show_achievement action: when the component is hovered the achievement information will be displayed
|
||||
*
|
||||
* @param achievement the achievement to display
|
||||
* @return a new HoverAction instance
|
||||
*/
|
||||
static HoverAction showAchievement(Achievement achievement) {
|
||||
return showAchievement(BookAchievement.toId(achievement));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a show_achievement action: when the component is hovered the statistic information will be displayed
|
||||
*
|
||||
* @param statisticId the id of the statistic to display
|
||||
* @return a new HoverAction instance
|
||||
*/
|
||||
static HoverAction showStatistic(String statisticId) {
|
||||
return new SimpleHoverAction(HoverEvent.Action.SHOW_ACHIEVEMENT, new TextComponent("statistic." + statisticId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Chat-Component action
|
||||
*
|
||||
* @return the Chat-Component action
|
||||
*/
|
||||
HoverEvent.Action action();
|
||||
|
||||
/**
|
||||
* The value paired to the action
|
||||
*
|
||||
* @return the value paired tot the action
|
||||
*/
|
||||
BaseComponent[] value();
|
||||
|
||||
class SimpleHoverAction implements HoverAction {
|
||||
private final HoverEvent.Action action;
|
||||
private final BaseComponent[] value;
|
||||
|
||||
public SimpleHoverAction(HoverEvent.Action action, BaseComponent... value) {
|
||||
this.action = action;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public HoverEvent.Action getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public BaseComponent[] getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HoverEvent.Action action() {
|
||||
return action;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseComponent[] value() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package me.skymc.taboolib.bookformatter.builder;
|
||||
|
||||
import com.ilummc.tlib.bungee.api.chat.BaseComponent;
|
||||
import me.skymc.taboolib.bookformatter.BookReflection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.BookMeta;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018-03-08 22:36:14
|
||||
*/
|
||||
public class BookBuilder {
|
||||
|
||||
private final BookMeta meta;
|
||||
private final ItemStack book;
|
||||
|
||||
/**
|
||||
* Creates a new instance of the BookBuilder from an ItemStack representing the book item
|
||||
* @param book the book's ItemStack
|
||||
*/
|
||||
public BookBuilder(ItemStack book) {
|
||||
this.book = book;
|
||||
this.meta = (BookMeta)book.getItemMeta();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of the BookBuilder from an ItemStack representing the book item
|
||||
* @param book the book's ItemStack
|
||||
*/
|
||||
public BookBuilder(ItemStack book, String title, String author) {
|
||||
this.book = book;
|
||||
this.meta = (BookMeta)book.getItemMeta();
|
||||
this.meta.setTitle(title);
|
||||
this.meta.setAuthor(author);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title of the book
|
||||
* @param title the title of the book
|
||||
* @return the BookBuilder's calling instance
|
||||
*/
|
||||
public BookBuilder title(String title) {
|
||||
meta.setTitle(title);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the author of the book
|
||||
* @param author the author of the book
|
||||
* @return the BookBuilder's calling instance
|
||||
*/
|
||||
public BookBuilder author(String author) {
|
||||
meta.setAuthor(author);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the generation of the book
|
||||
* Only works from MC 1.10
|
||||
* @param generation the Book generation
|
||||
* @return the BookBuilder calling instance
|
||||
*/
|
||||
public BookBuilder generation(BookMeta.Generation generation) {
|
||||
meta.setGeneration(generation);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pages of the book without worrying about json or interactivity
|
||||
* @param pages text-based pages
|
||||
* @return the BookBuilder's calling instance
|
||||
*/
|
||||
public BookBuilder pagesRaw(String... pages) {
|
||||
meta.setPages(pages);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pages of the book without worrying about json or interactivity
|
||||
* @param pages text-based pages
|
||||
* @return the BookBuilder's calling instance
|
||||
*/
|
||||
public BookBuilder pagesRaw(List<String> pages) {
|
||||
meta.setPages(pages);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pages of the book
|
||||
* @param pages the pages of the book
|
||||
* @return the BookBuilder's calling instance
|
||||
*/
|
||||
public BookBuilder pages(BaseComponent[]... pages) {
|
||||
BookReflection.setPages(meta, pages);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pages of the book
|
||||
* @param pages the pages of the book
|
||||
* @return the BookBuilder's calling instance
|
||||
*/
|
||||
public BookBuilder pages(List<BaseComponent[]> pages) {
|
||||
BookReflection.setPages(meta, pages.toArray(new BaseComponent[0][]));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the pages of the book
|
||||
* @param pages the pages of the book
|
||||
* @return the BookBuilder's calling instance
|
||||
*/
|
||||
public BookBuilder addPages(BaseComponent[]... pages) {
|
||||
BookReflection.addPages(meta, pages);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the book
|
||||
* @return the built book
|
||||
*/
|
||||
public ItemStack build() {
|
||||
book.setItemMeta(meta);
|
||||
return book;
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Getter and Setter
|
||||
//
|
||||
// *********************************
|
||||
|
||||
|
||||
public BookMeta getMeta() {
|
||||
return meta;
|
||||
}
|
||||
|
||||
public ItemStack getBook() {
|
||||
return book;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package me.skymc.taboolib.bookformatter.builder;
|
||||
|
||||
import com.ilummc.tlib.bungee.api.chat.*;
|
||||
import me.skymc.taboolib.string.ArrayUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018-03-08 22:36:58
|
||||
*/
|
||||
public class PageBuilder {
|
||||
|
||||
private BaseComponent[] text = TextComponent.fromLegacyText("");
|
||||
|
||||
/**
|
||||
* Adds a simple black-colored text to the page
|
||||
* @param text the text to add
|
||||
* @return the PageBuilder's calling instance
|
||||
*/
|
||||
public PageBuilder add(String text) {
|
||||
Arrays.stream(TextComponent.fromLegacyText(text)).forEach(component -> this.text = ArrayUtils.arrayAppend(this.text, component));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a component to the page
|
||||
* @param component the component to add
|
||||
* @return the PageBuilder's calling instance
|
||||
*/
|
||||
public PageBuilder add(BaseComponent component) {
|
||||
this.text = ArrayUtils.arrayAppend(this.text, component);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds one or more components to the page
|
||||
* @param components the components to add
|
||||
* @return the PageBuilder's calling instance
|
||||
*/
|
||||
public PageBuilder add(BaseComponent... components) {
|
||||
Arrays.stream(components).forEach(component -> this.text = ArrayUtils.arrayAppend(this.text, component));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a newline to the page (equivalent of adding \n to the previous component)
|
||||
* @return the PageBuilder's calling instance
|
||||
*/
|
||||
public PageBuilder newLine() {
|
||||
return add("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Another way of newLine(), better resolution (equivalent of adding \n to the previous component)
|
||||
* @return the PageBuilder's calling instance
|
||||
*/
|
||||
public PageBuilder endLine() {
|
||||
return newLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the page
|
||||
* @return an array of BaseComponents representing the page
|
||||
*/
|
||||
public BaseComponent[] build() {
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new PageBuilder instance wih the parameter as the initial text
|
||||
* @param text the initial text of the page
|
||||
* @return a new PageBuilder with the parameter as the initial text
|
||||
*/
|
||||
public static PageBuilder of(String text) {
|
||||
return new PageBuilder().add(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new PageBuilder instance wih the parameter as the initial component
|
||||
* @param text the initial component of the page
|
||||
* @return a new PageBuilder with the parameter as the initial component
|
||||
*/
|
||||
public static PageBuilder of(BaseComponent text) {
|
||||
return new PageBuilder().add(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new PageBuilder instance wih the parameter as the initial components
|
||||
* @param text the initial components of the page
|
||||
* @return a new PageBuilder with the parameter as the initial components
|
||||
*/
|
||||
public static PageBuilder of(BaseComponent... text) {
|
||||
PageBuilder res = new PageBuilder();
|
||||
for(BaseComponent b : text) {
|
||||
res.add(b);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package me.skymc.taboolib.bookformatter.builder;
|
||||
|
||||
import com.ilummc.tlib.bungee.api.chat.*;
|
||||
import me.skymc.taboolib.bookformatter.action.ClickAction;
|
||||
import me.skymc.taboolib.bookformatter.action.HoverAction;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018-03-08 22:37:27
|
||||
*/
|
||||
public class TextBuilder {
|
||||
|
||||
private String text = "";
|
||||
private ClickAction onClick = null;
|
||||
private HoverAction onHover = null;
|
||||
|
||||
public TextBuilder() {
|
||||
}
|
||||
|
||||
public TextBuilder(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new TextBuilder with the parameter as his initial text
|
||||
*
|
||||
* @param text initial text
|
||||
* @return a new TextBuilder with the parameter as his initial text
|
||||
*/
|
||||
public static TextBuilder of(String text) {
|
||||
return new TextBuilder(text);
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public ClickAction getClick() {
|
||||
return onClick;
|
||||
}
|
||||
|
||||
public HoverAction getHover() {
|
||||
return onHover;
|
||||
}
|
||||
|
||||
public void text(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public void onClick(ClickAction onClick) {
|
||||
this.onClick = onClick;
|
||||
}
|
||||
|
||||
public void onHover(HoverAction onHover) {
|
||||
this.onHover = onHover;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the component representing the built text
|
||||
*
|
||||
* @return the component representing the built text
|
||||
*/
|
||||
public BaseComponent build() {
|
||||
TextComponent res = new TextComponent(text);
|
||||
if (onClick != null) {
|
||||
res.setClickEvent(new ClickEvent(onClick.action(), onClick.value()));
|
||||
}
|
||||
if (onHover != null) {
|
||||
res.setHoverEvent(new HoverEvent(onHover.action(), onHover.value()));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
663
src/main/scala/me/skymc/taboolib/bstats/Metrics.java
Normal file
663
src/main/scala/me/skymc/taboolib/bstats/Metrics.java
Normal file
@@ -0,0 +1,663 @@
|
||||
package me.skymc.taboolib.bstats;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
/**
|
||||
* bStats collects some data for plugin authors.
|
||||
* Check out https://bStats.org/ to learn more about bStats!
|
||||
*
|
||||
* @author Bastian
|
||||
*/
|
||||
public class Metrics {
|
||||
|
||||
// The version of this bStats class
|
||||
public static final int B_STATS_VERSION = 1;
|
||||
// The url to which the data is sent
|
||||
private static final String URL = "https://bStats.org/submitData/bukkit";
|
||||
// Should failed requests be logged?
|
||||
private static boolean logFailedRequests;
|
||||
// The uuid of the server
|
||||
private static String serverUUID;
|
||||
|
||||
static {
|
||||
// You can use the property to disable the check in your test environment
|
||||
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
|
||||
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
|
||||
final String defaultPackage = new String(
|
||||
new byte[] {'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
|
||||
final String examplePackage = new String(new byte[] {'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
||||
// We want to make sure nobody just copy & pastes the example and use the wrong package names
|
||||
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) {
|
||||
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The plugin
|
||||
private final JavaPlugin plugin;
|
||||
|
||||
// A list with all custom charts
|
||||
private final List<CustomChart> charts = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param plugin The plugin which stats should be submitted.
|
||||
*/
|
||||
public Metrics(JavaPlugin plugin) {
|
||||
if (plugin == null) {
|
||||
throw new IllegalArgumentException("Plugin cannot be null!");
|
||||
}
|
||||
this.plugin = plugin;
|
||||
|
||||
// Get the config file
|
||||
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
||||
File configFile = new File(bStatsFolder, "config.yml");
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
|
||||
|
||||
// Check if the config file exists
|
||||
if (!config.isSet("serverUuid")) {
|
||||
|
||||
// Add default values
|
||||
config.addDefault("enabled", true);
|
||||
// Every server gets it's unique random id.
|
||||
config.addDefault("serverUuid", UUID.randomUUID().toString());
|
||||
// Should failed request be logged?
|
||||
config.addDefault("logFailedRequests", false);
|
||||
|
||||
// Inform the server owners about bStats
|
||||
config.options().header(
|
||||
"bStats collects some data for plugin authors like how many servers are using their plugins.\n" +
|
||||
"To honor their work, you should not disable it.\n" +
|
||||
"This has nearly no effect on the server performance!\n" +
|
||||
"Check out https://bStats.org/ to learn more :)"
|
||||
).copyDefaults(true);
|
||||
try {
|
||||
config.save(configFile);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
// Load the data
|
||||
serverUUID = config.getString("serverUuid");
|
||||
logFailedRequests = config.getBoolean("logFailedRequests", false);
|
||||
if (config.getBoolean("enabled", true)) {
|
||||
boolean found = false;
|
||||
// Search for all other bStats Metrics classes to see if we are the first one
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
found = true; // We aren't the first
|
||||
break;
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
}
|
||||
}
|
||||
// Register our service
|
||||
Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
|
||||
if (!found) {
|
||||
// We are the first!
|
||||
startSubmitting();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the data to the bStats server.
|
||||
*
|
||||
* @param data The data to send.
|
||||
* @throws Exception If the request failed.
|
||||
*/
|
||||
private static void sendData(JSONObject data) throws Exception {
|
||||
if (data == null) {
|
||||
throw new IllegalArgumentException("Data cannot be null!");
|
||||
}
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
throw new IllegalAccessException("This method must not be called from the main thread!");
|
||||
}
|
||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
|
||||
|
||||
// Compress the data to save bandwidth
|
||||
byte[] compressedData = compress(data.toString());
|
||||
|
||||
// Add headers
|
||||
connection.setRequestMethod("POST");
|
||||
connection.addRequestProperty("Accept", "application/json");
|
||||
connection.addRequestProperty("Connection", "close");
|
||||
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
|
||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
|
||||
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
|
||||
|
||||
// Send data
|
||||
connection.setDoOutput(true);
|
||||
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
|
||||
outputStream.write(compressedData);
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
||||
connection.getInputStream().close(); // We don't care about the response - Just send our data :)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gzips the given String.
|
||||
*
|
||||
* @param str The string to gzip.
|
||||
* @return The gzipped String.
|
||||
* @throws IOException If the compression failed.
|
||||
*/
|
||||
private static byte[] compress(final String str) throws IOException {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
|
||||
gzip.write(str.getBytes("UTF-8"));
|
||||
gzip.close();
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom chart.
|
||||
*
|
||||
* @param chart The chart to add.
|
||||
*/
|
||||
public void addCustomChart(CustomChart chart) {
|
||||
if (chart == null) {
|
||||
throw new IllegalArgumentException("Chart cannot be null!");
|
||||
}
|
||||
charts.add(chart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the Scheduler which submits our data every 30 minutes.
|
||||
*/
|
||||
private void startSubmitting() {
|
||||
final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags
|
||||
timer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!plugin.isEnabled()) { // Plugin was disabled
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
|
||||
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
|
||||
Bukkit.getScheduler().runTask(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
submitData();
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 1000 * 60 * 5, 1000 * 60 * 30);
|
||||
// Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start
|
||||
// WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
|
||||
// WARNING: Just don't do it!
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the plugin specific data.
|
||||
* This method is called using Reflection.
|
||||
*
|
||||
* @return The plugin specific data.
|
||||
*/
|
||||
public JSONObject getPluginData() {
|
||||
JSONObject data = new JSONObject();
|
||||
|
||||
String pluginName = plugin.getDescription().getName();
|
||||
String pluginVersion = plugin.getDescription().getVersion();
|
||||
|
||||
data.put("pluginName", pluginName); // Append the name of the plugin
|
||||
data.put("pluginVersion", pluginVersion); // Append the version of the plugin
|
||||
JSONArray customCharts = new JSONArray();
|
||||
for (CustomChart customChart : charts) {
|
||||
// Add the data of the custom charts
|
||||
JSONObject chart = customChart.getRequestJsonObject();
|
||||
if (chart == null) { // If the chart is null, we skip it
|
||||
continue;
|
||||
}
|
||||
customCharts.add(chart);
|
||||
}
|
||||
data.put("customCharts", customCharts);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the server specific data.
|
||||
*
|
||||
* @return The server specific data.
|
||||
*/
|
||||
private JSONObject getServerData() {
|
||||
// Minecraft specific data
|
||||
int playerAmount;
|
||||
try {
|
||||
// Around MC 1.8 the return type was changed to a collection from an array,
|
||||
// This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
|
||||
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
|
||||
playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class)
|
||||
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
|
||||
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
|
||||
} catch (Exception e) {
|
||||
playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed
|
||||
}
|
||||
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
|
||||
String bukkitVersion = org.bukkit.Bukkit.getVersion();
|
||||
bukkitVersion = bukkitVersion.substring(bukkitVersion.indexOf("MC: ") + 4, bukkitVersion.length() - 1);
|
||||
|
||||
// OS/Java specific data
|
||||
String javaVersion = System.getProperty("java.version");
|
||||
String osName = System.getProperty("os.name");
|
||||
String osArch = System.getProperty("os.arch");
|
||||
String osVersion = System.getProperty("os.version");
|
||||
int coreCount = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
JSONObject data = new JSONObject();
|
||||
|
||||
data.put("serverUUID", serverUUID);
|
||||
|
||||
data.put("playerAmount", playerAmount);
|
||||
data.put("onlineMode", onlineMode);
|
||||
data.put("bukkitVersion", bukkitVersion);
|
||||
|
||||
data.put("javaVersion", javaVersion);
|
||||
data.put("osName", osName);
|
||||
data.put("osArch", osArch);
|
||||
data.put("osVersion", osVersion);
|
||||
data.put("coreCount", coreCount);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the data and sends it afterwards.
|
||||
*/
|
||||
private void submitData() {
|
||||
final JSONObject data = getServerData();
|
||||
|
||||
JSONArray pluginData = new JSONArray();
|
||||
// Search for all other bStats Metrics classes to get their plugin data
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
|
||||
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
|
||||
try {
|
||||
pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider()));
|
||||
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {
|
||||
}
|
||||
}
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
data.put("plugins", pluginData);
|
||||
|
||||
// Create a new thread for the connection to the bStats server
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// Send the data
|
||||
sendData(data);
|
||||
} catch (Exception e) {
|
||||
// Something went wrong! :(
|
||||
if (logFailedRequests) {
|
||||
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom chart.
|
||||
*/
|
||||
public static abstract class CustomChart {
|
||||
|
||||
// The id of the chart
|
||||
final String chartId;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
*/
|
||||
CustomChart(String chartId) {
|
||||
if (chartId == null || chartId.isEmpty()) {
|
||||
throw new IllegalArgumentException("ChartId cannot be null or empty!");
|
||||
}
|
||||
this.chartId = chartId;
|
||||
}
|
||||
|
||||
private JSONObject getRequestJsonObject() {
|
||||
JSONObject chart = new JSONObject();
|
||||
chart.put("chartId", chartId);
|
||||
try {
|
||||
JSONObject data = getChartData();
|
||||
if (data == null) {
|
||||
// If the data is null we don't send the chart.
|
||||
return null;
|
||||
}
|
||||
chart.put("data", data);
|
||||
} catch (Throwable t) {
|
||||
if (logFailedRequests) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return chart;
|
||||
}
|
||||
|
||||
protected abstract JSONObject getChartData() throws Exception;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom simple pie.
|
||||
*/
|
||||
public static class SimplePie extends CustomChart {
|
||||
|
||||
private final Callable<String> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimplePie(String chartId, Callable<String> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
String value = callable.call();
|
||||
if (value == null || value.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("value", value);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom advanced pie.
|
||||
*/
|
||||
public static class AdvancedPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
values.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom drilldown pie.
|
||||
*/
|
||||
public static class DrilldownPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Map<String, Integer>>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Map<String, Integer>> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean reallyAllSkipped = true;
|
||||
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
|
||||
JSONObject value = new JSONObject();
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
|
||||
value.put(valueEntry.getKey(), valueEntry.getValue());
|
||||
allSkipped = false;
|
||||
}
|
||||
if (!allSkipped) {
|
||||
reallyAllSkipped = false;
|
||||
values.put(entryValues.getKey(), value);
|
||||
}
|
||||
}
|
||||
if (reallyAllSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom single line chart.
|
||||
*/
|
||||
public static class SingleLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Integer> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SingleLineChart(String chartId, Callable<Integer> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
int value = callable.call();
|
||||
if (value == 0) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("value", value);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom multi line chart.
|
||||
*/
|
||||
public static class MultiLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
values.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom simple bar chart.
|
||||
*/
|
||||
public static class SimpleBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
JSONArray categoryValues = new JSONArray();
|
||||
categoryValues.add(entry.getValue());
|
||||
values.put(entry.getKey(), categoryValues);
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom advanced bar chart.
|
||||
*/
|
||||
public static class AdvancedBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, int[]>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, int[]> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, int[]> entry : map.entrySet()) {
|
||||
if (entry.getValue().length == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
JSONArray categoryValues = new JSONArray();
|
||||
for (int categoryValue : entry.getValue()) {
|
||||
categoryValues.add(categoryValue);
|
||||
}
|
||||
values.put(entry.getKey(), categoryValues);
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
11
src/main/scala/me/skymc/taboolib/bungee/TabooLibBungee.java
Normal file
11
src/main/scala/me/skymc/taboolib/bungee/TabooLibBungee.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package me.skymc.taboolib.bungee;
|
||||
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-08-09 11:47
|
||||
*/
|
||||
public class TabooLibBungee extends Plugin {
|
||||
|
||||
}
|
||||
58
src/main/scala/me/skymc/taboolib/client/LogClient.java
Normal file
58
src/main/scala/me/skymc/taboolib/client/LogClient.java
Normal file
@@ -0,0 +1,58 @@
|
||||
package me.skymc.taboolib.client;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.BevelBorder;
|
||||
import java.awt.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
@Deprecated
|
||||
public class LogClient extends JFrame {
|
||||
|
||||
/**
|
||||
* DEFAULT VERSION UID
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
private JTextArea textArea = new JTextArea();
|
||||
private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
|
||||
|
||||
public LogClient(String title) {
|
||||
super(title);
|
||||
|
||||
// DEFAULT CLOSE OPERATION
|
||||
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
|
||||
// SETTINGS
|
||||
final JScrollPane scrollPane = new JScrollPane();
|
||||
scrollPane.setBorder(new BevelBorder(BevelBorder.RAISED));
|
||||
scrollPane.setViewportView(textArea);
|
||||
getContentPane().add(scrollPane, BorderLayout.CENTER);
|
||||
|
||||
setSize(700, 500);
|
||||
setVisible(true);
|
||||
|
||||
// CON'T EDIT
|
||||
textArea.setEditable(false);
|
||||
textArea.setFont(new Font("黑体", 0, 18));
|
||||
|
||||
textArea.setBackground(Color.black);
|
||||
textArea.setForeground(Color.LIGHT_GRAY);
|
||||
|
||||
addString(title);
|
||||
addString("");
|
||||
}
|
||||
|
||||
public void addString(String a) {
|
||||
textArea.append(a + '\n');
|
||||
textArea.setSelectionStart(textArea.getText().length());
|
||||
}
|
||||
|
||||
public void info(String a) {
|
||||
textArea.append("[" + sdf.format(System.currentTimeMillis()) + " INFO]: " + a + '\n');
|
||||
textArea.setSelectionStart(textArea.getText().length());
|
||||
}
|
||||
|
||||
public void warn(String a) {
|
||||
textArea.append("[" + sdf.format(System.currentTimeMillis()) + " WARN]: " + a + '\n');
|
||||
textArea.setSelectionStart(textArea.getText().length());
|
||||
}
|
||||
}
|
||||
250
src/main/scala/me/skymc/taboolib/cloud/TCloudCommand.java
Normal file
250
src/main/scala/me/skymc/taboolib/cloud/TCloudCommand.java
Normal file
@@ -0,0 +1,250 @@
|
||||
package me.skymc.taboolib.cloud;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.cloud.expansion.Expansion;
|
||||
import me.skymc.taboolib.cloud.expansion.ExpansionType;
|
||||
import me.skymc.taboolib.commands.internal.BaseMainCommand;
|
||||
import me.skymc.taboolib.commands.internal.BaseSubCommand;
|
||||
import me.skymc.taboolib.commands.internal.TCommand;
|
||||
import me.skymc.taboolib.commands.internal.plugin.TLibLocale;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandArgument;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandRegister;
|
||||
import me.skymc.taboolib.common.util.SimpleIterator;
|
||||
import me.skymc.taboolib.fileutils.FileUtils;
|
||||
import me.skymc.taboolib.plugin.PluginUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.util.NumberConversions;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-30 19:17
|
||||
*/
|
||||
@TCommand(
|
||||
name = "taboolibcloud",
|
||||
permission = "taboolib.admin",
|
||||
aliases = "tcloud"
|
||||
)
|
||||
public class TCloudCommand extends BaseMainCommand {
|
||||
|
||||
@CommandRegister
|
||||
BaseSubCommand refresh = new BaseSubCommand() {
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "refresh";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLibLocale.description("TCLOUD", "REFRESH");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.REFRESH.SUCCESS");
|
||||
TCloudLoader.refresh();
|
||||
}
|
||||
};
|
||||
@CommandRegister(priority = 1)
|
||||
BaseSubCommand status = new BaseSubCommand() {
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "status";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLibLocale.description("TCLOUD", "STATUS");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (!TCloudLoader.isConnected()) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.STATUS.CONNECT-FAILED");
|
||||
} else {
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.STATUS.STATUS", String.valueOf(TCloudLoader.getExpansionInternal().size() + TCloudLoader.getExpansionPlugins().size()), String.valueOf(TCloudLoader.getExpansionInternal().size()), String.valueOf(TCloudLoader.getExpansionPlugins().size()));
|
||||
}
|
||||
}
|
||||
};
|
||||
@CommandRegister(priority = 2)
|
||||
BaseSubCommand info = new BaseSubCommand() {
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "info";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLibLocale.description("TCLOUD", "INFO");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return TLibLocale.arguments("TCLOUD", "INFO", 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
Expansion expansion = TCloudLoader.getExpansion(args[0]);
|
||||
if (expansion == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.INFO.EXPANSION-NOT-FOUND", args[0]);
|
||||
} else {
|
||||
String builder = Arrays.stream(expansion.getAuthor()).map(author -> author + ", ").collect(Collectors.joining());
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.INFO.EXPANSION-INFO", expansion.getName(), builder.substring(0, builder.length() - 2), expansion.getVersion(), expansion.getDescription(), expansion.getLastUpdate(), expansion.getLastUpdateNote());
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.INFO.EXPANSION-INFO-DETAIL.0");
|
||||
Arrays.stream(expansion.getDetail()).forEach(detail -> TLocale.sendTo(sender, "COMMANDS.TCLOUD.INFO.EXPANSION-INFO-DETAIL.1", detail));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 3)
|
||||
BaseSubCommand download = new BaseSubCommand() {
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "download";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLibLocale.description("TCLOUD", "DOWNLOAD");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return TLibLocale.arguments("TCLOUD", "DOWNLOAD", 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
Expansion expansion = TCloudLoader.getExpansion(args[0]);
|
||||
if (expansion == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.DOWNLOAD.EXPANSION-NOT-FOUND", args[0]);
|
||||
} else if (!expansion.canUse()) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.DOWNLOAD.EXPANSION-VERSION", args[0], String.valueOf(expansion.getDependVersion()));
|
||||
} else if (TCloudLoader.isExpansionExists(expansion)) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.DOWNLOAD.EXPANSION-EXISTS", args[0]);
|
||||
} else {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(TabooLib.instance(), () -> {
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.DOWNLOAD.DOWNLOAD-START", args[0], expansion.getLink());
|
||||
FileUtils.download(expansion.getLink(), expansion.getFile());
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.DOWNLOAD.DOWNLOAD-SUCCESS", args[0]);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 4)
|
||||
BaseSubCommand update = new BaseSubCommand() {
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "update";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLibLocale.description("TCLOUD", "UPDATE");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return TLibLocale.arguments("TCLOUD", "UPDATE", 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
Expansion expansion = TCloudLoader.getExpansion(args[0]);
|
||||
if (expansion == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.UPDATE.EXPANSION-NOT-FOUND", args[0]);
|
||||
} else if (!TCloudLoader.isExpansionExists(expansion)) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.UPDATE.EXPANSION-NOT-EXISTS", args[0]);
|
||||
} else if (!expansion.canUpdate()) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.UPDATE.EXPANSION-NO-UPDATE", args[0]);
|
||||
} else if (!expansion.canUse()) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.UPDATE.EXPANSION-VERSION", args[0], String.valueOf(expansion.getDependVersion()));
|
||||
} else {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(TabooLib.instance(), () -> {
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.UPDATE.UPDATE-START", args[0], expansion.getVersion(), expansion.getLink());
|
||||
FileUtils.download(expansion.getLink(), PluginUtils.getPluginFile(expansion.getName()));
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.UPDATE.UPDATE-SUCCESS", args[0]);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 5)
|
||||
BaseSubCommand list = new BaseSubCommand() {
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "list";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLibLocale.description("TCLOUD", "LIST");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[] {
|
||||
TLibLocale.argument("TCLOUD", "LIST", 0),
|
||||
TLibLocale.argument("TCLOUD", "LIST", 1, false)
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
ExpansionType type;
|
||||
switch (args[0].toLowerCase()) {
|
||||
case "plugins":
|
||||
type = ExpansionType.PLUGIN;
|
||||
break;
|
||||
case "internal":
|
||||
type = ExpansionType.INTERNAL;
|
||||
break;
|
||||
default:
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.LIST.INVALID-TYPE.0");
|
||||
return;
|
||||
}
|
||||
Map<String, Expansion> expansions = type == ExpansionType.PLUGIN ? TCloudLoader.getExpansionPlugins() : TCloudLoader.getExpansionInternal();
|
||||
int page = args.length < 2 ? 1 : NumberConversions.toInt(args[1]);
|
||||
int pageMax = (expansions.size() / 5) + ((expansions.size() % 5) == 0 ? 0 : 1);
|
||||
if (page < 1 || page > pageMax) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.LIST.INVALID-TYPE.1");
|
||||
return;
|
||||
}
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.LIST.LIST-HEAD", type.name(), String.valueOf(page), String.valueOf(pageMax));
|
||||
int i = (page - 1) * 5;
|
||||
for (Map.Entry<String, Expansion> entry : new SimpleIterator(expansions).mapIterator((page - 1) * 5, page * 5)) {
|
||||
if (!TCloudLoader.isExpansionExists(entry.getValue())) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.LIST.LIST-EXPANSION.0", String.valueOf(++i), entry.getValue().getName(), Arrays.toString(entry.getValue().getAuthor()));
|
||||
} else if (entry.getValue().canUpdate()) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.LIST.LIST-EXPANSION.1", String.valueOf(++i), entry.getValue().getName(), Arrays.toString(entry.getValue().getAuthor()));
|
||||
} else {
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.LIST.LIST-EXPANSION.2", String.valueOf(++i), entry.getValue().getName(), Arrays.toString(entry.getValue().getAuthor()));
|
||||
}
|
||||
}
|
||||
TLocale.sendTo(sender, "COMMANDS.TCLOUD.LIST.LIST-BOTTOM");
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public String getCommandTitle() {
|
||||
return TLocale.asString("COMMANDS.TCLOUD.COMMAND-TITLE");
|
||||
}
|
||||
}
|
||||
131
src/main/scala/me/skymc/taboolib/cloud/TCloudLoader.java
Normal file
131
src/main/scala/me/skymc/taboolib/cloud/TCloudLoader.java
Normal file
@@ -0,0 +1,131 @@
|
||||
package me.skymc.taboolib.cloud;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.cloud.expansion.Expansion;
|
||||
import me.skymc.taboolib.cloud.expansion.ExpansionType;
|
||||
import me.skymc.taboolib.common.function.TFunction;
|
||||
import me.skymc.taboolib.fileutils.FileUtils;
|
||||
import me.skymc.taboolib.plugin.PluginUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-30 17:30
|
||||
*/
|
||||
@TFunction(enable = "init")
|
||||
public class TCloudLoader {
|
||||
|
||||
private static String url = "https://gitee.com/bkm016/TabooLibCloud/raw/master/cloud.json";
|
||||
private static String latestJsonOrigin;
|
||||
private static JsonObject latestJsonObject;
|
||||
private static Map<String, Expansion> expansionPlugins = Maps.newTreeMap();
|
||||
private static Map<String, Expansion> expansionInternal = Maps.newTreeMap();
|
||||
private static File expansionInternalFolder;
|
||||
|
||||
static void init() {
|
||||
createFolder();
|
||||
refresh();
|
||||
}
|
||||
|
||||
public static void createFolder() {
|
||||
if (!(expansionInternalFolder = new File(TabooLib.instance().getDataFolder(), "TCloud")).exists()) {
|
||||
expansionInternalFolder.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public static void refresh() {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(TabooLib.instance(), () -> {
|
||||
long time = System.currentTimeMillis();
|
||||
latestJsonOrigin = FileUtils.getStringFromURL(url, 1024);
|
||||
if (latestJsonOrigin == null) {
|
||||
if (!TabooLib.isSilent()) {
|
||||
TLocale.Logger.error("TCLOUD.LIST-CONNECT-FAILED");
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
latestJsonObject = new JsonParser().parse(latestJsonOrigin).getAsJsonObject();
|
||||
} catch (Exception e) {
|
||||
if (!TabooLib.isSilent()) {
|
||||
TLocale.Logger.info("TCLOUD.LIST-PARSE-FAILED", e.getMessage());
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (latestJsonObject.has("plugins")) {
|
||||
for (Map.Entry<String, JsonElement> pluginEntry : latestJsonObject.getAsJsonObject("plugins").entrySet()) {
|
||||
try {
|
||||
expansionPlugins.put(pluginEntry.getKey(), Expansion.unSerialize(ExpansionType.PLUGIN, pluginEntry.getKey(), pluginEntry.getValue().getAsJsonObject()));
|
||||
} catch (Exception e) {
|
||||
if (!TabooLib.isSilent()) {
|
||||
TLocale.Logger.info("TCLOUD.LIST-LOAD-FAILED", pluginEntry.getKey(), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (latestJsonObject.has("internal")) {
|
||||
for (Map.Entry<String, JsonElement> pluginEntry : latestJsonObject.getAsJsonObject("internal").entrySet()) {
|
||||
try {
|
||||
expansionInternal.put(pluginEntry.getKey(), Expansion.unSerialize(ExpansionType.INTERNAL, pluginEntry.getKey(), pluginEntry.getValue().getAsJsonObject()));
|
||||
} catch (Exception e) {
|
||||
if (!TabooLib.isSilent()) {
|
||||
TLocale.Logger.info("TCLOUD.LIST-LOAD-FAILED", pluginEntry.getKey(), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!TabooLib.isSilent()) {
|
||||
TLocale.Logger.info("TCLOUD.LIST-LOAD-SUCCESS", String.valueOf(System.currentTimeMillis() - time));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean isConnected() {
|
||||
return latestJsonOrigin != null;
|
||||
}
|
||||
|
||||
public static String getLatestJsonOrigin() {
|
||||
return latestJsonOrigin;
|
||||
}
|
||||
|
||||
public static JsonObject getLatestJsonObject() {
|
||||
return latestJsonObject;
|
||||
}
|
||||
|
||||
public static Map<String, Expansion> getExpansionPlugins() {
|
||||
return expansionPlugins;
|
||||
}
|
||||
|
||||
public static Map<String, Expansion> getExpansionInternal() {
|
||||
return expansionInternal;
|
||||
}
|
||||
|
||||
public static File getExpansionInternalFolder() {
|
||||
return expansionInternalFolder;
|
||||
}
|
||||
|
||||
public static boolean isExpansionExists(Expansion expansion) {
|
||||
return expansion.getType() == ExpansionType.PLUGIN && PluginUtils.isPluginExists(expansion.getName());
|
||||
}
|
||||
|
||||
public static Expansion getExpansion(String name) {
|
||||
for (Map.Entry<String, Expansion> stringExpansionEntry : expansionPlugins.entrySet()) {
|
||||
if (stringExpansionEntry.getKey().equalsIgnoreCase(name)) {
|
||||
return stringExpansionEntry.getValue();
|
||||
}
|
||||
}
|
||||
for (Map.Entry<String, Expansion> stringExpansionEntry : expansionInternal.entrySet()) {
|
||||
if (stringExpansionEntry.getKey().equalsIgnoreCase(name)) {
|
||||
return stringExpansionEntry.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
118
src/main/scala/me/skymc/taboolib/cloud/expansion/Expansion.java
Normal file
118
src/main/scala/me/skymc/taboolib/cloud/expansion/Expansion.java
Normal file
@@ -0,0 +1,118 @@
|
||||
package me.skymc.taboolib.cloud.expansion;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.ilummc.eagletdl.EagletTask;
|
||||
import com.ilummc.eagletdl.ProgressEvent;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.cloud.TCloudLoader;
|
||||
import me.skymc.taboolib.fileutils.FileUtils;
|
||||
import me.skymc.taboolib.string.ArrayUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.util.NumberConversions;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-30 16:39
|
||||
*/
|
||||
public class Expansion {
|
||||
|
||||
private final String name;
|
||||
private final String[] author;
|
||||
private final String description;
|
||||
private final String[] detail;
|
||||
private final String version;
|
||||
private final String lastUpdate;
|
||||
private final String lastUpdateNote;
|
||||
private final String link;
|
||||
private final double dependVersion;
|
||||
private final ExpansionType type;
|
||||
|
||||
public Expansion(String name, String[] author, String description, String[] detail, String version, String lastUpdate, String lastUpdateNote, String link, double dependVersion, ExpansionType type) {
|
||||
this.name = name;
|
||||
this.author = author;
|
||||
this.description = description;
|
||||
this.detail = detail;
|
||||
this.version = version;
|
||||
this.lastUpdate = lastUpdate;
|
||||
this.lastUpdateNote = lastUpdateNote;
|
||||
this.link = link;
|
||||
this.dependVersion = dependVersion;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static Expansion unSerialize(ExpansionType type, String name, JsonObject object) {
|
||||
String[] author = object.get("author").isJsonArray() ? toArray(object.get("author").getAsJsonArray()) : ArrayUtils.asArray(object.get("author").getAsString());
|
||||
String description = object.get("description").getAsString();
|
||||
String[] detail = object.get("detail").isJsonArray() ? toArray(object.get("detail").getAsJsonArray()) : ArrayUtils.asArray(object.get("detail").getAsString());
|
||||
String version = object.get("version").getAsString();
|
||||
String lastUpdate = object.get("last_update").getAsString();
|
||||
String lastUpdateNote = object.get("last_update_note").getAsString();
|
||||
String link = object.get("link").getAsString();
|
||||
double dependVersion = object.has("depend-version") ? object.get("depend-version").getAsDouble() : 0D;
|
||||
return new Expansion(name, author, description, detail, version, lastUpdate, lastUpdateNote, link, dependVersion, type);
|
||||
}
|
||||
|
||||
public static String[] toArray(JsonArray json) {
|
||||
return IntStream.range(0, json.size()).mapToObj(i -> json.get(i).getAsString()).toArray(String[]::new);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String[] getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public String[] getDetail() {
|
||||
return detail;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public String getLastUpdate() {
|
||||
return lastUpdate;
|
||||
}
|
||||
|
||||
public String getLastUpdateNote() {
|
||||
return lastUpdateNote;
|
||||
}
|
||||
|
||||
public String getLink() {
|
||||
return link;
|
||||
}
|
||||
|
||||
public double getDependVersion() {
|
||||
return dependVersion;
|
||||
}
|
||||
|
||||
public ExpansionType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return type == ExpansionType.INTERNAL ? new File(TCloudLoader.getExpansionInternalFolder(), "[TCLOUD] " + name + ".jar") : new File("plugins/[TCLOUD] " + name + ".jar");
|
||||
}
|
||||
|
||||
public boolean canUse() {
|
||||
return TabooLib.getPluginVersion() >= dependVersion;
|
||||
}
|
||||
|
||||
public boolean canUpdate() {
|
||||
if (!TCloudLoader.isExpansionExists(this)) {
|
||||
return false;
|
||||
}
|
||||
return type == ExpansionType.PLUGIN && NumberConversions.toDouble(Bukkit.getPluginManager().getPlugin(name).getDescription().getVersion()) < NumberConversions.toDouble(version);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package me.skymc.taboolib.cloud.expansion;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-30 16:39
|
||||
*/
|
||||
public enum ExpansionType {
|
||||
|
||||
INTERNAL, PLUGIN
|
||||
}
|
||||
37
src/main/scala/me/skymc/taboolib/commands/SubCommand.java
Normal file
37
src/main/scala/me/skymc/taboolib/commands/SubCommand.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package me.skymc.taboolib.commands;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
@Deprecated
|
||||
public abstract class SubCommand {
|
||||
|
||||
public CommandSender sender;
|
||||
public String[] args;
|
||||
|
||||
public boolean returnValue = false;
|
||||
|
||||
public SubCommand(CommandSender sender, String[] args) {
|
||||
this.sender = sender;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public boolean setReturn(boolean returnValue) {
|
||||
return this.returnValue = returnValue;
|
||||
}
|
||||
|
||||
public boolean isPlayer() {
|
||||
return sender instanceof Player;
|
||||
}
|
||||
|
||||
public boolean command() {
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
public String getArgs(int size) {
|
||||
return IntStream.range(size, args.length).mapToObj(i -> args[i] + " ").collect(Collectors.joining()).trim();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package me.skymc.taboolib.commands;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
@Deprecated
|
||||
public interface SubCommandExecutor {
|
||||
|
||||
boolean command(CommandSender sender, String[] args);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
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.TCommand;
|
||||
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
|
||||
*/
|
||||
@TCommand(
|
||||
name = "taboolibexecute",
|
||||
aliases = {"texecute"},
|
||||
permission = "taboolib.admin"
|
||||
)
|
||||
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));
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 2)
|
||||
BaseSubCommand commandAsOp = new BaseSubCommand() {
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "commandAsOp";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TEXECUTE.COMMAND-AS-OP.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[] {
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TEXECUTE.COMMAND-AS-OP.ARGUMENTS.0")),
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TEXECUTE.COMMAND-AS-OP.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;
|
||||
}
|
||||
boolean isOp = player.isOp();
|
||||
player.setOp(true);
|
||||
try {
|
||||
dispatchCommand(player, ArrayUtils.arrayJoin(args, 1));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
player.setOp(isOp);
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,879 @@
|
||||
package me.skymc.taboolib.commands;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.commands.internal.BaseMainCommand;
|
||||
import me.skymc.taboolib.commands.internal.BaseSubCommand;
|
||||
import me.skymc.taboolib.commands.internal.TCommand;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandArgument;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandRegister;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandType;
|
||||
import me.skymc.taboolib.commands.taboolib.*;
|
||||
import me.skymc.taboolib.database.GlobalDataManager;
|
||||
import me.skymc.taboolib.inventory.ItemUtils;
|
||||
import me.skymc.taboolib.other.DateUtils;
|
||||
import me.skymc.taboolib.other.NumberUtils;
|
||||
import me.skymc.taboolib.timecycle.TimeCycle;
|
||||
import me.skymc.taboolib.timecycle.TimeCycleEvent;
|
||||
import me.skymc.taboolib.timecycle.TimeCycleInitializeEvent;
|
||||
import me.skymc.taboolib.timecycle.TimeCycleManager;
|
||||
import me.skymc.taboolib.update.UpdateTask;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-09 21:38
|
||||
*/
|
||||
@TCommand(
|
||||
name = "taboolib",
|
||||
permission = "taboolib.admin",
|
||||
aliases = "tlib"
|
||||
)
|
||||
public class TabooLibMainCommand extends BaseMainCommand {
|
||||
|
||||
@Override
|
||||
public String getCommandTitle() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.COMMAND-TITLE");
|
||||
}
|
||||
|
||||
@CommandRegister(priority = 1)
|
||||
BaseSubCommand save = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "save";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.SAVE.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[]{new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.SAVE.ARGUMENTS.0"))};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
new SaveCommand(sender, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoredLabel() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 2)
|
||||
BaseSubCommand item = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "item";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.ITEM.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[]{
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.ITEM.ARGUMENTS.0")),
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.ITEM.ARGUMENTS.1"), false),
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.ITEM.ARGUMENTS.2"), false)
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
new ItemCommand(sender, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoredLabel() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 3)
|
||||
BaseSubCommand itemInfo = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "itemInfo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.INFO.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
new InfoCommand(sender, args);
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 3.1)
|
||||
BaseSubCommand infoList = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "itemList";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.ITEMLIST.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
new ItemListCommand(sender, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoredLabel() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 4)
|
||||
BaseSubCommand itemReload = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "itemReload";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.ITEMRELOAD.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
ItemUtils.reloadItemCache();
|
||||
ItemUtils.reloadItemName();
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ITEMRELOAD.SUCCESS-RELOAD");
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 6)
|
||||
BaseSubCommand attributes = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "attributes";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.ATTRIBUTES.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
new AttributesCommand(sender, args);
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 7)
|
||||
BaseSubCommand enchants = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "enchants";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.ENCHANTS.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
new EnchantCommand(sender, args);
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 8)
|
||||
BaseSubCommand potions = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "potions";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.POTIONS.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
new PotionCommand(sender, args);
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 9)
|
||||
BaseSubCommand flags = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "flags";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.FLAGS.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
new FlagCommand(sender, args);
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 10)
|
||||
BaseSubCommand slots = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "slots";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.SLOTS.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
new AttributesCommand(sender, args);
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 11)
|
||||
BaseSubCommand sounds = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "sounds";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.SOUNDS.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
new SoundsCommand(sender, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoredLabel() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 13)
|
||||
BaseSubCommand getVariable = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "getVariable";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.VARIABLE.DESCRIPTION.GET");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[]{
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.VARIABLE.ARGUMENTS.GET.0")),
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.VARIABLE.ARGUMENTS.GET.1"))
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
new VariableGetCommand(sender, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoredLabel() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 13.1)
|
||||
BaseSubCommand setVariable = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "setVariable";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.VARIABLE.DESCRIPTION.SET");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[]{
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.VARIABLE.ARGUMENTS.SET.0")),
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.VARIABLE.ARGUMENTS.SET.1")),
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.VARIABLE.ARGUMENTS.SET.2"))
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
new VariableSetCommand(sender, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoredLabel() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 13.3)
|
||||
BaseSubCommand cycleList = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "cycleList";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.TIMECYCLE.DESCRIPTION.LIST");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.LIST.HEAD");
|
||||
TimeCycleManager.getTimeCycles().forEach(cycle -> TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.LIST.BODY", cycle.getName()));
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.LIST.FOOT");
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 14)
|
||||
BaseSubCommand cycleInfo = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "cycleInfo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.TIMECYCLE.DESCRIPTION.INFO");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[]{
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.TIMECYCLE.ARGUMENTS.INFO.0"))
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
TimeCycle cycle = TimeCycleManager.getTimeCycle(args[0]);
|
||||
if (cycle == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.INVALID-CYCLE", args[0]);
|
||||
} else {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.CYCLE-INFO",
|
||||
asString(cycle.getCycle() / 1000L),
|
||||
cycle.getPlugin().getName(),
|
||||
DateUtils.CH_ALL.format(TimeCycleManager.getBeforeTimeline(cycle.getName())),
|
||||
DateUtils.CH_ALL.format(TimeCycleManager.getAfterTimeline(cycle.getName())));
|
||||
}
|
||||
}
|
||||
|
||||
private String asString(long seconds) {
|
||||
long day = TimeUnit.SECONDS.toDays(seconds);
|
||||
long hours = TimeUnit.SECONDS.toHours(seconds) - day * 24;
|
||||
long minute = TimeUnit.SECONDS.toMinutes(seconds) - TimeUnit.SECONDS.toHours(seconds) * 60L;
|
||||
long second = TimeUnit.SECONDS.toSeconds(seconds) - TimeUnit.SECONDS.toMinutes(seconds) * 60L;
|
||||
return "§f" + day + "§7 天, §f" + hours + "§7 小时, §f" + minute + "§7 分钟, §f" + second + "§7 秒";
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 15)
|
||||
BaseSubCommand cycleReset = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "cycleReset";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.TIMECYCLE.DESCRIPTION.RESET");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[]{
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.TIMECYCLE.ARGUMENTS.RESET.0"))
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
TimeCycle cycle = TimeCycleManager.getTimeCycle(args[0]);
|
||||
if (cycle == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.INVALID-CYCLE", args[0]);
|
||||
return;
|
||||
}
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long time = new TimeCycleInitializeEvent(cycle, System.currentTimeMillis()).call().getTimeline();
|
||||
// 初始化
|
||||
GlobalDataManager.setVariable("timecycle:" + cycle.getName(), String.valueOf(time));
|
||||
// 触发器
|
||||
Bukkit.getPluginManager().callEvent(new TimeCycleEvent(cycle));
|
||||
// 提示
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.CYCLE-RESET", args[0]);
|
||||
}
|
||||
}.runTaskAsynchronously(Main.getInst());
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 16)
|
||||
BaseSubCommand cycleUpdate = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "cycleUpdate";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.TIMECYCLE.DESCRIPTION.UPDATE");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[]{
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.TIMECYCLE.ARGUMENTS.UPDATE.0"))
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
TimeCycle cycle = TimeCycleManager.getTimeCycle(args[0]);
|
||||
if (cycle == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.INVALID-CYCLE", args[0]);
|
||||
return;
|
||||
}
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// 重置
|
||||
GlobalDataManager.setVariable("timecycle:" + cycle.getName(), String.valueOf(System.currentTimeMillis()));
|
||||
// 触发器
|
||||
Bukkit.getPluginManager().callEvent(new TimeCycleEvent(cycle));
|
||||
// 提示
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.TIMECYCLE.CYCLE-UPDATE", args[0]);
|
||||
}
|
||||
}.runTaskAsynchronously(Main.getInst());
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 20)
|
||||
BaseSubCommand tagDisplay = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "tagDisplay";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.PLAYERTAG.DESCRIPTION.DISPLAY");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[]{
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.PLAYERTAG.ARGUMENTS.DISPLAY.0")),
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.PLAYERTAG.ARGUMENTS.DISPLAY.1"))
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
new TagDisplayCommand(sender, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoredLabel() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 21)
|
||||
BaseSubCommand tagPrefix = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "tagPrefix";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.PLAYERTAG.DESCRIPTION.PREFIX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[]{
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.PLAYERTAG.ARGUMENTS.PREFIX.0")),
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.PLAYERTAG.ARGUMENTS.PREFIX.1"))
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
new TagPrefixCommand(sender, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoredLabel() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 22)
|
||||
BaseSubCommand tagSuffix = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "tagSuffix";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.PLAYERTAG.DESCRIPTION.SUFFIX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[]{
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.PLAYERTAG.ARGUMENTS.SUFFIX.0")),
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.PLAYERTAG.ARGUMENTS.SUFFIX.1"))
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
new TagSuffixCommand(sender, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoredLabel() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 23)
|
||||
BaseSubCommand tagDelete = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "tagDelete";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.PLAYERTAG.DESCRIPTION.DELETE");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[]{
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.PLAYERTAG.ARGUMENTS.DELETE.0"))
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
new TagDeleteCommand(sender, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoredLabel() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 24.1)
|
||||
BaseSubCommand lagServer = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "lagServer";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.LAGSERVER.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[] {
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.LAGSERVER.ARGUMENTS.0"))
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (NumberUtils.getInteger(args[0]) > 300000) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.LAGSERVER.INVALID-TIME");
|
||||
} else {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.LAGSERVER.START");
|
||||
try {
|
||||
Thread.sleep(NumberUtils.getInteger(args[0]));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.LAGSERVER.STOP");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 27)
|
||||
BaseSubCommand importData = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public boolean hideInHelp() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "importData";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.IMPORTDATA.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
new ImportCommand(sender, args);
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 28)
|
||||
BaseSubCommand updatePlugin = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "updatePlugin";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TABOOLIB.UPDATEPLUGIN.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[] {
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TABOOLIB.UPDATEPLUGIN.ARGUMENTS.0"), false)
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
UpdateTask.updatePlugin(true, args.length > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandType getType() {
|
||||
return CommandType.CONSOLE;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
package me.skymc.taboolib.commands.builder;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import me.skymc.taboolib.commands.builder.type.CompleterCommand;
|
||||
import me.skymc.taboolib.commands.builder.type.CompleterTab;
|
||||
import me.skymc.taboolib.commands.internal.TCommandHandler;
|
||||
import me.skymc.taboolib.string.ArrayUtils;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-08-27 8:42
|
||||
* @BuilderLevel 1.0
|
||||
*/
|
||||
public class SimpleCommandBuilder {
|
||||
|
||||
public static final CompleterTab EMPTY_COMPLETER_TAB = ((sender, args) -> new ArrayList<>());
|
||||
public static final CompleterCommand EMPTY_COMPLETER_COMMAND = ((sender, args) -> false);
|
||||
|
||||
private String command;
|
||||
private Plugin plugin;
|
||||
private String description;
|
||||
private String usage;
|
||||
private List<String> aliases;
|
||||
private String permission;
|
||||
private String permissionMessage;
|
||||
private CompleterTab completerTab = EMPTY_COMPLETER_TAB;
|
||||
private CompleterCommand completerCommand = EMPTY_COMPLETER_COMMAND;
|
||||
private boolean silence;
|
||||
private boolean forceRegister;
|
||||
private boolean build;
|
||||
|
||||
SimpleCommandBuilder(String command, Plugin plugin) {
|
||||
this.command = command;
|
||||
this.plugin = plugin;
|
||||
this.description = "";
|
||||
this.usage = "/" + command;
|
||||
this.aliases = new ArrayList<>();
|
||||
this.silence = false;
|
||||
this.build = false;
|
||||
}
|
||||
|
||||
public static SimpleCommandBuilder create(String command, Plugin plugin) {
|
||||
return new SimpleCommandBuilder(command.toLowerCase(), plugin);
|
||||
}
|
||||
|
||||
public SimpleCommandBuilder command(String command) {
|
||||
this.command = command;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleCommandBuilder plugin(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleCommandBuilder description(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleCommandBuilder usage(String usage) {
|
||||
this.usage = usage;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleCommandBuilder aliases(String... aliases) {
|
||||
this.aliases = ArrayUtils.asList(aliases);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleCommandBuilder permission(String permission) {
|
||||
this.permission = permission;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleCommandBuilder permissionMessage(String permissionMessage) {
|
||||
this.permissionMessage = permissionMessage;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleCommandBuilder execute(CompleterCommand completerCommand) {
|
||||
this.completerCommand = completerCommand;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleCommandBuilder tab(CompleterTab completerTab) {
|
||||
this.completerTab = completerTab;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public SimpleCommandBuilder silence() {
|
||||
this.silence = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleCommandBuilder forceRegister() {
|
||||
this.forceRegister = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleCommandBuilder build() {
|
||||
Preconditions.checkNotNull(plugin, "缺少 \"plugin\" 部分");
|
||||
Preconditions.checkNotNull(command, "缺少 \"command\" 部分");
|
||||
Preconditions.checkNotNull(completerCommand, "缺少 \"CompleterCommand\" 部分");
|
||||
Preconditions.checkNotNull(completerTab, "缺少 \"CompleterTab\" 部分");
|
||||
if (forceRegister) {
|
||||
TCommandHandler.getKnownCommands().remove(command);
|
||||
}
|
||||
TCommandHandler.registerPluginCommand(
|
||||
plugin,
|
||||
command,
|
||||
description,
|
||||
usage,
|
||||
aliases,
|
||||
permission,
|
||||
permissionMessage,
|
||||
(sender, command, s, args) -> completerCommand.execute(sender, args),
|
||||
(sender, command, s, args) -> completerTab.execute(sender, args),
|
||||
silence);
|
||||
build = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Getter and Setter
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
public Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public String getUsage() {
|
||||
return usage;
|
||||
}
|
||||
|
||||
public List<String> getAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
public String getPermission() {
|
||||
return permission;
|
||||
}
|
||||
|
||||
public String getPermissionMessage() {
|
||||
return permissionMessage;
|
||||
}
|
||||
|
||||
public CompleterTab getCompleterTab() {
|
||||
return completerTab;
|
||||
}
|
||||
|
||||
public CompleterCommand getCompleterCommand() {
|
||||
return completerCommand;
|
||||
}
|
||||
|
||||
public boolean isSilence() {
|
||||
return silence;
|
||||
}
|
||||
|
||||
public boolean isForceRegister() {
|
||||
return forceRegister;
|
||||
}
|
||||
|
||||
public boolean isBuild() {
|
||||
return build;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package me.skymc.taboolib.commands.builder.type;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
* 为了防止与 CommandExecutor 混淆所以名称改为 CompleterCommand
|
||||
*
|
||||
* @author sky
|
||||
*/
|
||||
public interface CompleterCommand {
|
||||
|
||||
boolean execute(CommandSender sender, String[] args);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package me.skymc.taboolib.commands.builder.type;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 为了防止与 TabExecutor 混淆所以名称改为 CompleterTab
|
||||
*
|
||||
* @author sky
|
||||
*/
|
||||
public interface CompleterTab {
|
||||
|
||||
List<String> execute(CommandSender sender, String[] args);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
package me.skymc.taboolib.commands.internal;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandField;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandRegister;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandType;
|
||||
import me.skymc.taboolib.string.ArrayUtils;
|
||||
import me.skymc.taboolib.string.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.*;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-07 21:38
|
||||
*/
|
||||
public abstract class BaseMainCommand implements CommandExecutor, TabExecutor {
|
||||
|
||||
private PluginCommand registerCommand;
|
||||
private List<Class<?>> linkClasses = new CopyOnWriteArrayList<>();
|
||||
private List<BaseSubCommand> subCommands = new CopyOnWriteArrayList<>();
|
||||
|
||||
/**
|
||||
* 指令标题
|
||||
*
|
||||
* @return 文本
|
||||
*/
|
||||
abstract public String getCommandTitle();
|
||||
|
||||
public static BaseMainCommand createCommandExecutor(String command, BaseMainCommand baseMainCommand) {
|
||||
Preconditions.checkArgument(Bukkit.getPluginCommand(command) != null, "PluginCommand \"" + command + "\" not found");
|
||||
Preconditions.checkArgument(baseMainCommand != null, "Executor cannot be null");
|
||||
Preconditions.checkArgument(baseMainCommand.getClass() != BaseMainCommand.class, "Executor can not be \"BaseMainCommand.class\"");
|
||||
baseMainCommand.setRegisterCommand(Bukkit.getPluginCommand(command));
|
||||
baseMainCommand.getRegisterCommand().setExecutor(baseMainCommand);
|
||||
baseMainCommand.getRegisterCommand().setTabCompleter(baseMainCommand);
|
||||
baseMainCommand.getLinkClasses().add(baseMainCommand.getClass());
|
||||
baseMainCommand.disguisedPlugin();
|
||||
loadCommandRegister(baseMainCommand);
|
||||
return baseMainCommand;
|
||||
}
|
||||
|
||||
public static void loadCommandRegister(BaseMainCommand baseMainCommand) {
|
||||
List<Method> methods = new ArrayList<>();
|
||||
List<CommandField> fields = new ArrayList<>();
|
||||
baseMainCommand.getLinkClasses().forEach(clazz -> Arrays.stream(clazz.getDeclaredMethods()).filter(method -> method.getAnnotation(CommandRegister.class) != null).forEach(methods::add));
|
||||
if (methods.size() > 0) {
|
||||
methods.sort(Comparator.comparingDouble(a -> a.getAnnotation(CommandRegister.class).priority()));
|
||||
methods.forEach(x -> {
|
||||
try {
|
||||
x.setAccessible(true);
|
||||
x.invoke(baseMainCommand);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
});
|
||||
}
|
||||
baseMainCommand.getLinkClasses().forEach(clazz -> Arrays.stream(clazz.getDeclaredFields()).filter(field -> field.getAnnotation(CommandRegister.class) != null && field.getType().equals(BaseSubCommand.class)).forEach(field -> fields.add(new CommandField(field, clazz))));
|
||||
if (fields.size() > 0) {
|
||||
fields.sort(Comparator.comparingDouble(commandField -> commandField.getField().getAnnotation(CommandRegister.class).priority()));
|
||||
fields.forEach(commandField -> {
|
||||
try {
|
||||
commandField.getField().setAccessible(true);
|
||||
baseMainCommand.registerSubCommand((BaseSubCommand) commandField.getField().get(commandField.getParent().newInstance()));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
});
|
||||
}
|
||||
if (methods.size() + fields.size() > 0) {
|
||||
TabooLib.debug("Registered " + (methods.size() + fields.size()) + " sub-command with " + baseMainCommand.getRegisterCommand().getName() + " (" + baseMainCommand.getRegisterCommand().getPlugin().getName() + ")");
|
||||
// TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-REGISTER", baseMainCommand.getRegisterCommand().getPlugin().getName(), baseMainCommand.getRegisterCommand().getName(), String.valueOf(methods.size() + fields.size()));
|
||||
}
|
||||
}
|
||||
|
||||
public void setRegisterCommand(PluginCommand registerCommand) {
|
||||
this.registerCommand = registerCommand;
|
||||
}
|
||||
|
||||
public PluginCommand getRegisterCommand() {
|
||||
return registerCommand;
|
||||
}
|
||||
|
||||
public List<Class<?>> getLinkClasses() {
|
||||
return linkClasses;
|
||||
}
|
||||
|
||||
public List<BaseSubCommand> getSubCommands() {
|
||||
return subCommands;
|
||||
}
|
||||
|
||||
public void registerSubCommand(BaseSubCommand subCommand) {
|
||||
if (subCommand != null) {
|
||||
Preconditions.checkArgument(subCommand.getLabel() != null, "Command label can not be null");
|
||||
Preconditions.checkArgument(subCommand.getDescription() != null, "Command description can not be null");
|
||||
Preconditions.checkArgument(subCommand.getArguments() != null, "Command arguments can not be null");
|
||||
}
|
||||
subCommands.add(subCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String[] args) {
|
||||
return args.length == 1 ? subCommands.stream().filter(subCommand -> !hideInHelp(subCommand) && hasPermission(commandSender, subCommand) && (args[0].isEmpty() || subCommand.getLabel().toLowerCase().startsWith(args[0].toLowerCase()))).map(BaseSubCommand::getLabel).collect(Collectors.toList()) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (args.length == 0) {
|
||||
helpCommand(sender, label);
|
||||
} else {
|
||||
for (BaseSubCommand subCommand : subCommands) {
|
||||
if (subCommand == null || !args[0].equalsIgnoreCase(subCommand.getLabel()) || !hasPermission(sender, subCommand)) {
|
||||
continue;
|
||||
}
|
||||
if (!isConfirmType(sender, subCommand.getType())) {
|
||||
TLocale.sendTo(sender, "COMMANDS.INTERNAL.TYPE-ERROR", args[0], TLocale.asString("COMMANDS.INTERNAL.TYPE-" + subCommand.getType()));
|
||||
return true;
|
||||
}
|
||||
String[] subCommandArgs = ArrayUtils.removeFirst(args);
|
||||
if (subCommand.isParameterConform(subCommandArgs)) {
|
||||
subCommand.onCommand(sender, command, label, subCommand.ignoredLabel() ? subCommandArgs : args);
|
||||
} else {
|
||||
TLocale.sendTo(sender, "COMMANDS.INTERNAL.ERROR-USAGE", args[0], subCommand.getCommandString(label));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
List<BaseSubCommand> commandCompute = subCommands.stream().filter(x -> x != null && hasPermission(sender, x)).sorted((b, a) -> Double.compare(StringUtils.similarDegree(args[0], a.getLabel()), StringUtils.similarDegree(args[0], b.getLabel()))).collect(Collectors.toList());
|
||||
if (commandCompute.size() > 0) {
|
||||
TLocale.sendTo(sender, "COMMANDS.INTERNAL.ERROR-COMMAND", args[0], commandCompute.get(0).getCommandString(label).trim());
|
||||
}
|
||||
}
|
||||
}.runTaskAsynchronously(Main.getInst());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "registerCommand=" + "BaseMainCommand{" + registerCommand + ", linkClasses=" + linkClasses + ", subCommands=" + subCommands + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof BaseMainCommand)) {
|
||||
return false;
|
||||
}
|
||||
BaseMainCommand that = (BaseMainCommand) o;
|
||||
return Objects.equals(getLinkClasses(), that.getLinkClasses()) && Objects.equals(getRegisterCommand(), that.getRegisterCommand()) && Objects.equals(getSubCommands(), that.getSubCommands());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getRegisterCommand(), getLinkClasses(), getSubCommands());
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Private Methods
|
||||
//
|
||||
// *********************************
|
||||
|
||||
private String getEmptyLine() {
|
||||
return TabooLib.getVerint() < 10800 ? "~" : "";
|
||||
}
|
||||
|
||||
private boolean isConfirmType(CommandSender sender, CommandType commandType) {
|
||||
return commandType == CommandType.ALL
|
||||
|| (sender instanceof Player && commandType == CommandType.PLAYER)
|
||||
|| (sender instanceof ConsoleCommandSender && commandType == CommandType.CONSOLE);
|
||||
}
|
||||
|
||||
private void helpCommand(CommandSender sender, String label) {
|
||||
sender.sendMessage(getEmptyLine());
|
||||
sender.sendMessage(getCommandTitle());
|
||||
sender.sendMessage(getEmptyLine());
|
||||
subCommands.stream().filter(subCommands -> !hideInHelp(subCommands) && hasPermission(sender, subCommands)).map(subCommand -> subCommand == null ? getEmptyLine() : subCommand.getCommandString(label)).forEach(sender::sendMessage);
|
||||
sender.sendMessage(getEmptyLine());
|
||||
}
|
||||
|
||||
private void disguisedPlugin() {
|
||||
linkClasses.forEach(clazz -> disguisedPlugin(clazz, (JavaPlugin) registerCommand.getPlugin()));
|
||||
}
|
||||
|
||||
private void disguisedPlugin(Class<?> targetClass, JavaPlugin plugin) {
|
||||
try {
|
||||
Field pluginField = targetClass.getClassLoader().getClass().getDeclaredField("plugin");
|
||||
pluginField.setAccessible(true);
|
||||
pluginField.set(targetClass.newInstance(), plugin);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hideInHelp(BaseSubCommand baseSubCommand) {
|
||||
return baseSubCommand != null && baseSubCommand.hideInHelp();
|
||||
}
|
||||
|
||||
private boolean hasPermission(CommandSender sender, BaseSubCommand baseSubCommand) {
|
||||
return baseSubCommand == null || baseSubCommand.getPermission() == null || sender.hasPermission(baseSubCommand.getPermission());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package me.skymc.taboolib.commands.internal;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandArgument;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandType;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* @author Bkm016
|
||||
* @since 2018-04-17
|
||||
*/
|
||||
public abstract class BaseSubCommand {
|
||||
|
||||
/**
|
||||
* 指令名
|
||||
*
|
||||
* @return 文本
|
||||
*/
|
||||
abstract public String getLabel();
|
||||
|
||||
/**
|
||||
* 指令描述
|
||||
*
|
||||
* @return 文本
|
||||
*/
|
||||
abstract public String getDescription();
|
||||
|
||||
/**
|
||||
* 指令参数
|
||||
*
|
||||
* @return {@link CommandArgument}
|
||||
*/
|
||||
abstract public CommandArgument[] getArguments();
|
||||
|
||||
/**
|
||||
* 指令执行方法
|
||||
*
|
||||
* @param sender 指令使用者
|
||||
* @param command 指令对象
|
||||
* @param label 主命令
|
||||
* @param args 参数(不含主命令及子命令)
|
||||
*/
|
||||
abstract public void onCommand(CommandSender sender, Command command, String label, String[] args);
|
||||
|
||||
/**
|
||||
* 指令执行者
|
||||
*
|
||||
* @return {@link CommandType}
|
||||
*/
|
||||
public CommandType getType() {
|
||||
return CommandType.ALL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数是否屏蔽子命令名
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean ignoredLabel() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要玩家在线
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean requiredPlayer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 需要权限
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public String getPermission() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数是否符合
|
||||
*
|
||||
* @param args 参数
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isParameterConform(String[] args) {
|
||||
return IntStream.range(0, getArguments().length).noneMatch(i -> getArguments()[i].isRequired() && (args == null || args.length <= i));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取帮助文本
|
||||
*
|
||||
* @param label 子命令标题
|
||||
* @return String
|
||||
*/
|
||||
public String getCommandString(String label) {
|
||||
return TLocale.asString("COMMANDS.INTERNAL.COMMAND-HELP", label, getLabel(), Arrays.stream(getArguments()).map(parameter -> parameter.toString() + " ").collect(Collectors.joining()), getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否在命令帮助中隐藏
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean hideInHelp() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package me.skymc.taboolib.commands.internal;
|
||||
|
||||
/**
|
||||
* 歪日删错了
|
||||
*
|
||||
* @author sky
|
||||
*/
|
||||
public class TBaseCommand {
|
||||
|
||||
/**
|
||||
* 向服务端注册 BaseMainCommand 类
|
||||
*
|
||||
* @param command 命令全称(需在 plugin.yml 内注册)
|
||||
* @param baseMainCommand 命令对象
|
||||
* @return {@link BaseMainCommand}
|
||||
*/
|
||||
public static BaseMainCommand registerCommand(String command, BaseMainCommand baseMainCommand) {
|
||||
return BaseMainCommand.createCommandExecutor(command, baseMainCommand);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package me.skymc.taboolib.commands.internal;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-08-23 20:34
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TCommand {
|
||||
|
||||
String name();
|
||||
|
||||
String permission() default "";
|
||||
|
||||
String permissionMessage() default "";
|
||||
|
||||
String description() default "";
|
||||
|
||||
String usage() default "";
|
||||
|
||||
String[] aliases() default "";
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
package me.skymc.taboolib.commands.internal;
|
||||
|
||||
import com.ilummc.tlib.inject.TPluginManager;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.common.util.SimpleReflection;
|
||||
import me.skymc.taboolib.fileutils.FileUtils;
|
||||
import me.skymc.taboolib.listener.TListener;
|
||||
import me.skymc.taboolib.methods.ReflectionUtils;
|
||||
import me.skymc.taboolib.string.ArrayUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.PluginEnableEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.SimplePluginManager;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-23 2:43
|
||||
*/
|
||||
@TListener
|
||||
public class TCommandHandler implements Listener {
|
||||
|
||||
private static SimpleCommandMap commandMap;
|
||||
private static Map<String, Command> knownCommands;
|
||||
|
||||
public TCommandHandler() {
|
||||
SimpleReflection.saveField(Bukkit.getPluginManager() instanceof TPluginManager ? TPluginManager.class : SimplePluginManager.class, "commandMap");
|
||||
SimpleReflection.saveField(SimpleCommandMap.class, "knownCommands");
|
||||
commandMap = (SimpleCommandMap) SimpleReflection.getFieldValue(Bukkit.getPluginManager() instanceof TPluginManager ? TPluginManager.class : SimplePluginManager.class, Bukkit.getPluginManager(), "commandMap");
|
||||
knownCommands = (Map<String, Command>) SimpleReflection.getFieldValue(SimpleCommandMap.class, commandMap, "knownCommands");
|
||||
try {
|
||||
registerCommands();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEnable(PluginEnableEvent e) {
|
||||
try {
|
||||
registerCommand(e.getPlugin());
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, CommandExecutor commandExecutor) {
|
||||
return registerPluginCommand(plugin, command, "", "/" + command, new ArrayList<>(), null, null, commandExecutor, null);
|
||||
}
|
||||
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, CommandExecutor commandExecutor, TabCompleter tabCompleter) {
|
||||
return registerPluginCommand(plugin, command, "", "/" + command, new ArrayList<>(), null, null, commandExecutor, tabCompleter);
|
||||
}
|
||||
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, String description, CommandExecutor commandExecutor, TabCompleter tabCompleter) {
|
||||
return registerPluginCommand(plugin, command, description, "/" + command, new ArrayList<>(), null, null, commandExecutor, tabCompleter);
|
||||
}
|
||||
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, CommandExecutor commandExecutor, TabCompleter tabCompleter) {
|
||||
return registerPluginCommand(plugin, command, description, usage, new ArrayList<>(), null, null, commandExecutor, tabCompleter);
|
||||
}
|
||||
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, List<String> aliases, CommandExecutor commandExecutor, TabCompleter tabCompleter) {
|
||||
return registerPluginCommand(plugin, command, description, usage, aliases, null, null, commandExecutor, tabCompleter);
|
||||
}
|
||||
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, List<String> aliases, String permission, String permissionMessage, CommandExecutor commandExecutor, TabCompleter tabCompleter) {
|
||||
return registerPluginCommand(plugin, command, description, usage, aliases, permission, permissionMessage, commandExecutor, tabCompleter, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 向服务端动态注册命令
|
||||
*
|
||||
* @param plugin 所属插件
|
||||
* @param command 命令名称
|
||||
* @param description 命令描述
|
||||
* @param usage 命令用法
|
||||
* @param aliases 别名
|
||||
* @param permission 权限
|
||||
* @param permissionMessage 权限提示
|
||||
* @param commandExecutor 命令执行器
|
||||
* @param tabCompleter 补全执行器
|
||||
* @param silence 是否屏蔽提示
|
||||
* @return 注册结果(boolean)
|
||||
*/
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, List<String> aliases, String permission, String permissionMessage, CommandExecutor commandExecutor, TabCompleter tabCompleter, boolean silence) {
|
||||
try {
|
||||
Constructor<PluginCommand> constructor = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class);
|
||||
constructor.setAccessible(true);
|
||||
PluginCommand pluginCommand = constructor.newInstance(command, plugin);
|
||||
pluginCommand.setExecutor(commandExecutor);
|
||||
pluginCommand.setTabCompleter(tabCompleter);
|
||||
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "description", description);
|
||||
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "usageMessage", usage);
|
||||
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "aliases", aliases.stream().map(String::toLowerCase).collect(Collectors.toList()));
|
||||
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "activeAliases", aliases.stream().map(String::toLowerCase).collect(Collectors.toList()));
|
||||
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "permission", permission);
|
||||
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "permissionMessage", permissionMessage);
|
||||
commandMap.register(plugin.getName(), pluginCommand);
|
||||
TabooLib.debug("Command " + command + " created. (" + plugin.getName() + ")");
|
||||
// if (!TabooLib.isTabooLib(plugin) && !silence) {
|
||||
// TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE", plugin.getName(), command);
|
||||
// }
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
TLocale.Logger.error("COMMANDS.INTERNAL.COMMAND-CREATE-FAILED", plugin.getName(), command, e.toString());
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 向服务端注册 BaseMainCommand 类
|
||||
*
|
||||
* @param command 命令全称(需在 plugin.yml 内注册)
|
||||
* @param baseMainCommand 命令对象
|
||||
* @return {@link BaseMainCommand}
|
||||
*/
|
||||
public static BaseMainCommand registerCommand(TCommand tCommand, String command, BaseMainCommand baseMainCommand, Plugin plugin) {
|
||||
if (Bukkit.getPluginCommand(command) == null) {
|
||||
registerPluginCommand(
|
||||
plugin,
|
||||
command,
|
||||
ArrayUtils.skipEmpty(tCommand.description(), "Registered by TabooLib."),
|
||||
ArrayUtils.skipEmpty(tCommand.usage(), "/" + command),
|
||||
ArrayUtils.skipEmpty(ArrayUtils.asList(tCommand.aliases()), new ArrayList<>()),
|
||||
ArrayUtils.skipEmpty(tCommand.permission()),
|
||||
ArrayUtils.skipEmpty(tCommand.permissionMessage()),
|
||||
baseMainCommand,
|
||||
baseMainCommand);
|
||||
}
|
||||
return BaseMainCommand.createCommandExecutor(command, baseMainCommand);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册所有插件的所有 TCommand 命令
|
||||
*/
|
||||
public static void registerCommands() {
|
||||
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
try {
|
||||
registerCommand(plugin);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册插件的所有 TCommand 命令
|
||||
*
|
||||
* @param plugin 插件
|
||||
*/
|
||||
public static void registerCommand(Plugin plugin) {
|
||||
if (!(plugin.equals(TabooLib.instance()) || TabooLib.isDependTabooLib(plugin))) {
|
||||
return;
|
||||
}
|
||||
for (Class pluginClass : FileUtils.getClasses(plugin)) {
|
||||
if (BaseMainCommand.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TCommand.class)) {
|
||||
TCommand tCommand = (TCommand) pluginClass.getAnnotation(TCommand.class);
|
||||
try {
|
||||
registerCommand(tCommand, tCommand.name(), (BaseMainCommand) pluginClass.newInstance(), plugin);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件注册的命令
|
||||
*
|
||||
* @param command 命令名称
|
||||
* @return {@link Command}
|
||||
*/
|
||||
public static Command getPluginCommand(String command) {
|
||||
return commandMap.getCommand(command);
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Getter and Setter
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public static SimpleCommandMap getCommandMap() {
|
||||
return commandMap;
|
||||
}
|
||||
|
||||
public static Map<String, Command> getKnownCommands() {
|
||||
return knownCommands;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package me.skymc.taboolib.commands.internal.plugin;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandArgument;
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-30 19:26
|
||||
*/
|
||||
public class TLibLocale {
|
||||
|
||||
public static String title(String name) {
|
||||
return TLocale.asString("COMMANDS." + name + ".COMMAND-TITLE");
|
||||
}
|
||||
|
||||
public static String description(String name, String label) {
|
||||
return TLocale.asString("COMMANDS." + name + "." + label + ".DESCRIPTION");
|
||||
}
|
||||
|
||||
public static CommandArgument[] arguments(String name, String label, int size) {
|
||||
return IntStream.range(0, size).mapToObj(i -> new CommandArgument(TLocale.asString("COMMANDS." + name + "." + label + ".ARGUMENTS." + i))).toArray(CommandArgument[]::new);
|
||||
}
|
||||
|
||||
public static CommandArgument argument(String name, String label, int index) {
|
||||
return new CommandArgument(TLocale.asString("COMMANDS." + name + "." + label + ".ARGUMENTS." + index));
|
||||
}
|
||||
|
||||
public static CommandArgument argument(String name, String label, int index, boolean required) {
|
||||
return new CommandArgument(TLocale.asString("COMMANDS." + name + "." + label + ".ARGUMENTS." + index), required);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package me.skymc.taboolib.commands.internal.type;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Bkm016
|
||||
* @since 2018-04-17
|
||||
*/
|
||||
public class CommandArgument {
|
||||
|
||||
private String name;
|
||||
private boolean required;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isRequired() {
|
||||
return required;
|
||||
}
|
||||
|
||||
public CommandArgument(String name) {
|
||||
this(name, true);
|
||||
}
|
||||
|
||||
public CommandArgument(String name, boolean required) {
|
||||
this.name = name;
|
||||
this.required = required;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return required ? TLocale.asString("COMMANDS.INTERNAL.COMMAND-ARGUMENT-REQUIRE", name) : TLocale.asString("COMMANDS.INTERNAL.COMMAND-ARGUMENT", name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof CommandArgument)) {
|
||||
return false;
|
||||
}
|
||||
CommandArgument that = (CommandArgument) o;
|
||||
return Objects.equals(getName(), that.getName()) && isRequired() == that.isRequired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getName(), isRequired());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package me.skymc.taboolib.commands.internal.type;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-23 3:07
|
||||
*/
|
||||
public class CommandField {
|
||||
|
||||
private final Field field;
|
||||
private final Class<?> parent;
|
||||
|
||||
public CommandField(Field field, Class<?> parent) {
|
||||
this.field = field;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public Field getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
public Class<?> getParent() {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package me.skymc.taboolib.commands.internal.type;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-09 22:38
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface CommandRegister {
|
||||
|
||||
double priority() default 0;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package me.skymc.taboolib.commands.internal.type;
|
||||
|
||||
/**
|
||||
* @author Bkm016
|
||||
* @since 2018-04-17
|
||||
*/
|
||||
public enum CommandType {
|
||||
|
||||
CONSOLE, PLAYER, ALL
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package me.skymc.taboolib.commands.language;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.commands.builder.SimpleCommandBuilder;
|
||||
import me.skymc.taboolib.common.loader.Instantiable;
|
||||
import me.skymc.taboolib.string.language2.Language2Value;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018年2月13日 下午5:11:01
|
||||
*/
|
||||
@Instantiable("Language2Command")
|
||||
public class Language2Command {
|
||||
|
||||
public Language2Command() {
|
||||
SimpleCommandBuilder.create("language2", TabooLib.instance())
|
||||
.aliases("lang2")
|
||||
.permission("taboolib.admin")
|
||||
.execute((sender, args) -> {
|
||||
if (args.length == 0) {
|
||||
TLocale.sendTo(sender, "COMMANDS.LANGUAGE2.HELP", "langauge2");
|
||||
} else if ("reload".equalsIgnoreCase(args[0])) {
|
||||
reload(sender);
|
||||
} else if ("send".equalsIgnoreCase(args[0])) {
|
||||
send(sender, args);
|
||||
}
|
||||
return true;
|
||||
}).build();
|
||||
}
|
||||
|
||||
private void send(CommandSender sender, String[] args) {
|
||||
if (args.length < 3) {
|
||||
TLocale.sendTo(sender, "COMMANDS.PARAMETER.UNKNOWN");
|
||||
} else {
|
||||
long time = System.currentTimeMillis();
|
||||
Language2Value value = getLanguage2Value(args);
|
||||
|
||||
if ("ALL".equalsIgnoreCase(args[1])) {
|
||||
value.broadcast();
|
||||
} else {
|
||||
Player player = Bukkit.getPlayerExact(args[1]);
|
||||
if (player == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.LANGUAGE2.INVALID-PLAYER", args[1]);
|
||||
} else {
|
||||
value.send(player);
|
||||
}
|
||||
}
|
||||
|
||||
if (sender instanceof Player && ((Player) sender).getItemInHand().getType().equals(Material.COMMAND)) {
|
||||
TLocale.sendTo(sender, "COMMANDS.LANGUAGE2.SUCCESS-SEND", String.valueOf(System.currentTimeMillis() - time));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Language2Value getLanguage2Value(String[] args) {
|
||||
Language2Value value = Main.getExampleLanguage2().get(args[2]);
|
||||
if (args.length > 3) {
|
||||
int i = 0;
|
||||
for (String variable : args[3].split("\\|")) {
|
||||
value.addPlaceholder("$" + i++, variable);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private void reload(CommandSender sender) {
|
||||
TLocale.sendTo(sender, "COMMANDS.RELOAD.LOADING");
|
||||
long time = System.currentTimeMillis();
|
||||
Main.getExampleLanguage2().reload();
|
||||
TLocale.sendTo(sender, "COMMANDS.RELOAD.SUCCESS-ELAPSED-TIME", String.valueOf(System.currentTimeMillis() - time));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package me.skymc.taboolib.commands.locale;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import com.ilummc.tlib.resources.TLocaleLoader;
|
||||
import me.skymc.taboolib.commands.internal.BaseMainCommand;
|
||||
import me.skymc.taboolib.commands.internal.BaseSubCommand;
|
||||
import me.skymc.taboolib.commands.internal.TCommand;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandArgument;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandRegister;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018-04-22 14:36:28
|
||||
*/
|
||||
@TCommand(
|
||||
name = "tabooliblocale",
|
||||
aliases = {"taboolocale", "tlocale"},
|
||||
permission = "taboolib.admin"
|
||||
)
|
||||
public class TabooLibLocaleCommand extends BaseMainCommand {
|
||||
|
||||
@Override
|
||||
public String getCommandTitle() {
|
||||
return TLocale.asString("COMMANDS.TLOCALE.COMMAND-TITLE");
|
||||
}
|
||||
|
||||
@CommandRegister
|
||||
BaseSubCommand send = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "send";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TLOCALE.SEND.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[] {
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TLOCALE.SEND.ARGUMENTS.0")),
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TLOCALE.SEND.ARGUMENTS.1")),
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TLOCALE.SEND.ARGUMENTS.2"), false)
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
List<CommandSender> target = new ArrayList<>();
|
||||
if (args[0].equalsIgnoreCase("all")) {
|
||||
target.add(Bukkit.getConsoleSender());
|
||||
target.addAll(Bukkit.getOnlinePlayers());
|
||||
} else if (args[0].equalsIgnoreCase("players")) {
|
||||
target.addAll(Bukkit.getOnlinePlayers());
|
||||
} else if (args[0].equalsIgnoreCase("console")) {
|
||||
target.add(Bukkit.getConsoleSender());
|
||||
} else {
|
||||
Player player = Bukkit.getPlayerExact(args[0]);
|
||||
if (player == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TLOCALE.SEND.INVALID-PLAYER", args[0]);
|
||||
return;
|
||||
}
|
||||
target.add(player);
|
||||
}
|
||||
|
||||
String[] arguments;
|
||||
if (args.length > 2) {
|
||||
arguments = new String[args.length - 2];
|
||||
IntStream.range(2, args.length).forEach(i -> arguments[i - 2] = args[i]);
|
||||
} else {
|
||||
arguments = new String[0];
|
||||
}
|
||||
|
||||
/*
|
||||
* 使用命令发送其他插件文本
|
||||
* /tlocale send BlackSKY testPlugin:message
|
||||
*/
|
||||
if (args[1].contains(":")) {
|
||||
String[] path = args[1].split(":");
|
||||
Plugin plugin = Bukkit.getPluginManager().getPlugin(path[0]);
|
||||
if (plugin == null || !TLocaleLoader.isLocaleLoaded(plugin)) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TLOCALE.SEND.INVALID-PLUGIN", path[0]);
|
||||
return;
|
||||
}
|
||||
if (path.length == 1) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TLOCALE.SEND.INVALID-PATH", args[1]);
|
||||
return;
|
||||
}
|
||||
target.forEach(x -> TLocaleLoader.sendTo(plugin, path[1], x, arguments));
|
||||
} else {
|
||||
target.forEach(x -> TLocale.sendTo(x, args[1], arguments));
|
||||
}
|
||||
|
||||
if (sender instanceof Player && ((Player) sender).getItemInHand().getType().equals(Material.COMMAND)) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TLOCALE.SEND.SUCCESS-SEND", String.valueOf(System.currentTimeMillis() - time));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
package me.skymc.taboolib.commands.plugin;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.commands.internal.BaseMainCommand;
|
||||
import me.skymc.taboolib.commands.internal.BaseSubCommand;
|
||||
import me.skymc.taboolib.commands.internal.TCommand;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandArgument;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandRegister;
|
||||
import me.skymc.taboolib.plugin.PluginLoadState;
|
||||
import me.skymc.taboolib.plugin.PluginLoadStateType;
|
||||
import me.skymc.taboolib.plugin.PluginUnloadState;
|
||||
import me.skymc.taboolib.plugin.PluginUtils;
|
||||
import me.skymc.taboolib.string.ArrayUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-07 20:14
|
||||
*/
|
||||
@TCommand(
|
||||
name = "taboolibplugin",
|
||||
aliases = {"tabooplugin", "tplugin"},
|
||||
permission = "taboolib.admin"
|
||||
)
|
||||
public class TabooLibPluginCommand extends BaseMainCommand {
|
||||
|
||||
@Override
|
||||
public String getCommandTitle() {
|
||||
return TLocale.asString("COMMANDS.TPLUGIN.COMMAND-TITLE");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getSubCommands().stream().filter(internalCommandExecutor -> internalCommandExecutor != null && (args[0].isEmpty() || internalCommandExecutor.getLabel().toLowerCase().startsWith(args[0].toLowerCase()))).map(BaseSubCommand::getLabel).collect(Collectors.toList());
|
||||
} else if (args.length > 1 && isPluginCommand(args[0])) {
|
||||
return Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(x -> !PluginUtils.isIgnored(x)).collect(Collectors.toList()).stream().filter(plugin -> args[1].isEmpty() || plugin.getName().toLowerCase().startsWith(args[1].toLowerCase())).map(Plugin::getName).collect(Collectors.toList());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@CommandRegister(priority = 1)
|
||||
BaseSubCommand load = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "load";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TPLUGIN.LOAD.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[] {new CommandArgument(TLocale.asString("COMMANDS.TPLUGIN.LOAD.ARGUMENTS.0"), true)};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
String name = ArrayUtils.arrayJoin(args, 0);
|
||||
if (PluginUtils.getPluginByName(name) != null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.LOAD.INVALID-PLUGIN", name, name + " already loaded!");
|
||||
} else {
|
||||
PluginLoadState loadState;
|
||||
try {
|
||||
loadState = PluginUtils.load(name);
|
||||
} catch (Exception e) {
|
||||
loadState = new PluginLoadState(PluginLoadStateType.INVALID_PLUGIN, e.toString());
|
||||
}
|
||||
switch (loadState.getStateType()) {
|
||||
case INVALID_DESCRIPTION: {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.LOAD.INVALID-DESCRIPTION");
|
||||
break;
|
||||
}
|
||||
case INVALID_PLUGIN: {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.LOAD.INVALID-PLUGIN", name, loadState.getMessage());
|
||||
break;
|
||||
}
|
||||
case FILE_NOT_FOUND: {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.LOAD.FILE-NOT-FOUND", name);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.LOAD.LOAD-SUCCESS", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 2)
|
||||
BaseSubCommand unload = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "unload";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TPLUGIN.UNLOAD.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[] {new CommandArgument(TLocale.asString("COMMANDS.TPLUGIN.UNLOAD.ARGUMENTS.0"), true)};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
String name = ArrayUtils.arrayJoin(args, 0);
|
||||
Plugin plugin = PluginUtils.getPluginByName(name);
|
||||
if (plugin == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.UNLOAD.INVALID-PLUGIN", name);
|
||||
} else if (PluginUtils.isIgnored(plugin)) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.UNLOAD.INVALID-PLUGIN-IGNORED", name);
|
||||
} else {
|
||||
PluginUnloadState unloadState;
|
||||
try {
|
||||
unloadState = PluginUtils.unload(plugin);
|
||||
} catch (Exception e) {
|
||||
unloadState = new PluginUnloadState(true, e.toString());
|
||||
}
|
||||
if (unloadState.isFailed()) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.UNLOAD.UNLOAD-FAIL", name, unloadState.getMessage());
|
||||
} else {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.UNLOAD.UNLOAD-SUCCESS", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 3)
|
||||
BaseSubCommand reload = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "reload";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TPLUGIN.RELOAD.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[] {new CommandArgument(TLocale.asString("COMMANDS.TPLUGIN.RELOAD.ARGUMENTS.0"), true)};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
String name = ArrayUtils.arrayJoin(args, 0);
|
||||
Plugin plugin = PluginUtils.getPluginByName(name);
|
||||
if (plugin == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.RELOAD.INVALID-PLUGIN", name);
|
||||
} else if (PluginUtils.isIgnored(plugin)) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.RELOAD.INVALID-PLUGIN-IGNORED", name);
|
||||
} else {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.RELOAD.TRY-RELOAD");
|
||||
PluginUtils.reload(plugin);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 4)
|
||||
BaseSubCommand info = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "info";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TPLUGIN.INFO.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[] {new CommandArgument(TLocale.asString("COMMANDS.TPLUGIN.INFO.ARGUMENTS.0"), true)};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
String name = ArrayUtils.arrayJoin(args, 0);
|
||||
Plugin plugin = PluginUtils.getPluginByName(name);
|
||||
if (plugin == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.INFO.INVALID-PLUGIN", name);
|
||||
} else {
|
||||
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() == null ? "" : plugin.getDescription().getCommands().keySet()));
|
||||
} catch (Exception e) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.INFO.INVALID-DESCRIPTION", name, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 5)
|
||||
BaseSubCommand list = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "list";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TPLUGIN.LIST.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
List<String> pluginList = Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(PluginUtils::getFormattedName).sorted(String.CASE_INSENSITIVE_ORDER).collect(Collectors.toList());
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.LIST.LIST-PLUGIN", String.valueOf(Bukkit.getPluginManager().getPlugins().length), Joiner.on(", ").join(pluginList));
|
||||
}
|
||||
};
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Private Methods
|
||||
//
|
||||
// *********************************
|
||||
|
||||
private boolean isPluginCommand(String label) {
|
||||
return "info".equalsIgnoreCase(label) || "load".equalsIgnoreCase(label) || "unload".equalsIgnoreCase(label) || "reload".equalsIgnoreCase(label);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package me.skymc.taboolib.commands.taboolib;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.commands.SubCommand;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class AttributesCommand extends SubCommand {
|
||||
|
||||
public AttributesCommand(CommandSender sender, String[] args) {
|
||||
super(sender, args);
|
||||
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ATTRIBUTES.HEAD");
|
||||
|
||||
Arrays.stream(new String[]{"damage", "speed", "attackspeed", "health", "knockback", "armor", "luck"}).forEach(attribute -> TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ATTRIBUTES.BODY", attribute));
|
||||
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ATTRIBUTES.FOOT");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package me.skymc.taboolib.commands.taboolib;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.commands.SubCommand;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class EnchantCommand extends SubCommand {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public EnchantCommand(CommandSender sender, String[] args) {
|
||||
super(sender, args);
|
||||
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ENCHANTS.HEAD");
|
||||
|
||||
Arrays.stream(Enchantment.values()).forEach(enchant -> TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ENCHANTS.BODY", String.valueOf(enchant.getId()), enchant.getName()));
|
||||
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ENCHANTS.FOOT");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package me.skymc.taboolib.commands.taboolib;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.commands.SubCommand;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class FlagCommand extends SubCommand {
|
||||
|
||||
public FlagCommand(CommandSender sender, String[] args) {
|
||||
super(sender, args);
|
||||
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.FLAGS.HEAD");
|
||||
|
||||
Arrays.stream(ItemFlag.values()).forEach(itemFlag -> TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ENCHANTS.BODY", itemFlag.name()));
|
||||
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.FLAGS.FOOT");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package me.skymc.taboolib.commands.taboolib;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.Main.StorageType;
|
||||
import me.skymc.taboolib.commands.SubCommand;
|
||||
import me.skymc.taboolib.fileutils.ConfigUtils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ImportCommand extends SubCommand {
|
||||
|
||||
public ImportCommand(CommandSender sender, String[] args) {
|
||||
super(sender, args);
|
||||
|
||||
if (isPlayer()) {
|
||||
TLocale.sendTo(sender, "COMMANDS.GLOBAL.ONLY-PLAYER");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Main.getStorageType() == StorageType.LOCAL) {
|
||||
TLocale.Logger.warn("COMMANDS.GLOBAL.ONLY-STORAGE-SQL");
|
||||
return;
|
||||
}
|
||||
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.IMPORTDATA.CLEARING");
|
||||
Main.getConnection().truncateTable(Main.getTablePrefix() + "_playerdata");
|
||||
|
||||
if (!Main.getPlayerDataFolder().exists()) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.IMPORTDATA.EMPTYDATA");
|
||||
return;
|
||||
}
|
||||
|
||||
int size = Objects.requireNonNull(Main.getPlayerDataFolder().listFiles()).length;
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.IMPORTDATA.IMPORTING-START", String.valueOf(size));
|
||||
|
||||
int loop = 1;
|
||||
for (File file : Objects.requireNonNull(Main.getPlayerDataFolder().listFiles())) {
|
||||
Main.getConnection().intoValue(Main.getTablePrefix() + "_playerdata", file.getName().replace(".yml", ""), ConfigUtils.encodeYAML(YamlConfiguration.loadConfiguration(file)));
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.IMPORTDATA.IMPORTING-PROGRESS", file.getName().replace(".yml", ""), String.valueOf(loop), String.valueOf(size));
|
||||
loop++;
|
||||
}
|
||||
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.IMPORTDATA.SUCCESS");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package me.skymc.taboolib.commands.taboolib;
|
||||
|
||||
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;
|
||||
|
||||
public class InfoCommand extends SubCommand {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public InfoCommand(CommandSender sender, String[] args) {
|
||||
super(sender, args);
|
||||
if (isPlayer()) {
|
||||
Player player = (Player) sender;
|
||||
if (player.getItemInHand().getType().equals(Material.AIR)) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.INFO.INVALID-ITEM");
|
||||
} else {
|
||||
NBTItem nbt = new NBTItem(player.getItemInHand());
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.INFO.ITEM-INFO",
|
||||
player.getItemInHand().getType().name(),
|
||||
ItemUtils.getCustomName(player.getItemInHand()),
|
||||
player.getItemInHand().getTypeId() + ":" + player.getItemInHand().getDurability(),
|
||||
JSONReader.formatJson(nbt.asNBTString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package me.skymc.taboolib.commands.taboolib;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.commands.SubCommand;
|
||||
import me.skymc.taboolib.inventory.ItemUtils;
|
||||
import me.skymc.taboolib.other.NumberUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ItemCommand extends SubCommand {
|
||||
|
||||
public ItemCommand(CommandSender sender, String[] args) {
|
||||
super(sender, args);
|
||||
|
||||
if (args.length < 2) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ITEM.INVALID-NAME");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ItemUtils.getCacheItem(args[1]) == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ITEM.INVALID-ITEM", args[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
Player player;
|
||||
Integer amount = 1;
|
||||
ItemStack item = ItemUtils.getCacheItem(args[1]).clone();
|
||||
|
||||
if (args.length > 2) {
|
||||
player = Bukkit.getPlayerExact(args[2]);
|
||||
if (player == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ITEM.INVALID-PLAYER", args[2]);
|
||||
return;
|
||||
}
|
||||
} else if (sender instanceof Player) {
|
||||
player = (Player) sender;
|
||||
} else {
|
||||
TLocale.sendTo(sender, "COMMANDS.GLOBAL.ONLY-PLAYER");
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length > 3) {
|
||||
amount = NumberUtils.getInteger(args[3]);
|
||||
if (amount < 1) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ITEM.INVALID-NUMBER");
|
||||
return;
|
||||
}
|
||||
}
|
||||
item.setAmount(amount);
|
||||
|
||||
HashMap<Integer, ItemStack> map = player.getInventory().addItem(item);
|
||||
if (map.size() > 0) {
|
||||
player.getWorld().dropItem(player.getLocation(), item);
|
||||
}
|
||||
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ITEM.SUCCESS", player.getName());
|
||||
setReturn(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package me.skymc.taboolib.commands.taboolib;
|
||||
|
||||
import me.skymc.taboolib.commands.SubCommand;
|
||||
import me.skymc.taboolib.commands.taboolib.listener.ListenerItemListCommand;
|
||||
import me.skymc.taboolib.other.NumberUtils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018年2月4日 下午8:08:22
|
||||
*/
|
||||
public class ItemListCommand extends SubCommand {
|
||||
|
||||
public ItemListCommand(CommandSender sender, String[] args) {
|
||||
super(sender, args);
|
||||
if (isPlayer()) {
|
||||
if (args.length == 1) {
|
||||
ListenerItemListCommand.openInventory((Player) sender, 1);
|
||||
} else {
|
||||
ListenerItemListCommand.openInventory((Player) sender, NumberUtils.getInteger(args[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package me.skymc.taboolib.commands.taboolib;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.commands.SubCommand;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
public class PotionCommand extends SubCommand {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public PotionCommand(CommandSender sender, String[] args) {
|
||||
super(sender, args);
|
||||
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.POTIONS.HEAD");
|
||||
|
||||
for (PotionEffectType potionEffectType : PotionEffectType.values()) {
|
||||
if (potionEffectType != null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.POTIONS.BODY", String.valueOf(potionEffectType.getId()), potionEffectType.getName());
|
||||
}
|
||||
}
|
||||
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.POTIONS.FOOT");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package me.skymc.taboolib.commands.taboolib;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.commands.SubCommand;
|
||||
import me.skymc.taboolib.fileutils.ConfigUtils;
|
||||
import me.skymc.taboolib.inventory.ItemUtils;
|
||||
import me.skymc.taboolib.message.ChatCatcher;
|
||||
import me.skymc.taboolib.message.ChatCatcher.Catcher;
|
||||
import me.skymc.taboolib.message.MsgUtils;
|
||||
import me.skymc.taboolib.playerdata.DataUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
*/
|
||||
public class SaveCommand extends SubCommand {
|
||||
|
||||
public SaveCommand(CommandSender sender, String[] args) {
|
||||
super(sender, args);
|
||||
if (!(sender instanceof Player)) {
|
||||
TLocale.sendTo(sender, "COMMANDS.GLOBAL.ONLY-PLAYER");
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length < 2) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SAVE.INVALID-NAME");
|
||||
return;
|
||||
}
|
||||
|
||||
if (((Player) sender).getItemInHand().getType().equals(Material.AIR)) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SAVE.INVALID-ITEM");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ItemUtils.getItemCachesFinal().containsKey(args[1])) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SAVE.INVALID-ITEM-FINAL-EXISTS");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ItemUtils.getItemCaches().containsKey(args[1])) {
|
||||
// 检查聊天引导
|
||||
if (ChatCatcher.contains((Player) sender)) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SAVE.GUIDE-EXISTS");
|
||||
return;
|
||||
}
|
||||
|
||||
ChatCatcher.call((Player) sender, new Catcher() {
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SAVE.GUIDE-QUIT");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Catcher before() {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SAVE.GUIDE-BEFORE", args[1]);
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean after(String message) {
|
||||
if ("yes".equalsIgnoreCase(message)) {
|
||||
saveItem(args[1], ((Player) sender).getItemInHand());
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SAVE.SUCCESS", args[1]);
|
||||
} else {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SAVE.GUIDE-QUIT");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
saveItem(args[1], ((Player) sender).getItemInHand());
|
||||
MsgUtils.send(sender, "物品 &f" + args[1] + " &7已保存");
|
||||
}
|
||||
}
|
||||
|
||||
private void saveItem(String name, ItemStack item) {
|
||||
FileConfiguration conf = ConfigUtils.load(Main.getInst(), ItemUtils.getItemCacheFile());
|
||||
conf.set(name + ".bukkit", item);
|
||||
DataUtils.saveConfiguration(conf, ItemUtils.getItemCacheFile());
|
||||
ItemUtils.reloadItemCache();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package me.skymc.taboolib.commands.taboolib;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.commands.SubCommand;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class SlotCommand extends SubCommand {
|
||||
|
||||
public SlotCommand(CommandSender sender, String[] args) {
|
||||
super(sender, args);
|
||||
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SLOTS.HEAD");
|
||||
|
||||
Arrays.stream(new String[]{"mainhand", "offhand", "feet", "legs", "chest", "head", "all"}).forEach(slots -> TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SLOTS.BODY", slots));
|
||||
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SLOTS.FOOT");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package me.skymc.taboolib.commands.taboolib;
|
||||
|
||||
import me.skymc.taboolib.commands.SubCommand;
|
||||
import me.skymc.taboolib.commands.taboolib.listener.ListenerSoundsCommand;
|
||||
import me.skymc.taboolib.other.NumberUtils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018-03-18 21:02:26
|
||||
*/
|
||||
public class SoundsCommand extends SubCommand {
|
||||
|
||||
public SoundsCommand(CommandSender sender, String[] args) {
|
||||
super(sender, args);
|
||||
if (isPlayer()) {
|
||||
if (args.length == 1) {
|
||||
ListenerSoundsCommand.openInventory((Player) sender, 1, null);
|
||||
} else if (args.length == 2) {
|
||||
ListenerSoundsCommand.openInventory((Player) sender, NumberUtils.getInteger(args[1]), null);
|
||||
} else {
|
||||
ListenerSoundsCommand.openInventory((Player) sender, NumberUtils.getInteger(args[1]), args[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package me.skymc.taboolib.commands.taboolib;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.commands.SubCommand;
|
||||
import me.skymc.taboolib.itagapi.TagDataHandler;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018-03-19 23:13:35
|
||||
*/
|
||||
public class TagDeleteCommand extends SubCommand {
|
||||
|
||||
public TagDeleteCommand(CommandSender sender, String[] args) {
|
||||
super(sender, args);
|
||||
if (args.length < 2) {
|
||||
TLocale.sendTo(sender, "COMMANDS.PARAMETER.UNKNOWN");
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = Bukkit.getPlayerExact(args[1]);
|
||||
if (player == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.INVALID-PLAYER", args[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
TagDataHandler.getHandler().reset(player);
|
||||
|
||||
if (sender instanceof Player) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.SUCCESS-DELETE", args[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package me.skymc.taboolib.commands.taboolib;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.commands.SubCommand;
|
||||
import me.skymc.taboolib.itagapi.TagDataHandler;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018-03-19 23:13:35
|
||||
*/
|
||||
public class TagDisplayCommand extends SubCommand {
|
||||
|
||||
public TagDisplayCommand(CommandSender sender, String[] args) {
|
||||
super(sender, args);
|
||||
if (args.length < 3) {
|
||||
TLocale.sendTo(sender, "COMMANDS.PARAMETER.UNKNOWN");
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = Bukkit.getPlayerExact(args[1]);
|
||||
if (player == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.INVALID-PLAYER", args[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
String value = TLocale.Translate.setPlaceholders(player, getArgs(2));
|
||||
TagDataHandler.getHandler().setDisplay(player, value);
|
||||
|
||||
if (sender instanceof Player) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.SUCCESS-DISPLAY-SET", args[1], value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package me.skymc.taboolib.commands.taboolib;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.commands.SubCommand;
|
||||
import me.skymc.taboolib.itagapi.TagDataHandler;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018-03-19 23:13:35
|
||||
*/
|
||||
public class TagPrefixCommand extends SubCommand {
|
||||
|
||||
public TagPrefixCommand(CommandSender sender, String[] args) {
|
||||
super(sender, args);
|
||||
if (args.length < 3) {
|
||||
TLocale.sendTo(sender, "COMMANDS.PARAMETER.UNKNOWN");
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = Bukkit.getPlayerExact(args[1]);
|
||||
if (player == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.INVALID-PLAYER", args[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
String value = TLocale.Translate.setPlaceholders(player, getArgs(2));
|
||||
TagDataHandler.getHandler().setPrefix(player, value);
|
||||
|
||||
if (sender instanceof Player) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.SUCCESS-PREFIX-SET", args[1], value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package me.skymc.taboolib.commands.taboolib;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.commands.SubCommand;
|
||||
import me.skymc.taboolib.itagapi.TagDataHandler;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018-03-19 23:13:35
|
||||
*/
|
||||
public class TagSuffixCommand extends SubCommand {
|
||||
|
||||
public TagSuffixCommand(CommandSender sender, String[] args) {
|
||||
super(sender, args);
|
||||
if (args.length < 3) {
|
||||
TLocale.sendTo(sender, "COMMANDS.PARAMETER.UNKNOWN");
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = Bukkit.getPlayerExact(args[1]);
|
||||
if (player == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.INVALID-PLAYER", args[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
String value = TLocale.Translate.setPlaceholders(player, getArgs(2));
|
||||
TagDataHandler.getHandler().setSuffix(player, value);
|
||||
|
||||
if (sender instanceof Player) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.SUCCESS-SUFFIX-SET", args[1], value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package me.skymc.taboolib.commands.taboolib;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.commands.SubCommand;
|
||||
import me.skymc.taboolib.database.GlobalDataManager;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
*/
|
||||
public class VariableGetCommand extends SubCommand {
|
||||
|
||||
public VariableGetCommand(CommandSender sender, String[] args) {
|
||||
super(sender, args);
|
||||
|
||||
if (args.length < 3) {
|
||||
TLocale.sendTo(sender, "COMMANDS.PARAMETER.INSUFFICIENT");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!("-a".equals(args[1]) || "-s".equals(args[1]))) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.VARIABLE.READ-ERROR-TYPE");
|
||||
return;
|
||||
}
|
||||
|
||||
Long time = System.currentTimeMillis();
|
||||
String value = null;
|
||||
|
||||
if ("-s".equals(args[1])) {
|
||||
value = GlobalDataManager.getVariable(args[2], null);
|
||||
} else if ("-a".equals(args[1])) {
|
||||
value = GlobalDataManager.getVariableAsynchronous(args[2], null);
|
||||
}
|
||||
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.VARIABLE.READ-SUCCESS", String.valueOf(System.currentTimeMillis() - time));
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.VARIABLE.READ-RESULT", value == null ? "null" : value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package me.skymc.taboolib.commands.taboolib;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.commands.SubCommand;
|
||||
import me.skymc.taboolib.database.GlobalDataManager;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class VariableSetCommand extends SubCommand {
|
||||
|
||||
public VariableSetCommand(CommandSender sender, String[] args) {
|
||||
super(sender, args);
|
||||
|
||||
if (args.length < 4) {
|
||||
TLocale.sendTo(sender, "COMMANDS.PARAMETER.INSUFFICIENT");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!("-a".equals(args[1]) || "-s".equals(args[1]))) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.VARIABLE.WRITE-ERROR-TYPE");
|
||||
return;
|
||||
}
|
||||
|
||||
Long time = System.currentTimeMillis();
|
||||
String value = getArgs(3);
|
||||
|
||||
if ("-s".equals(args[1])) {
|
||||
GlobalDataManager.setVariable(args[2], value);
|
||||
} else if ("-a".equals(args[1])) {
|
||||
GlobalDataManager.setVariableAsynchronous(args[2], value);
|
||||
}
|
||||
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.VARIABLE.WRITE-SUCCESS", String.valueOf(System.currentTimeMillis() - time));
|
||||
setReturn(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package me.skymc.taboolib.commands.taboolib.listener;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.inventory.InventoryUtil;
|
||||
import me.skymc.taboolib.inventory.ItemUtils;
|
||||
import me.skymc.taboolib.listener.TListener;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018年2月4日 下午4:35:00
|
||||
*/
|
||||
@TListener
|
||||
public class ListenerItemListCommand implements Listener {
|
||||
|
||||
/**
|
||||
* 打开物品库界面
|
||||
*
|
||||
* @param player
|
||||
* @param page
|
||||
*/
|
||||
public static void openInventory(Player player, int page) {
|
||||
ItemLibraryHolder holder = new ItemLibraryHolder(page);
|
||||
Inventory inventory = Bukkit.createInventory(holder, 54, TLocale.asString("COMMANDS.TABOOLIB.ITEMLIST.MENU.TITLE", String.valueOf(page)));
|
||||
|
||||
LinkedHashMap<String, ItemStack> map = new LinkedHashMap<>();
|
||||
map.putAll(ItemUtils.getItemCachesFinal());
|
||||
map.putAll(ItemUtils.getItemCaches());
|
||||
|
||||
int loop = 0;
|
||||
for (String name : map.keySet()) {
|
||||
if (loop >= (page - 1) * 28) {
|
||||
if (loop < page * 28) {
|
||||
int slot = InventoryUtil.SLOT_OF_CENTENTS.get(loop - ((page - 1) * 28));
|
||||
ItemStack item = map.get(name).clone();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
|
||||
lore.addAll(TLocale.asStringList("COMMANDS.TABOOLIB.ITEMLIST.MENU.LORE", name));
|
||||
meta.setLore(lore);
|
||||
item.setItemMeta(meta);
|
||||
inventory.setItem(slot, item);
|
||||
holder.ITEMS_DATA.put(slot, name);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
loop++;
|
||||
}
|
||||
|
||||
if (page > 1) {
|
||||
inventory.setItem(47, ItemUtils.setName(new ItemStack(Material.ARROW), TLocale.asString("COMMANDS.TABOOLIB.ITEMLIST.MENU.BACK")));
|
||||
}
|
||||
if (((int) Math.ceil(map.size() / 28D)) > page) {
|
||||
inventory.setItem(51, ItemUtils.setName(new ItemStack(Material.ARROW), TLocale.asString("COMMANDS.TABOOLIB.ITEMLIST.MENU.NEXT")));
|
||||
}
|
||||
player.openInventory(inventory);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void inventoryClick(InventoryClickEvent e) {
|
||||
if (e.getInventory().getHolder() instanceof ItemLibraryHolder) {
|
||||
e.setCancelled(true);
|
||||
|
||||
if (e.getCurrentItem() == null || e.getCurrentItem().getType().equals(Material.AIR) || e.getRawSlot() >= e.getInventory().getSize()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int i = e.getRawSlot();
|
||||
if (i == 47) {
|
||||
openInventory((Player) e.getWhoClicked(), ((ItemLibraryHolder) e.getInventory().getHolder()).PAGE - 1);
|
||||
} else if (i == 51) {
|
||||
openInventory((Player) e.getWhoClicked(), ((ItemLibraryHolder) e.getInventory().getHolder()).PAGE + 1);
|
||||
} else {
|
||||
e.getWhoClicked().getInventory().addItem(ItemUtils.getCacheItem(((ItemLibraryHolder) e.getInventory().getHolder()).ITEMS_DATA.get(e.getRawSlot())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ItemLibraryHolder implements InventoryHolder {
|
||||
|
||||
public final int PAGE;
|
||||
public final HashMap<Integer, String> ITEMS_DATA = new HashMap<>();
|
||||
|
||||
public ItemLibraryHolder(int page) {
|
||||
this.PAGE = page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package me.skymc.taboolib.commands.taboolib.listener;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.inventory.InventoryUtil;
|
||||
import me.skymc.taboolib.inventory.ItemUtils;
|
||||
import me.skymc.taboolib.listener.TListener;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018年2月4日 下午4:35:00
|
||||
*/
|
||||
@TListener
|
||||
public class ListenerSoundsCommand implements Listener {
|
||||
|
||||
public static void openInventory(Player player, int page, String search) {
|
||||
if (page < 1) {
|
||||
page = 1;
|
||||
}
|
||||
|
||||
SoundLibraryHolder holder = new SoundLibraryHolder(page, search);
|
||||
Inventory inventory = Bukkit.createInventory(holder, 54, TLocale.asString("COMMANDS.TABOOLIB.SOUNDS.MENU.TITLE", String.valueOf(page)));
|
||||
List<Sound> soundFilter = Arrays.stream(Sound.values()).filter(sound -> search == null || sound.name().contains(search.toUpperCase())).collect(Collectors.toList());
|
||||
List<String> soundLore = TLocale.asStringList("COMMANDS.TABOOLIB.SOUNDS.MENU.LORE");
|
||||
|
||||
int loop = 0;
|
||||
for (Sound sound : soundFilter) {
|
||||
if (loop >= (page - 1) * 28) {
|
||||
if (loop < page * 28) {
|
||||
int slot = InventoryUtil.SLOT_OF_CENTENTS.get(loop - ((page - 1) * 28));
|
||||
ItemStack item = new ItemStack(Material.MAP);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
meta.setDisplayName("§f§n" + sound);
|
||||
meta.setLore(soundLore);
|
||||
item.setItemMeta(meta);
|
||||
inventory.setItem(slot, item);
|
||||
holder.SOUNDS_DATA.put(slot, sound);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
loop++;
|
||||
}
|
||||
|
||||
if (page > 1) {
|
||||
inventory.setItem(47, ItemUtils.setName(new ItemStack(Material.ARROW), TLocale.asString("COMMANDS.TABOOLIB.SOUNDS.MENU.BACK")));
|
||||
}
|
||||
if (((int) Math.ceil(Sound.values().length / 28D)) > page) {
|
||||
inventory.setItem(51, ItemUtils.setName(new ItemStack(Material.ARROW), TLocale.asString("COMMANDS.TABOOLIB.SOUNDS.MENU.NEXT")));
|
||||
}
|
||||
|
||||
if (!(player.getOpenInventory().getTopInventory().getHolder() instanceof SoundLibraryHolder)) {
|
||||
TLocale.sendTo(player, "COMMANDS.TABOOLIB.SOUNDS.RESULT.SEARCH", (search == null ? "*" : search), String.valueOf(soundFilter.size()));
|
||||
}
|
||||
player.openInventory(inventory);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void inventoryClick(InventoryClickEvent e) {
|
||||
if (e.getInventory().getHolder() instanceof SoundLibraryHolder) {
|
||||
e.setCancelled(true);
|
||||
|
||||
if (e.getCurrentItem() == null || e.getCurrentItem().getType().equals(Material.AIR) || e.getRawSlot() >= e.getInventory().getSize()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SoundLibraryHolder soundLibraryHolder = ((SoundLibraryHolder) e.getInventory().getHolder());
|
||||
int i = e.getRawSlot();
|
||||
if (i == 47) {
|
||||
openInventory((Player) e.getWhoClicked(), soundLibraryHolder.PAGE - 1, soundLibraryHolder.SEARCH);
|
||||
} else if (i == 51) {
|
||||
openInventory((Player) e.getWhoClicked(), soundLibraryHolder.PAGE + 1, soundLibraryHolder.SEARCH);
|
||||
} else {
|
||||
Sound sound = soundLibraryHolder.SOUNDS_DATA.get(e.getRawSlot());
|
||||
if (e.getClick().isKeyboardClick()) {
|
||||
((Player) e.getWhoClicked()).playSound(e.getWhoClicked().getLocation(), sound, 1f, 0f);
|
||||
} else if (e.getClick().isLeftClick()) {
|
||||
((Player) e.getWhoClicked()).playSound(e.getWhoClicked().getLocation(), sound, 1f, 1f);
|
||||
} else if (e.getClick().isRightClick()) {
|
||||
((Player) e.getWhoClicked()).playSound(e.getWhoClicked().getLocation(), sound, 1f, 2f);
|
||||
} else if (e.getClick().isCreativeAction()) {
|
||||
TLocale.sendTo(e.getWhoClicked(), "COMMANDS.TABOOLIB.SOUNDS.RESULT.COPY", sound.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class SoundLibraryHolder implements InventoryHolder {
|
||||
|
||||
public final int PAGE;
|
||||
public final String SEARCH;
|
||||
public final HashMap<Integer, Sound> SOUNDS_DATA = new HashMap<>();
|
||||
|
||||
public SoundLibraryHolder(int page, String search) {
|
||||
this.PAGE = page;
|
||||
this.SEARCH = search;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package me.skymc.taboolib.common.configuration;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.ilummc.tlib.TLib;
|
||||
import com.ilummc.tlib.logger.TLogger;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import com.ilummc.tlib.util.Ref;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-08 15:00
|
||||
*/
|
||||
public class TConfiguration extends YamlConfiguration {
|
||||
|
||||
private static Map<String, List<File>> files = Maps.newHashMap();
|
||||
private File file;
|
||||
private Runnable runnable;
|
||||
|
||||
private TConfiguration(File file, Plugin plugin) {
|
||||
files.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(file);
|
||||
this.file = file;
|
||||
reload();
|
||||
TLib.getTLib().getConfigWatcher().addSimpleListener(this.file, this::reload);
|
||||
TabooLib.debug("Loaded TConfiguration \"" + file.getName() + "\" from Plugin \"" + plugin.getName() + "\"");
|
||||
}
|
||||
|
||||
public static Map<String, List<File>> getFiles() {
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建配置文件
|
||||
*
|
||||
* @param file 文件
|
||||
* @return {@link TConfiguration}
|
||||
*/
|
||||
public static TConfiguration create(File file) {
|
||||
return new TConfiguration(file, Ref.getCallerPlugin(Ref.getCallerClass(3).orElse(Main.class)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建配置文件
|
||||
*
|
||||
* @param file 文件
|
||||
* @param plugin 插件
|
||||
* @return {@link TConfiguration}
|
||||
*/
|
||||
public static TConfiguration create(File file, Plugin plugin) {
|
||||
return new TConfiguration(file, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从插件里释放文件并创建
|
||||
*
|
||||
* @param plugin 插件
|
||||
* @param path 目录
|
||||
* @return {@link TConfiguration}
|
||||
*/
|
||||
public static TConfiguration createInResource(Plugin plugin, String path) {
|
||||
File file = new File(plugin.getDataFolder(), path);
|
||||
if (!file.exists()) {
|
||||
plugin.saveResource(path, true);
|
||||
}
|
||||
return create(file, plugin);
|
||||
}
|
||||
|
||||
public String getStringColored(String path) {
|
||||
return TLocale.Translate.setColored(getString(path));
|
||||
}
|
||||
|
||||
public String getStringColored(String path, String def) {
|
||||
return TLocale.Translate.setColored(getString(path, def));
|
||||
}
|
||||
|
||||
public List<String> getStringListColored(String path) {
|
||||
return TLocale.Translate.setColored(getStringList(path));
|
||||
}
|
||||
|
||||
public void release() {
|
||||
TLib.getTLib().getConfigWatcher().removeListener(file);
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
try {
|
||||
load(file);
|
||||
runListener();
|
||||
} catch (IOException | InvalidConfigurationException e) {
|
||||
TLogger.getGlobalLogger().warn("Cannot load configuration from stream: " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Getter and Setter
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public TConfiguration listener(Runnable runnable) {
|
||||
this.runnable = runnable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void runListener() {
|
||||
try {
|
||||
Optional.ofNullable(runnable).ifPresent(Runnable::run);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package me.skymc.taboolib.common.function;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-08 14:01
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TFunction {
|
||||
|
||||
String enable() default "onEnable";
|
||||
String disable() default "onDisable";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package me.skymc.taboolib.common.function;
|
||||
|
||||
import com.ilummc.tlib.logger.TLogger;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.TabooLibLoader;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-08 14:00
|
||||
*/
|
||||
public class TFunctionLoader implements TabooLibLoader.Loader {
|
||||
|
||||
@Override
|
||||
public void postLoad(Plugin plugin, Class<?> pluginClass) {
|
||||
if (pluginClass.isAnnotationPresent(TFunction.class)) {
|
||||
TFunction function = pluginClass.getAnnotation(TFunction.class);
|
||||
try {
|
||||
Method method = pluginClass.getDeclaredMethod(function.enable());
|
||||
if (!Modifier.isStatic(method.getModifiers())) {
|
||||
TLogger.getGlobalLogger().error(method.getName() + " is not a static method.");
|
||||
return;
|
||||
}
|
||||
method.setAccessible(true);
|
||||
method.invoke(null);
|
||||
TabooLib.debug("Function " + pluginClass.getSimpleName() + " loaded. (" + plugin.getName() + ")");
|
||||
} catch (NoSuchMethodException ignore) {
|
||||
} catch (Exception e) {
|
||||
TLogger.getGlobalLogger().warn("TFunction load Failed: " + pluginClass.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload(Plugin plugin, Class<?> pluginClass) {
|
||||
if (pluginClass.isAnnotationPresent(TFunction.class)) {
|
||||
TFunction function = pluginClass.getAnnotation(TFunction.class);
|
||||
try {
|
||||
Method method = pluginClass.getDeclaredMethod(function.disable());
|
||||
if (!Modifier.isStatic(method.getModifiers())) {
|
||||
TLogger.getGlobalLogger().error(method.getName() + " is not a static method.");
|
||||
return;
|
||||
}
|
||||
method.setAccessible(true);
|
||||
method.invoke(null);
|
||||
TabooLib.debug("Function " + pluginClass.getSimpleName() + " unloaded. (" + plugin.getName() + ")");
|
||||
} catch (NoSuchMethodException ignore) {
|
||||
} catch (Exception e) {
|
||||
TLogger.getGlobalLogger().warn("TFunction unload Failed: " + pluginClass.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
18
src/main/scala/me/skymc/taboolib/common/inject/TInject.java
Normal file
18
src/main/scala/me/skymc/taboolib/common/inject/TInject.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package me.skymc.taboolib.common.inject;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-10-05 12:11
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TInject {
|
||||
|
||||
String[] value() default {};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package me.skymc.taboolib.common.inject;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.ilummc.tlib.logger.TLogger;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.TabooLibLoader;
|
||||
import me.skymc.taboolib.commands.builder.SimpleCommandBuilder;
|
||||
import me.skymc.taboolib.common.configuration.TConfiguration;
|
||||
import me.skymc.taboolib.common.packet.TPacketHandler;
|
||||
import me.skymc.taboolib.common.packet.TPacketListener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-10-05 13:40
|
||||
*/
|
||||
public class TInjectLoader implements TabooLibLoader.Loader {
|
||||
|
||||
private static Map<Class<?>, TInjectTask> injectTypes = Maps.newHashMap();
|
||||
|
||||
static {
|
||||
// Instance Inject
|
||||
injectTypes.put(Plugin.class, (plugin, field, args, instance) -> {
|
||||
try {
|
||||
field.set(instance, plugin);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
// TLogger Inject
|
||||
injectTypes.put(TLogger.class, (plugin, field, args, instance) -> {
|
||||
try {
|
||||
field.set(instance, args.length == 0 ? TLogger.getUnformatted(plugin) : TLogger.getUnformatted(args[0]));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
// TPacketListener Inject
|
||||
injectTypes.put(TPacketListener.class, (plugin, field, args, instance) -> {
|
||||
try {
|
||||
TPacketHandler.addListener(plugin, ((TPacketListener) field.get(instance)));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
// TConfiguration Inject
|
||||
injectTypes.put(TConfiguration.class, (plugin, field, args, instance) -> {
|
||||
try {
|
||||
if (args.length == 0) {
|
||||
TLogger.getGlobalLogger().error("Invalid inject arguments: " + field.getName() + " (" + field.getType().getName() + ")");
|
||||
} else {
|
||||
field.set(instance, TConfiguration.createInResource(plugin, args[0]));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
// SimpleCommandBuilder Inject
|
||||
injectTypes.put(SimpleCommandBuilder.class, (plugin, field, args, instance) -> {
|
||||
try {
|
||||
SimpleCommandBuilder builder = (SimpleCommandBuilder) field.get(instance);
|
||||
if (builder.isBuild()) {
|
||||
TLogger.getGlobalLogger().error("Command was registered. (" + field.getType().getName() + ")");
|
||||
} else {
|
||||
if (builder.getPlugin() == null) {
|
||||
builder.plugin(plugin);
|
||||
}
|
||||
builder.build();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
return -999;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preLoad(Plugin plugin, Class<?> pluginClass) {
|
||||
for (Field declaredField : pluginClass.getDeclaredFields()) {
|
||||
TInject annotation = declaredField.getAnnotation(TInject.class);
|
||||
// 是否为主类类型
|
||||
if (annotation == null || !declaredField.getType().equals(plugin.getClass())) {
|
||||
continue;
|
||||
}
|
||||
Object instance = null;
|
||||
// 如果是非静态类型
|
||||
if (!Modifier.isStatic(declaredField.getModifiers())) {
|
||||
// 是否为主类
|
||||
if (pluginClass.equals(plugin.getClass())) {
|
||||
instance = plugin;
|
||||
} else {
|
||||
TLogger.getGlobalLogger().error(declaredField.getName() + " is not a static field. (" + declaredField.getType().getName() + ")");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
inject(plugin, declaredField, instance, annotation, injectTypes.get(Plugin.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postLoad(Plugin plugin, Class<?> pluginClass) {
|
||||
for (Field declaredField : pluginClass.getDeclaredFields()) {
|
||||
TInject annotation = declaredField.getAnnotation(TInject.class);
|
||||
if (annotation == null || declaredField.getType().equals(plugin.getClass())) {
|
||||
continue;
|
||||
}
|
||||
Object instance = null;
|
||||
// 如果是非静态类型
|
||||
if (!Modifier.isStatic(declaredField.getModifiers())) {
|
||||
// 是否为主类
|
||||
if (pluginClass.equals(plugin.getClass())) {
|
||||
instance = plugin;
|
||||
} else {
|
||||
TLogger.getGlobalLogger().error(declaredField.getName() + " is not a static field. (" + declaredField.getType().getName() + ")");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
TInjectTask tInjectTask = injectTypes.get(declaredField.getType());
|
||||
if (tInjectTask != null) {
|
||||
inject(plugin, declaredField, instance, annotation, tInjectTask);
|
||||
} else {
|
||||
TLogger.getGlobalLogger().error(declaredField.getName() + " is an invalid inject type. (" + declaredField.getType().getName() + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void inject(Plugin plugin, Field field, Object instance, TInject annotation, TInjectTask injectTask) {
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
injectTask.run(plugin, field, annotation.value(), instance);
|
||||
TabooLib.debug(field.getName() + " injected. (" + field.getType().getName() + ")");
|
||||
} catch (Throwable e) {
|
||||
TLogger.getGlobalLogger().error(field.getName() + " inject failed: " + e.getMessage() + " (" + field.getType().getName() + ")");
|
||||
if (e.getMessage() == null) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package me.skymc.taboolib.common.inject;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-10-05 13:41
|
||||
*/
|
||||
public interface TInjectTask {
|
||||
|
||||
void run(Plugin plugin, Field field, String[] args, Object instance);
|
||||
|
||||
}
|
||||
350
src/main/scala/me/skymc/taboolib/common/json/TJsonArray.java
Normal file
350
src/main/scala/me/skymc/taboolib/common/json/TJsonArray.java
Normal file
@@ -0,0 +1,350 @@
|
||||
package me.skymc.taboolib.common.json;
|
||||
|
||||
import com.google.gson.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Spliterator;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* 让 JsonObject 有更加人性化的操作,目前版本只能获取数据。
|
||||
*
|
||||
* @Author 坏黑
|
||||
* @Since 2018-10-27 23:46
|
||||
*/
|
||||
public class TJsonArray implements Iterable<TJsonObject> {
|
||||
|
||||
private JsonArray jsonArray;
|
||||
|
||||
TJsonArray(JsonArray jsonArray) {
|
||||
this.jsonArray = jsonArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 Json 原代码中获取
|
||||
*
|
||||
* @param json 源代码
|
||||
* @return {@link TJsonArray}
|
||||
* @throws JsonParseException if the specified text is not valid JSON
|
||||
* @throws IllegalStateException This is not a JSON Array.
|
||||
*/
|
||||
public static TJsonArray fromJson(String json) throws JsonParseException, IllegalStateException {
|
||||
return new TJsonArray(new JsonParser().parse(json).getAsJsonArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 JsonArray 创建
|
||||
*
|
||||
* @param jsonArray JsonArray 对象
|
||||
* @return {@link TJsonObject}
|
||||
*/
|
||||
public static TJsonArray fromJsonArray(JsonArray jsonArray) {
|
||||
return new TJsonArray(jsonArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加成员
|
||||
*
|
||||
* @param obj 成员
|
||||
*/
|
||||
public void add(TJsonObject obj) {
|
||||
jsonArray.add(obj.asOriginJsonElement());
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加成员
|
||||
*
|
||||
* @param obj 成员
|
||||
*/
|
||||
public void add(Boolean obj) {
|
||||
jsonArray.add(new JsonPrimitive(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加成员
|
||||
*
|
||||
* @param obj 成员
|
||||
*/
|
||||
public void add(Character obj) {
|
||||
jsonArray.add(new JsonPrimitive(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加成员
|
||||
*
|
||||
* @param obj 成员
|
||||
*/
|
||||
public void add(Number obj) {
|
||||
jsonArray.add(new JsonPrimitive(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加成员
|
||||
*
|
||||
* @param obj 成员
|
||||
*/
|
||||
public void add(String obj) {
|
||||
jsonArray.add(new JsonPrimitive(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加所有成员
|
||||
*
|
||||
* @param array 成员集合
|
||||
*/
|
||||
public void addAll(TJsonArray array) {
|
||||
jsonArray.add(array.asOriginJsonArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置成员
|
||||
*
|
||||
* @param index 位置
|
||||
* @param obj 成员
|
||||
*/
|
||||
public void set(int index, TJsonObject obj) {
|
||||
jsonArray.set(index, obj.asOriginJsonElement());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置成员
|
||||
*
|
||||
* @param index 位置
|
||||
* @param obj 成员
|
||||
*/
|
||||
public void set(int index, Boolean obj) {
|
||||
jsonArray.set(index, new JsonPrimitive(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置成员
|
||||
*
|
||||
* @param index 位置
|
||||
* @param obj 成员
|
||||
*/
|
||||
public void set(int index, Number obj) {
|
||||
jsonArray.set(index, new JsonPrimitive(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置成员
|
||||
*
|
||||
* @param index 位置
|
||||
* @param obj 成员
|
||||
*/
|
||||
public void set(int index, String obj) {
|
||||
jsonArray.set(index, new JsonPrimitive(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除成员
|
||||
*
|
||||
* @param obj 成员
|
||||
*/
|
||||
public void remove(JsonElement obj) {
|
||||
jsonArray.remove(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除成员
|
||||
*
|
||||
* @param obj 成员
|
||||
*/
|
||||
public void remove(Boolean obj) {
|
||||
jsonArray.remove(new JsonPrimitive(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除成员
|
||||
*
|
||||
* @param obj 成员
|
||||
*/
|
||||
public void remove(Number obj) {
|
||||
jsonArray.remove(new JsonPrimitive(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除成员
|
||||
*
|
||||
* @param obj 成员
|
||||
*/
|
||||
public void remove(String obj) {
|
||||
jsonArray.remove(new JsonPrimitive(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* 含有成员
|
||||
*
|
||||
* @param obj 成员
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean contains(JsonElement obj) {
|
||||
return jsonArray.contains(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 含有成员
|
||||
*
|
||||
* @param obj 成员
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean contains(Boolean obj) {
|
||||
return jsonArray.contains(new JsonPrimitive(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* 含有成员
|
||||
*
|
||||
* @param obj 成员
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean contains(Number obj) {
|
||||
return jsonArray.contains(new JsonPrimitive(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* 含有成员
|
||||
*
|
||||
* @param obj 成员
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean contains(String obj) {
|
||||
return jsonArray.contains(new JsonPrimitive(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成员,默认值:null
|
||||
*
|
||||
* @param index 序号
|
||||
* @return {@link TJsonObject}
|
||||
*/
|
||||
public TJsonObject getJsonObject(int index) {
|
||||
return jsonArray.get(index).isJsonObject() ? TJsonObject.fromJsonObject(jsonArray.get(index).getAsJsonObject()) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成员,默认值:null
|
||||
*
|
||||
* @param index 序号
|
||||
* @return {@link TJsonArray}
|
||||
*/
|
||||
public TJsonArray getJsonArray(int index) {
|
||||
return jsonArray.get(index).isJsonArray() ? TJsonArray.fromJsonArray(jsonArray.get(index).getAsJsonArray()) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成员,默认值:false
|
||||
*
|
||||
* @param index 序号
|
||||
* @return boolean
|
||||
*/
|
||||
public Boolean getBoolean(int index) {
|
||||
return jsonArray.get(index).isJsonPrimitive() && jsonArray.get(index).getAsBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成员
|
||||
*
|
||||
* @param index 序号
|
||||
* @param def 默认值
|
||||
* @return boolean
|
||||
*/
|
||||
public Boolean getBoolean(int index, boolean def) {
|
||||
return jsonArray.get(index).isJsonPrimitive() ? jsonArray.get(index).getAsBoolean() : def;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成员,默认值:0
|
||||
*
|
||||
* @param index 序号
|
||||
* @return number
|
||||
*/
|
||||
public Number getNumber(int index) {
|
||||
return jsonArray.get(index).isJsonPrimitive() ? jsonArray.get(index).getAsNumber() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成员
|
||||
*
|
||||
* @param index 序号
|
||||
* @param def 默认值
|
||||
* @return number
|
||||
*/
|
||||
public Number getNumber(int index, Number def) {
|
||||
return jsonArray.get(index).isJsonPrimitive() ? jsonArray.get(index).getAsNumber() : def;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成员,默认值:null
|
||||
*
|
||||
* @param index 序号
|
||||
* @return string
|
||||
*/
|
||||
public String getString(int index) {
|
||||
return jsonArray.get(index).isJsonPrimitive() ? jsonArray.get(index).getAsString() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成员
|
||||
*
|
||||
* @param index 序号
|
||||
* @param def 默认值
|
||||
* @return string
|
||||
*/
|
||||
public String getString(int index, String def) {
|
||||
return jsonArray.get(index).isJsonPrimitive() ? jsonArray.get(index).getAsString() : def;
|
||||
}
|
||||
|
||||
/**
|
||||
* 成员数量
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public int size() {
|
||||
return jsonArray.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为 JsonArray 类型
|
||||
*
|
||||
* @return {@link JsonArray}
|
||||
*/
|
||||
public JsonArray asOriginJsonArray() {
|
||||
return jsonArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<TJsonObject> iterator() {
|
||||
List<TJsonObject> jsonObjectList = new ArrayList<>();
|
||||
for (JsonElement jsonElement : jsonArray) {
|
||||
jsonObjectList.add(TJsonObject.fromJsonObject(jsonElement));
|
||||
}
|
||||
return jsonObjectList.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Consumer<? super TJsonObject> action) {
|
||||
List<TJsonObject> jsonObjectList = new ArrayList<>();
|
||||
for (JsonElement jsonElement : jsonArray) {
|
||||
jsonObjectList.add(TJsonObject.fromJsonObject(jsonElement));
|
||||
}
|
||||
jsonObjectList.forEach(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spliterator<TJsonObject> spliterator() {
|
||||
List<TJsonObject> jsonObjectList = new ArrayList<>();
|
||||
for (JsonElement jsonElement : jsonArray) {
|
||||
jsonObjectList.add(TJsonObject.fromJsonObject(jsonElement));
|
||||
}
|
||||
return jsonObjectList.spliterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return jsonArray.toString();
|
||||
}
|
||||
|
||||
}
|
||||
253
src/main/scala/me/skymc/taboolib/common/json/TJsonObject.java
Normal file
253
src/main/scala/me/skymc/taboolib/common/json/TJsonObject.java
Normal file
@@ -0,0 +1,253 @@
|
||||
package me.skymc.taboolib.common.json;
|
||||
|
||||
import com.google.gson.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 让 JsonObject 有更加人性化的操作,目前版本只能获取数据。
|
||||
*
|
||||
* @Author 坏黑
|
||||
* @Since 2018-10-27 23:06
|
||||
*/
|
||||
public class TJsonObject {
|
||||
|
||||
private JsonElement jsonObject;
|
||||
|
||||
TJsonObject(JsonElement jsonObject) {
|
||||
this.jsonObject = jsonObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 Json 原代码中获取
|
||||
*
|
||||
* @param json 源代码
|
||||
* @return {@link TJsonObject}
|
||||
* @throws JsonParseException if the specified text is not valid JSON
|
||||
*/
|
||||
public static TJsonObject fromJson(String json) throws JsonParseException {
|
||||
return new TJsonObject(new JsonParser().parse(json));
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 JsonElement 创建
|
||||
*
|
||||
* @param jsonElement JsonElement 对象
|
||||
* @return {@link TJsonObject}
|
||||
*/
|
||||
public static TJsonObject fromJsonObject(JsonElement jsonElement) {
|
||||
return new TJsonObject(jsonElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否含有该节点
|
||||
*
|
||||
* @param path 地址
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean contains(String path) {
|
||||
return get(path) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文本,默认值:空
|
||||
*
|
||||
* @param path 地址
|
||||
* @return String
|
||||
*/
|
||||
public String getString(String path) {
|
||||
return getString(path, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文本
|
||||
*
|
||||
* @param path 地址
|
||||
* @param def 默认值
|
||||
* @return String
|
||||
*/
|
||||
public String getString(String path, String def) {
|
||||
JsonElement jsonElement = get(path);
|
||||
return !(jsonElement instanceof JsonPrimitive) || jsonElement == null ? def : jsonElement.getAsString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数字,默认值:0
|
||||
*
|
||||
* @param path 地址
|
||||
* @return Number
|
||||
*/
|
||||
public Number getNumber(String path) {
|
||||
return getNumber(path, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数字
|
||||
*
|
||||
* @param path 地址
|
||||
* @param def 默认值
|
||||
* @return Number
|
||||
*/
|
||||
public Number getNumber(String path, Number def) {
|
||||
JsonElement jsonElement = get(path);
|
||||
return !(jsonElement instanceof JsonPrimitive) || jsonElement == null ? def : jsonElement.getAsNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取布尔值,默认值:false
|
||||
*
|
||||
* @param path 地址
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean getBoolean(String path) {
|
||||
return getBoolean(path, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取布尔值
|
||||
*
|
||||
* @param path 地址
|
||||
* @param def 默认值
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean getBoolean(String path, boolean def) {
|
||||
JsonElement jsonElement = get(path);
|
||||
return !(jsonElement instanceof JsonPrimitive) || jsonElement == null ? def : jsonElement.getAsBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 TJsonObject 对象,默认值:null
|
||||
*
|
||||
* @param path 地址
|
||||
* @return {@link TJsonObject}
|
||||
*/
|
||||
public TJsonObject getJsonObject(String path) {
|
||||
JsonElement jsonElement = get(path);
|
||||
return !(jsonElement instanceof JsonObject) || jsonElement == null ? null : TJsonObject.fromJsonObject(jsonElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 TJsonArray 对象,默认值:null
|
||||
*
|
||||
* @param path 地址
|
||||
* @return {@link TJsonArray}
|
||||
*/
|
||||
public TJsonArray getJsonArray(String path) {
|
||||
JsonElement jsonElement = get(path);
|
||||
return !(jsonElement instanceof JsonArray) || jsonElement == null ? null : TJsonArray.fromJsonArray((JsonArray) jsonElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有成员
|
||||
*
|
||||
* @return {@link Map.Entry}
|
||||
*/
|
||||
public Set<Map.Entry<String, TJsonObject>> entrySet() {
|
||||
return !(jsonObject instanceof JsonObject) ? new HashSet<>() : ((JsonObject) jsonObject).entrySet().stream().map(jsonElementEntry -> new HashMap.SimpleEntry<>(jsonElementEntry.getKey(), fromJsonObject(jsonElementEntry.getValue()))).collect(Collectors.toCollection(HashSet::new));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有键
|
||||
*
|
||||
* @return {@link Set}
|
||||
*/
|
||||
public Set<String> keySet() {
|
||||
return !(jsonObject instanceof JsonObject) ? new HashSet<>() : ((JsonObject) jsonObject).entrySet().stream().map(Map.Entry::getKey).collect(Collectors.toCollection(HashSet::new));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有值
|
||||
*
|
||||
* @return {@link Collection}
|
||||
*/
|
||||
public Collection<TJsonObject> values() {
|
||||
return !(jsonObject instanceof JsonObject) ? new ArrayList<>() : ((JsonObject) jsonObject).entrySet().stream().map(jsonElementEntry -> new TJsonObject(jsonElementEntry.getValue())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为 JsonObject 类型
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isJsonObject() {
|
||||
return jsonObject instanceof JsonObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为 JsonArray 类型
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isJsonArray() {
|
||||
return jsonObject instanceof JsonArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为 JsonPrimitive 类型
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isJsonPrimitive() {
|
||||
return jsonObject instanceof JsonPrimitive;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为 JsonObject 类型
|
||||
*
|
||||
* @return {@link JsonObject}
|
||||
*/
|
||||
public JsonObject asOriginJsonObject() {
|
||||
return (JsonObject) jsonObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为 JsonArray 类型
|
||||
*
|
||||
* @return {@link JsonArray}
|
||||
*/
|
||||
public JsonArray asOriginJsonArray() {
|
||||
return (JsonArray) jsonObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为 JsonElement 类型
|
||||
*
|
||||
* @return {@link JsonElement}
|
||||
*/
|
||||
public JsonElement asOriginJsonElement() {
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为 JsonPrimitive 类型
|
||||
*
|
||||
* @return {@link JsonPrimitive}
|
||||
*/
|
||||
public JsonPrimitive asOriginJsonPrimitive() {
|
||||
return (JsonPrimitive) jsonObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return jsonObject.toString();
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Private Methods
|
||||
//
|
||||
// *********************************
|
||||
|
||||
private JsonElement get(String path) {
|
||||
JsonElement subElement = jsonObject;
|
||||
for (String p : path.split("/")) {
|
||||
if (subElement instanceof JsonObject && ((JsonObject) subElement).has(p)) {
|
||||
subElement = ((JsonObject) subElement).get(p);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return subElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package me.skymc.taboolib.common.loader;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-08-27 10:04
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Instantiable {
|
||||
|
||||
String value();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package me.skymc.taboolib.common.loader;
|
||||
|
||||
import com.ilummc.tlib.logger.TLogger;
|
||||
import com.ilummc.tlib.util.Ref;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.TabooLibLoader;
|
||||
import me.skymc.taboolib.listener.TListener;
|
||||
import me.skymc.taboolib.methods.ReflectionUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.event.server.PluginEnableEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-08-27 10:04
|
||||
*/
|
||||
@TListener
|
||||
public class InstantiableLoader implements Listener {
|
||||
|
||||
private static ConcurrentHashMap<String, Object> instance = new ConcurrentHashMap<>();
|
||||
|
||||
public InstantiableLoader() {
|
||||
loadInstantiable();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEnable(PluginEnableEvent e) {
|
||||
loadInstantiable(e.getPlugin());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDisable(PluginDisableEvent e) {
|
||||
clear(e.getPlugin());
|
||||
}
|
||||
|
||||
public static void clear(Plugin plugin) {
|
||||
instance.entrySet().stream().filter(entry -> Ref.getCallerPlugin(entry.getValue().getClass()).equals(plugin)).forEach(entry -> instance.remove(entry.getKey()));
|
||||
}
|
||||
|
||||
public static void loadInstantiable() {
|
||||
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
try {
|
||||
loadInstantiable(plugin);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadInstantiable(Plugin plugin) {
|
||||
TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> {
|
||||
for (Class pluginClass : classes) {
|
||||
if (pluginClass.isAnnotationPresent(Instantiable.class)) {
|
||||
Instantiable instantiable = (Instantiable) pluginClass.getAnnotation(Instantiable.class);
|
||||
try {
|
||||
instance.put(instantiable.value(), ReflectionUtils.instantiateObject(pluginClass));
|
||||
TabooLib.debug("Instantiable " + pluginClass.getSimpleName() + " instanced. (" + plugin.getName() + ")");
|
||||
} catch (Exception e) {
|
||||
TLogger.getGlobalLogger().warn("Instance Failed: " + pluginClass.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Getter and Setter
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public static ConcurrentHashMap<String, Object> getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static Optional<Object> getInstance(String name) {
|
||||
return Optional.ofNullable(instance.get(name));
|
||||
}
|
||||
}
|
||||
40
src/main/scala/me/skymc/taboolib/common/nms/NMSHandler.java
Normal file
40
src/main/scala/me/skymc/taboolib/common/nms/NMSHandler.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package me.skymc.taboolib.common.nms;
|
||||
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.commands.builder.SimpleCommandBuilder;
|
||||
import me.skymc.taboolib.common.function.TFunction;
|
||||
import me.skymc.taboolib.common.versioncontrol.SimpleVersionControl;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-11-09 14:38
|
||||
*/
|
||||
@TFunction(enable = "init")
|
||||
public abstract class NMSHandler {
|
||||
|
||||
private static NMSHandler handler;
|
||||
|
||||
static void init() {
|
||||
try {
|
||||
handler = (NMSHandler) SimpleVersionControl.createNMS("me.skymc.taboolib.common.nms.NMSHandlerImpl").translate().newInstance();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
SimpleCommandBuilder.create("title", TabooLib.instance())
|
||||
.execute((sender, args) -> {
|
||||
handler.sendTitle((Player) sender, "TabooLib", 10, 40, 10, "author Bkm016", 10, 40, 10);
|
||||
return true;
|
||||
}).build();
|
||||
}
|
||||
|
||||
abstract public void sendTitle(Player player, String title, int titleFadein, int titleStay, int titleFadeout, String subtitle, int subtitleFadein, int subtitleStay, int subtitleFadeout);
|
||||
|
||||
abstract public void sendActionBar(Player player, String text);
|
||||
|
||||
abstract public double[] getTPS();
|
||||
|
||||
public static NMSHandler getHandler() {
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package me.skymc.taboolib.common.nms;
|
||||
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.common.packet.TPacketHandler;
|
||||
import net.minecraft.server.v1_12_R1.ChatMessageType;
|
||||
import net.minecraft.server.v1_12_R1.MinecraftServer;
|
||||
import net.minecraft.server.v1_8_R3.ChatComponentText;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutChat;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutTitle;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-11-09 14:42
|
||||
*/
|
||||
public class NMSHandlerImpl extends NMSHandler {
|
||||
|
||||
@Override
|
||||
public void sendTitle(Player player, String title, int titleFadein, int titleStay, int titleFadeout, String subtitle, int subtitleFadein, int subtitleStay, int subtitleFadeout) {
|
||||
TPacketHandler.sendPacket(player, new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.TIMES, new ChatComponentText(String.valueOf(title)), titleFadein, titleStay, titleFadeout));
|
||||
TPacketHandler.sendPacket(player, new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.TITLE, new ChatComponentText(String.valueOf(title)), titleFadein, titleStay, titleFadeout));
|
||||
TPacketHandler.sendPacket(player, new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.TIMES, new ChatComponentText(String.valueOf(subtitle)), subtitleFadein, subtitleStay, subtitleFadeout));
|
||||
TPacketHandler.sendPacket(player, new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.SUBTITLE, new ChatComponentText(String.valueOf(subtitle)), subtitleFadein, subtitleStay, subtitleFadeout));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendActionBar(Player player, String text) {
|
||||
if (TabooLib.getVersionNumber() > 11100) {
|
||||
TPacketHandler.sendPacket(player, new net.minecraft.server.v1_12_R1.PacketPlayOutChat(new net.minecraft.server.v1_12_R1.ChatComponentText(String.valueOf(text)), ChatMessageType.GAME_INFO));
|
||||
} else {
|
||||
TPacketHandler.sendPacket(player, new PacketPlayOutChat(new ChatComponentText(String.valueOf(text)), (byte) 2));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] getTPS() {
|
||||
return MinecraftServer.getServer().recentTps;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package me.skymc.taboolib.common.packet;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import me.skymc.taboolib.common.packet.channel.ChannelExecutor;
|
||||
import me.skymc.taboolib.common.versioncontrol.SimpleVersionControl;
|
||||
import me.skymc.taboolib.listener.TListener;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-10-28 14:52
|
||||
*/
|
||||
@TListener
|
||||
public class TPacketHandler implements Listener {
|
||||
|
||||
private static Map<String, List<TPacketListener>> packetListeners = Maps.newHashMap();
|
||||
private static ChannelExecutor channelExecutor;
|
||||
|
||||
public TPacketHandler() {
|
||||
try {
|
||||
channelExecutor = (ChannelExecutor) SimpleVersionControl.createNMS("me.skymc.taboolib.common.packet.channel.InternalChannelExecutor").translate().newInstance();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
channelExecutor.addPlayerChannel(e.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent e) {
|
||||
channelExecutor.removePlayerChannel(e.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDisable(PluginDisableEvent e) {
|
||||
removeListener(e.getPlugin());
|
||||
}
|
||||
|
||||
public static void sendPacket(Player player, Object packet) {
|
||||
channelExecutor.sendPacket(player, packet);
|
||||
}
|
||||
|
||||
public static void addListener(Plugin plugin, TPacketListener listener) {
|
||||
packetListeners.computeIfAbsent(plugin.getName(), name -> Lists.newArrayList()).add(listener);
|
||||
}
|
||||
|
||||
public static void removeListener(Plugin plugin) {
|
||||
packetListeners.remove(plugin.getName());
|
||||
}
|
||||
|
||||
public static void removeListener(Plugin plugin, TPacketListener listener) {
|
||||
Optional.ofNullable(packetListeners.get(plugin.getName())).ifPresent(list -> list.remove(listener));
|
||||
}
|
||||
|
||||
public static Collection<List<TPacketListener>> getListeners() {
|
||||
return packetListeners.values();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package me.skymc.taboolib.common.packet;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-10-28 14:35
|
||||
*/
|
||||
public abstract class TPacketListener {
|
||||
|
||||
public boolean onSend(Player player, Object packet) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onReceive(Player player, Object packet) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package me.skymc.taboolib.common.packet.channel;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import me.skymc.taboolib.common.packet.TPacketHandler;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-10-28 14:34
|
||||
*/
|
||||
public abstract class ChannelExecutor {
|
||||
|
||||
private ExecutorService addChannelService = Executors.newSingleThreadExecutor();
|
||||
private ExecutorService removeChannelService = Executors.newSingleThreadExecutor();
|
||||
|
||||
public abstract void sendPacket(Player player, Object packet);
|
||||
|
||||
public abstract Channel getPlayerChannel(Player player);
|
||||
|
||||
public void addPlayerChannel(Player player) {
|
||||
addChannelService.submit(() -> {
|
||||
getPlayerChannel(player).pipeline().addBefore("packet_handler", "taboolib_packet_handler", new ChannelHandler(player));
|
||||
});
|
||||
}
|
||||
|
||||
public void removePlayerChannel(Player player) {
|
||||
removeChannelService.submit(() -> {
|
||||
Channel playerChannel = getPlayerChannel(player);
|
||||
if (playerChannel.pipeline().get("taboolib_packet_handler") != null) {
|
||||
playerChannel.pipeline().remove("taboolib_packet_handler");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class ChannelHandler extends ChannelDuplexHandler {
|
||||
|
||||
private Player player;
|
||||
|
||||
public ChannelHandler(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext channelHandlerContext, Object o, ChannelPromise channelPromise) throws Exception {
|
||||
try {
|
||||
if (TPacketHandler.getListeners().stream().flatMap(Collection::stream).anyMatch(packetListener -> !packetListener.onSend(player, o))) {
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
super.write(channelHandlerContext, o, channelPromise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {
|
||||
try {
|
||||
if (TPacketHandler.getListeners().stream().flatMap(Collection::stream).anyMatch(packetListener -> !packetListener.onReceive(player, o))) {
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
super.channelRead(channelHandlerContext, o);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package me.skymc.taboolib.common.packet.channel;
|
||||
|
||||
import com.ilummc.tlib.logger.TLogger;
|
||||
import io.netty.channel.Channel;
|
||||
import net.minecraft.server.v1_8_R3.Packet;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-10-28 15:12
|
||||
*/
|
||||
public class InternalChannelExecutor extends ChannelExecutor {
|
||||
|
||||
@Override
|
||||
public void sendPacket(Player player, Object packet) {
|
||||
if (packet instanceof Packet) {
|
||||
((CraftPlayer) player).getHandle().playerConnection.sendPacket((Packet) packet);
|
||||
} else {
|
||||
TLogger.getGlobalLogger().warn("Invalid packet: " + packet.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Channel getPlayerChannel(Player player) {
|
||||
return ((CraftPlayer) player).getHandle().playerConnection.networkManager.channel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package me.skymc.taboolib.common.pathfinder;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-21 13:06
|
||||
*/
|
||||
public interface PathfinderCreator {
|
||||
|
||||
Object createPathfinderGoal(SimpleAi ai);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package me.skymc.taboolib.common.pathfinder;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-20 20:47
|
||||
*/
|
||||
public abstract class PathfinderExecutor {
|
||||
|
||||
public abstract Object getEntityInsentient(LivingEntity entity);
|
||||
|
||||
public abstract Object getNavigation(LivingEntity entity);
|
||||
|
||||
public abstract Object getControllerJump(LivingEntity entity);
|
||||
|
||||
public abstract Object getControllerMove(LivingEntity entity);
|
||||
|
||||
public abstract Object getControllerLook(LivingEntity entity);
|
||||
|
||||
public abstract Object getGoalSelector(LivingEntity entity);
|
||||
|
||||
public abstract Object getTargetSelector(LivingEntity entity);
|
||||
|
||||
public abstract Object getPathEntity(LivingEntity entity);
|
||||
|
||||
public abstract void setPathEntity(LivingEntity entity, Object pathEntity);
|
||||
|
||||
public abstract void setGoalAi(LivingEntity entity, SimpleAi ai, int priority);
|
||||
|
||||
public abstract void setTargetAi(LivingEntity entity, SimpleAi ai, int priority);
|
||||
|
||||
public abstract void clearGoalAi(LivingEntity entity);
|
||||
|
||||
public abstract void clearTargetAi(LivingEntity entity);
|
||||
|
||||
public abstract Iterable getGoalAi(LivingEntity entity);
|
||||
|
||||
public abstract Iterable getTargetAi(LivingEntity entity);
|
||||
|
||||
public abstract void setGoalAi(LivingEntity entity, Iterable ai);
|
||||
|
||||
public abstract void setTargetAi(LivingEntity entity, Iterable ai);
|
||||
|
||||
public abstract boolean navigationMove(LivingEntity entity, Location location);
|
||||
|
||||
public abstract boolean navigationMove(LivingEntity entity, Location location, double speed);
|
||||
|
||||
public abstract boolean navigationMove(LivingEntity entity, LivingEntity target);
|
||||
|
||||
public abstract boolean navigationMove(LivingEntity entity, LivingEntity target, double speed);
|
||||
|
||||
public abstract boolean navigationReach(LivingEntity entity);
|
||||
|
||||
public abstract void controllerLookAt(LivingEntity entity, Location target);
|
||||
|
||||
public abstract void controllerLookAt(LivingEntity entity, Entity target);
|
||||
|
||||
public abstract void controllerJumpReady(LivingEntity entity);
|
||||
|
||||
public abstract boolean controllerJumpCurrent(LivingEntity entity);
|
||||
|
||||
public abstract void setFollowRange(LivingEntity entity, double value);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package me.skymc.taboolib.common.pathfinder;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-19 19:42
|
||||
*/
|
||||
public abstract class SimpleAi {
|
||||
|
||||
public abstract boolean shouldExecute();
|
||||
|
||||
public boolean continueExecute() {
|
||||
return shouldExecute();
|
||||
}
|
||||
|
||||
public void startTask() {
|
||||
}
|
||||
|
||||
public void resetTask() {
|
||||
}
|
||||
|
||||
public void updateTask() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package me.skymc.taboolib.common.pathfinder;
|
||||
|
||||
import me.skymc.taboolib.common.loader.Instantiable;
|
||||
import me.skymc.taboolib.common.versioncontrol.SimpleVersionControl;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-19 20:31
|
||||
*/
|
||||
@Instantiable("SimpleAiSelector")
|
||||
public class SimpleAiSelector {
|
||||
|
||||
private static PathfinderCreator internalPathfinderCreator;
|
||||
private static PathfinderExecutor internalPathfinderExecutor;
|
||||
|
||||
public SimpleAiSelector() {
|
||||
try {
|
||||
internalPathfinderCreator = (PathfinderCreator) SimpleVersionControl.createNMS("me.skymc.taboolib.common.pathfinder.internal.InternalPathfinderCreator").translate().newInstance();
|
||||
internalPathfinderExecutor = (PathfinderExecutor) SimpleVersionControl.createNMS("me.skymc.taboolib.common.pathfinder.internal.InternalPathfinderExecutor").translate().newInstance();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Getter and Setter
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public static PathfinderExecutor getExecutor() {
|
||||
return internalPathfinderExecutor;
|
||||
}
|
||||
|
||||
public static PathfinderCreator getCreator() {
|
||||
return internalPathfinderCreator;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package me.skymc.taboolib.common.pathfinder.internal;
|
||||
|
||||
import me.skymc.taboolib.common.pathfinder.PathfinderCreator;
|
||||
import me.skymc.taboolib.common.pathfinder.SimpleAi;
|
||||
|
||||
/**
|
||||
* 该类仅用作生成 ASM 代码,无任何意义
|
||||
*
|
||||
* @Author sky
|
||||
* @Since 2018-09-19 22:31
|
||||
*/
|
||||
public class InternalPathfinderCreator extends net.minecraft.server.v1_8_R3.PathfinderGoal implements PathfinderCreator {
|
||||
|
||||
private SimpleAi simpleAI;
|
||||
|
||||
public InternalPathfinderCreator() {
|
||||
}
|
||||
|
||||
public InternalPathfinderCreator(SimpleAi ai) {
|
||||
this.simpleAI = ai;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createPathfinderGoal(SimpleAi ai) {
|
||||
return new InternalPathfinderCreator(ai);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean a() {
|
||||
return simpleAI.shouldExecute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean b() {
|
||||
return simpleAI.continueExecute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void c() {
|
||||
simpleAI.startTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void d() {
|
||||
simpleAI.resetTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void e() {
|
||||
simpleAI.updateTask();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
package me.skymc.taboolib.common.pathfinder.internal;
|
||||
|
||||
import me.skymc.taboolib.common.pathfinder.PathfinderExecutor;
|
||||
import me.skymc.taboolib.common.pathfinder.SimpleAi;
|
||||
import me.skymc.taboolib.common.pathfinder.SimpleAiSelector;
|
||||
import me.skymc.taboolib.nms.NMSUtils;
|
||||
import net.minecraft.server.v1_8_R3.*;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 该类仅用作生成 ASM 代码,无任何意义
|
||||
*
|
||||
* @Author sky
|
||||
* @Since 2018-09-20 20:57
|
||||
*/
|
||||
public class InternalPathfinderExecutor extends PathfinderExecutor {
|
||||
|
||||
private Field pathEntity;
|
||||
private Field pathfinderGoalSelectorSet;
|
||||
private Field controllerJumpCurrent;
|
||||
|
||||
public InternalPathfinderExecutor() {
|
||||
try {
|
||||
pathfinderGoalSelectorSet = NMSUtils.getNMSClass("PathfinderGoalSelector").getDeclaredField("b");
|
||||
pathfinderGoalSelectorSet.setAccessible(true);
|
||||
controllerJumpCurrent = NMSUtils.getNMSClass("ControllerJump").getDeclaredField("a");
|
||||
controllerJumpCurrent.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
Class<?> pathEntityClass = NMSUtils.getNMSClass("PathEntity");
|
||||
for (Field field : NMSUtils.getNMSClass("NavigationAbstract").getDeclaredFields()) {
|
||||
if (field.getType().equals(pathEntityClass)) {
|
||||
field.setAccessible(true);
|
||||
pathEntity = field;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getEntityInsentient(LivingEntity entity) {
|
||||
return ((CraftEntity) entity).getHandle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNavigation(LivingEntity entity) {
|
||||
return ((EntityInsentient) getEntityInsentient(entity)).getNavigation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getControllerJump(LivingEntity entity) {
|
||||
return ((EntityInsentient) getEntityInsentient(entity)).getControllerJump();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getControllerMove(LivingEntity entity) {
|
||||
return ((EntityInsentient) getEntityInsentient(entity)).getControllerMove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getControllerLook(LivingEntity entity) {
|
||||
return ((EntityInsentient) getEntityInsentient(entity)).getControllerLook();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGoalSelector(LivingEntity entity) {
|
||||
return ((EntityInsentient) getEntityInsentient(entity)).goalSelector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTargetSelector(LivingEntity entity) {
|
||||
return ((EntityInsentient) getEntityInsentient(entity)).targetSelector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPathEntity(LivingEntity entity) {
|
||||
try {
|
||||
return pathEntity.get(getNavigation(entity));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPathEntity(LivingEntity entity, Object pathEntity) {
|
||||
try {
|
||||
this.pathEntity.set(getNavigation(entity), pathEntity);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGoalAi(LivingEntity entity, SimpleAi ai, int priority) {
|
||||
((EntityInsentient) getEntityInsentient(entity)).goalSelector.a(priority, (PathfinderGoal) SimpleAiSelector.getCreator().createPathfinderGoal(ai));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetAi(LivingEntity entity, SimpleAi ai, int priority) {
|
||||
((EntityInsentient) getEntityInsentient(entity)).targetSelector.a(priority, (PathfinderGoal) SimpleAiSelector.getCreator().createPathfinderGoal(ai));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearGoalAi(LivingEntity entity) {
|
||||
try {
|
||||
((Collection) pathfinderGoalSelectorSet.get(((EntityInsentient) getEntityInsentient(entity)).goalSelector)).clear();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearTargetAi(LivingEntity entity) {
|
||||
try {
|
||||
((Collection) pathfinderGoalSelectorSet.get(((EntityInsentient) getEntityInsentient(entity)).targetSelector)).clear();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable getGoalAi(LivingEntity entity) {
|
||||
try {
|
||||
return ((Collection) pathfinderGoalSelectorSet.get(((EntityInsentient) getEntityInsentient(entity)).goalSelector));
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable getTargetAi(LivingEntity entity) {
|
||||
try {
|
||||
return ((Collection) pathfinderGoalSelectorSet.get(((EntityInsentient) getEntityInsentient(entity)).targetSelector));
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGoalAi(LivingEntity entity, Iterable ai) {
|
||||
try {
|
||||
pathfinderGoalSelectorSet.set(((EntityInsentient) getEntityInsentient(entity)).goalSelector, ai);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargetAi(LivingEntity entity, Iterable ai) {
|
||||
try {
|
||||
pathfinderGoalSelectorSet.set(((EntityInsentient) getEntityInsentient(entity)).targetSelector, ai);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean navigationMove(LivingEntity entity, Location location) {
|
||||
return navigationMove(entity, location, 0.6);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean navigationMove(LivingEntity entity, Location location, double speed) {
|
||||
return ((Navigation) getNavigation(entity)).a(location.getX(), location.getY(), location.getZ(), speed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean navigationMove(LivingEntity entity, LivingEntity target) {
|
||||
return navigationMove(entity, target, 0.6);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean navigationMove(LivingEntity entity, LivingEntity target, double speed) {
|
||||
return ((Navigation) getNavigation(entity)).a(((CraftEntity) target).getHandle(), speed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean navigationReach(LivingEntity entity) {
|
||||
Object pathEntity = getPathEntity(entity);
|
||||
return pathEntity == null || ((PathEntity) pathEntity).b();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void controllerLookAt(LivingEntity entity, Location target) {
|
||||
((ControllerLook) getControllerLook(entity)).a(target.getX(), target.getY(), target.getZ(), 10, 40);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void controllerLookAt(LivingEntity entity, Entity target) {
|
||||
((ControllerLook) getControllerLook(entity)).a(((CraftEntity) target).getHandle(), 10, 40);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void controllerJumpReady(LivingEntity entity) {
|
||||
((ControllerJump) getControllerJump(entity)).a();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean controllerJumpCurrent(LivingEntity entity) {
|
||||
try {
|
||||
return controllerJumpCurrent.getBoolean(getControllerJump(entity));
|
||||
} catch (Exception ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFollowRange(LivingEntity entity, double value) {
|
||||
((EntityInsentient) getEntityInsentient(entity)).getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package me.skymc.taboolib.common.playercontainer;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
*/
|
||||
public class Container {
|
||||
|
||||
private final Object container;
|
||||
private final boolean uniqueId;
|
||||
|
||||
public Container(Object container, boolean uniqueId) {
|
||||
this.container = container;
|
||||
this.uniqueId = uniqueId;
|
||||
}
|
||||
|
||||
public Object getContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
public boolean isUniqueId() {
|
||||
return uniqueId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package me.skymc.taboolib.common.playercontainer;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-14 23:45
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface PlayerContainer {
|
||||
|
||||
boolean uniqueId() default false;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package me.skymc.taboolib.common.playercontainer;
|
||||
|
||||
import com.ilummc.tlib.logger.TLogger;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.TabooLibLoader;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-14 23:45
|
||||
*/
|
||||
public class PlayerContainerLoader implements Listener, TabooLibLoader.Loader {
|
||||
|
||||
Map<String, List<Container>> pluginContainer = new ConcurrentHashMap<>();
|
||||
|
||||
PlayerContainerLoader() {
|
||||
Bukkit.getPluginManager().registerEvents(this, TabooLib.instance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postLoad(Plugin plugin, Class<?> pluginClass) {
|
||||
for (Field field : pluginClass.getDeclaredFields()) {
|
||||
PlayerContainer annotation = field.getAnnotation(PlayerContainer.class);
|
||||
if (annotation == null) {
|
||||
continue;
|
||||
}
|
||||
field.setAccessible(true);
|
||||
try {
|
||||
pluginContainer.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(new Container(field.get(pluginClass), annotation.uniqueId()));
|
||||
} catch (IllegalAccessException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload(Plugin plugin, Class<?> cancelClass) {
|
||||
pluginContainer.remove(plugin.getName());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onQuit(PlayerQuitEvent e) {
|
||||
pluginContainer.values().stream().flatMap(Collection::stream).forEach(container -> {
|
||||
if (container.getContainer() instanceof Map) {
|
||||
((Map) container.getContainer()).remove(container.isUniqueId() ? e.getPlayer().getUniqueId() : e.getPlayer().getName());
|
||||
} else if (container.getContainer() instanceof Collection) {
|
||||
((Collection) container.getContainer()).remove(container.isUniqueId() ? e.getPlayer().getUniqueId() : e.getPlayer().getName());
|
||||
} else {
|
||||
TLogger.getGlobalLogger().error("Invalid Container: " + container.getContainer().getClass().getSimpleName());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package me.skymc.taboolib.common.schedule;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-12-15 15:07
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TSchedule {
|
||||
|
||||
int delay() default 0;
|
||||
int period() default -1;
|
||||
|
||||
boolean async() default false;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package me.skymc.taboolib.common.schedule;
|
||||
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-12-15 15:25
|
||||
*/
|
||||
public class TScheduleData {
|
||||
|
||||
private final TSchedule annotation;
|
||||
private final BukkitRunnable runnable;
|
||||
|
||||
public TScheduleData(TSchedule annotation, BukkitRunnable runnable) {
|
||||
this.annotation = annotation;
|
||||
this.runnable = runnable;
|
||||
}
|
||||
|
||||
public TSchedule getAnnotation() {
|
||||
return annotation;
|
||||
}
|
||||
|
||||
public BukkitRunnable getRunnable() {
|
||||
return runnable;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package me.skymc.taboolib.common.schedule;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.ilummc.tlib.logger.TLogger;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.TabooLibLoader;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.PluginEnableEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-12-15 15:09
|
||||
*/
|
||||
public class TScheduleLoader implements Listener, TabooLibLoader.Loader {
|
||||
|
||||
private Map<String, List<TScheduleData>> schedules = Maps.newHashMap();
|
||||
|
||||
TScheduleLoader() {
|
||||
Bukkit.getPluginManager().registerEvents(this, TabooLib.instance());
|
||||
}
|
||||
|
||||
public static void run(Plugin plugin, BukkitRunnable runnable, int delay, int period, boolean async) {
|
||||
if (async) {
|
||||
runnable.runTaskTimerAsynchronously(plugin, delay, period);
|
||||
} else {
|
||||
runnable.runTaskTimer(plugin, delay, period);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEnable(PluginEnableEvent e) {
|
||||
Optional.ofNullable(schedules.remove(e.getPlugin().getName())).ifPresent(list -> list.forEach(scheduleData -> {
|
||||
run(e.getPlugin(), scheduleData.getRunnable(), scheduleData.getAnnotation().delay(), scheduleData.getAnnotation().period(), scheduleData.getAnnotation().async());
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postLoad(Plugin plugin, Class<?> loadClass) {
|
||||
for (Method method : loadClass.getDeclaredMethods()) {
|
||||
TSchedule annotation = method.getAnnotation(TSchedule.class);
|
||||
if (annotation == null) {
|
||||
continue;
|
||||
}
|
||||
Object instance = loadClass.equals(plugin.getClass()) ? plugin : null;
|
||||
// 如果是非静态类型
|
||||
if (!Modifier.isStatic(method.getModifiers()) && instance == null) {
|
||||
// 是否为主类
|
||||
TLogger.getGlobalLogger().error(method.getName() + " is not a static method.");
|
||||
continue;
|
||||
}
|
||||
method.setAccessible(true);
|
||||
// 如果是本插件
|
||||
if (plugin.equals(TabooLib.instance())) {
|
||||
run(plugin, new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
method.invoke(instance);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, annotation.delay(), annotation.period(), annotation.async());
|
||||
}
|
||||
// 其他插件则添加到列队
|
||||
else {
|
||||
schedules.computeIfAbsent(plugin.getName(), n -> Lists.newArrayList()).add(new TScheduleData(annotation, new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
method.invoke(instance);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package me.skymc.taboolib.common.util;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-25 15:21
|
||||
*/
|
||||
public class SimpleCounter {
|
||||
|
||||
private int timer;
|
||||
private int limit;
|
||||
private boolean ignoredFirst;
|
||||
private boolean counterFirst;
|
||||
|
||||
public SimpleCounter(int limit) {
|
||||
this(limit, false);
|
||||
}
|
||||
|
||||
public SimpleCounter(int limit, boolean ignoredFirst) {
|
||||
this.timer = 0;
|
||||
this.limit = limit;
|
||||
this.ignoredFirst = ignoredFirst;
|
||||
this.counterFirst = true;
|
||||
}
|
||||
|
||||
public boolean next() {
|
||||
if (--timer <= 0) {
|
||||
timer = limit;
|
||||
if (ignoredFirst && counterFirst) {
|
||||
counterFirst = false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
timer = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package me.skymc.taboolib.common.util;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-10-01 16:19
|
||||
*/
|
||||
public class SimpleIterator {
|
||||
|
||||
private final Object container;
|
||||
|
||||
public SimpleIterator(Object container) {
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
public List<Map.Entry> mapIterator(int start, int end) {
|
||||
List<Map.Entry> iterator = Lists.newArrayList();
|
||||
Map container = (Map) this.container;
|
||||
int loop = 0;
|
||||
for (Object entry : container.entrySet()) {
|
||||
if (loop++ >= start) {
|
||||
if (loop <= end) {
|
||||
iterator.add((Map.Entry) entry);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return iterator;
|
||||
}
|
||||
|
||||
public List listIterator(int start, int end) {
|
||||
List iterator = Lists.newArrayList();
|
||||
List container = (List) this.container;
|
||||
int loop = 0;
|
||||
for (Object entry : container) {
|
||||
if (loop++ >= start) {
|
||||
if (loop <= end) {
|
||||
iterator.add(entry);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return iterator;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package me.skymc.taboolib.common.util;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-10-25 22:51
|
||||
*/
|
||||
public class SimpleReflection {
|
||||
|
||||
private static Map<String, Map<String, Field>> fieldCached = Maps.newHashMap();
|
||||
|
||||
public static void saveField(Class<?> nmsClass) {
|
||||
try {
|
||||
Arrays.stream(nmsClass.getDeclaredFields()).forEach(declaredField -> saveField(nmsClass, declaredField.getName()));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveField(Class<?> nmsClass, String fieldName) {
|
||||
try {
|
||||
Field declaredField = nmsClass.getDeclaredField(fieldName);
|
||||
declaredField.setAccessible(true);
|
||||
fieldCached.computeIfAbsent(nmsClass.getName(), name -> Maps.newHashMap()).put(fieldName, declaredField);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void setFieldValue(Class<?> nmsClass, Object instance, String fieldName, Object value) {
|
||||
try {
|
||||
Map<String, Field> fields = fieldCached.get(nmsClass.getName());
|
||||
if (fields == null) {
|
||||
return;
|
||||
}
|
||||
Field field = fields.get(fieldName);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
field.set(instance, value);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Object getFieldValue(Class<?> nmsClass, Object instance, String fieldName) {
|
||||
try {
|
||||
Map<String, Field> fields = fieldCached.get(nmsClass.getName());
|
||||
if (fields == null) {
|
||||
return null;
|
||||
}
|
||||
Field field = fields.get(fieldName);
|
||||
if (field == null) {
|
||||
return null;
|
||||
}
|
||||
return field.get(instance);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T getFieldValue(Class<?> nmsClass, Object instance, String fieldName, T def) {
|
||||
try {
|
||||
Map<String, Field> fields = fieldCached.get(nmsClass.getName());
|
||||
if (fields == null) {
|
||||
return def;
|
||||
}
|
||||
Field field = fields.get(fieldName);
|
||||
if (field == null) {
|
||||
return def;
|
||||
}
|
||||
return (T) field.get(instance);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package me.skymc.taboolib.common.versioncontrol;
|
||||
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* 我不信 ClassNotFoundException 的邪,自己写了一个发现还是一样。。。
|
||||
*
|
||||
* @Author sky
|
||||
* @Since 2018-09-19 21:17
|
||||
*/
|
||||
public class SimpleClassVisitor extends ClassVisitor {
|
||||
|
||||
private final SimpleVersionControl simpleVersionControl;
|
||||
|
||||
public SimpleClassVisitor(SimpleVersionControl simpleVersionControl, ClassVisitor classVisitor) {
|
||||
super(Opcodes.ASM5, classVisitor);
|
||||
this.simpleVersionControl = simpleVersionControl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
|
||||
super.visit(version, access, translate(name), translate(signature), translate(superName), translate(interfaces));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInnerClass(String name, String outerName, String innerName, int access) {
|
||||
super.visitInnerClass(translate(name), translate(outerName), translate(innerName), access);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
|
||||
return super.visitField(access, translate(name), translate(descriptor), translate(signature), value instanceof String ? translate((String) value) : value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitOuterClass(String owner, String name, String descriptor) {
|
||||
super.visitOuterClass(translate(owner), translate(name), translate(descriptor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
|
||||
return new SimpleMethodVisitor(simpleVersionControl, super.visitMethod(access, translate(name), translate(descriptor), translate(signature), translate(exceptions)));
|
||||
}
|
||||
|
||||
private String translate(String target) {
|
||||
return target == null ? null : simpleVersionControl.replace(target);
|
||||
}
|
||||
|
||||
private String[] translate(String[] target) {
|
||||
if (target == null) {
|
||||
return target;
|
||||
}
|
||||
IntStream.range(0, target.length).forEach(i -> target[i] = translate(target[i]));
|
||||
return target;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package me.skymc.taboolib.common.versioncontrol;
|
||||
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* 我不信 ClassNotFound 的邪,自己写了一个发现还是一样。。。
|
||||
*
|
||||
* @Author sky
|
||||
* @Since 2018-9-19 21:33
|
||||
*/
|
||||
public class SimpleMethodVisitor extends MethodVisitor {
|
||||
|
||||
private final SimpleVersionControl simpleVersionControl;
|
||||
|
||||
public SimpleMethodVisitor(SimpleVersionControl simpleVersionControl, MethodVisitor methodVisitor) {
|
||||
super(Opcodes.ASM5, methodVisitor);
|
||||
this.simpleVersionControl = simpleVersionControl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitParameter(String name, int access) {
|
||||
super.visitParameter(translate(name), access);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodInsn(int opcode, String owner, String name, String descriptor) {
|
||||
super.visitMethodInsn(opcode, translate(owner), translate(name), translate(descriptor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
|
||||
super.visitMethodInsn(opcode, translate(owner), translate(name), translate(descriptor), isInterface);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLdcInsn(Object value) {
|
||||
if (value instanceof Type) {
|
||||
super.visitLdcInsn(Type.getType(translate(((Type) value).getDescriptor())));
|
||||
} else {
|
||||
super.visitLdcInsn(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeInsn(int opcode, String type) {
|
||||
super.visitTypeInsn(opcode, translate(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFieldInsn(int opcode, String owner, String name, String descriptor) {
|
||||
super.visitFieldInsn(opcode, translate(owner), translate(name), translate(descriptor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) {
|
||||
super.visitLocalVariable(translate(name), translate(descriptor), translate(signature), start, end, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInvokeDynamicInsn(String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) {
|
||||
super.visitInvokeDynamicInsn(translate(name), translate(descriptor), bootstrapMethodHandle, bootstrapMethodArguments);
|
||||
}
|
||||
|
||||
private String translate(String target) {
|
||||
return target == null ? null : simpleVersionControl.replace(target);
|
||||
}
|
||||
|
||||
private String[] translate(String[] target) {
|
||||
if (target == null) {
|
||||
return target;
|
||||
}
|
||||
IntStream.range(0, target.length).forEach(i -> target[i] = translate(target[i]));
|
||||
return target;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
package me.skymc.taboolib.common.versioncontrol;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.ilummc.tlib.util.asm.AsmClassLoader;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.fileutils.FileUtils;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-19 21:05
|
||||
*/
|
||||
public class SimpleVersionControl {
|
||||
|
||||
private static Map<String, Class<?>> cacheClasses = new HashMap<>();
|
||||
private String target;
|
||||
private String to;
|
||||
private List<String> from = Lists.newArrayList();
|
||||
private Plugin plugin;
|
||||
private boolean useCache;
|
||||
private boolean useNMS;
|
||||
|
||||
SimpleVersionControl() {
|
||||
useCache = false;
|
||||
}
|
||||
|
||||
public static SimpleVersionControl create() {
|
||||
return new SimpleVersionControl().to(TabooLib.getVersion()).plugin(Main.getInst());
|
||||
}
|
||||
|
||||
public static SimpleVersionControl create(String toVersion) {
|
||||
return new SimpleVersionControl().to(toVersion).plugin(Main.getInst());
|
||||
}
|
||||
|
||||
public static SimpleVersionControl createSimple(String target, String... from) {
|
||||
return create().target(target).from(from);
|
||||
}
|
||||
|
||||
public static SimpleVersionControl createNMS(String target) {
|
||||
return create().target(target).useNMS();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置转换类地址,写法如:me.skymc.taboolib.packet.InternalPacket
|
||||
*/
|
||||
public SimpleVersionControl target(String target) {
|
||||
this.target = target;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置原版本,写法如:v1_8_R3
|
||||
*/
|
||||
public SimpleVersionControl from(String from) {
|
||||
this.from.add(from.startsWith("v") ? from : "v" + from);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* 设置原版本,写法如:v1_8_R3, v1_12_R1
|
||||
*/
|
||||
public SimpleVersionControl from(String... from) {
|
||||
Arrays.stream(from).forEach(v -> this.from.add(v.startsWith("v") ? v : "v" + v));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置目标版本
|
||||
*/
|
||||
public SimpleVersionControl to(String to) {
|
||||
this.to = to.startsWith("v") ? to : "v" + to;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置插件,不填默认指向 TabooLib
|
||||
*/
|
||||
public SimpleVersionControl plugin(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换类将会保存在 TabooLib 中,防止出现 NoClassDefFoundError 异常
|
||||
*/
|
||||
public SimpleVersionControl useCache() {
|
||||
this.useCache = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动转换所有使用到的 NMS 或 OBC 方法
|
||||
*/
|
||||
public SimpleVersionControl useNMS() {
|
||||
this.useNMS = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Class<?> translate() throws IOException {
|
||||
return translate(plugin);
|
||||
}
|
||||
|
||||
public Class<?> translate(Plugin plugin) throws IOException {
|
||||
if (useCache && cacheClasses.containsKey(target)) {
|
||||
return cacheClasses.get(target);
|
||||
}
|
||||
ClassReader classReader = new ClassReader(FileUtils.getResource(plugin, target.replace(".", "/") + ".class"));
|
||||
ClassWriter classWriter = new ClassWriter(0);
|
||||
ClassVisitor classVisitor = new SimpleClassVisitor(this, classWriter);
|
||||
classReader.accept(classVisitor, 0);
|
||||
classWriter.visitEnd();
|
||||
classVisitor.visitEnd();
|
||||
Class<?> newClass = AsmClassLoader.createNewClass(target, classWriter.toByteArray());
|
||||
if (useCache) {
|
||||
cacheClasses.put(target, newClass);
|
||||
}
|
||||
return newClass;
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Getter and Setter
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public String getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public List<String> getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
public String getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
public String replace(String origin) {
|
||||
if (useNMS) {
|
||||
origin = origin.replaceAll("net/minecraft/server/.*?/", "net/minecraft/server/" + to + "/").replaceAll("org/bukkit/craftbukkit/.*?/", "org/bukkit/craftbukkit/" + to + "/");
|
||||
}
|
||||
for (String from : from) {
|
||||
origin = origin.replace("/" + from + "/", "/" + to + "/");
|
||||
}
|
||||
return origin;
|
||||
}
|
||||
}
|
||||
44
src/main/scala/me/skymc/taboolib/damage/DamageUtils.java
Normal file
44
src/main/scala/me/skymc/taboolib/damage/DamageUtils.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package me.skymc.taboolib.damage;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
*/
|
||||
public class DamageUtils {
|
||||
|
||||
public static Player getAttackerInDamageEvent(EntityDamageByEntityEvent e) {
|
||||
if (e.getDamager() instanceof Player) {
|
||||
return (Player) e.getDamager();
|
||||
} else if (e.getDamager() instanceof Projectile && ((Projectile) e.getDamager()).getShooter() instanceof Player) {
|
||||
return (Player) ((Projectile) e.getDamager()).getShooter();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Deprecated
|
||||
//
|
||||
// *********************************
|
||||
|
||||
@Deprecated
|
||||
public static void damage(Player player, LivingEntity victim, double damage) {
|
||||
dmg(player, victim, damage);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void damage(Player player, Entity victim, double damage) {
|
||||
dmg(player, (LivingEntity) victim, damage);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void dmg(LivingEntity attacker, LivingEntity victim, double damage) {
|
||||
attacker.damage(damage, victim);
|
||||
}
|
||||
}
|
||||
415
src/main/scala/me/skymc/taboolib/database/GlobalDataManager.java
Normal file
415
src/main/scala/me/skymc/taboolib/database/GlobalDataManager.java
Normal file
@@ -0,0 +1,415 @@
|
||||
package me.skymc.taboolib.database;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.Main.StorageType;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.playerdata.DataUtils;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class GlobalDataManager {
|
||||
|
||||
public static FileConfiguration data = DataUtils.addPluginData("TabooLibrary-Variable.yml", null);
|
||||
|
||||
/**
|
||||
* 获取变量
|
||||
*
|
||||
* @param name 名称
|
||||
* @param defaultVariable 默认值
|
||||
* @return
|
||||
*/
|
||||
public static String getVariable(String name, String defaultVariable) {
|
||||
if (Main.getStorageType() == StorageType.SQL) {
|
||||
Object obj = Main.getConnection().getValueLast(Main.getTablePrefix() + "_plugindata", "name", name, "variable");
|
||||
return obj != null ? "null".equals(obj.toString()) ? defaultVariable : obj.toString() : defaultVariable;
|
||||
} else {
|
||||
return data.contains(name) ? data.getString(name) : defaultVariable;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存变量(该方法仅限数据库储存方式)
|
||||
*
|
||||
* @param name 名称
|
||||
* @param defaultVariable 默认值
|
||||
* @return
|
||||
*/
|
||||
public static String getVariableAsynchronous(String name, String defaultVariable) {
|
||||
if (Main.getStorageType() == StorageType.SQL) {
|
||||
SQLVariable variable = SQLMethod.getSQLVariable(name);
|
||||
return variable == null ? defaultVariable : "null".equals(variable.getVariable()) ? defaultVariable : variable.getVariable();
|
||||
} else {
|
||||
return getVariable(name, defaultVariable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置变量
|
||||
*
|
||||
* @param name 名称
|
||||
* @param variable 变量
|
||||
*/
|
||||
public static void setVariable(String name, String variable) {
|
||||
if (Main.getStorageType() == StorageType.SQL) {
|
||||
Main.getConnection().intoValue(Main.getTablePrefix() + "_plugindata", name, variable == null ? "null" : variable, TabooLib.getServerUID());
|
||||
} else {
|
||||
data.set(name, variable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置缓存变量(该方法仅限数据库储存方式)
|
||||
*
|
||||
* @param name
|
||||
* @param variable
|
||||
*/
|
||||
public static void setVariableAsynchronous(String name, String variable) {
|
||||
if (Main.getStorageType() == StorageType.SQL) {
|
||||
SQLVariable _variable = SQLMethod.contains(name) ? SQLMethod.getSQLVariable(name).setVariable(variable == null ? "null" : variable) : SQLMethod.addSQLVariable(name, variable == null ? "null" : variable);
|
||||
// 更新数据
|
||||
SQLMethod.uploadVariable(_variable, true);
|
||||
} else {
|
||||
setVariable(name, variable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查变量是否存在
|
||||
*
|
||||
* @param name 名称
|
||||
*/
|
||||
public static boolean contains(String name) {
|
||||
if (Main.getStorageType() == StorageType.SQL) {
|
||||
return getVariable(name, null) != null;
|
||||
} else {
|
||||
return data.contains(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查变量是否被缓存(该方法仅限数据库储存方式)
|
||||
*
|
||||
* @param name 名称
|
||||
* @return
|
||||
*/
|
||||
public static boolean containsAsynchronous(String name) {
|
||||
if (Main.getStorageType() == StorageType.SQL) {
|
||||
return getVariableAsynchronous(name, null) != null;
|
||||
} else {
|
||||
return contains(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理所有失效的变量
|
||||
* 该方法仅限数据库储存时有效
|
||||
*/
|
||||
public static void clearInvalidVariables() {
|
||||
if (Main.getStorageType() == StorageType.SQL) {
|
||||
HashMap<String, String> map = getVariables();
|
||||
Main.getConnection().truncateTable(Main.getTablePrefix() + "_plugindata");
|
||||
for (String name : map.keySet()) {
|
||||
Main.getConnection().intoValue(Main.getTablePrefix() + "_plugindata", name, map.get(name), TabooLib.getServerUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有有效变量
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static HashMap<String, String> getVariables() {
|
||||
HashMap<String, String> map = new HashMap<>();
|
||||
if (Main.getStorageType() == StorageType.SQL) {
|
||||
LinkedList<HashMap<String, Object>> list = Main.getConnection().getValues(Main.getTablePrefix() + "_plugindata", "id", -1, false, "name", "variable");
|
||||
for (HashMap<String, Object> _map : list) {
|
||||
if (!"null".equals(_map.get("variable").toString())) {
|
||||
map.put(_map.get("name").toString(), _map.get("variable").toString());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (String name : data.getConfigurationSection("").getKeys(false)) {
|
||||
map.put(name, data.getString(name));
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存变量(该方法仅限数据库储存方式)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static HashMap<String, String> getVariablesAsynchronous() {
|
||||
if (Main.getStorageType() == StorageType.SQL) {
|
||||
HashMap<String, String> map = new HashMap<>();
|
||||
for (SQLVariable variable : SQLMethod.getSQLVariables()) {
|
||||
if (!"null".equals(variable.getVariable())) {
|
||||
map.put(variable.getName(), variable.getVariable());
|
||||
}
|
||||
}
|
||||
return map;
|
||||
} else {
|
||||
return getVariables();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库变量
|
||||
*
|
||||
* @author sky
|
||||
*/
|
||||
public static class SQLVariable {
|
||||
|
||||
public String name = "";
|
||||
public String variable = "";
|
||||
public String upgradeUID = "";
|
||||
|
||||
public SQLVariable(String name, String variable, String upgradeUID) {
|
||||
this.name = name;
|
||||
this.variable = variable;
|
||||
this.upgradeUID = upgradeUID;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getVariable() {
|
||||
return variable;
|
||||
}
|
||||
|
||||
public SQLVariable setVariable(String args) {
|
||||
this.variable = args;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getUpgradeUID() {
|
||||
return upgradeUID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库方法
|
||||
*
|
||||
* @author sky
|
||||
*/
|
||||
public static class SQLMethod {
|
||||
|
||||
private static ConcurrentHashMap<String, SQLVariable> variables = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 获取数据
|
||||
*
|
||||
* @param name 名字
|
||||
*/
|
||||
public static SQLVariable getSQLVariable(String name) {
|
||||
return variables.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有变量
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Collection<SQLVariable> getSQLVariables() {
|
||||
return variables.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个变量
|
||||
*
|
||||
* @param name 名字
|
||||
* @param value 值
|
||||
* @return
|
||||
*/
|
||||
public static SQLVariable addSQLVariable(String name, String value) {
|
||||
SQLVariable variable = new SQLVariable(name, value, TabooLib.getServerUID());
|
||||
variables.put(name, variable);
|
||||
return variable;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除一个变量
|
||||
*
|
||||
* @param name 名字
|
||||
* @return
|
||||
*/
|
||||
public static SQLVariable removeSQLVariable(String name) {
|
||||
if (variables.contains(name)) {
|
||||
variables.get(name).setVariable("null");
|
||||
}
|
||||
return variables.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否包含变量
|
||||
*
|
||||
* @param name 名字
|
||||
* @return
|
||||
*/
|
||||
public static boolean contains(String name) {
|
||||
return variables.containsKey(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 载入数据库中的所有变量缓存
|
||||
*
|
||||
* @param sync 是否异步
|
||||
*/
|
||||
public static void loadVariables(boolean sync) {
|
||||
if (Main.getStorageType() == StorageType.LOCAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
BukkitRunnable runnable = new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LinkedList<HashMap<String, Object>> list = Main.getConnection().getValues(Main.getTablePrefix() + "_plugindata", "id", -1, false, "name", "variable", "upgrade");
|
||||
for (HashMap<String, Object> _map : list) {
|
||||
if (!"null".equals(_map.get("variable").toString())) {
|
||||
variables.put(_map.get("name").toString(), new SQLVariable(_map.get("name").toString(), _map.get("variable").toString(), _map.get("upgrade").toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (sync) {
|
||||
runnable.runTaskAsynchronously(Main.getInst());
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查当前变量是否被其他服务器更新
|
||||
*
|
||||
* @param sync 是否异步
|
||||
*/
|
||||
public static void checkVariable(boolean sync) {
|
||||
if (Main.getStorageType() == StorageType.LOCAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
BukkitRunnable runnable = new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LinkedList<HashMap<String, Object>> list = Main.getConnection().getValues(Main.getTablePrefix() + "_plugindata", "id", -1, false, "name", "variable", "upgrade");
|
||||
// 循环变量
|
||||
for (HashMap<String, Object> value : list) {
|
||||
Object name = value.get("name");
|
||||
try {
|
||||
// 如果变量存在
|
||||
if (variables.containsKey(name)) {
|
||||
// 如果变量不是由本服更新
|
||||
if (!value.get("upgrade").equals(variables.get(name).getUpgradeUID())) {
|
||||
// 如果变量是空
|
||||
if ("null".equals(value.get("variable"))) {
|
||||
// 删除变量
|
||||
variables.remove(name);
|
||||
} else {
|
||||
// 更新变量
|
||||
variables.get(name).setVariable(value.get("variable").toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
// 如果变量存在则下载到本地
|
||||
else if (!"null".equals(value.get("variable"))) {
|
||||
variables.put(value.get("name").toString(), new SQLVariable(value.get("name").toString(), value.get("variable").toString(), value.get("upgrade").toString()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 移除
|
||||
variables.remove(name);
|
||||
// 提示
|
||||
TLocale.Logger.error("GLOBAL-DATAMANAGER.ERROR-CHECK-VARIABLE", String.valueOf(name), e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (sync) {
|
||||
runnable.runTaskAsynchronously(Main.getInst());
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 向数据库上传所有数据
|
||||
*
|
||||
* @param sync 是否异步
|
||||
*/
|
||||
public static void uploadVariables(boolean sync) {
|
||||
if (Main.getStorageType() == StorageType.LOCAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (SQLVariable variable : variables.values()) {
|
||||
uploadVariable(variable, sync);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 向数据库上传当前数据
|
||||
*
|
||||
* @param variable 数据
|
||||
* @param sync 是否异步
|
||||
*/
|
||||
public static void uploadVariable(SQLVariable variable, boolean sync) {
|
||||
if (Main.getStorageType() == StorageType.LOCAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
BukkitRunnable runnable = new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Main.getConnection().intoValue(Main.getTablePrefix() + "_plugindata", variable.getName(), variable.getVariable() == null ? "null" : variable.getVariable(), TabooLib.getServerUID());
|
||||
}
|
||||
};
|
||||
|
||||
if (sync) {
|
||||
runnable.runTaskAsynchronously(Main.getInst());
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动数据库储存方法
|
||||
*/
|
||||
public static void startSQLMethod() {
|
||||
long time = System.currentTimeMillis();
|
||||
// 载入数据
|
||||
loadVariables(false);
|
||||
// 提示信息
|
||||
TLocale.Logger.info("GLOBAL-DATAMANAGER.SUCCESS-LOADED-VARIABLE", String.valueOf(variables.size()), String.valueOf(System.currentTimeMillis() - time));
|
||||
|
||||
// 检查更新
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
checkVariable(true);
|
||||
}
|
||||
}.runTaskTimerAsynchronously(Main.getInst(), Main.getInst().getConfig().getInt("PluginData.CHECK-DELAY") * 20, Main.getInst().getConfig().getInt("PluginData.CHECK-DELAY") * 20);
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束数据库储存方法
|
||||
*/
|
||||
public static void cancelSQLMethod() {
|
||||
// 上传数据
|
||||
uploadVariables(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
262
src/main/scala/me/skymc/taboolib/database/PlayerDataManager.java
Normal file
262
src/main/scala/me/skymc/taboolib/database/PlayerDataManager.java
Normal file
@@ -0,0 +1,262 @@
|
||||
package me.skymc.taboolib.database;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.Main.StorageType;
|
||||
import me.skymc.taboolib.events.PlayerLoadedEvent;
|
||||
import me.skymc.taboolib.exception.PlayerOfflineException;
|
||||
import me.skymc.taboolib.fileutils.ConfigUtils;
|
||||
import me.skymc.taboolib.fileutils.FileUtils;
|
||||
import me.skymc.taboolib.listener.TListener;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@TListener
|
||||
public class PlayerDataManager implements Listener {
|
||||
|
||||
private static final ConcurrentHashMap<String, FileConfiguration> PLAYER_DATA = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 获取用户储存方式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static UsernameType getUsernameType() {
|
||||
return Main.getInst().getConfig().getBoolean("ENABLE-UUID") ? UsernameType.UUID : UsernameType.USERNAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家数据
|
||||
*
|
||||
* @param player 玩家
|
||||
* @return
|
||||
* @throws PlayerOfflineException
|
||||
*/
|
||||
public static FileConfiguration getPlayerData(Player player) {
|
||||
if (getUsernameType() == UsernameType.UUID) {
|
||||
return getPlayerData(player.getUniqueId().toString(), false);
|
||||
} else {
|
||||
return getPlayerData(player.getName(), false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家数据
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public static FileConfiguration getPlayerData(OfflinePlayer player) {
|
||||
if (!player.isOnline()) {
|
||||
return null;
|
||||
}
|
||||
if (getUsernameType() == UsernameType.UUID) {
|
||||
return getPlayerData(player.getUniqueId().toString(), false);
|
||||
} else {
|
||||
return getPlayerData(player.getName(), false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取玩家数据
|
||||
*
|
||||
* @param username 玩家
|
||||
* @return
|
||||
* @throws PlayerOfflineException
|
||||
*/
|
||||
public static FileConfiguration getPlayerData(String username, boolean offline) {
|
||||
if (PLAYER_DATA.containsKey(username)) {
|
||||
return PLAYER_DATA.get(username);
|
||||
} else if (offline) {
|
||||
if (Main.getStorageType() == StorageType.SQL) {
|
||||
throw new PlayerOfflineException(TLocale.asString("PLAYER-DATAMANAGER.ERROR-STORAGE-SQL"));
|
||||
}
|
||||
return loadPlayerData(username);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 载入玩家数据
|
||||
*
|
||||
* @param username 玩家
|
||||
* @return
|
||||
*/
|
||||
public static FileConfiguration loadPlayerData(String username) {
|
||||
// 本地储存
|
||||
if (Main.getStorageType() == StorageType.LOCAL) {
|
||||
// 读取文件
|
||||
File file = FileUtils.file(Main.getPlayerDataFolder(), username + ".yml");
|
||||
// 载入配置
|
||||
PLAYER_DATA.put(username, YamlConfiguration.loadConfiguration(file));
|
||||
} else {
|
||||
// 数据是否存在
|
||||
if (Main.getConnection().isExists(Main.getTablePrefix() + "_playerdata", "username", username)) {
|
||||
// 获取数据
|
||||
String code = Main.getConnection().getValue(Main.getTablePrefix() + "_playerdata", "username", username, "configuration").toString();
|
||||
try {
|
||||
// 载入配置
|
||||
PLAYER_DATA.put(username, ConfigUtils.decodeYAML(code));
|
||||
} catch (Exception e) {
|
||||
// 创建空数据
|
||||
PLAYER_DATA.put(username, new YamlConfiguration());
|
||||
// 反馈信息
|
||||
TLocale.Logger.error("PLAYER-DATAMANAGER.ERROR-PLAYER-DATA", username, e.toString());
|
||||
}
|
||||
} else {
|
||||
// 创建空数据
|
||||
PLAYER_DATA.put(username, new YamlConfiguration());
|
||||
}
|
||||
}
|
||||
return PLAYER_DATA.get(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存玩家数据
|
||||
*
|
||||
* @param username 玩家
|
||||
* @param remove 是否移除缓存
|
||||
*/
|
||||
public static void savePlayerData(String username, boolean remove) {
|
||||
// 没有数据
|
||||
if (!PLAYER_DATA.containsKey(username)) {
|
||||
return;
|
||||
}
|
||||
// 本地储存
|
||||
if (Main.getStorageType() == StorageType.LOCAL) {
|
||||
// 读取文件
|
||||
File file = FileUtils.file(Main.getPlayerDataFolder(), username + ".yml");
|
||||
// 保存配置
|
||||
try {
|
||||
PLAYER_DATA.get(username).save(file);
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
}
|
||||
// 如果是数据库储存且有数据
|
||||
else if (PLAYER_DATA.get(username).getConfigurationSection("").getKeys(false).size() > 0) {
|
||||
// 数据是否存在
|
||||
if (Main.getConnection().isExists(Main.getTablePrefix() + "_playerdata", "username", username)) {
|
||||
// 写入数据
|
||||
Main.getConnection().setValue(Main.getTablePrefix() + "_playerdata", "username", username, "configuration", ConfigUtils.encodeYAML(PLAYER_DATA.get(username)));
|
||||
} else {
|
||||
// 插入数据
|
||||
Main.getConnection().intoValue(Main.getTablePrefix() + "_playerdata", username, ConfigUtils.encodeYAML(PLAYER_DATA.get(username)));
|
||||
}
|
||||
}
|
||||
// 获取这个属性对应的玩家
|
||||
Player player;
|
||||
if (getUsernameType() == UsernameType.UUID) {
|
||||
player = Bukkit.getPlayer(UUID.fromString(username));
|
||||
} else {
|
||||
player = Bukkit.getPlayerExact(username);
|
||||
}
|
||||
// 如果移除数据 或 玩家不在线
|
||||
if (remove || player == null) {
|
||||
PLAYER_DATA.remove(username);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存所有玩家的缓存
|
||||
*
|
||||
* @param sync 是否异步进行
|
||||
* @param remove 是否移除数据
|
||||
*/
|
||||
public static void saveAllCaches(boolean sync, boolean remove) {
|
||||
BukkitRunnable runnable = new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long time = System.currentTimeMillis();
|
||||
// 保存
|
||||
for (String name : PLAYER_DATA.keySet()) {
|
||||
savePlayerData(name, false);
|
||||
}
|
||||
// 提示
|
||||
if (!Main.getInst().getConfig().getBoolean("HIDE-NOTIFY")) {
|
||||
TLocale.Logger.info("PLAYER-DATAMANAGER.SUCCESS-SAVE-DATA", String.valueOf(PLAYER_DATA.size()), String.valueOf(System.currentTimeMillis() - time));
|
||||
}
|
||||
}
|
||||
};
|
||||
// 如果异步
|
||||
if (sync) {
|
||||
runnable.runTaskAsynchronously(Main.getInst());
|
||||
}
|
||||
// 如果同步
|
||||
else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存所有玩家的数据
|
||||
*
|
||||
* @param sync 是否异步进行
|
||||
* @param remove 是否移除数据
|
||||
*/
|
||||
public static void saveAllPlayers(boolean sync, boolean remove) {
|
||||
// 创建任务
|
||||
BukkitRunnable runnable = new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
savePlayerData(Main.getInst().getConfig().getBoolean("ENABLE-UUID") ? player.getUniqueId().toString() : player.getName(), remove);
|
||||
}
|
||||
}
|
||||
};
|
||||
// 如果异步
|
||||
if (sync) {
|
||||
runnable.runTaskAsynchronously(Main.getInst());
|
||||
}
|
||||
// 如果同步
|
||||
else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void join(PlayerJoinEvent e) {
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// 载入数据
|
||||
loadPlayerData(Main.getInst().getConfig().getBoolean("ENABLE-UUID") ? e.getPlayer().getUniqueId().toString() : e.getPlayer().getName());
|
||||
// 载入完成
|
||||
Bukkit.getPluginManager().callEvent(new PlayerLoadedEvent(e.getPlayer()));
|
||||
}
|
||||
}.runTaskAsynchronously(Main.getInst());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void quit(PlayerQuitEvent e) {
|
||||
if (!Main.isDisable()) {
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// 保存数据
|
||||
savePlayerData(Main.getInst().getConfig().getBoolean("ENABLE-UUID") ? e.getPlayer().getUniqueId().toString() : e.getPlayer().getName(), true);
|
||||
}
|
||||
}.runTaskAsynchronously(Main.getInst());
|
||||
}
|
||||
}
|
||||
|
||||
public enum UsernameType {
|
||||
UUID, USERNAME
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package me.skymc.taboolib.events;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* The event called when a book is opened trough this Util
|
||||
*/
|
||||
public class CustomBookOpenEvent extends Event implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private boolean cancelled;
|
||||
|
||||
/**
|
||||
* The player
|
||||
*/
|
||||
private final Player player;
|
||||
|
||||
/**
|
||||
* The hand used to open the book (the previous item will be restored after the opening)
|
||||
*/
|
||||
private Hand hand;
|
||||
|
||||
/**
|
||||
* The actual book to be opened
|
||||
*/
|
||||
private ItemStack book;
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public Hand getHand() {
|
||||
return hand;
|
||||
}
|
||||
|
||||
public void setHand(Hand hand) {
|
||||
this.hand = hand;
|
||||
}
|
||||
|
||||
public ItemStack getBook() {
|
||||
return book;
|
||||
}
|
||||
|
||||
public void setBook(ItemStack book) {
|
||||
this.book = book;
|
||||
}
|
||||
|
||||
public CustomBookOpenEvent(Player player, ItemStack book, boolean offHand) {
|
||||
this.player = player;
|
||||
this.book = book;
|
||||
this.hand = offHand ? Hand.OFF_HAND : Hand.MAIN_HAND;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public enum Hand {
|
||||
MAIN_HAND, OFF_HAND
|
||||
}
|
||||
}
|
||||
41
src/main/scala/me/skymc/taboolib/events/PlayerJumpEvent.java
Normal file
41
src/main/scala/me/skymc/taboolib/events/PlayerJumpEvent.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package me.skymc.taboolib.events;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
public class PlayerJumpEvent extends Event implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean isCancelled;
|
||||
private Player player;
|
||||
|
||||
public PlayerJumpEvent(boolean b, Player player) {
|
||||
this.isCancelled = false;
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return this.isCancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean e) {
|
||||
this.isCancelled = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user