This commit is contained in:
Izzel_Aliz 2018-09-30 15:11:12 +08:00
commit cd8bf36df4
82 changed files with 3367 additions and 1700 deletions

120
README.md
View File

@ -1,68 +1,76 @@
# TabooLib
<h1 align="center">
<br>
<br>
<br>
TabooLib
<h4 align="center">
<a href="#function">插件功能</a>&nbsp;&nbsp;
<a href="#document">插件文档</a>&nbsp;&nbsp;
<a href="#commands">插件命令</a>&nbsp;&nbsp;
<a href="#download">插件下载</a>&nbsp;&nbsp;
<a href="#mcbbs">MCBBS</a>
</h4>
<br>
<br>
<br>
<br>
<br>
</h1>
> Bukkit 开发工具库集合
<a name="function"></a>
插件功能
---
本插件包含大量常用开发工具及扩展工具,可以帮助入门开发者完成一些繁琐或是复杂的操作,在你没有自己的工具库时,这些工具可以大量提升你的而开发速度,本插件自带的大部分计算都是异步处理,不会影响服务器的正常运行,你只要不去使用我标注为过时的工具,那么我可以向你保证工具的运行效率。插件在 3.55 版本后开始逐渐将一些常用的工具添加到配置文件中, 来让不会开发的服主使用。
[![](http://ci.pcd.ac.cn/job/TabooLib/badge/icon)](http://ci.pcd.ac.cn/job/TabooLib)
<br>
<a name="document"></a>
插件文档
---
| 文档(更新中) | 地址 |
| --- | --- |
| 主文档 | https://bkm016.github.io/TabooLib/#/ |
<br>
<a name="commands"></a>
插件命令
---
| 命令 | 作用 | 权限 |
| --- | --- | --- |
| /taboolib | 插件主命令 | taboolib.admin |
| /tabooliblocale | TLocale 工具主命令 | taboolib.admin |
| /taboolibplugin | TPlugin 工具主命令 | taboolib.admin |
| /taboolibexecute | TExecute 工具主命令 | taboolib.admin |
| /tabooliblogs | TLogs 工具主命令 | taboolib.admin |
| /taboolibrarymodule | TLM 模块主命令 | tlm.use |
| /language2 | Language2 工具主命令 | taboolib.admin |
| /translateuuid | TranslateUUID 工具主命令 | taboolib.admin |
<br>
<a name="download"></a>
插件下载
---
[![](http://jenkins.mirez.cc/buildStatus/icon?job=TabooLib)](http://jenkins.mirez.cc/job/TabooLib/)
[![](https://img.shields.io/github/downloads/Bkm016/TabooLib/total.svg)](https://github.com/Bkm016/TabooLib/releases)
[![](https://img.shields.io/github/release/Bkm016/TabooLib.svg)](https://github.com/Bkm016/TabooLib/tags)
[![](https://img.shields.io/github/stars/Bkm016/TabooLib.svg?style=flat-square&label=Stars)](https://github.com/Bkm016/TabooLib)
[![](https://jitpack.io/v/Bkm016/TabooLib.svg)](https://jitpack.io/#Bkm016/TabooLib)
## 插件文档
你可以在 [**这里**](https://github.com/Bkm016/TabooLib/releases) 下载正式版本
如果你的服务器没有连接互联网(内网跨服),请下载 **libs.rar** 文件并手动解压至服务端目录
[TabooLib 文档](https://bkm016.github.io/TabooLib/#/)
如果你无法连接到 Github可以在由 **Mirez** 服务器提供的 [**构建站**](http://jenkins.15imc.com:8080/job/TabooLib/) 下载最新版本
该网站下载到的插件有可能是 **正在测试** 的不稳定版本,最新版本以 Github 为准
## 下载 TabooLib 插件
**4.0** 版本起,不再对 **1.7.10** 进行支持与维护,部分功能在该版本可能会失效
如果你需要在 1.7.10 安装本插件,请在 [**这里**](https://pcd.ac.cn/2018/05/19/71/) 修复因 **SpecialSource** 版本过低导致插件无法载入的问题。
在 [这里](https://github.com/bkm016/TabooLib/releases) 根据您服务器的网络状态下载**在线**或**离线**版本
离线版为 **offline** 结尾的 **jar** 文件
如果你的服务器是 **1.7.10** 版本,在 [这里](https://pcd.ac.cn/2018/05/19/71/) 修复因 **SpecialSource** 版本过低导致插件无法载入的问题
## 添加 TabooLib 为库
### Maven
```xml
<build>
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.Bkm016</groupId>
<artifactId>TabooLib</artifactId>
<version>JitPack版本</version>
</dependency>
</build>
```
### Gradle
```groovy
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
compile 'com.github.Bkm016:TabooLib:JitPack版本'
}
```
### sbt
```scala
resolvers += "jitpack" at "https://jitpack.io"
libraryDependencies += "com.github.Bkm016" % "TabooLib" % "JitPack版本"
```
在添加依赖后,你还需要在 `plugin.yml` 中添加 `softdepend` 或者 `depend` 才能享受到 TabooLib 的全部功能。
<br>
<a name="mcbbs"></a>
MCBBS
---
**3.56** 版本开始 `com.sun.tools.jar` 不再和插件一起发布。
如果需要启用 *JavaShell* 功能请将 [com.sun.tools.jar](http://skymc.oss-cn-shanghai.aliyuncs.com/plugins/com.sun.tools.jar) 放入 *"TabooLib/JavaShell/lib"* 文件夹中。  
---
**3.832** 版本后开源协议更改为 `MIT`
本插件仅在 [**MCBBS**](http://www.mcbbs.net/thread-773065-1-1.html) 发布
<hr>

View File

@ -6,7 +6,7 @@
<groupId>me.skymc</groupId>
<artifactId>TabooLib</artifactId>
<version>4.2</version>
<version>4.325</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

View File

@ -13,6 +13,8 @@ import java.util.concurrent.TimeUnit;
@TConfig(name = "cfg.yml", charset = "GBK")
public class ExampleMain extends JavaPlugin {
private Property<Boolean> update = Property.of(false);
public static void main(String[] args) {
MemoryMXBean bean = ManagementFactory.getMemoryMXBean();
System.out.println(bean.getHeapMemoryUsage().toString());
@ -34,8 +36,6 @@ public class ExampleMain extends JavaPlugin {
}
}
private Property<Boolean> update = Property.of(false);
@Override
public void onEnable() {
update.addListener(((oldVal, newVal) -> {

View File

@ -14,15 +14,16 @@ import com.ilummc.tlib.resources.TLocaleLoader;
import com.ilummc.tlib.util.IO;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.fileutils.FileUtils;
import me.skymc.taboolib.plugin.PluginUtils;
import org.bukkit.Bukkit;
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.lang.reflect.Field;
import java.nio.charset.Charset;
import java.util.Arrays;
@Dependency(type = Dependency.Type.LIBRARY, maven = "com.zaxxer:HikariCP:3.1.0")
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.slf4j:slf4j-api:1.7.25")
@ -58,14 +59,6 @@ public class TLib {
}
}
public static TLib getTLib() {
return tLib;
}
public static YamlConfiguration getInternalLanguage() {
return internalLanguage;
}
public static void init() {
tLib = new TLib();
@ -94,6 +87,11 @@ public class TLib {
}
public static void injectPluginManager() {
if (!tLib.isInjectEnabled() || tLib.isBlackListPluginExists()) {
TLocale.Logger.fatal("TLIB.INJECTION-DISABLED");
Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin != Main.getInst()).forEach(plugin -> TDependencyInjector.inject(plugin, plugin));
return;
}
try {
Field field = Bukkit.getServer().getClass().getDeclaredField("pluginManager");
field.setAccessible(true);
@ -101,14 +99,18 @@ public class TLib {
TLocale.Logger.info("TLIB.INJECTION-SUCCESS");
} catch (NoSuchFieldException | IllegalAccessException | IllegalArgumentException ignored) {
TLocale.Logger.fatal("TLIB.INJECTION-FAILED");
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
if (plugin != Main.getInst()) {
TDependencyInjector.inject(plugin, plugin);
}
}
Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin != Main.getInst()).forEach(plugin -> TDependencyInjector.inject(plugin, plugin));
}
}
public static TLib getTLib() {
return tLib;
}
public static YamlConfiguration getInternalLanguage() {
return internalLanguage;
}
public TLogger getLogger() {
return logger;
}
@ -124,4 +126,18 @@ public class TLib {
public File getLibsFolder() {
return libsFolder;
}
// *********************************
//
// Private Methods
//
// *********************************
private boolean isInjectEnabled() {
return Main.getInst().getConfig().getBoolean("PLUGIN-INJECTOR.ENABLE", true);
}
private boolean isBlackListPluginExists() {
return Main.getInst().getConfig().getStringList("PLUGIN-INJECTOR.DISABLE-ON-PLUGIN-EXISTS").stream().anyMatch(PluginUtils::isPluginExists);
}
}

View File

@ -1,9 +1,12 @@
package com.ilummc.tlib.logger;
import com.ilummc.tlib.resources.TLocale;
import com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.TabooLib;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.plugin.Plugin;
public class TLogger {
@ -12,7 +15,7 @@ public class TLogger {
private static TLogger globalLogger = new TLogger("§8[§3§lTabooLib§8][§r{1}§8] §f{2}", Main.getInst(), TLogger.FINE);
private final String pattern;
private Plugin plugin;
private String name;
private int level;
public static TLogger getGlobalLogger() {
@ -23,8 +26,8 @@ public class TLogger {
return pattern;
}
public Plugin getPlugin() {
return plugin;
public String getName() {
return name;
}
public int getLevel() {
@ -37,49 +40,83 @@ public class TLogger {
public TLogger(String pattern, Plugin plugin, int level) {
this.pattern = pattern;
this.plugin = plugin;
this.name = plugin.getName();
this.level = level;
}
public TLogger(String pattern, String name, int level) {
this.pattern = pattern;
this.name = name;
this.level = level;
}
public void verbose(String msg) {
if (level <= VERBOSE) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§f全部", ChatColor.translateAlternateColorCodes('&', msg)));
if (TabooLib.isSpigot()) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§f全部", TLocale.Translate.setColored(msg)));
} else {
BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§f全部", TLocale.Translate.setColored(msg))));
}
}
}
public void finest(String msg) {
if (level <= FINEST) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§e良好", ChatColor.translateAlternateColorCodes('&', msg)));
if (TabooLib.isSpigot()) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§e良好", TLocale.Translate.setColored(msg)));
} else {
BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§e良好", TLocale.Translate.setColored(msg))));
}
}
}
public void fine(String msg) {
if (level <= FINE) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§a正常", ChatColor.translateAlternateColorCodes('&', msg)));
if (TabooLib.isSpigot()) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§a正常", TLocale.Translate.setColored(msg)));
} else {
BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§a正常", TLocale.Translate.setColored(msg))));
}
}
}
public void info(String msg) {
if (level <= INFO) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§b信息", ChatColor.translateAlternateColorCodes('&', msg)));
if (TabooLib.isSpigot()) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§b信息", TLocale.Translate.setColored(msg)));
} else {
BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§b信息", TLocale.Translate.setColored(msg))));
}
}
}
public void warn(String msg) {
if (level <= WARN) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§6警告", "§6" + ChatColor.translateAlternateColorCodes('&', msg)));
if (TabooLib.isSpigot()) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§6警告", "§6" + TLocale.Translate.setColored(msg)));
} else {
BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§6警告", "§6" + TLocale.Translate.setColored(msg))));
}
}
}
public void error(String msg) {
if (level <= ERROR) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§c错误", "§c" + ChatColor.translateAlternateColorCodes('&', msg)));
if (TabooLib.isSpigot()) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§c错误", "§c" + TLocale.Translate.setColored(msg)));
} else {
BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§c错误", "§c" + TLocale.Translate.setColored(msg))));
}
}
}
public void fatal(String msg) {
if (level <= FATAL) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§4致命错误", "§4" + ChatColor.translateAlternateColorCodes('&', msg)));
if (TabooLib.isSpigot()) {
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§4致命错误", "§4" + TLocale.Translate.setColored(msg)));
} else {
BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§4致命错误", "§4" + TLocale.Translate.setColored(msg))));
}
}
}
@ -87,4 +124,7 @@ public class TLogger {
return new TLogger("§8[§3§l{0}§8][§r{1}§8] §f{2}", plugin, TLogger.FINE);
}
public static TLogger getUnformatted(String name) {
return new TLogger("§8[§3§l{0}§8][§r{1}§8] §f{2}", name, TLogger.FINE);
}
}

View File

@ -40,10 +40,8 @@ public abstract class ActionBar {
@Override
public void send(Player player, String text) {
net.minecraft.server.v1_12_R1.ChatComponentText component = new net.minecraft.server.v1_12_R1.ChatComponentText(text);
net.minecraft.server.v1_12_R1.PacketPlayOutChat packet = new net.minecraft.server.v1_12_R1.PacketPlayOutChat(component,
net.minecraft.server.v1_12_R1.ChatMessageType.a((byte) 2));
net.minecraft.server.v1_12_R1.PacketPlayOutChat packet = new net.minecraft.server.v1_12_R1.PacketPlayOutChat(component, net.minecraft.server.v1_12_R1.ChatMessageType.a((byte) 2));
((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
}
}
}

View File

@ -13,16 +13,15 @@ import java.util.Map;
public class AsmClassTransformer extends ClassVisitor implements Opcodes {
private final Class<?> from;
private final String fromVer, toVer;
private final String fromVer;
private final String toVer;
private final ClassWriter writer;
private String newClassName, prevName;
private String newClassName;
private String prevName;
private AsmClassTransformer(Class<?> from, String fromVer, String toVer, ClassWriter classWriter) {
super(Opcodes.ASM6, classWriter);
writer = classWriter;
super(Opcodes.ASM5, classWriter);
this.writer = classWriter;
this.from = from;
this.fromVer = fromVer;
this.toVer = toVer;
@ -51,6 +50,10 @@ public class AsmClassTransformer extends ClassVisitor implements Opcodes {
return new Builder().toVersion(Bukkit.getServer().getClass().getName().split("\\.")[3]);
}
public static Builder builder(String ver) {
return new Builder().toVersion(ver);
}
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
MethodVisitor visitor = super.visitMethod(access, name, replace(descriptor), replace(signature), replace(exceptions));
@ -67,9 +70,15 @@ public class AsmClassTransformer extends ClassVisitor implements Opcodes {
super.visitInnerClass(replace(name), outerName, replace(name).substring(outerName.length() + 1), access);
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, newClassName.replace('.', '/'), replace(signature), replace(superName), replace(interfaces));
}
private String replace(String text) {
if (text != null) {
return text.replace("net/minecraft/server/" + fromVer, "net/minecraft/server/" + toVer)
return text
.replace("net/minecraft/server/" + fromVer, "net/minecraft/server/" + toVer)
.replace("org/bukkit/craftbukkit/" + fromVer, "org/bukkit/craftbukkit/" + toVer)
.replace(prevName, newClassName.replace('.', '/'));
} else {
@ -88,16 +97,10 @@ public class AsmClassTransformer extends ClassVisitor implements Opcodes {
}
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, newClassName.replace('.', '/'), replace(signature),
replace(superName), replace(interfaces));
}
private class AsmMethodTransformer extends MethodVisitor {
AsmMethodTransformer(MethodVisitor visitor) {
super(Opcodes.ASM6, visitor);
super(Opcodes.ASM5, visitor);
}
@Override

View File

@ -4,6 +4,7 @@ import com.ilummc.tlib.TLib;
import com.ilummc.tlib.resources.TLocale;
import com.ilummc.tlib.util.IO;
import com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.common.function.TFunctionLoader;
import me.skymc.taboolib.database.GlobalDataManager;
import me.skymc.taboolib.database.PlayerDataManager;
import me.skymc.taboolib.economy.EcoUtils;
@ -22,6 +23,7 @@ import me.skymc.taboolib.permission.PermissionUtils;
import me.skymc.taboolib.playerdata.DataUtils;
import me.skymc.taboolib.skript.SkriptHandler;
import me.skymc.taboolib.socket.TabooLibClient;
import me.skymc.taboolib.socket.TabooLibServer;
import me.skymc.taboolib.string.language2.Language2;
import me.skymc.taboolib.support.SupportPlaceholder;
import me.skymc.taboolib.timecycle.TimeCycleManager;
@ -111,7 +113,7 @@ public class Main extends JavaPlugin {
// 载入权限
PermissionUtils.loadRegisteredServiceProvider();
// 物品名称
ItemUtils.LoadLib();
ItemUtils.init();
// 低层工具
DabItemUtils.getInstance();
// 载入周期管理器
@ -162,6 +164,10 @@ public class Main extends JavaPlugin {
}
} catch (IOException ignored) {
}
// 本地通讯网络终端
if (getConfig().getBoolean("SERVER")) {
TabooLibServer.main(new String[0]);
}
// 本地通讯网络
TabooLibClient.init();
}
@ -198,6 +204,8 @@ public class Main extends JavaPlugin {
HikariHandler.closeDataSourceForce();
// 注销监听器
TListenerHandler.cancelListeners();
// 注销子模块
TFunctionLoader.unloadFunction();
// 结束数据库储存方法
if (getStorageType() == StorageType.SQL) {
GlobalDataManager.SQLMethod.cancelSQLMethod();

View File

@ -1,5 +1,6 @@
package me.skymc.taboolib;
import me.skymc.taboolib.nms.NMSUtils;
import me.skymc.taboolib.other.NumberUtils;
import me.skymc.taboolib.playerdata.DataUtils;
import net.md_5.bungee.api.ChatColor;
@ -18,41 +19,128 @@ public class TabooLib {
static {
try {
spigot = Bukkit.getConsoleSender() != null;
Class.forName("org.bukkit.Bukkit");
spigot = true;
} catch (Exception ignored) {
}
}
/**
* 获取主类对象 Main 名称容易造成混淆所以转移至此
*
* @return {@link Main}
*/
public static Main instance() {
return (Main) Main.getInst();
}
/**
* 插件是否为 TabooLib沙雕方法
*
* @param plugin 插件
* @return boolean
*/
public static boolean isTabooLib(Plugin plugin) {
return plugin.equals(instance()) || plugin.getName().equals("TabooLib");
}
/**
* 插件是否依赖于 TabooLib依赖或软兼容
*
* @param plugin 插件
* @return boolean
*/
public static boolean isDependTabooLib(Plugin plugin) {
return plugin.getDescription().getDepend().contains("TabooLib") || plugin.getDescription().getSoftDepend().contains("TabooLib");
}
/**
* 是否为 Spigot 核心 TabooLib 可在 BungeeCord 上运行所以添加此方法
*
* @return boolean
*/
public static boolean isSpigot() {
return spigot;
}
public static boolean isDebug() {
return Main.getInst().getConfig().getBoolean("DEBUG");
}
public static void debug(Plugin plugin, String... args) {
if (Main.getInst().getConfig().getBoolean("DEBUG")) {
Arrays.stream(args).forEach(var -> Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "[TabooLib - DEBUG][" + plugin.getName() + "] " + ChatColor.RED + var));
}
}
/**
* 获取 TabooLib 插件版本
*
* @return double
*/
public static double getPluginVersion() {
return NumberUtils.getDouble(Main.getInst().getDescription().getVersion());
}
/**
* 获取服务端版本
*
* @return String
*/
public static String getVersion() {
return Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
return Bukkit.getServer().getClass().getName().split("\\.")[3];
}
/**
* 获取服务端版本数字
*
* @return int
*/
public static int getVersionNumber() {
return getVerint();
}
/**
* 重置服务器序列号
*/
public static void resetServerUID() {
DataUtils.getPluginData("TabooLibrary", null).set("serverUID", UUID.randomUUID().toString());
}
/**
* 是否为调试模式
*
* @return boolean
*/
public static boolean isDebug() {
return DataUtils.getPluginData("TabooLibrary", instance()).getBoolean("debug");
}
/**
* 切换调试模式
*
* @param debug
*/
public static void setDebug(boolean debug) {
DataUtils.getPluginData("TabooLibrary", instance()).set("debug", debug);
}
/**
* 发送调试信息
*
* @param args 内容
*/
public static void debug(String... args) {
debug(instance(), args);
}
/**
* 发送调试信息
*
* @param plugin 插件名
* @param 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));
}
}
/**
* 获取服务器序列号
*
* @return String
*/
public static String getServerUID() {
if (!DataUtils.getPluginData("TabooLibrary", null).contains("serverUID")) {
DataUtils.getPluginData("TabooLibrary", null).set("serverUID", UUID.randomUUID().toString());
@ -60,8 +148,19 @@ public class TabooLib {
return DataUtils.getPluginData("TabooLibrary", null).getString("serverUID");
}
public static void resetServerUID() {
DataUtils.getPluginData("TabooLibrary", null).set("serverUID", UUID.randomUUID().toString());
/**
* 获取服务器 TPS
*
* @return double[3]
*/
public static double[] getTPS() {
try {
Class<?> minecraftServer = NMSUtils.getNMSClass("MinecraftServer");
Object server = minecraftServer.getMethod("getServer").invoke(null);
return (double[]) server.getClass().getField("recentTps").get(server);
} catch (Exception e) {
return new double[] {0, 0, 0};
}
}
@Deprecated

View File

@ -5,25 +5,34 @@ import com.ilummc.tlib.annotations.Dependency;
import com.ilummc.tlib.inject.TDependencyInjector;
import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.bstats.Metrics;
import me.skymc.taboolib.commands.language.Language2Command;
import me.skymc.taboolib.fileutils.FileUtils;
import me.skymc.taboolib.listener.TListener;
import me.skymc.taboolib.listener.TListenerHandler;
import me.skymc.taboolib.playerdata.DataUtils;
import me.skymc.tlm.command.TLMCommands;
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.event.server.PluginEnableEvent;
import org.bukkit.plugin.Plugin;
import java.io.File;
import java.io.InputStream;
import java.net.InetAddress;
import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
/**
* @Author sky
* @Since 2018-08-23 17:04
*/
class TabooLibLoader {
@TListener
public class TabooLibLoader implements Listener {
static HashMap<String, List<Class>> pluginClasses = new HashMap<>();
static void setup() {
testInternet();
@ -33,11 +42,21 @@ class TabooLibLoader {
}
static void register() {
setupClasses();
registerListener();
registerCommands();
registerMetrics();
}
/**
* 获取插件所有被读取到的类
*
* @param plugin 插件
* @return List
*/
public static Optional<List<Class>> getPluginClasses(Plugin plugin) {
return Optional.ofNullable(pluginClasses.get(plugin.getName()));
}
/**
* 初始化插件文件夹
*/
@ -46,6 +65,40 @@ class TabooLibLoader {
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 setupClasses() {
Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(TabooLibLoader::setupClasses);
}
/**
* 读取插件类
*/
static void setupClasses(Plugin plugin) {
if (!(TabooLib.isTabooLib(plugin) || TabooLib.isDependTabooLib(plugin))) {
return;
}
try {
long time = System.currentTimeMillis();
List<Class> classes = FileUtils.getClasses(plugin);
TLocale.Logger.info("DEPENDENCY.LOAD-CLASSES", plugin.getName(), String.valueOf(classes.size()), String.valueOf(System.currentTimeMillis() - time));
pluginClasses.put(plugin.getName(), classes);
} catch (Exception ignored) {
}
}
/**
* 初始化插件依赖库
*/
@ -85,25 +138,6 @@ class TabooLibLoader {
}
}
/**
* 载入插件数据库
*/
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 registerCommands() {
Bukkit.getPluginCommand("language2").setExecutor(new Language2Command());
Bukkit.getPluginCommand("taboolibrarymodule").setExecutor(new TLMCommands());
}
/**
* 载入插件监听
*/
@ -120,7 +154,15 @@ class TabooLibLoader {
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())));
metrics.addCustomChart(new Metrics.AdvancedPie("plugins_using_taboolib_name", () -> Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin.getDescription().getDepend().contains("TabooLib")).collect(Collectors.toMap(Plugin::getName, plugin -> 1, (a, b) -> b))));
}
@EventHandler(priority = EventPriority.LOWEST)
public void onEnable(PluginEnableEvent e) {
setupClasses(e.getPlugin());
}
@EventHandler(priority = EventPriority.MONITOR)
public void onDisable(PluginDisableEvent e) {
pluginClasses.remove(e.getPlugin().getName());
}
}

View File

@ -1,78 +1,29 @@
package me.skymc.taboolib.anvil;
import me.skymc.taboolib.nms.NMSUtils;
import org.bukkit.entity.Player;
/**
* @author sky
* @Author sky
* @Since 2018-09-08 15:47
*/
public class AnvilContainer {
public class AnvilContainer extends net.minecraft.server.v1_12_R1.ContainerAnvil {
// private static IAnvilContainer instance;
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);
}
private static Class<?> ChatMessage = NMSUtils.getNMSClass("ChatMessage");
private static Class<?> PacketPlayOutOpenWindow = NMSUtils.getNMSClass("PacketPlayOutOpenWindow");
private static Class<?> IChatBaseComponent = NMSUtils.getNMSClass("IChatBaseComponent");
private static Class<?> Packet = NMSUtils.getNMSClass("Packet");
// public static IAnvilContainer getInstance() {
// return instance;
// }
//
// static {
// /*
// * 玩不懂玩不懂... 似乎不会更改父类的包名?
// */
// instance = (IAnvilContainer) AsmClassTransformer.builder()
// .from(AnvilContainerImpl.class)
// .fromVersion("v1_12_R1")
// .toVersion(Bukkit.getServer().getClass().getName().split("\\.")[3])
// .build()
// .transform();
// }
@Override
public boolean a(net.minecraft.server.v1_12_R1.EntityHuman player) {
return true;
}
public static void openAnvil(Player p) {
try {
Object player = p.getClass().getMethod("getHandle").invoke(p);
int c = (int) player.getClass().getMethod("nextContainerCounter").invoke(player);
Object chatMessage = ChatMessage.getConstructor(String.class, Object[].class).newInstance("Repairing", new Object[0]);
Object packetPlayOutOpenWindow = PacketPlayOutOpenWindow.getConstructor(Integer.TYPE, String.class, IChatBaseComponent, Integer.TYPE).newInstance(c, "minecraft:anvil", chatMessage, 0);
Object playerConnection = player.getClass().getDeclaredField("playerConnection").get(player);
playerConnection.getClass().getMethod("sendPacket", Packet).invoke(playerConnection, packetPlayOutOpenWindow);
} catch (Exception ignored) {
}
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);
}
}
//interface IAnvilContainer {
//
// /**
// * 打开铁砧界面
// *
// * @param player 玩家
// */
// void openAnvil(Player player);
//}
//
//class AnvilContainerImpl extends net.minecraft.server.v1_12_R1.ContainerAnvil implements IAnvilContainer {
//
// public AnvilContainerImpl(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 void openAnvil(Player p) {
// net.minecraft.server.v1_12_R1.EntityPlayer player = ((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) p).getHandle();
// AnvilContainerImpl container = new AnvilContainerImpl(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);
// }
//
// @Override
// public boolean a(net.minecraft.server.v1_12_R1.EntityHuman player) {
// return true;
// }
//}
}

View File

@ -1,105 +1,44 @@
package me.skymc.taboolib.anvil;
import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.listener.TListener;
import com.ilummc.tlib.util.asm.AsmClassLoader;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.object.Instantiable;
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.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@TListener
/**
* @author sky
*/
@Instantiable("AnvilContainerAPI")
public class AnvilContainerAPI implements Listener {
public static List<String> list = new ArrayList<>();
public static ItemStack item = new ItemStack(Material.NAME_TAG);
public static HashMap<String, String> isOpen = new HashMap<>();
public static AnvilContainerAPIEvent event;
private static Class<?> impl;
public static void send(Player p, String type, String str, List<String> lorelist) {
isOpen.put(p.getName(), type);
AnvilContainer.openAnvil(p);
ItemMeta meta = item.getItemMeta();
list.clear();
if (lorelist == null) {
list.addAll(TLocale.asStringList("ANVIL-CONTAINER.LORE-NORMAL"));
} else {
list = lorelist;
}
meta.setLore(list);
meta.setDisplayName(str);
item.setItemMeta(meta);
p.getOpenInventory().getTopInventory().setItem(0, item);
p.playSound(p.getLocation(), Sound.BLOCK_ANVIL_PLACE, 1, 1);
}
@EventHandler
public void close(InventoryCloseEvent e) {
if (isOpen.containsKey(e.getPlayer().getName())) {
isOpen.remove(e.getPlayer().getName());
if (e.getInventory().getType() == InventoryType.ANVIL) {
e.getInventory().clear();
}
public AnvilContainerAPI() {
try {
impl = AsmClassLoader.createNewClass("me.skymc.taboolib.anvil.AnvilContainer", AnvilContainerGenerator.generate());
Bukkit.getPluginManager().registerEvents(this, TabooLib.instance());
} catch (Exception e) {
e.printStackTrace();
}
}
@EventHandler
public void click(InventoryClickEvent e) {
if (!isOpen.containsKey(e.getWhoClicked().getName())) {
return;
}
if (e.getInventory().getType() != InventoryType.ANVIL) {
return;
}
e.setCancelled(true);
int slot = e.getRawSlot();
if (slot != 2) {
return;
}
Inventory inv = e.getInventory();
if (inv.getItem(2) == null) {
return;
}
if (inv.getItem(2).getItemMeta().hasDisplayName()) {
event = new AnvilContainerAPIEvent(e, isOpen.get(e.getWhoClicked().getName()), inv.getItem(2).getItemMeta().getDisplayName());
e.getWhoClicked().closeInventory();
Bukkit.getPluginManager().callEvent(event);
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 ("/anvilexample".equals(e.getMessage())) {
if (e.getPlayer().hasPermission("taboolib.admin")) {
e.setCancelled(true);
AnvilContainerAPI.send(e.getPlayer(), "EXAMPLE", TLocale.asString("ANVIL-CONTAINER.NAME-EXAMPLE"), null);
}
}
}
@EventHandler
public void example2(AnvilContainerAPIEvent e) {
if ("EXAMPLE".equals(e.type)) {
e.event.getWhoClicked().sendMessage(e.string);
if (e.getMessage().equalsIgnoreCase("/anvilExample") && e.getPlayer().hasPermission("taboolib.admin")) {
e.setCancelled(true);
openAnvil(e.getPlayer());
}
}
}

View File

@ -1,28 +0,0 @@
package me.skymc.taboolib.anvil;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.inventory.InventoryClickEvent;
public class AnvilContainerAPIEvent extends Event {
public static final HandlerList handlers = new HandlerList();
public InventoryClickEvent event;
public String string;
public String type;
public AnvilContainerAPIEvent(InventoryClickEvent e, String t, String s) {
event = e;
string = s;
type = t;
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}

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

@ -17,13 +17,7 @@ import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.zip.GZIPOutputStream;
@ -36,13 +30,22 @@ import java.util.zip.GZIPOutputStream;
*/
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'});
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!");
@ -50,18 +53,6 @@ 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;
// The plugin
private final JavaPlugin plugin;
@ -103,7 +94,8 @@ public class Metrics {
).copyDefaults(true);
try {
config.save(configFile);
} catch (IOException ignored) { }
} catch (IOException ignored) {
}
}
// Load the data
@ -117,7 +109,8 @@ public class Metrics {
service.getField("B_STATS_VERSION"); // Our identifier :)
found = true; // We aren't the first
break;
} catch (NoSuchFieldException ignored) { }
} catch (NoSuchFieldException ignored) {
}
}
// Register our service
Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
@ -128,6 +121,61 @@ public class Metrics {
}
}
/**
* 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.
*
@ -161,7 +209,7 @@ public class Metrics {
}
});
}
}, 1000*60*5, 1000*60*30);
}, 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!
@ -256,9 +304,11 @@ public class Metrics {
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
try {
pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider()));
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {
}
}
} catch (NoSuchFieldException ignored) { }
} catch (NoSuchFieldException ignored) {
}
}
data.put("plugins", pluginData);
@ -280,61 +330,6 @@ public class Metrics {
}).start();
}
/**
* 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();
}
/**
* Represents a custom chart.
*/
@ -388,7 +383,7 @@ public class Metrics {
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @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) {
@ -419,7 +414,7 @@ public class Metrics {
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @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) {
@ -463,7 +458,7 @@ public class Metrics {
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @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) {
@ -512,7 +507,7 @@ public class Metrics {
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @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) {
@ -544,7 +539,7 @@ public class Metrics {
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @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) {
@ -589,7 +584,7 @@ public class Metrics {
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @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) {
@ -627,7 +622,7 @@ public class Metrics {
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @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) {

View File

@ -97,6 +97,47 @@ public class TabooLibExecuteCommand extends BaseMainCommand {
}
};
@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)) {

View File

@ -779,39 +779,12 @@ public class TabooLibMainCommand extends BaseMainCommand {
@Override
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!UpdateTask.isHaveUpdate()) {
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.UPDATEPLUGIN.UPDATE-NOT-FOUND");
return;
}
UpdateTask.updatePlugin(true);
}
File pluginFile = PluginUtils.getPluginFile(Main.getInst());
if (pluginFile == null) {
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.UPDATEPLUGIN.FILE-NOT-FOUND");
return;
}
new BukkitRunnable() {
@Override
public void run() {
if (PlayerUtils.getOnlinePlayers().size() > 0) {
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.UPDATEPLUGIN.PLAYER-ONLINE");
return;
}
String url = Strings.replaceWithOrder("https://github.com/Bkm016/TabooLib/releases/download/{0}/TabooLib-{0}.jar", UpdateTask.getNewVersion());
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.UPDATEPLUGIN.UPDATE-START", url);
File file = new File("plugins/update");
if (file.exists()) {
FileUtils.download(url, new File(file, pluginFile.getName()));
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.UPDATEPLUGIN.UPDATE-SUCCESS");
} else {
FileUtils.download(url, pluginFile);
Bukkit.shutdown();
}
}
}.runTaskAsynchronously(Main.getInst());
@Override
public CommandType getType() {
return CommandType.CONSOLE;
}
};
}

View File

@ -0,0 +1,97 @@
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.Bukkit;
import org.bukkit.command.*;
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 final String command;
private final 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;
SimpleCommandBuilder(String command, Plugin plugin) {
this.command = command;
this.plugin = plugin;
this.description = "";
this.usage = "/" + command;
this.aliases = new ArrayList<>();
}
public static SimpleCommandBuilder create(String command, Plugin plugin) {
return new SimpleCommandBuilder(command, plugin);
}
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;
}
public SimpleCommandBuilder build() {
Preconditions.checkNotNull(completerCommand, "缺少 \"CompleterCommand\" 部分");
Preconditions.checkNotNull(completerTab, "缺少 \"CompleterTab\" 部分");
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));
return this;
}
}

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

@ -76,7 +76,7 @@ public abstract class BaseMainCommand implements CommandExecutor, TabExecutor {
}
});
}
if (methods.size() + fields.size() > 0) {
if (methods.size() + fields.size() > 0 && !TabooLib.isTabooLib(baseMainCommand.getRegisterCommand().getPlugin())) {
TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-REGISTER", baseMainCommand.getRegisterCommand().getPlugin().getName(), baseMainCommand.getRegisterCommand().getName(), String.valueOf(methods.size() + fields.size()));
}
}

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

@ -54,20 +54,20 @@ public class TCommandHandler implements Listener {
return registerPluginCommand(plugin, command, "", "/" + command, new ArrayList<>(), null, null, commandExecutor, null);
}
public static boolean registerPluginCommand(Plugin plugin, String command, CommandExecutor commandExecutor, TabExecutor tabExecutor) {
return registerPluginCommand(plugin, command, "", "/" + command, new ArrayList<>(), null, null, commandExecutor, tabExecutor);
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, TabExecutor tabExecutor) {
return registerPluginCommand(plugin, command, description, "/" + command, new ArrayList<>(), null, null, commandExecutor, tabExecutor);
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, TabExecutor tabExecutor) {
return registerPluginCommand(plugin, command, description, usage, new ArrayList<>(), null, null, commandExecutor, tabExecutor);
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, TabExecutor tabExecutor) {
return registerPluginCommand(plugin, command, description, usage, aliases, null, null, commandExecutor, tabExecutor);
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);
}
/**
@ -81,16 +81,16 @@ public class TCommandHandler implements Listener {
* @param permission 权限
* @param permissionMessage 权限提示
* @param commandExecutor 命令执行器
* @param tabExecutor 补全执行器
* @param tabCompleter 补全执行器
* @return 注册结果(boolean)
*/
public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, List<String> aliases, String permission, String permissionMessage, CommandExecutor commandExecutor, TabExecutor tabExecutor) {
public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, List<String> aliases, String permission, String permissionMessage, CommandExecutor commandExecutor, TabCompleter tabCompleter) {
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(tabExecutor);
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);
@ -98,7 +98,9 @@ public class TCommandHandler implements Listener {
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "permission", permission);
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "permissionMessage", permissionMessage);
commandMap.register(command, pluginCommand);
TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE", plugin.getName(), command);
if (!TabooLib.isTabooLib(plugin)) {
TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE", plugin.getName(), command);
}
return true;
} catch (Exception e) {
TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE-FAILED", plugin.getName(), command, e.getMessage());
@ -134,12 +136,10 @@ public class TCommandHandler implements Listener {
*/
public static void registerCommands() {
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
if (plugin.equals(TabooLib.instance()) || plugin.getDescription().getDepend().contains("TabooLib")) {
try {
registerCommand(plugin);
} catch (Exception e) {
e.printStackTrace();
}
try {
registerCommand(plugin);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@ -150,6 +150,9 @@ public class TCommandHandler implements Listener {
* @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);

View File

@ -2,11 +2,12 @@ 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.object.Instantiable;
import me.skymc.taboolib.string.language2.Language2Value;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -14,18 +15,23 @@ import org.bukkit.entity.Player;
* @author sky
* @since 2018年2月13日 下午5:11:01
*/
public class Language2Command implements CommandExecutor {
@Instantiable("Language2Command")
public class Language2Command {
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (args.length == 0) {
TLocale.sendTo(sender, "COMMANDS.LANGUAGE2.HELP", label);
} else if ("reload".equalsIgnoreCase(args[0])) {
reload(sender);
} else if ("send".equalsIgnoreCase(args[0])) {
send(sender, args);
}
return true;
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) {

View File

@ -0,0 +1,113 @@
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.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() + "\"");
}
/**
* 创建配置文件
*
* @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 static Map<String, List<File>> getFiles() {
return files;
}
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 void runListener() {
try {
Optional.ofNullable(runnable).ifPresent(Runnable::run);
} catch (Exception e) {
e.printStackTrace();
}
}
public File getFile() {
return file;
}
public TConfiguration listener(Runnable runnable) {
this.runnable = runnable;
return this;
}
}

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,82 @@
package me.skymc.taboolib.common.function;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.TabooLibLoader;
import me.skymc.taboolib.listener.TListener;
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.lang.reflect.Method;
import java.util.*;
/**
* @Author sky
* @Since 2018-09-08 14:00
*/
@TListener
public class TFunctionLoader implements Listener {
private static HashMap<String, List<Class>> pluginFunction = new HashMap<>();
TFunctionLoader() {
loadFunction();
}
public static void loadFunction() {
Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(TFunctionLoader::loadFunction);
}
public static void loadFunction(Plugin plugin) {
if (!(TabooLib.isTabooLib(plugin) || TabooLib.isDependTabooLib(plugin))) {
return;
}
TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> {
for (Class pluginClass : classes) {
if (pluginClass.isAnnotationPresent(TFunction.class)) {
TFunction function = (TFunction) pluginClass.getAnnotation(TFunction.class);
try {
Method method = pluginClass.getDeclaredMethod(function.enable());
method.setAccessible(true);
method.invoke(pluginClass.newInstance());
pluginFunction.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(pluginClass);
} catch (Exception ignored) {
}
}
}
});
}
public static void unloadFunction() {
Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(TFunctionLoader::unloadFunction);
}
public static void unloadFunction(Plugin plugin) {
Optional.ofNullable(pluginFunction.remove(plugin.getName())).ifPresent(classes -> {
for (Class pluginClass : classes) {
if (pluginClass.isAnnotationPresent(TFunction.class)) {
TFunction function = (TFunction) pluginClass.getAnnotation(TFunction.class);
try {
Method method = pluginClass.getDeclaredMethod(function.disable());
method.setAccessible(true);
method.invoke(pluginClass.newInstance());
} catch (Exception ignored) {
}
}
}
});
}
@EventHandler
public void onEnable(PluginEnableEvent e) {
loadFunction(e.getPlugin());
}
@EventHandler
public void onDisable(PluginDisableEvent e) {
unloadFunction(e.getPlugin());
}
}

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,58 @@
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 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,46 @@
package me.skymc.taboolib.common.pathfinder;
import me.skymc.taboolib.common.versioncontrol.SimpleVersionControl;
import me.skymc.taboolib.object.Instantiable;
/**
* @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.create()
.from("1_8_R3")
.target("me.skymc.taboolib.common.pathfinder.internal.InternalPathfinderCreator")
.translate()
.newInstance();
internalPathfinderExecutor = (PathfinderExecutor) SimpleVersionControl.create()
.from("1_8_R3")
.target("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,187 @@
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 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,91 @@
package me.skymc.taboolib.common.playercontainer;
import com.ilummc.tlib.logger.TLogger;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.TabooLibLoader;
import me.skymc.taboolib.listener.TListener;
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.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.plugin.Plugin;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* @Author sky
* @Since 2018-09-14 23:45
*/
@TListener
public class PlayerContainerLoader implements Listener {
private static Map<String, List<Container>> pluginContainer = new ConcurrentHashMap<>();
PlayerContainerLoader() {
load();
}
public static void load() {
Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(PlayerContainerLoader::load);
}
public static void load(Plugin plugin) {
if (!(TabooLib.isTabooLib(plugin) || TabooLib.isDependTabooLib(plugin))) {
return;
}
TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> {
for (Class pluginClass : classes) {
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) {
}
}
}
});
}
public static void unload() {
Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(PlayerContainerLoader::unload);
}
public static void unload(Plugin plugin) {
pluginContainer.remove(plugin.getName());
}
@EventHandler
public void onEnable(PluginEnableEvent e) {
load(e.getPlugin());
}
@EventHandler
public void onDisable(PluginDisableEvent e) {
unload(e.getPlugin());
}
@EventHandler(priority = EventPriority.MONITOR)
public void onQuit(PlayerQuitEvent e) {
for (List<Container> containers : pluginContainer.values()) {
for (Container container : containers) {
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,28 @@
package me.skymc.taboolib.common.util;
/**
* @Author sky
* @Since 2018-09-25 15:21
*/
public class SimpleCounter {
private int timer;
private int limit;
public SimpleCounter(int limit) {
this.timer = 0;
this.limit = limit;
}
public boolean next() {
if (--timer <= 0) {
timer = limit;
return true;
}
return false;
}
public void reset() {
timer = 0;
}
}

View File

@ -0,0 +1,56 @@
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, name, signature, translate(superName), translate(interfaces));
}
@Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
super.visitInnerClass(name, translate(outerName), translate(innerName), access);
}
@Override
public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
return super.visitField(access, name, translate(descriptor), translate(signature), value);
}
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
return new SimpleMethodVisitor(simpleVersionControl, super.visitMethod(access, 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,60 @@
package me.skymc.taboolib.common.versioncontrol;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
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 visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
super.visitMethodInsn(opcode, translate(owner), name, translate(descriptor), isInterface);
}
@Override
public void visitLdcInsn(Object value) {
super.visitLdcInsn(value instanceof String ? translate((String) value) : 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), name, translate(descriptor));
}
@Override
public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) {
super.visitLocalVariable(name, translate(descriptor), translate(signature), start, end, index);
}
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,100 @@
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.ArrayList;
import java.util.List;
/**
* 我不信 ClassNotFound 的邪自己写了一个发现还是一样
*
* @Author sky
* @Since 2018-09-19 21:05
*/
public class SimpleVersionControl {
private String target;
private List<String> from = Lists.newArrayList();
private String to;
private Plugin plugin;
SimpleVersionControl() {
}
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 SimpleVersionControl target(Class<?> target) {
this.target = target.getName();
return this;
}
public SimpleVersionControl target(String target) {
this.target = target;
return this;
}
public SimpleVersionControl from(String from) {
this.from.add(from.startsWith("v") ? from : "v" + from);
return this;
}
public SimpleVersionControl to(String to) {
this.to = to.startsWith("v") ? to : "v" + to;
return this;
}
public SimpleVersionControl plugin(Plugin plugin) {
this.plugin = plugin;
return this;
}
public Class<?> translate() throws IOException {
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();
return AsmClassLoader.createNewClass(target, classWriter.toByteArray());
}
// *********************************
//
// Getter and Setter
//
// *********************************
public String getTarget() {
return target;
}
public List<String> getFrom() {
return from;
}
public String getTo() {
return to;
}
public String replace(String origin) {
for (String from : from) {
origin = origin.replace("/" + from + "/", "/" + to + "/");
}
return origin;
}
}

View File

@ -1,58 +1,44 @@
package me.skymc.taboolib.damage;
import me.skymc.taboolib.TabooLib;
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;
import java.lang.reflect.InvocationTargetException;
/**
* @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) {
if (victim instanceof LivingEntity) {
dmg(player, (LivingEntity) victim, damage);
}
dmg(player, (LivingEntity) victim, damage);
}
public static void dmg(LivingEntity paramLivingEntity1, LivingEntity paramLivingEntity2, double paramDouble) {
if ((paramLivingEntity2.hasMetadata("NPC")) || (paramLivingEntity1.hasMetadata("NPC"))) {
return;
}
Object localObject1;
try {
localObject1 = paramLivingEntity1.getClass().getDeclaredMethod("getHandle").invoke(paramLivingEntity1);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException localIllegalAccessException1) {
return;
}
Object localObject2;
try {
localObject2 = paramLivingEntity2.getClass().getDeclaredMethod("getHandle").invoke(paramLivingEntity2);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException localIllegalAccessException2) {
return;
}
try {
Class<?> DamageSource = nmsClass("DamageSource");
Object localObject3 = DamageSource.getDeclaredMethod("playerAttack", nmsClass("EntityHuman")).invoke(DamageSource, localObject1);
localObject2.getClass().getDeclaredMethod("damageEntity", new Class[]{DamageSource, Float.TYPE}).invoke(localObject2, localObject3, (float) paramDouble);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException ignored) {
}
}
private static Class<?> nmsClass(String paramString) {
String str = "net.minecraft.server." + TabooLib.getVersion() + "." + paramString;
try {
return Class.forName(str);
} catch (ClassNotFoundException e) {
return null;
}
@Deprecated
public static void dmg(LivingEntity attacker, LivingEntity victim, double damage) {
attacker.damage(damage, victim);
}
}

View File

@ -4,19 +4,11 @@ import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
@Deprecated
public class GetDamager {
public static Player get(EntityDamageByEntityEvent e) {
Player p = null;
if (e.getDamager() instanceof Projectile) {
Projectile arrow = (Projectile) e.getDamager();
if (arrow.getShooter() instanceof Player) {
p = (Player) arrow.getShooter();
}
} else if (e.getDamager() instanceof Player) {
p = (Player) e.getDamager();
}
return p;
return DamageUtils.getAttackerInDamageEvent(e);
}
}

View File

@ -1,22 +1,13 @@
package me.skymc.taboolib.damage;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.EntityDeathEvent;
@Deprecated
public class GetKiller {
public static Player get(EntityDeathEvent e) {
Player p = null;
if (e.getEntity().getKiller() instanceof Projectile) {
Projectile arrow = (Projectile) e.getEntity().getKiller();
if (arrow.getShooter() instanceof Player) {
p = (Player) arrow.getShooter();
}
} else if (e.getEntity().getKiller() != null) {
p = e.getEntity().getKiller();
}
return p;
return e.getEntity().getKiller();
}
}

View File

@ -18,7 +18,7 @@ public class VectorUtils {
/**
* 物品丢弃
*
* <p>
* 常用参数
* itemDrop(player, itemStack, 0.2, 0.5)
*
@ -57,7 +57,7 @@ public class VectorUtils {
/**
* 生物抛射
*
* <p>
* 常用参数
* entityPush(entity, location, 15)
*
@ -69,17 +69,17 @@ public class VectorUtils {
Location from = entity.getLocation();
Vector test = to.clone().subtract(from).toVector();
Double elevation = test.getY();
double elevation = test.getY();
Double launchAngle = calculateLaunchAngle(from, to, velocity, elevation, 20.0D);
Double distance = Math.sqrt(Math.pow(test.getX(), 2.0D) + Math.pow(test.getZ(), 2.0D));
double distance = Math.sqrt(Math.pow(test.getX(), 2.0D) + Math.pow(test.getZ(), 2.0D));
if (distance == 0.0D) {
return;
}
if (launchAngle == null) {
launchAngle = Math.atan((40.0D * elevation + Math.pow(velocity, 2.0D)) / (40.0D * elevation + 2.0D * Math.pow(velocity, 2.0D)));
}
Double hangTime = calculateHangTime(launchAngle, velocity, elevation, 20.0D);
double hangTime = calculateHangTime(launchAngle, velocity, elevation, 20.0D);
test.setY(Math.tan(launchAngle) * distance);
test = normalizeVector(test);
@ -113,7 +113,7 @@ public class VectorUtils {
private static Double calculateLaunchAngle(Location from, Location to, double v, double elevation, double g) {
Vector vector = from.clone().subtract(to).toVector();
Double distance = Math.sqrt(Math.pow(vector.getX(), 2.0D) + Math.pow(vector.getZ(), 2.0D));
double distance = Math.sqrt(Math.pow(vector.getX(), 2.0D) + Math.pow(vector.getZ(), 2.0D));
double v2 = Math.pow(v, 2.0D);
double v4 = Math.pow(v, 4.0D);
double check = g * (g * Math.pow(distance, 2.0D) + 2.0D * elevation * v2);

View File

@ -1,53 +0,0 @@
package me.skymc.taboolib.events;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
public class DefaultEvent2 extends PlayerEvent {
private static final HandlerList handlers;
static {
handlers = new HandlerList();
}
private DefaultEvent2(final Player who) {
super(who);
}
public static HandlerList getHandlerList() {
return DefaultEvent2.handlers;
}
@Override
public HandlerList getHandlers() {
return DefaultEvent2.handlers;
}
public static class Pre extends DefaultEvent2 implements Cancellable {
private boolean cancelled;
public Pre(Player who) {
super(who);
this.cancelled = false;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(final boolean cancelled) {
this.cancelled = cancelled;
}
}
public static class Post extends DefaultEvent2 {
public Post(Player who) {
super(who);
}
}
}

View File

@ -1,13 +1,15 @@
package me.skymc.taboolib.fileutils;
import ch.njol.util.Closeable;
import com.ilummc.eagletdl.EagletTask;
import com.ilummc.eagletdl.ProgressEvent;
import com.ilummc.tlib.resources.TLocale;
import com.ilummc.tlib.util.IO;
import me.skymc.taboolib.Main;
import org.apache.commons.io.IOUtils;
import org.bukkit.plugin.Plugin;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
@ -133,13 +135,9 @@ public class FileUtils {
public static InputStream getResource(Plugin plugin, String filename) {
try {
URL url = plugin.getClass().getClassLoader().getResource(filename);
if (url == null) {
return null;
} else {
URLConnection connection = url.openConnection();
connection.setUseCaches(false);
return connection.getInputStream();
}
URLConnection connection = url.openConnection();
connection.setUseCaches(false);
return connection.getInputStream();
} catch (IOException ignored) {
return null;
}
@ -409,35 +407,38 @@ public class FileUtils {
/**
* 下载文件
*
* @param downloadURL 下载地址
* @param file 保存位置
* @param url 下载地址
* @param file 下载位置
* @param async 是否异步
*/
public static void download(String downloadURL, File file) {
HttpURLConnection conn = null;
InputStream inputStream = null;
FileOutputStream fos = null;
try {
URL url = new URL(downloadURL);
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5 * 1000);
conn.setRequestProperty("User-Agent", "Mozilla/31.0 (compatible; MSIE 10.0; Windows NT; DigExt)");
inputStream = conn.getInputStream();
byte[] data = read(inputStream);
fos = new FileOutputStream(createNewFile(file));
fos.write(data);
} catch (Exception ignored) {
} finally {
IOUtils.close(conn);
IOUtils.closeQuietly(fos);
IOUtils.closeQuietly(inputStream);
public static void download(String url, File file, boolean async) {
EagletTask eagletTask = new EagletTask()
.url(url)
.file(file)
.setThreads(8)
.setOnError(event -> {
})
.setOnConnected(event -> TLocale.Logger.info("UTIL.DOWNLOAD-CONNECTED", file.getName(), ProgressEvent.format(event.getContentLength())))
.setOnProgress(event -> TLocale.Logger.info("UTIL.DOWNLOAD-PROGRESS", event.getSpeedFormatted(), event.getPercentageFormatted()))
.setOnComplete(event -> {
if (event.isSuccess()) {
TLocale.Logger.info("UTIL.DOWNLOAD-SUCCESS", file.getName());
} else {
TLocale.Logger.error("UTIL.DOWNLOAD-FAILED", file.getName());
}
}).start();
if (!async) {
eagletTask.waitUntil();
}
}
public static void download(String url, File file) {
download(url, file, false);
}
@Deprecated
public static void download(String downloadURL, String filename, File saveDir) {
download(downloadURL, new File(saveDir, filename));
public static void download(String url, String filename, File saveDir) {
download(url, new File(saveDir, filename));
}
@Deprecated

View File

@ -4,13 +4,13 @@ import com.ilummc.tlib.resources.TLocale;
import me.clip.placeholderapi.PlaceholderAPI;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.common.configuration.TConfiguration;
import me.skymc.taboolib.fileutils.ConfigUtils;
import me.skymc.taboolib.itemnbtapi.NBTItem;
import me.skymc.taboolib.itemnbtapi.NBTList;
import me.skymc.taboolib.itemnbtapi.NBTListCompound;
import me.skymc.taboolib.itemnbtapi.NBTType;
import me.skymc.taboolib.other.NumberUtils;
import me.skymc.taboolib.string.Language;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
@ -39,74 +39,59 @@ import java.util.stream.IntStream;
*/
public class ItemUtils {
private static FileConfiguration itemdir = null;
private static FileConfiguration itemCache = null;
private static File finalItemsFolder;
private static LinkedHashMap<String, String> itemlib = new LinkedHashMap<>();
private static FileConfiguration itemDir;
private static FileConfiguration itemCache;
private static TConfiguration itemName;
private static LinkedHashMap<String, String> itemLib = new LinkedHashMap<>();
private static LinkedHashMap<String, ItemStack> itemCaches = new LinkedHashMap<>();
private static LinkedHashMap<String, ItemStack> itemCachesFinal = new LinkedHashMap<>();
public static FileConfiguration getItemdir() {
return itemdir;
}
public static FileConfiguration getItemCache() {
return itemCache;
}
public static File getFinalItemsFolder() {
return finalItemsFolder;
}
public static LinkedHashMap<String, String> getItemlib() {
return itemlib;
}
public static LinkedHashMap<String, ItemStack> getItemCaches() {
return itemCaches;
}
public static LinkedHashMap<String, ItemStack> getItemCachesFinal() {
return itemCachesFinal;
}
/**
* 获取物品缓存
* 检测顺序
* 1. 固定物品库
* 2. 动态物品库
*
* @param name 物品名称
* @return
*/
public static ItemStack getCacheItem(String name) {
// 检测固定物品库是否存在该物品
if (itemCachesFinal.containsKey(name)) {
return itemCachesFinal.get(name);
}
// 返回动态物品库
return itemCaches.get(name);
}
public static boolean isExists(String name) {
return itemCachesFinal.containsKey(name) || itemCaches.containsKey(name);
}
public static void LoadLib() {
public static void init() {
try {
reloadItemDir();
reloadItemName();
reloadItemCache();
itemdir = YamlConfiguration.loadConfiguration(new File(Main.getInst().getConfig().getString("DATAURL.ITEMDIR")));
} catch (Exception e) {
TLocale.Logger.error("ITEM-UTILS.FAIL-LOAD-ITEMS", e.toString());
}
}
public static void reloadItemDir() {
File file = new File(Main.getInst().getConfig().getString("DATAURL.ITEMDIR"));
if (file.exists()) {
itemDir = YamlConfiguration.loadConfiguration(file);
}
}
public static void reloadItemName() {
itemName = TConfiguration.createInResource(Main.getInst(), "Language/ITEM_NAME.yml");
itemName.listener(() -> {
itemName.getConfigurationSection("").getKeys(false).forEach(a -> itemLib.put(a, itemName.getString(a)));
TLocale.Logger.info("ITEM-UTILS.SUCCESS-LOAD-NAMES", String.valueOf(itemLib.size()));
}).runListener();
}
public static void reloadItemCache() {
itemCaches.clear();
itemCachesFinal.clear();
loadItemsFile(getItemCacheFile(), false);
finalItemsFolder = new File(Main.getInst().getDataFolder(), "FinalItems");
if (!finalItemsFolder.exists()) {
finalItemsFolder.mkdir();
}
Arrays.stream(finalItemsFolder.listFiles()).forEach(file -> loadItemsFile(file, true));
TLocale.Logger.info("ITEM-UTILS.SUCCESS-LOAD-CACHES", String.valueOf(itemCaches.size() + itemCachesFinal.size()));
}
public static File getItemCacheFile() {
File itemCacheFile = new File(Main.getInst().getDataFolder(), "items.yml");
if (!itemCacheFile.exists()) {
Main.getInst().saveResource("items.yml", true);
}
return itemCacheFile;
}
public static void loadItemsFile(File file, boolean finalFile) {
FileConfiguration conf = ConfigUtils.load(Main.getInst(), file);
for (String name : conf.getConfigurationSection("").getKeys(false)) {
@ -120,33 +105,22 @@ public class ItemUtils {
}
}
public static void reloadItemCache() {
itemCaches.clear();
itemCachesFinal.clear();
loadItemsFile(getItemCacheFile(), false);
// 创建固定物品库
finalItemsFolder = new File(Main.getInst().getDataFolder(), "FinalItems");
if (!finalItemsFolder.exists()) {
finalItemsFolder.mkdir();
}
// 检查固定物品库中的物品
Arrays.stream(finalItemsFolder.listFiles()).forEach(file -> loadItemsFile(file, true));
TLocale.Logger.info("ITEM-UTILS.SUCCESS-LOAD-CACHES", String.valueOf(itemCaches.size() + itemCachesFinal.size()));
// *********************************
//
// API
//
// *********************************
public static boolean isExists(String name) {
return itemCachesFinal.containsKey(name) || itemCaches.containsKey(name);
}
public static void reloadItemName() {
FileConfiguration conf = new Language("ITEM_NAME", Main.getInst(), true).getConfiguration();
itemlib.clear();
conf.getConfigurationSection("").getKeys(false).forEach(a -> itemlib.put(a, conf.getString(a)));
TLocale.Logger.info("ITEM-UTILS.SUCCESS-LOAD-NAMES", String.valueOf(itemlib.size()));
public static ItemStack getCacheItem(String name) {
return itemCachesFinal.containsKey(name) ? itemCachesFinal.get(name) : itemCaches.get(name);
}
public static File getItemCacheFile() {
File itemCacheFile = new File(Main.getInst().getDataFolder(), "items.yml");
if (!itemCacheFile.exists()) {
Main.getInst().saveResource("items.yml", true);
}
return itemCacheFile;
public static ItemStack getItemFromDir(String name) {
return itemDir != null ? itemDir.getItemStack("item." + name) : null;
}
public static String getCustomName(ItemStack item) {
@ -154,19 +128,7 @@ public class ItemUtils {
return TLocale.asString("ITEM-UTILS.EMPTY-ITEM");
}
int data = item.getType().getMaxDurability() == 0 ? item.getDurability() : 0;
return item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName() : itemlib.get(item.getType() + ":" + data) == null ? item.getType().toString() : itemlib.get(item.getType() + ":" + data);
}
public static ItemStack getItemFromDir(String name) {
if (itemdir != null) {
return itemdir.getItemStack("item." + name);
}
return null;
}
@SuppressWarnings("deprecation")
public static ItemStack item(int n, int a, int d) {
return new ItemStack(n, a, (short) d);
return item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName() : itemLib.get(item.getType() + ":" + data) == null ? item.getType().toString() : itemLib.get(item.getType() + ":" + data);
}
public static ItemStack setName(ItemStack i, String n) {
@ -176,7 +138,7 @@ public class ItemUtils {
return i;
}
public static ItemStack Enchant(ItemStack i, Enchantment e, int l) {
public static ItemStack enchant(ItemStack i, Enchantment e, int l) {
ItemMeta meta = i.getItemMeta();
meta.addEnchant(e, l, false);
i.setItemMeta(meta);
@ -203,10 +165,7 @@ public class ItemUtils {
}
public static String asString(String args, Player placeholderPlayer) {
if (placeholderPlayer == null) {
return args.replace("&", "§");
}
return PlaceholderAPI.setPlaceholders(placeholderPlayer, args.replace("&", "§"));
return placeholderPlayer == null ? args.replace("&", "§") : PlaceholderAPI.setPlaceholders(placeholderPlayer, args.replace("&", "§"));
}
public static List<String> asString(List<String> args, Player placeholderPlayer) {
@ -281,58 +240,30 @@ public class ItemUtils {
}
}
/**
* 包含介绍
*
* @param i 物品
* @param a 关键字
*/
public static int getLore(ItemStack i, String a) {
return isLored(i) ? IntStream.range(0, i.getItemMeta().getLore().size()).filter(j -> i.getItemMeta().getLore().get(j).contains(a)).findFirst().orElse(0) : 0;
}
public static boolean hasLore(ItemStack i, String a) {
return isLored(i) && i.getItemMeta().getLore().toString().contains(a);
}
/**
* 如果已描述
*
* @param i
* @return
*/
public static boolean isLored(ItemStack i) {
return i != null && i.getItemMeta() != null && i.getItemMeta().getLore() != null;
}
/**
* 如果已命名
*
* @param i
* @return
*/
public static boolean isNamed(ItemStack i) {
return i != null && i.getItemMeta() != null && i.getItemMeta().getDisplayName() != null;
}
/**
* 添加描述
*
* @param is 物品
* @param lore 描述
*/
public static ItemStack addLore(ItemStack is, String lore) {
public static ItemStack addLore(ItemStack is, String line) {
ItemMeta meta = is.getItemMeta();
List<String> _lore = meta.hasLore() ? meta.getLore() : Collections.emptyList();
_lore.add(lore.replaceAll("&", "§"));
List<String> lore = meta.hasLore() ? meta.getLore() : Collections.emptyList();
lore.add(TLocale.Translate.setColored(line));
is.setItemMeta(meta);
return is;
}
/**
* 移除描述
*
* @param is 物品
* @param line 行数
*/
public static ItemStack delLore(ItemStack is, int line) {
ItemMeta meta = is.getItemMeta();
if (meta.hasLore()) {
@ -346,40 +277,7 @@ public class ItemUtils {
return is;
}
/**
* 获取介绍所在行数
*
* @param i 物品
* @param a 关键字
*/
public static int getLore(ItemStack i, String a) {
return isLored(i) ? IntStream.range(0, i.getItemMeta().getLore().size()).filter(j -> i.getItemMeta().getLore().get(j).contains(a)).findFirst().orElse(0) : 0;
}
/**
* 添加耐久
*
* @param i 物品
* @param d 耐久
*/
public static ItemStack addDurability(ItemStack i, int d) {
i.setDurability((short) (i.getDurability() + d));
int min = i.getDurability();
int max = i.getType().getMaxDurability();
if (min >= max) {
i.setType(Material.AIR);
}
return i;
}
/**
* 替换描述
*
* @param i 物品
* @param l1 关键字1
* @param l2 关键字2
*/
public static ItemStack repalceLore(ItemStack i, String l1, String l2) {
public static ItemStack replaceLore(ItemStack i, String l1, String l2) {
if (!isLored(i)) {
return i;
} else {
@ -392,6 +290,16 @@ public class ItemUtils {
return i;
}
public static ItemStack addDurability(ItemStack i, int d) {
i.setDurability((short) (i.getDurability() + d));
int min = i.getDurability();
int max = i.getType().getMaxDurability();
if (min >= max) {
i.setType(Material.AIR);
}
return i;
}
public static ItemStack loadItem(FileConfiguration f, String s) {
return loadItem(f, s, null);
}
@ -552,6 +460,62 @@ public class ItemUtils {
return nbt;
}
// *********************************
//
// Getter and Setter
//
// *********************************
public static FileConfiguration getItemDir() {
return itemDir;
}
public static LinkedHashMap<String, String> getItemLib() {
return itemLib;
}
public static FileConfiguration getItemCache() {
return itemCache;
}
public static File getFinalItemsFolder() {
return finalItemsFolder;
}
public static LinkedHashMap<String, ItemStack> getItemCaches() {
return itemCaches;
}
public static LinkedHashMap<String, ItemStack> getItemCachesFinal() {
return itemCachesFinal;
}
// *********************************
//
// Deprecated
//
// *********************************
@Deprecated
public static FileConfiguration getItemdir() {
return itemDir;
}
@Deprecated
public static LinkedHashMap<String, String> getItemlib() {
return itemLib;
}
@Deprecated
public static ItemStack item(int n, int a, int d) {
return new ItemStack(n, a, (short) d);
}
@Deprecated
public static ItemStack repalceLore(ItemStack i, String l1, String l2) {
return replaceLore(i, l1, l2);
}
@Deprecated
public static void putO(ItemStack item, Inventory inv, int i) {
inv.setItem(i, item);

View File

@ -3,8 +3,10 @@ package me.skymc.taboolib.inventory.builder;
import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.string.ArrayUtils;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.banner.Pattern;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType;
@ -20,7 +22,7 @@ import java.util.List;
/**
* @Author sky
* @Since 2018-08-22 11:37
* @BuilderVersion 1.0
* @BuilderVersion 1.1
*/
public class ItemBuilder {
@ -40,6 +42,11 @@ public class ItemBuilder {
itemMeta = itemStack.getItemMeta();
}
public ItemBuilder(OfflinePlayer player) {
this(Material.SKULL_ITEM, 1, 3);
this.skullOwner(player.getName());
}
public ItemBuilder material(int id) {
itemStack.setType(Material.getMaterial(id));
return this;
@ -147,6 +154,13 @@ public class ItemBuilder {
return this;
}
public ItemBuilder skullOwner(String name) {
if (itemMeta instanceof SkullMeta) {
((SkullMeta) itemMeta).setOwner(name);
}
return this;
}
public ItemBuilder unbreakable(boolean value) {
if (TabooLib.getVersionNumber() >= 12000) {
itemMeta.setUnbreakable(value);
@ -173,4 +187,14 @@ public class ItemBuilder {
}
return buildItem;
}
/**
* 从文本中获取物品name:名字;lore:描述||描述;material:材质
*
* @param str
* @return
*/
public static ItemStack fromString(String str) {
return null;
}
}

View File

@ -2,6 +2,7 @@ package me.skymc.taboolib.itagapi;
import com.google.common.base.Preconditions;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.packet.PacketUtils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@ -132,7 +133,10 @@ public class TagDataHandler implements Listener {
entryTeam.addEntry(playerData.getNameDisplay());
entryTeam.setPrefix(playerData.getPrefix());
entryTeam.setSuffix(playerData.getSuffix());
TagUtils.cleanEmptyTeamInScoreboard(scoreboard);
// 傻逼 BedWarsRel 我草你妈的
if (TabooLib.instance().getConfig().getBoolean("TABLIST-AUTO-CLEAN-TEAM", true)) {
TagUtils.cleanEmptyTeamInScoreboard(scoreboard);
}
}
private void cancelPlayerVariable(Player player, TagPlayerData playerData) {
@ -142,7 +146,10 @@ public class TagDataHandler implements Listener {
for (Player online : Bukkit.getOnlinePlayers()) {
Scoreboard scoreboard = TagUtils.getScoreboardComputeIfAbsent(player);
TagUtils.cleanEntryInScoreboard(scoreboard, playerData.getNameDisplay());
TagUtils.cleanEmptyTeamInScoreboard(scoreboard);
// 傻逼 BedWarsRel 我草你妈的
if (TabooLib.instance().getConfig().getBoolean("TABLIST-AUTO-CLEAN-TEAM", true)) {
TagUtils.cleanEmptyTeamInScoreboard(scoreboard);
}
}
}
@ -157,7 +164,7 @@ public class TagDataHandler implements Listener {
downloadPlayerVariable(e.getPlayer());
}
@EventHandler (priority = EventPriority.MONITOR)
@EventHandler(priority = EventPriority.MONITOR)
public void onQuit(PlayerQuitEvent e) {
cancelPlayerVariable(e.getPlayer(), unregisterPlayerData(e.getPlayer()));
}

View File

@ -4,33 +4,30 @@ import com.ilummc.tlib.bungee.api.chat.*;
import com.ilummc.tlib.bungee.chat.ComponentSerializer;
import com.ilummc.tlib.logger.TLogger;
import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.inventory.ItemUtils;
import me.skymc.taboolib.methods.ReflectionUtils;
import me.skymc.taboolib.nms.NMSUtils;
import me.skymc.taboolib.other.NumberUtils;
import me.skymc.taboolib.string.ArrayUtils;
import me.skymc.taboolib.string.VariableFormatter;
import org.bukkit.command.CommandSender;
import org.bukkit.inventory.ItemStack;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Author sky
* @Since 2018-05-26 14:42json
* @BuilderLevel 1.2
*/
public class TellrawJson {
private BaseComponent[] components = TextComponent.fromLegacyText("");
private final Class<?> craftItemStackClazz = NMSUtils.getOBCClass("inventory.CraftItemStack");
private final Class<?> nmsItemStackClazz = NMSUtils.getNMSClass("ItemStack");
private final Class<?> nbtTagCompoundClazz = NMSUtils.getNMSClass("NBTTagCompound");
private final String INVALID_ITEM = "{id:stone,tag:{display:{Name:§c* Invalid ItemStack *}}}";
private List<BaseComponent> components = new ArrayList<>();
private List<BaseComponent> componentsLatest = new ArrayList<>();
private static final Class<?> craftItemStackClazz = NMSUtils.getOBCClass("inventory.CraftItemStack");
private static final Class<?> nmsItemStackClazz = NMSUtils.getNMSClass("ItemStack");
private static final Class<?> nbtTagCompoundClazz = NMSUtils.getNMSClass("NBTTagCompound");
private static final String INVALID_ITEM = "{id:stone,tag:{display:{Name:§c* Invalid ItemStack *}}}";
TellrawJson() {
}
@ -39,12 +36,16 @@ public class TellrawJson {
return new TellrawJson();
}
public void send(CommandSender sender) {
TLocale.Tellraw.send(sender, toRawMessage());
}
public String toRawMessage() {
return ComponentSerializer.toString(components);
return ComponentSerializer.toString(getComponentsAll());
}
public String toLegacyText() {
return TextComponent.toLegacyText(components);
return TextComponent.toLegacyText(getComponentsAll());
}
public TellrawJson newLine() {
@ -52,50 +53,51 @@ public class TellrawJson {
}
public TellrawJson append(String text) {
Arrays.stream(TextComponent.fromLegacyText(text)).forEach(component -> this.components = ArrayUtils.arrayAppend(this.components, component));
appendComponents();
componentsLatest.addAll(ArrayUtils.asList(TextComponent.fromLegacyText(text)));
return this;
}
public TellrawJson append(TellrawJson json) {
BaseComponent[] newArray = new BaseComponent[components.length + json.components.length];
System.arraycopy(components, 0, newArray, 0, components.length);
System.arraycopy(json.components, 0, newArray, components.length, json.components.length);
components = newArray;
appendComponents();
componentsLatest.addAll(ArrayUtils.asList(json.getComponentsAll()));
return this;
}
public TellrawJson hoverText(String text) {
getLatestComponent().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(text).create()));
getLatestComponent().forEach(component -> component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(text).create())));
return this;
}
public TellrawJson hoverItem(ItemStack itemStack) {
getLatestComponent().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new ComponentBuilder(getItemComponent(itemStack)).create()));
getLatestComponent().forEach(component -> component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new ComponentBuilder(getItemComponent(itemStack)).create())));
return this;
}
public TellrawJson clickCommand(String command) {
getLatestComponent().setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command));
getLatestComponent().forEach(component -> component.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command)));
return this;
}
public TellrawJson clickSuggest(String command) {
getLatestComponent().setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command));
getLatestComponent().forEach(component -> component.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command)));
return this;
}
public TellrawJson clickOpenURL(String url) {
getLatestComponent().setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url));
getLatestComponent().forEach(component -> component.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url)));
return this;
}
public TellrawJson clickChangePage(int page) {
getLatestComponent().setClickEvent(new ClickEvent(ClickEvent.Action.CHANGE_PAGE, String.valueOf(page)));
getLatestComponent().forEach(component -> component.setClickEvent(new ClickEvent(ClickEvent.Action.CHANGE_PAGE, String.valueOf(page))));
return this;
}
public void send(CommandSender sender) {
TLocale.Tellraw.send(sender, toRawMessage());
public BaseComponent[] getComponentsAll() {
List<BaseComponent> components = this.components.stream().filter(component -> !(component instanceof TextComponent) || !((TextComponent) component).getText().isEmpty()).collect(Collectors.toList());
this.componentsLatest.stream().filter(component -> !(component instanceof TextComponent) || !((TextComponent) component).getText().isEmpty()).forEach(components::add);
return components.toArray(new BaseComponent[0]);
}
public String getItemComponent(ItemStack itemStack) {
@ -106,7 +108,7 @@ public class TellrawJson {
Object nmsItemStackObj = asNMSCopyMethod.invoke(null, itemStack);
return saveNmsItemStackMethod.invoke(nmsItemStackObj, nmsNbtTagCompoundObj).toString();
} catch (Throwable t) {
TLogger.getGlobalLogger().error("failed to serialize itemstack to nms item: " + t.toString());
TLogger.getGlobalLogger().error("failed to serialize bukkit item to nms item: " + t.toString());
return INVALID_ITEM;
}
}
@ -117,12 +119,17 @@ public class TellrawJson {
//
// *********************************
private BaseComponent getLatestComponent() {
return components[components.length - 1];
private List<BaseComponent> getLatestComponent() {
return componentsLatest;
}
private void setLatestComponent(BaseComponent component) {
components[components.length - 1] = component;
private void setLatestComponent(BaseComponent... component) {
componentsLatest.addAll(ArrayUtils.asList(component));
}
private void appendComponents() {
components.addAll(componentsLatest);
componentsLatest.clear();
}
// *********************************
@ -131,12 +138,11 @@ public class TellrawJson {
//
// *********************************
public BaseComponent[] getComponents() {
return components;
}
public void setComponents(BaseComponent[] components) {
this.components = components;
this.components = ArrayUtils.asList(components);
}
public BaseComponent[] getComponents() {
return components.toArray(new BaseComponent[0]);
}
}

View File

@ -1,9 +1,12 @@
package me.skymc.taboolib.listener;
import com.ilummc.tlib.logger.TLogger;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.database.PlayerDataManager;
import me.skymc.taboolib.inventory.ItemUtils;
import me.skymc.taboolib.itemnbtapi.NBTItem;
import me.skymc.taboolib.json.tellraw.TellrawJson;
import me.skymc.taboolib.message.MsgUtils;
import me.skymc.taboolib.permission.PermissionUtils;
import me.skymc.taboolib.playerdata.DataUtils;
@ -13,31 +16,51 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.server.ServerCommandEvent;
/**
* @author sky
*/
@TListener
public class ListenerPlayerCommand implements Listener {
@EventHandler
public void cmd(ServerCommandEvent e) {
if ("savefile".equals(e.getCommand())) {
if (e.getCommand().equalsIgnoreCase("saveFiles")) {
if (TabooLib.getVerint() > 10700) {
e.setCancelled(true);
}
Bukkit.getScheduler().runTask(Main.getInst(), DataUtils::saveAllCaches);
Bukkit.getScheduler().runTask(Main.getInst(), () -> PlayerDataManager.saveAllCaches(true, false));
TLogger.getGlobalLogger().info("Successfully.");
} else if (e.getCommand().equalsIgnoreCase("tDebug")) {
if (TabooLib.getVerint() > 10700) {
e.setCancelled(true);
}
if (TabooLib.isDebug()) {
TabooLib.setDebug(false);
TLogger.getGlobalLogger().info("&cDisabled.");
} else {
TabooLib.setDebug(true);
TLogger.getGlobalLogger().info("&aEnabled.");
}
}
}
@SuppressWarnings("deprecation")
@EventHandler
public void cmd(PlayerCommandPreprocessEvent e) {
if ("/unbreakable".equals(e.getMessage()) && PermissionUtils.hasPermission(e.getPlayer(), "taboolib.unbreakable")) {
if (e.getMessage().equals("/unbreakable") && PermissionUtils.hasPermission(e.getPlayer(), "taboolib.unbreakable")) {
e.setCancelled(true);
NBTItem nbti = new NBTItem(e.getPlayer().getItemInHand());
nbti.setInteger("Unbreakable", 1);
e.getPlayer().setItemInHand(nbti.getItem());
NBTItem nbt = new NBTItem(e.getPlayer().getItemInHand());
nbt.setInteger("Unbreakable", 1);
e.getPlayer().setItemInHand(nbt.getItem());
MsgUtils.send(e.getPlayer(), "Success!");
} else if (e.getMessage().equals("/tellrawTest") && PermissionUtils.hasPermission(e.getPlayer(), "taboolib.tellraw")) {
e.setCancelled(true);
TellrawJson.create()
.append("§8[§3§lTabooLib§8] §7TellrawJson Test: §f[")
.append(ItemUtils.getCustomName(e.getPlayer().getItemInHand())).hoverItem(e.getPlayer().getItemInHand())
.append("§f]")
.send(e.getPlayer());
}
}
}

View File

@ -1,9 +1,13 @@
package me.skymc.taboolib.listener;
import com.ilummc.tlib.TLib;
import com.ilummc.tlib.inject.TConfigWatcher;
import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.message.MsgUtils;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.common.configuration.TConfiguration;
import me.skymc.taboolib.mysql.MysqlUtils;
import me.skymc.taboolib.mysql.hikari.HikariHandler;
import me.skymc.taboolib.mysql.protect.MySQLConnection;
import me.skymc.taboolib.timecycle.TimeCycleManager;
import org.bukkit.event.EventHandler;
@ -11,33 +15,48 @@ import org.bukkit.event.Listener;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.scheduler.BukkitRunnable;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
/**
* @author sky
*/
@TListener
public class ListenerPluginDisable implements Listener {
@EventHandler
public void disable(PluginDisableEvent e) {
TabooLib.debug("Plugin \"" + e.getPlugin().getName() + "\" was disabled.");
// 注销时间周期
TimeCycleManager.cancel(e.getPlugin());
// 注销插件配置
Optional.ofNullable(TConfiguration.getFiles().get(e.getPlugin().getName())).ifPresent(files -> {
TConfigWatcher tConfigWatcher = TLib.getTLib().getConfigWatcher();
for (File file : files) {
tConfigWatcher.removeListener(file);
TabooLib.debug("Remove TConfiguration \"" + file.getName() + "\" from Plugin \"" + e.getPlugin().getName() + "\"");
}
});
// 注销数据库连接
new HashSet<>(HikariHandler.getDataSource().keySet()).stream().filter(host -> e.getPlugin().equals(host.getPlugin()) && host.isAutoClose()).forEach(HikariHandler::closeDataSource);
// 获取连接
List<MySQLConnection> conns = new ArrayList<>();
List<MySQLConnection> connection = new ArrayList<>();
for (MySQLConnection conn : MysqlUtils.CONNECTIONS) {
if (conn.getPlugin().equals(e.getPlugin())) {
conns.add(conn);
connection.add(conn);
MysqlUtils.CONNECTIONS.remove(conn);
}
}
// 异步注销
BukkitRunnable runnable = new BukkitRunnable() {
@Override
public void run() {
int i = 0;
for (MySQLConnection conn : conns) {
for (MySQLConnection conn : connection) {
conn.setFallReconnection(false);
conn.closeConnection();
i++;
@ -47,7 +66,6 @@ public class ListenerPluginDisable implements Listener {
}
}
};
// 如果插件关闭
try {
runnable.runTaskLater(Main.getInst(), 40);

View File

@ -2,7 +2,8 @@ package me.skymc.taboolib.listener;
import com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.fileutils.FileUtils;
import me.skymc.taboolib.TabooLibLoader;
import me.skymc.taboolib.methods.ReflectionUtils;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
@ -28,12 +29,10 @@ public class TListenerHandler implements Listener {
*/
public static void setupListeners() {
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
if (plugin.equals(TabooLib.instance()) || plugin.getDescription().getDepend().contains("TabooLib")) {
try {
setupListener(plugin);
} catch (Exception e) {
e.printStackTrace();
}
try {
setupListener(plugin);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@ -45,25 +44,27 @@ public class TListenerHandler implements Listener {
* @param plugin 插件
*/
public static void setupListener(Plugin plugin) {
List<Class> classes = FileUtils.getClasses(plugin);
for (Class<?> pluginClass : classes) {
if (Listener.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TListener.class)) {
try {
TListener tListener = pluginClass.getAnnotation(TListener.class);
// 检查注册条件
if (tListener.depend().length > 0 && !Strings.isBlank(tListener.depend()[0])) {
if (Arrays.stream(tListener.depend()).anyMatch(depend -> Bukkit.getPluginManager().getPlugin(depend) == null)) {
continue;
TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> {
for (Class<?> pluginClass : classes) {
if (org.bukkit.event.Listener.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TListener.class)) {
try {
TListener tListener = pluginClass.getAnnotation(TListener.class);
// 检查注册条件
if (tListener.depend().length > 0 && !Strings.isBlank(tListener.depend()[0])) {
if (Arrays.stream(tListener.depend()).anyMatch(depend -> Bukkit.getPluginManager().getPlugin(depend) == null)) {
continue;
}
}
// 实例化监听器
Listener listener = plugin.getClass().equals(pluginClass) ? (Listener) plugin : (Listener) ReflectionUtils.instantiateObject(pluginClass);
listeners.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(listener);
TabooLib.debug("Listener " + listener.getClass().getSimpleName() + " setup successfully. (" + plugin.getName() + ")");
} catch (Exception e) {
TabooLib.debug("Listener setup failed: " + e.toString());
}
// 实例化监听器
Listener listener = plugin.getClass().equals(pluginClass) ? (Listener) plugin : (Listener) pluginClass.newInstance();
listeners.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(listener);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
/**
@ -113,6 +114,7 @@ public class TListenerHandler implements Listener {
}
// 注册监听
Bukkit.getPluginManager().registerEvents(listener, plugin);
TabooLib.debug("Listener " + listener.getClass().getSimpleName() + " registered. (" + plugin.getName() + ")");
}
});
}
@ -154,6 +156,10 @@ public class TListenerHandler implements Listener {
});
}
public static HashMap<String, List<Listener>> getListeners() {
return listeners;
}
@EventHandler
public void onPluginEnable(PluginEnableEvent e) {
try {
@ -170,14 +176,4 @@ public class TListenerHandler implements Listener {
} catch (Exception ignored) {
}
}
// *********************************
//
// Getter and Setter
//
// *********************************
public static HashMap<String, List<Listener>> getListeners() {
return listeners;
}
}

View File

@ -5,6 +5,7 @@ import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
@Deprecated
public class MsgUtils {
public static void send(CommandSender sender, String s) {

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,7 @@ public class SQLColumn {
private SQLColumnOption[] columnOptions;
/**
* 文本类型常用构造器
* 文本 类型常用构造器
* new SQLColumn(SQLColumnType.TEXT, "username");
*/
public SQLColumn(SQLColumnType columnType, String columnName) {
@ -30,7 +30,17 @@ public class SQLColumn {
}
/**
* 主键类型常用构造器
* CHAR 类型常用构造器
*
* @param columnType
* @param columnName
*/
public SQLColumn(SQLColumnType columnType, int m, String columnName) {
this(columnType, m, 0, columnName, null);
}
/**
* 主键 类型常用构造器
* new SQLColumn(SQLColumnType.TEXT, "username", SQLColumnOption.PRIMARY_KEY, SQLColumnOption.AUTO_INCREMENT);
*/
public SQLColumn(SQLColumnType columnType, String columnName, SQLColumnOption... columnOptions) {
@ -38,7 +48,7 @@ public class SQLColumn {
}
/**
* 数据类型常用构造器
* 数据 类型常用构造器
* new SQLColumn(SQLColumnType.TEXT, "player_group", "PLAYER");
*/
public SQLColumn(SQLColumnType columnType, String columnName, Object defaultValue) {
@ -99,25 +109,25 @@ public class SQLColumn {
for (SQLColumnOption options : columnOptions) {
switch (options) {
case NOTNULL:
builder.append(" not null");
builder.append(" NOT NULL");
break;
case PRIMARY_KEY:
builder.append(" primary key");
builder.append(" PRIMARY KEY");
break;
case AUTO_INCREMENT:
builder.append(" auto_increment");
builder.append(" AUTO_INCREMENT");
break;
case UNIQUE_KEY:
builder.append(" unique key");
builder.append(" UNIQUE KEY");
break;
default:
}
}
if (defaultValue != null) {
if (defaultValue instanceof String) {
builder.append(" default '").append(defaultValue).append("'");
builder.append(" DEFAULT '").append(defaultValue).append("'");
} else {
builder.append(" default ").append(defaultValue);
builder.append(" DEFAULT ").append(defaultValue);
}
}
return builder.toString();

View File

@ -1,31 +0,0 @@
package me.skymc.taboolib.mysql.builder;
import com.zaxxer.hikari.HikariDataSource;
import org.bukkit.plugin.java.JavaPlugin;
/**
* @Author sky
* @Since 2018-07-02 23:43
*/
public class SQLExample extends JavaPlugin {
private SQLHost sqlHost;
private SQLTable sqlTable;
private HikariDataSource dataSource;
@Override
public void onEnable() {
int value = sqlTable.executeQuery("select * from table where username = ?")
.dataSource(dataSource)
.statement(statement -> statement.setString(1, "BlackSKY"))
.resultNext(result -> result.getInt("value"))
.run(0, 0);
sqlTable.executeUpdate("statement table set value = ? where username = ?")
.dataSource(dataSource)
.statement(statement -> {
statement.setInt(1, 999);
statement.setString(2, "BlackSKY");
}).run();
}
}

View File

@ -4,7 +4,6 @@ import com.ilummc.tlib.util.Strings;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.plugin.Plugin;
import java.text.MessageFormat;
import java.util.Objects;
/**
@ -19,18 +18,28 @@ public class SQLHost {
private String password;
private String database;
private Plugin plugin;
private boolean autoClose;
public SQLHost(ConfigurationSection section, Plugin plugin) {
this(section, plugin, false);
}
public SQLHost(ConfigurationSection section, Plugin plugin, boolean autoClose) {
this(section.getString("host", "localhost"), section.getString("user", "root"), section.getString("port", "3306"), section.getString("password", ""), section.getString("database", "test"), plugin);
}
public SQLHost(String host, String user, String port, String password, String database, Plugin plugin) {
this(host, user, port, password, database, plugin, false);
}
public SQLHost(String host, String user, String port, String password, String database, Plugin plugin, boolean autoClose) {
this.host = host;
this.user = user;
this.port = port;
this.password = password;
this.database = database;
this.plugin = plugin;
this.autoClose = false;
}
public String getHost() {
@ -57,6 +66,10 @@ public class SQLHost {
return plugin;
}
public boolean isAutoClose() {
return autoClose;
}
public String getConnectionUrl() {
return Strings.replaceWithOrder("jdbc:mysql://{0}:{1}/{2}?characterEncoding=utf-8&useSSL=false", this.host, this.port, this.database);
}
@ -74,16 +87,18 @@ public class SQLHost {
return false;
}
SQLHost sqlHost = (SQLHost) o;
return Objects.equals(getHost(), sqlHost.getHost()) &&
return autoClose == sqlHost.autoClose &&
Objects.equals(getHost(), sqlHost.getHost()) &&
Objects.equals(getUser(), sqlHost.getUser()) &&
Objects.equals(getPort(), sqlHost.getPort()) &&
Objects.equals(getPassword(), sqlHost.getPassword()) &&
Objects.equals(getDatabase(), sqlHost.getDatabase());
Objects.equals(getDatabase(), sqlHost.getDatabase()) &&
Objects.equals(getPlugin(), sqlHost.getPlugin());
}
@Override
public int hashCode() {
return Objects.hash(getHost(), getUser(), getPort(), getPassword(), getDatabase());
return Objects.hash(getHost(), getUser(), getPort(), getPassword(), getDatabase(), getPlugin(), autoClose);
}
@Override
@ -95,6 +110,7 @@ public class SQLHost {
", password='" + password + '\'' +
", database='" + database + '\'' +
", plugin=" + plugin +
", autoClose=" + autoClose +
'}';
}
}

View File

@ -26,11 +26,7 @@ public class SQLTable {
}
public SQLTable addColumn(SQLColumn sqlColumn) {
if (columns == null) {
columns = new SQLColumn[] {sqlColumn};
} else {
columns = ArrayUtils.arrayAppend(columns, sqlColumn);
}
columns = columns == null ? new SQLColumn[] {sqlColumn} : ArrayUtils.arrayAppend(columns, sqlColumn);
return this;
}
@ -52,6 +48,22 @@ public class SQLTable {
return Strings.replaceWithOrder("truncate table `{0}`", tableName);
}
public RunnableUpdate executeInsert(String values) {
return executeUpdate("insert into " + tableName + " values(" + values + ")");
}
public RunnableQuery executeSelect(String where) {
return executeQuery("select * from " + tableName + " where " + where);
}
public RunnableQuery executeSelect() {
return executeQuery("select * from " + tableName);
}
public RunnableUpdate executeUpdate(String update, String where) {
return executeUpdate("update " + tableName + " set " + update + " where " + where);
}
public RunnableUpdate executeUpdate(String query) {
return new RunnableUpdate(query);
}

View File

@ -6,10 +6,8 @@ import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.fileutils.ConfigUtils;
import me.skymc.taboolib.fileutils.FileUtils;
import me.skymc.taboolib.mysql.builder.SQLHost;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import javax.sql.DataSource;
import java.util.concurrent.ConcurrentHashMap;
@ -91,4 +89,18 @@ public class HikariHandler {
}
return config;
}
// *********************************
//
// Getter and Setter
//
// *********************************
public static ConcurrentHashMap<SQLHost, MapDataSource> getDataSource() {
return dataSource;
}
public static FileConfiguration getSettings() {
return settings;
}
}

View File

@ -0,0 +1,18 @@
package me.skymc.taboolib.object;
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,82 @@
package me.skymc.taboolib.object;
import com.ilummc.tlib.util.Ref;
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));
} catch (Exception e) {
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

@ -3,6 +3,9 @@ package me.skymc.taboolib.other;
import java.text.DecimalFormat;
import java.util.Random;
/**
* @author sky
*/
public class NumberUtils {
private static Random random = new Random();
@ -52,6 +55,22 @@ public class NumberUtils {
}
}
public static Boolean getBooleanAbbreviation(String str) {
if (str == null || str.isEmpty()) {
return false;
}
if (str.length() < 4) {
char var = str.charAt(0);
if (var == 'y' || var == 'Y' || var == 't' || var == 'T' || var == '1') {
return true;
}
if (var == 'n' || var == 'N' || var == 'f' || var == 'F' || var == '0') {
return false;
}
}
return getBoolean(str);
}
@Deprecated
public static Random getRand() {
return random;

View File

@ -30,7 +30,7 @@ public class PluginUtils {
}
public static File getPluginFile(Plugin plugin) {
for (File pluginFile : Objects.requireNonNull(new File("plugins").listFiles())) {
for (File pluginFile : new File("plugins").listFiles()) {
if (pluginFile.getName().endsWith(".jar")) {
try {
PluginDescriptionFile desc = Main.getInst().getPluginLoader().getPluginDescription(pluginFile);
@ -44,6 +44,21 @@ public class PluginUtils {
return null;
}
public static boolean isPluginExists(String name) {
for (File pluginFile : new File("plugins").listFiles()) {
if (pluginFile.getName().endsWith(".jar")) {
try {
PluginDescriptionFile desc = Main.getInst().getPluginLoader().getPluginDescription(pluginFile);
if (desc.getName().equalsIgnoreCase(name)) {
return true;
}
} catch (Exception ignored) {
}
}
}
return false;
}
public static void enable(Plugin plugin) {
if (plugin != null && !plugin.isEnabled()) {
Bukkit.getPluginManager().enablePlugin(plugin);

View File

@ -1,36 +1,19 @@
package me.skymc.taboolib.skull;
import org.bukkit.Bukkit;
import me.skymc.taboolib.inventory.builder.ItemBuilder;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
@Deprecated
public class SkullUtils {
public static ItemStack getItme(OfflinePlayer p ) {
SkullMeta s = (SkullMeta) Bukkit.getItemFactory().getItemMeta(Material.SKULL_ITEM);
s.setOwner(p.getName());
ItemStack i = new ItemStack(Material.SKULL_ITEM);
i.setDurability((short) 3);
i.setItemMeta(s);
return i;
}
public static ItemStack getOnlineItem(OfflinePlayer p ) {
if (p.isOnline())
{
SkullMeta s = (SkullMeta) Bukkit.getItemFactory().getItemMeta(Material.SKULL_ITEM);
s.setOwner(p.getName());
ItemStack i = new ItemStack(Material.SKULL_ITEM);
i.setDurability((short) 3);
i.setItemMeta(s);
return i;
}
return new ItemStack(Material.SKULL_ITEM);
}
public static ItemStack getItme(OfflinePlayer p) {
return new ItemBuilder(p).build();
}
public static ItemStack getOnlineItem(OfflinePlayer p) {
return p.isOnline() ? new ItemBuilder(p).build() : new ItemStack(Material.SKULL_ITEM);
}
}

View File

@ -2,9 +2,13 @@ package me.skymc.taboolib.socket;
import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.commands.builder.SimpleCommandBuilder;
import me.skymc.taboolib.other.NumberUtils;
import me.skymc.taboolib.socket.packet.Packet;
import me.skymc.taboolib.socket.packet.PacketSerializer;
import me.skymc.taboolib.socket.packet.impl.PacketCommand;
import me.skymc.taboolib.socket.packet.impl.PacketMessage;
import me.skymc.taboolib.string.ArrayUtils;
import org.bukkit.Bukkit;
import java.io.*;
@ -83,6 +87,23 @@ public class TabooLibClient {
TLocale.sendToConsole("COMMUNICATION.FAILED-READING-PACKET", e.getMessage());
}
});
SimpleCommandBuilder.create("TabooLibClient", TabooLib.instance())
.aliases("tclient")
.permission("*")
.execute((sender, args) -> {
if (args.length == 0) {
sender.sendMessage("§c[TabooLibClient] §f/tclient message §7[TEXT] §8- §7发送测试信息");
sender.sendMessage("§c[TabooLibClient] §f/tclient command §7[TEXT] §8- §7发送测试命令");
} else if (args[0].equalsIgnoreCase("message") && args.length > 1) {
sendPacket(new PacketMessage(ArrayUtils.arrayJoin(args, 1)));
} else if (args[0].equalsIgnoreCase("command") && args.length > 1) {
sendPacket(new PacketCommand(ArrayUtils.arrayJoin(args, 1)));
} else {
sender.sendMessage("§c[TabooLibClient] §7指令错误.");
}
return true;
}).build();
}
// *********************************

View File

@ -1,5 +1,6 @@
package me.skymc.taboolib.socket;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.other.NumberUtils;
import me.skymc.taboolib.socket.packet.Packet;
import me.skymc.taboolib.socket.packet.PacketSerializer;
@ -55,20 +56,25 @@ public class TabooLibServer {
/*
检测无效的客户端连接如果超过 5000 毫秒没有收到客户端的回应上一次心跳包的回应则注销链接
*/
client.entrySet().stream().filter(connection -> connection.getValue().isAlive()).map(connection -> new PacketQuit(connection.getKey(), "Lost connection")).forEach(TabooLibServer::sendPacket);
client.entrySet().stream().filter(connection -> !connection.getValue().isAlive()).map(connection -> new PacketQuit(connection.getKey(), "Lost connection")).forEach(TabooLibServer::sendPacket);
}, 0, 1, TimeUnit.SECONDS);
while (true) {
try {
Socket socket = server.accept();
ClientConnection connection = new ClientConnection(socket);
client.put(socket.getPort(), connection);
executorService.execute(connection);
println("Client accepted: " + socket.getPort() + " online: " + client.size());
} catch (Exception e) {
println("Client accept failed: " + e.toString());
/*
异步接收连接请求
*/
Executors.newSingleThreadScheduledExecutor().execute(() -> {
while (true) {
try {
Socket socket = server.accept();
ClientConnection connection = new ClientConnection(socket);
client.put(socket.getPort(), connection);
executorService.execute(connection);
println("Client accepted: " + socket.getPort() + " online: " + client.size());
} catch (Exception e) {
println("Client accept failed: " + e.toString());
}
}
}
});
}
public static void sendPacket(Packet packet) {
@ -76,7 +82,6 @@ public class TabooLibServer {
}
public static void sendPacket(String origin) {
println("Packet sending: " + origin + ", online: " + client.size());
// 在服务端尝试解析动作并运行
Optional.ofNullable(PacketSerializer.unSerialize(origin)).ifPresent(Packet::readOnServer);
// 将动作发送至所有客户端
@ -90,10 +95,9 @@ public class TabooLibServer {
}
public static void println(Object obj) {
System.out.println("[" + infoFormat.format(System.currentTimeMillis()) + " INFO]: " + obj);
System.out.println(TabooLib.isSpigot() ? obj : "[" + infoFormat.format(System.currentTimeMillis()) + " INFO]: " + obj);
}
public static Optional<Map.Entry<Integer, ClientConnection>> getConnection(int port) {
return client.entrySet().stream().filter(entry -> entry.getKey().equals(port)).findFirst();
}

View File

@ -4,6 +4,7 @@ import com.google.gson.JsonObject;
import me.skymc.taboolib.fileutils.FileUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@ -31,6 +32,43 @@ public class PacketParser {
try {
Packet packetObject = (Packet) packetFind.get().getConstructor(Integer.TYPE).newInstance(json.get("port").getAsInt());
packetObject.unSerialize(json);
Arrays.stream(packetObject.getClass().getDeclaredFields()).filter(field -> field.isAnnotationPresent(PacketValue.class)).forEach(field -> {
field.setAccessible(true);
try {
switch (field.getType().getSimpleName().toLowerCase()) {
case "double":
field.set(packetObject, json.get(field.getName()).getAsDouble());
break;
case "long":
field.set(packetObject, json.get(field.getName()).getAsLong());
break;
case "short":
field.set(packetObject, json.get(field.getName()).getAsShort());
break;
case "boolean":
field.set(packetObject, json.get(field.getName()).getAsBoolean());
break;
case "string":
field.set(packetObject, json.get(field.getName()).getAsString());
break;
case "number":
field.set(packetObject, json.get(field.getName()).getAsNumber());
break;
case "int":
case "integer":
field.set(packetObject, json.get(field.getName()).getAsInt());
break;
case "char":
case "character":
field.set(packetObject, json.get(field.getName()).getAsCharacter());
break;
default:
System.out.println("UnSerialize: Invalid packet value: " + field.getName());
}
} catch (Exception e) {
e.printStackTrace();
}
});
return packetObject;
} catch (Exception e) {
e.printStackTrace();

View File

@ -3,22 +3,88 @@ package me.skymc.taboolib.socket.packet;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.TabooLibLoader;
import me.skymc.taboolib.listener.TListener;
import me.skymc.taboolib.socket.packet.impl.PacketEmpty;
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.lang.reflect.Field;
import java.util.Arrays;
/**
* @Author sky
* @Since 2018-08-22 23:32
*/
public class PacketSerializer {
@TListener
public class PacketSerializer implements Listener {
private static PacketParser parser = new PacketParser();
public PacketSerializer() {
loadPacket();
}
@EventHandler
public void onEnable(PluginEnableEvent e) {
loadPacket(e.getPlugin());
}
@EventHandler
public void onDisable(PluginDisableEvent e) {
unloadPacket(e.getPlugin());
}
public static void loadPacket() {
Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(PacketSerializer::loadPacket);
}
public static void loadPacket(Plugin plugin) {
if (TabooLib.isTabooLib(plugin) || TabooLib.isDependTabooLib(plugin)) {
TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> classes.stream().filter(pluginClass -> pluginClass.isAnnotationPresent(PacketType.class)).forEach(pluginClass -> parser.getPackets().add(pluginClass)));
}
}
public static void unloadPacket() {
Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(PacketSerializer::unloadPacket);
}
public static void unloadPacket(Plugin plugin) {
if (TabooLib.isTabooLib(plugin) || TabooLib.isDependTabooLib(plugin)) {
TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> classes.stream().filter(pluginClass -> pluginClass.isAnnotationPresent(PacketType.class)).forEach(pluginClass -> parser.getPackets().remove(pluginClass)));
}
}
public static String serialize(Packet packet) {
JsonObject json = new JsonObject();
packet.serialize(json);
json.addProperty("uid", packet.getUid());
json.addProperty("port", packet.getPort());
json.addProperty("packet", packet.getClass().getAnnotation(PacketType.class).name());
packet.serialize(json);
Arrays.stream(packet.getClass().getDeclaredFields()).filter(field -> field.isAnnotationPresent(PacketValue.class)).forEach(field -> {
field.setAccessible(true);
try {
Object obj = field.get(packet);
if (obj instanceof Number) {
json.addProperty(field.getName(), (Number) obj);
} else if (obj instanceof Boolean) {
json.addProperty(field.getName(), (Boolean) obj);
} else if (obj instanceof String) {
json.addProperty(field.getName(), (String) obj);
} else if (obj instanceof Character) {
json.addProperty(field.getName(), (Character) obj);
} else {
System.out.println("Serialize: Invalid packet value: " + field.getName());
}
} catch (Exception e) {
e.printStackTrace();
}
});
return json.toString();
}

View File

@ -0,0 +1,25 @@
package me.skymc.taboolib.socket.packet;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 使用该注解的成员变量
* 将会被自动序列化
*
* 仅限以下类型
* - Number
* - String
* - Boolean
* - Character
*
* @Author sky
* @Since 2018-08-22 23:09
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PacketValue {
}

View File

@ -0,0 +1,37 @@
package me.skymc.taboolib.socket.packet.impl;
import me.skymc.taboolib.socket.TabooLibServer;
import me.skymc.taboolib.socket.packet.Packet;
import me.skymc.taboolib.socket.packet.PacketType;
import me.skymc.taboolib.socket.packet.PacketValue;
import org.bukkit.Bukkit;
/**
* @Author sky
* @Since 2018-08-22 23:01
*/
@PacketType(name = "command")
public class PacketCommand extends Packet {
@PacketValue
private String command;
public PacketCommand(int port) {
super(port);
}
public PacketCommand(String command) {
super(Bukkit.getPort());
this.command = command;
}
@Override
public void readOnServer() {
String[] args = command.split(" ");
if (args[0].equalsIgnoreCase("online")) {
TabooLibServer.sendPacket(new PacketMessage(0, "Online: " + TabooLibServer.getClient().size()));
} else {
TabooLibServer.sendPacket(new PacketMessage(0, "Invalid arguments."));
}
}
}

View File

@ -3,6 +3,7 @@ package me.skymc.taboolib.socket.packet.impl;
import me.skymc.taboolib.socket.TabooLibClient;
import me.skymc.taboolib.socket.packet.Packet;
import me.skymc.taboolib.socket.packet.PacketType;
import org.bukkit.Bukkit;
/**
* @Author sky

View File

@ -5,6 +5,8 @@ import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.socket.TabooLibServer;
import me.skymc.taboolib.socket.packet.Packet;
import me.skymc.taboolib.socket.packet.PacketType;
import me.skymc.taboolib.socket.packet.PacketValue;
import org.bukkit.Bukkit;
/**
* @Author sky
@ -13,6 +15,7 @@ import me.skymc.taboolib.socket.packet.PacketType;
@PacketType(name = "message")
public class PacketMessage extends Packet {
@PacketValue
private String message;
public PacketMessage(int port) {
@ -24,23 +27,18 @@ public class PacketMessage extends Packet {
this.message = message;
}
public PacketMessage(String message) {
super(Bukkit.getPort());
this.message = message;
}
@Override
public void readOnServer() {
TabooLibServer.println(message);
TabooLibServer.println(getPort() + ": " + message);
}
@Override
public void readOnClient() {
TLocale.sendToConsole("COMMUNICATION.PACKET-MESSAGE", String.valueOf(getPort()), message);
}
@Override
public void serialize(JsonObject json) {
json.addProperty("message", message);
}
@Override
public void unSerialize(JsonObject json) {
message = json.get("message").getAsString();
}
}

View File

@ -1,10 +1,10 @@
package me.skymc.taboolib.socket.packet.impl;
import com.google.gson.JsonObject;
import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.socket.TabooLibServer;
import me.skymc.taboolib.socket.packet.Packet;
import me.skymc.taboolib.socket.packet.PacketType;
import me.skymc.taboolib.socket.packet.PacketValue;
/**
* @Author sky
@ -13,6 +13,7 @@ import me.skymc.taboolib.socket.packet.PacketType;
@PacketType(name = "quit")
public class PacketQuit extends Packet {
@PacketValue
private String message;
public PacketQuit(int port) {
@ -43,14 +44,4 @@ public class PacketQuit extends Packet {
public void readOnClient() {
TLocale.sendToConsole("COMMUNICATION.CLIENT-QUITED", String.valueOf(getPort()));
}
@Override
public void serialize(JsonObject json) {
json.addProperty("message", message);
}
@Override
public void unSerialize(JsonObject json) {
message = json.get("message").getAsString();
}
}

View File

@ -46,7 +46,7 @@ public class ClientConnection implements Runnable {
/*
连接丢失客户端退出
*/
TabooLibServer.sendPacket(new PacketQuit(socket.getPort(), e.getMessage()));
TabooLibServer.sendPacket(new PacketQuit(socket.getPort(), "SocketException: " + e.getMessage()));
} catch (Exception e) {
TabooLibServer.println("Client running failed: " + e.toString());
}

View File

@ -2,7 +2,6 @@ package me.skymc.taboolib.string;
import com.ilummc.tlib.util.Strings;
import javax.annotation.Nullable;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
@ -20,15 +19,21 @@ import java.util.stream.IntStream;
*/
public class ArrayUtils {
public static String arrayJoin(String[] args, int start) {
return IntStream.range(start, args.length).mapToObj(i -> args[i] + " ").collect(Collectors.joining()).trim();
public static <T> int indexOf(T[] array, T obj) {
return array == null || array.length == 0 ? -1 : IntStream.range(0, array.length).filter(i -> array[i] != null && array[i].equals(obj)).findFirst().orElse(-1);
}
public static <T> boolean contains(T[] array, T obj) {
return indexOf(array, obj) != -1;
}
@SafeVarargs
public static <T> List<T> asList(T... args) {
List<T> list = new ArrayList<>();
Collections.addAll(list, args);
return list;
public static <T> T[] asArray(T... args) {
return args;
}
public static String arrayJoin(String[] args, int start) {
return IntStream.range(start, args.length).mapToObj(i -> args[i] + " ").collect(Collectors.joining()).trim();
}
public static <T> T[] arrayAppend(T[] array, T obj) {
@ -88,6 +93,13 @@ public class ArrayUtils {
return firstElement == null ? def : obj;
}
@SafeVarargs
public static <T> List<T> asList(T... args) {
List<T> list = new ArrayList<>();
Collections.addAll(list, args);
return list;
}
// *********************************
//
// Deprecated

View File

@ -1,5 +1,6 @@
package me.skymc.taboolib.support;
import com.google.common.base.Preconditions;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
@ -9,60 +10,59 @@ import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Author AgarthaLib
*/
public class SupportWorldGuard {
String Source_code_from_AgarthaLib;
private WorldGuardPlugin worldGuard;
public SupportWorldGuard() {
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin("WorldGuard");
if (plugin != null) {
this.worldGuard = (WorldGuardPlugin) plugin;
}
Preconditions.checkNotNull(Bukkit.getServer().getPluginManager().getPlugin("WorldGuard"), "WorldGuard was not found.");
worldGuard = WorldGuardPlugin.inst();
}
public final WorldGuardPlugin getWorldGuard() {
public WorldGuardPlugin getWorldGuard() {
return this.worldGuard;
}
public final RegionManager getRegionManager(final World world) {
public RegionManager getRegionManager(World world) {
return this.worldGuard.getRegionManager(world);
}
public final boolean isRegionManagerExists(final World world) {
public boolean isRegionManagerExists(World world) {
return this.getRegionManager(world) != null;
}
public final Collection<String> getRegionIDs(final World world) {
final RegionManager regionManager = this.getRegionManager(world);
return regionManager.getRegions().keySet();
public Collection<String> getRegionIDs(World world) {
return getRegionManager(world).getRegions().keySet();
}
public final Collection<ProtectedRegion> getRegions(final World world) {
final RegionManager regionManager = this.getRegionManager(world);
return regionManager.getRegions().values();
public Collection<ProtectedRegion> getRegions(World world) {
return getRegionManager(world).getRegions().values();
}
public final ProtectedRegion getRegion(final World world, final String id) {
final RegionManager regionManager = this.getRegionManager(world);
if (regionManager != null) {
for (final String key : regionManager.getRegions().keySet()) {
if (key.equalsIgnoreCase(id)) {
return regionManager.getRegion(key);
}
}
}
return null;
public List<String> getRegionsAtLocation(World world, Location location) {
return getRegions(world).stream().filter(protectedRegion -> protectedRegion.contains(location.getBlockX(), location.getBlockY(), location.getBlockZ())).map(ProtectedRegion::getId).collect(Collectors.toList());
}
public final boolean isRegionExists(final World world, final String id) {
public ProtectedRegion getRegion(World world, String id) {
RegionManager regionManager = this.getRegionManager(world);
return regionManager != null ? regionManager.getRegions().keySet().stream().filter(key -> key.equalsIgnoreCase(id)).findFirst().map(regionManager::getRegion).orElse(null) : null;
}
public boolean isRegionExists(World world, String id) {
return this.getRegion(world, id) != null;
}
public final boolean isPlayerInsideRegion(final ProtectedRegion region, final Player player) {
final Location location = player.getLocation();
public boolean isPlayerInsideRegion(ProtectedRegion region, Player player) {
Location location = player.getLocation();
return region.contains(location.getBlockX(), location.getBlockY(), location.getBlockZ());
}
}

View File

@ -1,32 +1,26 @@
package me.skymc.taboolib.update;
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.Main;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.fileutils.FileUtils;
import me.skymc.taboolib.player.PlayerUtils;
import me.skymc.taboolib.plugin.PluginUtils;
import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitRunnable;
import java.io.File;
/**
* @author sky
* @since 2018年2月23日 下午10:39:14
*/
public class UpdateTask {
private static boolean haveUpdate = false;
private static double newVersion = 0;
public static boolean isHaveUpdate() {
return haveUpdate;
}
public static double getNewVersion() {
return newVersion;
}
public UpdateTask() {
new BukkitRunnable() {
@ -35,34 +29,53 @@ public class UpdateTask {
if (!Main.getInst().getConfig().getBoolean("UPDATE-CHECK")) {
return;
}
String value = FileUtils.getStringFromURL("https://api.github.com/repos/Bkm016/TabooLib/tags", null);
if (value == null) {
TLocale.Logger.error("UPDATETASK.VERSION-FAIL");
return;
}
JsonElement json = new JsonParser().parse(value);
if (json.isJsonArray()) {
JsonObject latestObject = json.getAsJsonArray().get(0).getAsJsonObject();
newVersion = latestObject.get("name").getAsDouble();
newVersion = json.getAsJsonArray().get(0).getAsJsonObject().get("name").getAsDouble();
if (TabooLib.getPluginVersion() >= newVersion) {
TLocale.Logger.info("UPDATETASK.VERSION-LATEST");
} else {
haveUpdate = true;
TLocale.Logger.info("UPDATETASK.VERSION-OUTDATED", String.valueOf(TabooLib.getPluginVersion()), String.valueOf(newVersion));
new BukkitRunnable() {
@Override
public void run() {
if (Main.getInst().getConfig().getBoolean("UPDATE-DOWNLOAD", false)) {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "taboolib updatePlugin");
}
}
}.runTask(Main.getInst());
Bukkit.getScheduler().runTask(TabooLib.instance(), () -> updatePlugin(true));
}
}
}
}.runTaskTimerAsynchronously(Main.getInst(), 100, 20 * 60 * 60 * 6);
}
public static boolean isHaveUpdate() {
return newVersion > 0;
}
public static double getNewVersion() {
return newVersion;
}
public static void updatePlugin(boolean shutdown) {
if (!UpdateTask.isHaveUpdate()) {
TLocale.Logger.info("COMMANDS.TABOOLIB.UPDATEPLUGIN.UPDATE-NOT-FOUND");
return;
}
if (PlayerUtils.getOnlinePlayers().size() > 0) {
TLocale.Logger.info("COMMANDS.TABOOLIB.UPDATEPLUGIN.PLAYER-ONLINE");
return;
}
File pluginFile = PluginUtils.getPluginFile(Main.getInst());
if (pluginFile == null) {
TLocale.Logger.info("COMMANDS.TABOOLIB.UPDATEPLUGIN.FILE-NOT-FOUND");
return;
}
Bukkit.getScheduler().runTaskAsynchronously(TabooLib.instance(), () -> {
FileUtils.download("https://github.com/Bkm016/TabooLib/releases/download/" + newVersion + "/TabooLib-" + newVersion + ".jar", pluginFile);
TLocale.Logger.info("COMMANDS.TABOOLIB.UPDATEPLUGIN.UPDATE-SUCCESS");
if (shutdown) {
Bukkit.shutdown();
}
});
}
}

View File

@ -1,63 +1,68 @@
package me.skymc.tlm.command;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.commands.builder.SimpleCommandBuilder;
import me.skymc.taboolib.object.Instantiable;
import me.skymc.tlm.TLM;
import me.skymc.tlm.command.sub.TLMInvCommand;
import me.skymc.tlm.command.sub.TLMKitCommand;
import me.skymc.tlm.command.sub.TLMListCommand;
import me.skymc.tlm.command.sub.TLMReloadCommand;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
/**
* @author sky
* @since 2018年2月18日 上午12:02:08
*/
public class TLMCommands implements CommandExecutor {
@Instantiable("TLMCommands")
public class TLMCommands {
@Override
public boolean onCommand(CommandSender sender, Command arg1, String arg2, String[] args) {
if (args.length == 0 || "help".equalsIgnoreCase(args[0])) {
if (sender.hasPermission("taboolib.admin")) {
TLM.getInst().getLanguage().get("COMMAND-HELP").send(sender);
} else {
TLM.getInst().getLanguage().get("NOPERMISSION-HELP").send(sender);
}
}
public TLMCommands() {
SimpleCommandBuilder.create("taboolibrarymodule", TabooLib.instance())
.aliases("tlm")
.permission("tlm.use")
.execute((sender, args) -> {
if (args.length == 0 || "help".equalsIgnoreCase(args[0])) {
if (sender.hasPermission("taboolib.admin")) {
TLM.getInst().getLanguage().get("COMMAND-HELP").send(sender);
} else {
TLM.getInst().getLanguage().get("NOPERMISSION-HELP").send(sender);
}
}
// 重载
else if ("reload".equalsIgnoreCase(args[0])) {
if (sender.hasPermission("taboolib.admin")) {
new TLMReloadCommand(sender, args);
} else {
TLM.getInst().getLanguage().get("NOPERMISSION-RELOAD").send(sender);
}
}
// 重载
else if ("reload".equalsIgnoreCase(args[0])) {
if (sender.hasPermission("taboolib.admin")) {
new TLMReloadCommand(sender, args);
} else {
TLM.getInst().getLanguage().get("NOPERMISSION-RELOAD").send(sender);
}
}
// 列出
else if ("list".equalsIgnoreCase(args[0])) {
if (sender.hasPermission("taboolib.admin")) {
new TLMListCommand(sender, args);
} else {
TLM.getInst().getLanguage().get("NOPERMISSION-LIST").send(sender);
}
}
// 列出
else if ("list".equalsIgnoreCase(args[0])) {
if (sender.hasPermission("taboolib.admin")) {
new TLMListCommand(sender, args);
} else {
TLM.getInst().getLanguage().get("NOPERMISSION-LIST").send(sender);
}
}
// InventorySave 模块
else if ("inv".equalsIgnoreCase(args[0])) {
if (sender.hasPermission("taboolib.admin")) {
new TLMInvCommand(sender, args);
} else {
TLM.getInst().getLanguage().get("NOPERMISSION-INV").send(sender);
}
}
// InventorySave 模块
else if ("inv".equalsIgnoreCase(args[0])) {
if (sender.hasPermission("taboolib.admin")) {
new TLMInvCommand(sender, args);
} else {
TLM.getInst().getLanguage().get("NOPERMISSION-INV").send(sender);
}
}
// Kit 模块
else if ("kit".equalsIgnoreCase(args[0])) {
new TLMKitCommand(sender, args);
} else {
TLM.getInst().getLanguage().get("COMMAND-ERROR").send(sender);
}
return true;
// Kit 模块
else if ("kit".equalsIgnoreCase(args[0])) {
new TLMKitCommand(sender, args);
} else {
TLM.getInst().getLanguage().get("COMMAND-ERROR").send(sender);
}
return true;
}).build();
}
}

View File

@ -12,16 +12,6 @@ DATAURL:
SERVER-DATA: 'plugins/TabooLib/serverdata/'
# 物品数据(来自 ItemSave 插件)
ITEMDIR: 'plugins/Skript/scripts/config/item.yml'
# 是否启用调试模式
# 启用后将收到来自其他插件的调试信息
DEBUG: false
# 网络连接测试地址
TEST-URL: 'aliyun.com'
# 下载依赖时启用的线程数
DOWNLOAD-POOL-SIZE: 4
# 语言文件相关设置
LOCALE:
@ -33,10 +23,29 @@ LOCALE:
# 关闭可提升性能
# 如果需要开启仍然可以在语言文件中加入 papi: true
USE_PAPI: false
# 玩家列表TAB是否根据前缀排序
# 启用后将会导致部分通过计分板获取玩家数据的插件出错BedwarsRel、SkyWars
TABLIST-SORT: false
# 是否注入 PluginManager关闭后可能会导致部分功能出错。
PLUGIN-INJECTOR:
ENABLE: true
# 检测下面的插件并自动关闭注入
DISABLE-ON-PLUGIN-EXISTS:
- LuckPerms
# 是否在当前服务器启用交流网终端
# 启用后将会收到大量调试信息, 不建议使用
SERVER: false
# 网络连接测试地址
TEST-URL: 'aliyun.com'
# 下载依赖时启用的线程数
DOWNLOAD-POOL-SIZE: 4
# 玩家列表TAB-API是否根据前缀排序
TABLIST-SORT: true
# 玩家列表TAB-API是否自动清理没有成员的队伍
TABLIST-AUTO-CLEAN-TEAM: true
# 是否启用更新检测
UPDATE-CHECK: true
@ -62,6 +71,7 @@ ENABLE-UUID: false
HIDE-NOTIFY: true
# 数据库信息
# 该功能在当前版本下无法使用,请勿启用
MYSQL:
# 是否启用数据库
ENABLE: false
@ -77,7 +87,7 @@ MYSQL:
DATABASE: 'test'
# 数据表前缀
PREFIX: 'taboolib'
# 全局变量信息
PluginData:
# 检查更新间隔(单位:秒)

View File

@ -1,8 +1,11 @@
TLIB:
INJECTION-SUCCESS: '注入成功'
INJECTION-FAILED:
- '注入失败'
- '&c提前加载依赖于 TabooLib 的所有插件的相关功能'
- '注入失败'
- '&c提前加载依赖于 TabooLib 的所有插件的相关功能'
INJECTION-DISABLED:
- '关闭注入'
- '&c提前加载依赖于 TabooLib 的所有插件的相关功能'
LOAD-FAIL-OFFLINE:
- '**********************************************'
- '** TabooLib-{0} 无法在您的服务器上使用'
@ -12,15 +15,15 @@ TLIB:
- '**'
- '** 详情查阅: https://github.com/Bkm016/TabooLib'
- '**********************************************'
DEPENDENCY:
DOWNLOAD-OFFLINE: '已启用离线模式, 将不会下载第三方依赖库'
DOWNLOAD-CONNECTED: ' 正在下载 {0} 大小 {1}'
DOWNLOAD-PROGRESS: ' 下载速度 {0} 进度 {1}'
DOWNLOAD-SUCCESS: ' 下载 {0} 完成'
DOWNLOAD-FAILED:
- ' 下载 {0} 失败'
- ' 请手动下载 {1} 并重命名为 {2} 后放在 /{0}/libs 文件夹内'
- ' 下载 {0} 失败'
- ' 请手动下载 {1} 并重命名为 {2} 后放在 /{0}/libs 文件夹内'
PLUGIN-AUTOLOAD-FAIL: '{0} 所依赖的插件 {1} 尝试自动加载失败,请尝试手动下载'
PLUGIN-LOAD-SUCCESS: ' {0} 请求的插件 {1} 加载成功'
PLUGIN-LOAD-FAIL: ' {0} 请求的插件 {1} 加载失败'
@ -28,7 +31,8 @@ DEPENDENCY:
LIBRARY-LOAD-SUCCESS: ' {0} 请求的库文件 {1} 加载成功'
LIBRARY-LOAD-FAIL: ' {0} 请求的库文件 {1} 加载失败'
LOAD-COMPLETE: '依赖加载完成'
LOAD-CLASSES: '&7缓存 &f{0} &7插件的 &f{1} &7个类耗时&f {2} &7毫秒.'
CONFIG:
LOAD-FAIL-NO-ANNOTATION: '插件 {0} 的配置类 {1} 加载失败:没有 @Config 注解'
LOAD-FAIL: '插件 {0} 的配置类 {1} 加载失败:没有 @Config 注解'
@ -40,7 +44,7 @@ CONFIG:
RELOAD-SUCCESS: '插件 {0} 的配置 {1} 成功重载'
RELOAD-FAIL: '插件 {0} 的配置 {1} 成功重载'
LISTEN-START: '开始监听 {0} 插件的 {1} 配置文件'
NOTIFY:
ERROR-SERVER-KEY: '&4检测到本服序列号与其他服务器相同, 已重新生成!'
ERROR-CONNECTION-FAIL: '&4数据库连接失败, 请检查配置是否正确!'
@ -55,7 +59,7 @@ NOTIFY:
FAIL-DISABLE:
- '&c插件尚未启动完成, 已跳过卸载代码'
- '&c插件作者: &4坏黑'
LOCALE:
TITLE-SEND-TO-NON-PLAYER: '该语言类型只能发送给玩家:{0}'
PLUGIN-NOT-FOUND: '无效的语言文件发送形式: &4{0}'
@ -65,36 +69,36 @@ LOCALE:
BAR-PLUGIN-NOT-FOUND: 'TLocaleBossBar 的依赖插件 BossBarAPI 不存在'
CALLER-PLUGIN-NOT-FOUND: '{0} 不是一个由插件加载的类'
STATIC-CLASS-LOADER: '{0} 由静态类加载器初始化,无法获得其从属的插件'
MISC:
FIELD-COPY-FAILED: '拷贝 {0} 对象失败'
FIELD-COPY-ERROR: '拷贝 {0} 对象出错:{1}'
COOLDOWNPACK:
PACK-REGISTER: '注册冷却包: {0}, 时间: {1} 秒 ({2})'
PACK-REGISTER-ANONYMOUS: '注册冷却包: {0}, 时间: {1} 秒 (匿名注册)'
PACK-UNREGISTER: '注销冷却包: {0} (主动注销)'
PACK-UNREGISTER-AUTO: '注销冷却包: {0} (自动注销)'
GLOBAL-DATAMANAGER:
ERROR-CHECK-VARIABLE: '&4变量 &c{0} &4载入异常: &c{1}'
SUCCESS-LOADED-VARIABLE: '&7从数据库中获取 &f{0} &7个变量, 耗时: &f{1} &7(ms)'
PLAYER-DATAMANAGER:
ERROR-STORAGE-SQL: '不允许在储存模式为数据库的情况下获取离线玩家数据'
ERROR-PLAYER-DATA: '&4玩家 &c{0} &4的数据载入出现异常: &c{1}'
SUCCESS-SAVE-DATA: '&7保存 &f{0} &7条玩家数据, 耗时: &f{1} &7(ms)'
ENTITY-UTILS:
NOTFOUND-PROTOCOLLIB: '缺少前置插件 ProtocolLib'
FILE-UTILS:
FAIL-LOAD-CONFIGURATION: '&4配置文件载入失败!, 插件: &c{0}&4, 文件: &c{1}'
DATA-UTILS:
SUCCESS-SAVE-DATA: '&7保存 &f{0} &7条插件数据, 耗时: &f{1} &7(ms)'
FAIL-SAVE-FILE: '&4文件 &c{0}&4 保存失败, 原因: &c{1}'
ITEM-UTILS:
FAIL-LOAD-ITEMS: '物品库载入失败: &4{0}'
FAIL-LOAD-ATTRIBUTE: '&c{0} &4不是一个有效的属性名称, 输入 &c/tlib attributes&4 查看所有属性'
@ -105,20 +109,13 @@ ITEM-UTILS:
SUCCESS-LOAD-CACHES: '&7载入 &f{0} &7项缓存物品'
SUCCESS-LOAD-NAMES: '&7载入 &f{0} &7项物品名称'
EMPTY-ITEM: '空'
LANGUAGE2:
FAIL-NOTFOUND-FILE: '语言文件 {0} 不存在'
TIMECYCLE:
FAIL-CYCLE-EXISTS: '注册周期管理器 &8{0}&c 失败, 原因: &4名称重复'
ANVIL-CONTAINER:
NAME-EXAMPLE: '在这里输入文本'
LORE-NORMAL:
- ''
- '&7在上方文本框内输入信息'
- '&7随后点击右侧输出物品'
UPDATETASK:
VERSION-FAIL: '&4更新记录获取失败, 请检查网络连接!'
VERSION-LATEST: '&7插件已是最新版, 无需更新!'
@ -130,7 +127,7 @@ UPDATETASK:
- '&7 下载地址: &fhttp://www.mcbbs.net/thread-773065-1-1.html'
- '&7 开源地址: &fhttps://github.com/Bkm016/TabooLib/'
- '&8####################################################'
MYSQL-CONNECTION:
FAIL-CONNECT: '&4数据库 &c{0} &4连接失败, 原因: &c{0}'
FAIL-NOTFOUND-DRIVE: '&7驱动器获取失败, 无法连接到数据库'
@ -144,26 +141,26 @@ MYSQL-CONNECTION:
SUCCESS-CONNECTION-CANCEL: '已停止插件 &f{0}&7 的 &f{1}&7 条数据库连接'
NOTIFY-CONNECTING: '&7正在连接数据库, 地址: &f{0}'
NOTIFY-CONNECTED: '&7数据库连接成功 ({0}ms)'
MYSQL-HIKARI:
CREATE-SUCCESS: '&7插件 &f{0}&7 注册新的数据库连接: &f{1}'
CREATE-EXISTS: '&7插件 &f{0}&7 引用插件 &f{1}&7 注册的数据库连接'
CLOSE-SUCCESS: '&7插件 &f{0} &7注册的数据库连接 &f{1} &7已被注销!'
CLOSE-FAIL: '&7插件 &f{0} &7注册的数据库连接正在被 &f{1} &7个插件使用, 无法注销!'
TABOOLIB-MODULE:
SUCCESS-LOADED: '&7载入 &f{0} &7个 &fTLM &7模块'
FAIL-LOADED: '&4模块载入异常: &c{0}&4, 模块: &c{1}&4, 位于: &c{2}'
FAIL-RUNTIME: '&4模块运行异常: &c{0}&4, 模块: &c{1}&4, 位于: &c{2}'
COMMANDS:
GLOBAL:
ONLY-PLAYER: '&8[&3&lTabooLib&8] &4控制台无法这么做'
ONLY-STORAGE-SQL: '&8[&3&lTabooLib&8] &4只有启用数据库储存时才能这么做'
INTERNAL:
TYPE-ERROR: '&8[&3&lTabooLib&8] &7指令 &f{0} &7只能由 &f{1} &7执行'
TYPE-PLAYER: 玩家
TYPE-CONSOLE: 控制台
TYPE-PLAYER: '玩家'
TYPE-CONSOLE: '控制台'
ERROR-USAGE:
- '&8[&3&lTabooLib&8] &7指令 &f{0} &7参数不足'
- '&8[&3&lTabooLib&8] &7正确用法:'
@ -240,10 +237,9 @@ COMMANDS:
DESCRIPTION: '&4更新插件 &8(谨防非正规途径的插件获取方式)'
UPDATE-NOT-FOUND: '&8[&3&lTabooLib&8] &7插件已是最新版, 无需更新!'
UPDATE-NOT-SUPPORT: '&8[&3&lTabooLib&8] &4您的服务器不支持在线更新!'
UPDATE-SUCCESS: '&8[&3&lTabooLib&8] &7最新版下载完成, 服务器即将重启!'
FILE-NOT-FOUND: '&8[&3&lTabooLib&8] &4尚未寻找到插件文件'
PLAYER-ONLINE: '&8[&3&lTabooLib&8] &4服务器有玩家在线无法更新插件.'
UPDATE-START: '&8[&3&lTabooLib&8] &7开始下载:&f {0}'
UPDATE-SUCCESS: '&8[&3&lTabooLib&8] &7最新版下载完成, 服务器即将重启!'
PLAYERTAG:
DESCRIPTION:
DISPLAY: '设置玩家展示名称'
@ -385,7 +381,7 @@ COMMANDS:
hover: '&f点击复制'
suggest: '{0}'
FOOT:
- ''
- ''
ENCHANTS:
DESCRIPTION: '查看所有附魔'
HEAD:
@ -430,7 +426,7 @@ COMMANDS:
hover: '&f点击复制'
suggest: '{0}'
FOOT:
- ''
- ''
SLOTS:
DESCRIPTION: '查看所有部位'
HEAD:
@ -473,7 +469,7 @@ COMMANDS:
COMMAND-TITLE: '&e&l----- &6&lTabooLibPlugin Commands &e&l-----'
LIST:
DESCRIPTION: '列出插件'
LIST-PLUGIN:
LIST-PLUGIN:
- '&8[&3&lTabooLib&8] &7插件总数: &f{0}'
- '&8[&3&lTabooLib&8] &7插件列表: &f{1}'
INFO:
@ -533,7 +529,13 @@ COMMANDS:
1: '内容'
INVALID-PLAYER-OFFLINE: '&8[&3&lTabooLib&8] &4玩家 &c{0} &4不在线.'
COMMAND:
DESCRIPTION: '使目标输入执行指令'
DESCRIPTION: '使目标执行指令'
ARGUMENTS:
0: '目标'
1: '内容'
INVALID-TARGET-NOT-FOUND: '&8[&3&lTabooLib&8] &4目标 &c{0} &4不存在.'
COMMAND-AS-OP:
DESCRIPTION: '使目标以管理员身份执行指令'
ARGUMENTS:
0: '目标'
1: '内容'
@ -562,13 +564,20 @@ COMMANDS:
DATABASE:
CONNECTION-ESTABLISHED: '成功连接到 {0} 数据库,连接池大小 {1}'
CONNECTION-ERROR: '连接到数据库错误:{0}'
COMMUNICATION:
FAILED-LOAD-SETTINGS: '§8[§3§lTabooLibClient§8] &4配置载入失败: {0}'
FAILED-CONNECT-SERVER: '§8[§3§lTabooLibClient§8] &4本地通讯网络连接失败.'
FAILED-CONNECT-CLIENT: '§8[§3§lTabooLibClient§8] &4本地通讯网络连接出错: {0}'
FAILED-READING-PACKET: '§8[§3§lTabooLibClient§8] &4本地通讯网络数据包读取失败: {0}'
SUCCESS-CONNECTED: '§8[§3§lTabooLibClient§8] &7本地通讯网络连接成功.'
CLIENT-JOINED: '§8[§3§lTabooLibClient§8] &7服务器 &flocalhost:{0} &7加入本地通讯网络.'
CLIENT-QUITED: '§8[§3§lTabooLibClient§8] &7服务器 &flocalhost:{0} &7退出本地通讯网络.'
PACKET-MESSAGE: '§8[§3§lTabooLibClient§8] &7服务器 &flocalhost:{0} &7发送信息: &f{1}'
CLIENT-JOINED: '§8[§3§lTabooLibClient§8] &7服务器 &f{0} &7加入本地通讯网络.'
CLIENT-QUITED: '§8[§3§lTabooLibClient§8] &7服务器 &f{0} &7退出本地通讯网络.'
PACKET-MESSAGE: '§8[§3§lTabooLibClient§8] &7服务器 &f{0} &7发送信息: &f{1}'
PACKET-COMMAND: '§8[§3§lTabooLibClient§8] &7服务器 &f{0} &7运行命令: &f{1}'
UTIL:
DOWNLOAD-CONNECTED: '开始下载文件 {0} 大小 {1}'
DOWNLOAD-PROGRESS: ' 下载速度 {0} 进度 {1}'
DOWNLOAD-SUCCESS: '下载 {0} 完成!'
DOWNLOAD-FAILED: '下载 {0} 失败!'

View File

@ -4,12 +4,4 @@ version: ${project.version}
author: [lzzelAliz, 坏黑]
depend: [Vault]
softdepend: [PlaceholderAPI, Skript, MassiveLag]
# 两个命令删除预定
commands:
language2:
aliases: [lang2]
permission: taboolib.admin
taboolibrarymodule:
aliases: [tlm]
softdepend: [PlaceholderAPI, Skript, MassiveLag]