更换至 Gradle

This commit is contained in:
IzzelAliz
2019-03-02 15:48:21 +08:00
parent b3233e4049
commit 57ac4e072c
311 changed files with 332 additions and 930 deletions

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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]
第一阶段:运行 @TInjectInstance 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();
}
}

View 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);
}
}

View File

@@ -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());
}
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View 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;
}
}
}

View 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 {
}

View 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());
}
}

View 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");
}
}

View 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;
}
}

View 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);
}
}

View File

@@ -0,0 +1,10 @@
package me.skymc.taboolib.cloud.expansion;
/**
* @Author sky
* @Since 2018-09-30 16:39
*/
public enum ExpansionType {
INTERNAL, PLUGIN
}

View 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();
}
}

View File

@@ -0,0 +1,10 @@
package me.skymc.taboolib.commands;
import org.bukkit.command.CommandSender;
@Deprecated
public interface SubCommandExecutor {
boolean command(CommandSender sender, String[] args);
}

View File

@@ -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;
}
}

View File

@@ -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;
}
};
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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());
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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 "";
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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());
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -0,0 +1,11 @@
package me.skymc.taboolib.commands.internal.type;
/**
* @author Bkm016
* @since 2018-04-17
*/
public enum CommandType {
CONSOLE, PLAYER, ALL
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}
};
}

View File

@@ -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);
}
}

View File

@@ -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");
}
}

View File

@@ -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");
}
}

View File

@@ -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");
}
}

View File

@@ -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");
}
}

View File

@@ -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()));
}
}
}
}

View File

@@ -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);
}
}

View File

@@ -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]));
}
}
}
}

View File

@@ -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");
}
}

View File

@@ -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();
}
}

View File

@@ -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");
}
}

View File

@@ -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]);
}
}
}
}

View File

@@ -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]);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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";
}

View File

@@ -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();
}
}
}
}

View 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 {};
}

View File

@@ -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();
}
}
}
}

View File

@@ -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);
}

View 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();
}
}

View 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;
}
}

View File

@@ -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();
}

View File

@@ -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));
}
}

View 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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() {
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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());
}
});
}
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}
}));
}
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View 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);
}
}

View 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);
}
}
}

View 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
}
}

View File

@@ -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
}
}

View 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