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/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/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://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://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) 根据您服务器的网络状态下载**在线**或**离线**版本 <br>
离线版为 **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 的全部功能。
<a name="mcbbs"></a>
MCBBS
--- ---
**3.56** 版本开始 `com.sun.tools.jar` 不再和插件一起发布。 本插件仅在 [**MCBBS**](http://www.mcbbs.net/thread-773065-1-1.html) 发布
<hr>
如果需要启用 *JavaShell* 功能请将 [com.sun.tools.jar](http://skymc.oss-cn-shanghai.aliyuncs.com/plugins/com.sun.tools.jar) 放入 *"TabooLib/JavaShell/lib"* 文件夹中。  
---
**3.832** 版本后开源协议更改为 `MIT`

View File

@ -6,7 +6,7 @@
<groupId>me.skymc</groupId> <groupId>me.skymc</groupId>
<artifactId>TabooLib</artifactId> <artifactId>TabooLib</artifactId>
<version>4.2</version> <version>4.325</version>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <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") @TConfig(name = "cfg.yml", charset = "GBK")
public class ExampleMain extends JavaPlugin { public class ExampleMain extends JavaPlugin {
private Property<Boolean> update = Property.of(false);
public static void main(String[] args) { public static void main(String[] args) {
MemoryMXBean bean = ManagementFactory.getMemoryMXBean(); MemoryMXBean bean = ManagementFactory.getMemoryMXBean();
System.out.println(bean.getHeapMemoryUsage().toString()); System.out.println(bean.getHeapMemoryUsage().toString());
@ -34,8 +36,6 @@ public class ExampleMain extends JavaPlugin {
} }
} }
private Property<Boolean> update = Property.of(false);
@Override @Override
public void onEnable() { public void onEnable() {
update.addListener(((oldVal, newVal) -> { update.addListener(((oldVal, newVal) -> {

View File

@ -14,15 +14,16 @@ import com.ilummc.tlib.resources.TLocaleLoader;
import com.ilummc.tlib.util.IO; import com.ilummc.tlib.util.IO;
import me.skymc.taboolib.Main; import me.skymc.taboolib.Main;
import me.skymc.taboolib.fileutils.FileUtils; import me.skymc.taboolib.fileutils.FileUtils;
import me.skymc.taboolib.plugin.PluginUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.nio.charset.Charset; 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 = "com.zaxxer:HikariCP:3.1.0")
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.slf4j:slf4j-api:1.7.25") @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() { public static void init() {
tLib = new TLib(); tLib = new TLib();
@ -94,6 +87,11 @@ public class TLib {
} }
public static void injectPluginManager() { 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 { try {
Field field = Bukkit.getServer().getClass().getDeclaredField("pluginManager"); Field field = Bukkit.getServer().getClass().getDeclaredField("pluginManager");
field.setAccessible(true); field.setAccessible(true);
@ -101,12 +99,16 @@ public class TLib {
TLocale.Logger.info("TLIB.INJECTION-SUCCESS"); TLocale.Logger.info("TLIB.INJECTION-SUCCESS");
} catch (NoSuchFieldException | IllegalAccessException | IllegalArgumentException ignored) { } catch (NoSuchFieldException | IllegalAccessException | IllegalArgumentException ignored) {
TLocale.Logger.fatal("TLIB.INJECTION-FAILED"); TLocale.Logger.fatal("TLIB.INJECTION-FAILED");
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin != Main.getInst()).forEach(plugin -> TDependencyInjector.inject(plugin, plugin));
if (plugin != Main.getInst()) {
TDependencyInjector.inject(plugin, plugin);
} }
} }
public static TLib getTLib() {
return tLib;
} }
public static YamlConfiguration getInternalLanguage() {
return internalLanguage;
} }
public TLogger getLogger() { public TLogger getLogger() {
@ -124,4 +126,18 @@ public class TLib {
public File getLibsFolder() { public File getLibsFolder() {
return libsFolder; 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; package com.ilummc.tlib.logger;
import com.ilummc.tlib.resources.TLocale;
import com.ilummc.tlib.util.Strings; import com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.Main; 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.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
public class TLogger { 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 static TLogger globalLogger = new TLogger("§8[§3§lTabooLib§8][§r{1}§8] §f{2}", Main.getInst(), TLogger.FINE);
private final String pattern; private final String pattern;
private Plugin plugin; private String name;
private int level; private int level;
public static TLogger getGlobalLogger() { public static TLogger getGlobalLogger() {
@ -23,8 +26,8 @@ public class TLogger {
return pattern; return pattern;
} }
public Plugin getPlugin() { public String getName() {
return plugin; return name;
} }
public int getLevel() { public int getLevel() {
@ -37,49 +40,83 @@ public class TLogger {
public TLogger(String pattern, Plugin plugin, int level) { public TLogger(String pattern, Plugin plugin, int level) {
this.pattern = pattern; 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; this.level = level;
} }
public void verbose(String msg) { public void verbose(String msg) {
if (level <= VERBOSE) { 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) { public void finest(String msg) {
if (level <= FINEST) { 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) { public void fine(String msg) {
if (level <= FINE) { 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) { public void info(String msg) {
if (level <= INFO) { 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) { public void warn(String msg) {
if (level <= WARN) { 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) { public void error(String msg) {
if (level <= ERROR) { 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) { public void fatal(String msg) {
if (level <= FATAL) { 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); 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 @Override
public void send(Player player, String text) { 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.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.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.ChatMessageType.a((byte) 2));
((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); ((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 { public class AsmClassTransformer extends ClassVisitor implements Opcodes {
private final Class<?> from; private final Class<?> from;
private final String fromVer;
private final String fromVer, toVer; private final String toVer;
private final ClassWriter writer; private final ClassWriter writer;
private String newClassName;
private String newClassName, prevName; private String prevName;
private AsmClassTransformer(Class<?> from, String fromVer, String toVer, ClassWriter classWriter) { private AsmClassTransformer(Class<?> from, String fromVer, String toVer, ClassWriter classWriter) {
super(Opcodes.ASM6, classWriter); super(Opcodes.ASM5, classWriter);
writer = classWriter; this.writer = classWriter;
this.from = from; this.from = from;
this.fromVer = fromVer; this.fromVer = fromVer;
this.toVer = toVer; this.toVer = toVer;
@ -51,6 +50,10 @@ public class AsmClassTransformer extends ClassVisitor implements Opcodes {
return new Builder().toVersion(Bukkit.getServer().getClass().getName().split("\\.")[3]); return new Builder().toVersion(Bukkit.getServer().getClass().getName().split("\\.")[3]);
} }
public static Builder builder(String ver) {
return new Builder().toVersion(ver);
}
@Override @Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { 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)); 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); 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) { private String replace(String text) {
if (text != null) { 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("org/bukkit/craftbukkit/" + fromVer, "org/bukkit/craftbukkit/" + toVer)
.replace(prevName, newClassName.replace('.', '/')); .replace(prevName, newClassName.replace('.', '/'));
} else { } 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 { private class AsmMethodTransformer extends MethodVisitor {
AsmMethodTransformer(MethodVisitor visitor) { AsmMethodTransformer(MethodVisitor visitor) {
super(Opcodes.ASM6, visitor); super(Opcodes.ASM5, visitor);
} }
@Override @Override

View File

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

View File

@ -1,5 +1,6 @@
package me.skymc.taboolib; package me.skymc.taboolib;
import me.skymc.taboolib.nms.NMSUtils;
import me.skymc.taboolib.other.NumberUtils; import me.skymc.taboolib.other.NumberUtils;
import me.skymc.taboolib.playerdata.DataUtils; import me.skymc.taboolib.playerdata.DataUtils;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
@ -18,41 +19,128 @@ public class TabooLib {
static { static {
try { try {
spigot = Bukkit.getConsoleSender() != null; Class.forName("org.bukkit.Bukkit");
spigot = true;
} catch (Exception ignored) { } catch (Exception ignored) {
} }
} }
/**
* 获取主类对象 Main 名称容易造成混淆所以转移至此
*
* @return {@link Main}
*/
public static Main instance() { public static Main instance() {
return (Main) Main.getInst(); 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() { public static boolean isSpigot() {
return spigot; return spigot;
} }
public static boolean isDebug() { /**
return Main.getInst().getConfig().getBoolean("DEBUG"); * 获取 TabooLib 插件版本
} *
* @return double
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));
}
}
public static double getPluginVersion() { public static double getPluginVersion() {
return NumberUtils.getDouble(Main.getInst().getDescription().getVersion()); return NumberUtils.getDouble(Main.getInst().getDescription().getVersion());
} }
/**
* 获取服务端版本
*
* @return String
*/
public static String getVersion() { 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() { public static int getVersionNumber() {
return getVerint(); 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() { public static String getServerUID() {
if (!DataUtils.getPluginData("TabooLibrary", null).contains("serverUID")) { if (!DataUtils.getPluginData("TabooLibrary", null).contains("serverUID")) {
DataUtils.getPluginData("TabooLibrary", null).set("serverUID", UUID.randomUUID().toString()); DataUtils.getPluginData("TabooLibrary", null).set("serverUID", UUID.randomUUID().toString());
@ -60,8 +148,19 @@ public class TabooLib {
return DataUtils.getPluginData("TabooLibrary", null).getString("serverUID"); 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 @Deprecated

View File

@ -5,25 +5,34 @@ import com.ilummc.tlib.annotations.Dependency;
import com.ilummc.tlib.inject.TDependencyInjector; import com.ilummc.tlib.inject.TDependencyInjector;
import com.ilummc.tlib.resources.TLocale; import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.bstats.Metrics; import me.skymc.taboolib.bstats.Metrics;
import me.skymc.taboolib.commands.language.Language2Command;
import me.skymc.taboolib.fileutils.FileUtils; import me.skymc.taboolib.fileutils.FileUtils;
import me.skymc.taboolib.listener.TListener;
import me.skymc.taboolib.listener.TListenerHandler; import me.skymc.taboolib.listener.TListenerHandler;
import me.skymc.taboolib.playerdata.DataUtils; import me.skymc.taboolib.playerdata.DataUtils;
import me.skymc.tlm.command.TLMCommands;
import org.bukkit.Bukkit; 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 org.bukkit.plugin.Plugin;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.Arrays; import java.util.Arrays;
import java.util.stream.Collectors; import java.util.HashMap;
import java.util.List;
import java.util.Optional;
/** /**
* @Author sky * @Author sky
* @Since 2018-08-23 17:04 * @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() { static void setup() {
testInternet(); testInternet();
@ -33,11 +42,21 @@ class TabooLibLoader {
} }
static void register() { static void register() {
setupClasses();
registerListener(); registerListener();
registerCommands();
registerMetrics(); 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"))); 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() { static void registerMetrics() {
Metrics metrics = new Metrics(TabooLib.instance()); 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.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; package me.skymc.taboolib.anvil;
import me.skymc.taboolib.nms.NMSUtils;
import org.bukkit.entity.Player; 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"); @Override
private static Class<?> PacketPlayOutOpenWindow = NMSUtils.getNMSClass("PacketPlayOutOpenWindow"); public boolean a(net.minecraft.server.v1_12_R1.EntityHuman player) {
private static Class<?> IChatBaseComponent = NMSUtils.getNMSClass("IChatBaseComponent"); return true;
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();
// }
public static void openAnvil(Player p) { public static void openAnvil(Player p) {
try { net.minecraft.server.v1_12_R1.EntityPlayer player = ((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) p).getHandle();
Object player = p.getClass().getMethod("getHandle").invoke(p); AnvilContainer container = new AnvilContainer(player);
int c = (int) player.getClass().getMethod("nextContainerCounter").invoke(player); int c = player.nextContainerCounter();
Object chatMessage = ChatMessage.getConstructor(String.class, Object[].class).newInstance("Repairing", new Object[0]); player.playerConnection.sendPacket(new net.minecraft.server.v1_12_R1.PacketPlayOutOpenWindow(c, "minecraft:anvil", new net.minecraft.server.v1_12_R1.ChatMessage("Repairing"), 0));
Object packetPlayOutOpenWindow = PacketPlayOutOpenWindow.getConstructor(Integer.TYPE, String.class, IChatBaseComponent, Integer.TYPE).newInstance(c, "minecraft:anvil", chatMessage, 0); player.activeContainer = container;
Object playerConnection = player.getClass().getDeclaredField("playerConnection").get(player); player.activeContainer.windowId = c;
playerConnection.getClass().getMethod("sendPacket", Packet).invoke(playerConnection, packetPlayOutOpenWindow); player.activeContainer.addSlotListener(player);
} catch (Exception ignored) {
} }
} }
}
//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; package me.skymc.taboolib.anvil;
import com.ilummc.tlib.resources.TLocale; import com.ilummc.tlib.util.asm.AsmClassLoader;
import me.skymc.taboolib.listener.TListener; import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.object.Instantiable;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; 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.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; * @author sky
import java.util.List; */
@Instantiable("AnvilContainerAPI")
@TListener
public class AnvilContainerAPI implements Listener { public class AnvilContainerAPI implements Listener {
public static List<String> list = new ArrayList<>(); private static Class<?> impl;
public static ItemStack item = new ItemStack(Material.NAME_TAG);
public static HashMap<String, String> isOpen = new HashMap<>();
public static AnvilContainerAPIEvent event;
public static void send(Player p, String type, String str, List<String> lorelist) { public AnvilContainerAPI() {
isOpen.put(p.getName(), type); try {
impl = AsmClassLoader.createNewClass("me.skymc.taboolib.anvil.AnvilContainer", AnvilContainerGenerator.generate());
AnvilContainer.openAnvil(p); Bukkit.getPluginManager().registerEvents(this, TabooLib.instance());
ItemMeta meta = item.getItemMeta(); } catch (Exception e) {
e.printStackTrace();
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();
}
} }
} }
@EventHandler public static void openAnvil(Player player) {
public void click(InventoryClickEvent e) { try {
if (!isOpen.containsKey(e.getWhoClicked().getName())) { impl.getMethod("openAnvil", Player.class).invoke(impl, player);
return; } catch (Exception e) {
} e.printStackTrace();
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);
} }
} }
@EventHandler @EventHandler
public void example(PlayerCommandPreprocessEvent e) { public void example(PlayerCommandPreprocessEvent e) {
if ("/anvilexample".equals(e.getMessage())) { if (e.getMessage().equalsIgnoreCase("/anvilExample") && e.getPlayer().hasPermission("taboolib.admin")) {
if (e.getPlayer().hasPermission("taboolib.admin")) {
e.setCancelled(true); e.setCancelled(true);
AnvilContainerAPI.send(e.getPlayer(), "EXAMPLE", TLocale.asString("ANVIL-CONTAINER.NAME-EXAMPLE"), null); openAnvil(e.getPlayer());
}
}
}
@EventHandler
public void example2(AnvilContainerAPIEvent e) {
if ("EXAMPLE".equals(e.type)) {
e.event.getWhoClicked().sendMessage(e.string);
} }
} }
} }

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.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.*;
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.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
@ -36,6 +30,15 @@ import java.util.zip.GZIPOutputStream;
*/ */
public class Metrics { 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 { static {
// You can use the property to disable the check in your test environment // 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")) { if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
@ -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 // The plugin
private final JavaPlugin plugin; private final JavaPlugin plugin;
@ -103,7 +94,8 @@ public class Metrics {
).copyDefaults(true); ).copyDefaults(true);
try { try {
config.save(configFile); config.save(configFile);
} catch (IOException ignored) { } } catch (IOException ignored) {
}
} }
// Load the data // Load the data
@ -117,7 +109,8 @@ public class Metrics {
service.getField("B_STATS_VERSION"); // Our identifier :) service.getField("B_STATS_VERSION"); // Our identifier :)
found = true; // We aren't the first found = true; // We aren't the first
break; break;
} catch (NoSuchFieldException ignored) { } } catch (NoSuchFieldException ignored) {
}
} }
// Register our service // Register our service
Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal); 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. * Adds a custom chart.
* *
@ -256,9 +304,11 @@ public class Metrics {
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) { for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
try { try {
pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider())); 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); data.put("plugins", pluginData);
@ -280,61 +330,6 @@ public class Metrics {
}).start(); }).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. * Represents a custom chart.
*/ */

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) { public static boolean dispatchCommand(CommandSender sender, String command) {
try { try {
if ((sender instanceof Player)) { if ((sender instanceof Player)) {

View File

@ -779,39 +779,12 @@ public class TabooLibMainCommand extends BaseMainCommand {
@Override @Override
public void onCommand(CommandSender sender, Command command, String label, String[] args) { public void onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!UpdateTask.isHaveUpdate()) { UpdateTask.updatePlugin(true);
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.UPDATEPLUGIN.UPDATE-NOT-FOUND");
return;
} }
File pluginFile = PluginUtils.getPluginFile(Main.getInst());
if (pluginFile == null) {
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.UPDATEPLUGIN.FILE-NOT-FOUND");
return;
}
new BukkitRunnable() {
@Override @Override
public void run() { public CommandType getType() {
if (PlayerUtils.getOnlinePlayers().size() > 0) { return CommandType.CONSOLE;
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());
} }
}; };
} }

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())); 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); return registerPluginCommand(plugin, command, "", "/" + command, new ArrayList<>(), null, null, commandExecutor, null);
} }
public static boolean registerPluginCommand(Plugin plugin, String command, CommandExecutor commandExecutor, TabExecutor tabExecutor) { public static boolean registerPluginCommand(Plugin plugin, String command, CommandExecutor commandExecutor, TabCompleter tabCompleter) {
return registerPluginCommand(plugin, command, "", "/" + command, new ArrayList<>(), null, null, commandExecutor, tabExecutor); 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) { 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, tabExecutor); 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) { 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, tabExecutor); 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) { 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, tabExecutor); return registerPluginCommand(plugin, command, description, usage, aliases, null, null, commandExecutor, tabCompleter);
} }
/** /**
@ -81,16 +81,16 @@ public class TCommandHandler implements Listener {
* @param permission 权限 * @param permission 权限
* @param permissionMessage 权限提示 * @param permissionMessage 权限提示
* @param commandExecutor 命令执行器 * @param commandExecutor 命令执行器
* @param tabExecutor 补全执行器 * @param tabCompleter 补全执行器
* @return 注册结果(boolean) * @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 { try {
Constructor<PluginCommand> constructor = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class); Constructor<PluginCommand> constructor = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class);
constructor.setAccessible(true); constructor.setAccessible(true);
PluginCommand pluginCommand = constructor.newInstance(command, plugin); PluginCommand pluginCommand = constructor.newInstance(command, plugin);
pluginCommand.setExecutor(commandExecutor); 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, "description", description);
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "usageMessage", usage); ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "usageMessage", usage);
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "aliases", aliases); 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, "permission", permission);
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "permissionMessage", permissionMessage); ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "permissionMessage", permissionMessage);
commandMap.register(command, pluginCommand); commandMap.register(command, pluginCommand);
if (!TabooLib.isTabooLib(plugin)) {
TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE", plugin.getName(), command); TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE", plugin.getName(), command);
}
return true; return true;
} catch (Exception e) { } catch (Exception e) {
TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE-FAILED", plugin.getName(), command, e.getMessage()); TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE-FAILED", plugin.getName(), command, e.getMessage());
@ -134,7 +136,6 @@ public class TCommandHandler implements Listener {
*/ */
public static void registerCommands() { public static void registerCommands() {
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
if (plugin.equals(TabooLib.instance()) || plugin.getDescription().getDepend().contains("TabooLib")) {
try { try {
registerCommand(plugin); registerCommand(plugin);
} catch (Exception e) { } catch (Exception e) {
@ -142,7 +143,6 @@ public class TCommandHandler implements Listener {
} }
} }
} }
}
/** /**
* 注册插件的所有 TCommand 命令 * 注册插件的所有 TCommand 命令
@ -150,6 +150,9 @@ public class TCommandHandler implements Listener {
* @param plugin 插件 * @param plugin 插件
*/ */
public static void registerCommand(Plugin plugin) { public static void registerCommand(Plugin plugin) {
if (!(plugin.equals(TabooLib.instance()) || TabooLib.isDependTabooLib(plugin))) {
return;
}
for (Class pluginClass : FileUtils.getClasses(plugin)) { for (Class pluginClass : FileUtils.getClasses(plugin)) {
if (BaseMainCommand.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TCommand.class)) { if (BaseMainCommand.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TCommand.class)) {
TCommand tCommand = (TCommand) pluginClass.getAnnotation(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 com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.Main; 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 me.skymc.taboolib.string.language2.Language2Value;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -14,18 +15,23 @@ import org.bukkit.entity.Player;
* @author sky * @author sky
* @since 2018年2月13日 下午5:11:01 * @since 2018年2月13日 下午5:11:01
*/ */
public class Language2Command implements CommandExecutor { @Instantiable("Language2Command")
public class Language2Command {
@Override public Language2Command() {
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { SimpleCommandBuilder.create("language2", TabooLib.instance())
.aliases("lang2")
.permission("taboolib.admin")
.execute((sender, args) -> {
if (args.length == 0) { if (args.length == 0) {
TLocale.sendTo(sender, "COMMANDS.LANGUAGE2.HELP", label); TLocale.sendTo(sender, "COMMANDS.LANGUAGE2.HELP", "langauge2");
} else if ("reload".equalsIgnoreCase(args[0])) { } else if ("reload".equalsIgnoreCase(args[0])) {
reload(sender); reload(sender);
} else if ("send".equalsIgnoreCase(args[0])) { } else if ("send".equalsIgnoreCase(args[0])) {
send(sender, args); send(sender, args);
} }
return true; return true;
}).build();
} }
private void send(CommandSender sender, String[] args) { 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; package me.skymc.taboolib.damage;
import me.skymc.taboolib.TabooLib;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; 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 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) { public static void damage(Player player, LivingEntity victim, double damage) {
dmg(player, victim, damage); dmg(player, victim, damage);
} }
@Deprecated
public static void damage(Player player, Entity victim, double damage) { 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) { @Deprecated
if ((paramLivingEntity2.hasMetadata("NPC")) || (paramLivingEntity1.hasMetadata("NPC"))) { public static void dmg(LivingEntity attacker, LivingEntity victim, double damage) {
return; attacker.damage(damage, victim);
}
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;
}
} }
} }

View File

@ -4,19 +4,11 @@ import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile; import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent;
@Deprecated
public class GetDamager { public class GetDamager {
public static Player get(EntityDamageByEntityEvent e) { public static Player get(EntityDamageByEntityEvent e) {
Player p = null; return DamageUtils.getAttackerInDamageEvent(e);
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;
} }
} }

View File

@ -1,22 +1,13 @@
package me.skymc.taboolib.damage; package me.skymc.taboolib.damage;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityDeathEvent;
@Deprecated
public class GetKiller { public class GetKiller {
public static Player get(EntityDeathEvent e) { public static Player get(EntityDeathEvent e) {
Player p = null; return e.getEntity().getKiller();
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;
} }
} }

View File

@ -18,7 +18,7 @@ public class VectorUtils {
/** /**
* 物品丢弃 * 物品丢弃
* * <p>
* 常用参数 * 常用参数
* itemDrop(player, itemStack, 0.2, 0.5) * itemDrop(player, itemStack, 0.2, 0.5)
* *
@ -57,7 +57,7 @@ public class VectorUtils {
/** /**
* 生物抛射 * 生物抛射
* * <p>
* 常用参数 * 常用参数
* entityPush(entity, location, 15) * entityPush(entity, location, 15)
* *
@ -69,17 +69,17 @@ public class VectorUtils {
Location from = entity.getLocation(); Location from = entity.getLocation();
Vector test = to.clone().subtract(from).toVector(); 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 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) { if (distance == 0.0D) {
return; return;
} }
if (launchAngle == null) { if (launchAngle == null) {
launchAngle = Math.atan((40.0D * elevation + Math.pow(velocity, 2.0D)) / (40.0D * elevation + 2.0D * Math.pow(velocity, 2.0D))); 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.setY(Math.tan(launchAngle) * distance);
test = normalizeVector(test); test = normalizeVector(test);
@ -113,7 +113,7 @@ public class VectorUtils {
private static Double calculateLaunchAngle(Location from, Location to, double v, double elevation, double g) { private static Double calculateLaunchAngle(Location from, Location to, double v, double elevation, double g) {
Vector vector = from.clone().subtract(to).toVector(); 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 v2 = Math.pow(v, 2.0D);
double v4 = Math.pow(v, 4.0D); double v4 = Math.pow(v, 4.0D);
double check = g * (g * Math.pow(distance, 2.0D) + 2.0D * elevation * v2); 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; package me.skymc.taboolib.fileutils;
import ch.njol.util.Closeable; 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 com.ilummc.tlib.util.IO;
import me.skymc.taboolib.Main; import me.skymc.taboolib.Main;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import java.io.*; import java.io.*;
import java.net.HttpURLConnection;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
@ -133,13 +135,9 @@ public class FileUtils {
public static InputStream getResource(Plugin plugin, String filename) { public static InputStream getResource(Plugin plugin, String filename) {
try { try {
URL url = plugin.getClass().getClassLoader().getResource(filename); URL url = plugin.getClass().getClassLoader().getResource(filename);
if (url == null) {
return null;
} else {
URLConnection connection = url.openConnection(); URLConnection connection = url.openConnection();
connection.setUseCaches(false); connection.setUseCaches(false);
return connection.getInputStream(); return connection.getInputStream();
}
} catch (IOException ignored) { } catch (IOException ignored) {
return null; return null;
} }
@ -409,35 +407,38 @@ public class FileUtils {
/** /**
* 下载文件 * 下载文件
* *
* @param downloadURL 下载地址 * @param url 下载地址
* @param file 保存位置 * @param file 下载位置
* @param async 是否异步
*/ */
public static void download(String downloadURL, File file) { public static void download(String url, File file, boolean async) {
HttpURLConnection conn = null; EagletTask eagletTask = new EagletTask()
InputStream inputStream = null; .url(url)
FileOutputStream fos = null; .file(file)
try { .setThreads(8)
URL url = new URL(downloadURL); .setOnError(event -> {
conn = (HttpURLConnection) url.openConnection(); })
conn.setConnectTimeout(5 * 1000); .setOnConnected(event -> TLocale.Logger.info("UTIL.DOWNLOAD-CONNECTED", file.getName(), ProgressEvent.format(event.getContentLength())))
conn.setRequestProperty("User-Agent", "Mozilla/31.0 (compatible; MSIE 10.0; Windows NT; DigExt)"); .setOnProgress(event -> TLocale.Logger.info("UTIL.DOWNLOAD-PROGRESS", event.getSpeedFormatted(), event.getPercentageFormatted()))
.setOnComplete(event -> {
inputStream = conn.getInputStream(); if (event.isSuccess()) {
byte[] data = read(inputStream); TLocale.Logger.info("UTIL.DOWNLOAD-SUCCESS", file.getName());
} else {
fos = new FileOutputStream(createNewFile(file)); TLocale.Logger.error("UTIL.DOWNLOAD-FAILED", file.getName());
fos.write(data);
} catch (Exception ignored) {
} finally {
IOUtils.close(conn);
IOUtils.closeQuietly(fos);
IOUtils.closeQuietly(inputStream);
} }
}).start();
if (!async) {
eagletTask.waitUntil();
}
}
public static void download(String url, File file) {
download(url, file, false);
} }
@Deprecated @Deprecated
public static void download(String downloadURL, String filename, File saveDir) { public static void download(String url, String filename, File saveDir) {
download(downloadURL, new File(saveDir, filename)); download(url, new File(saveDir, filename));
} }
@Deprecated @Deprecated

View File

@ -4,13 +4,13 @@ import com.ilummc.tlib.resources.TLocale;
import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.PlaceholderAPI;
import me.skymc.taboolib.Main; import me.skymc.taboolib.Main;
import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.common.configuration.TConfiguration;
import me.skymc.taboolib.fileutils.ConfigUtils; import me.skymc.taboolib.fileutils.ConfigUtils;
import me.skymc.taboolib.itemnbtapi.NBTItem; import me.skymc.taboolib.itemnbtapi.NBTItem;
import me.skymc.taboolib.itemnbtapi.NBTList; import me.skymc.taboolib.itemnbtapi.NBTList;
import me.skymc.taboolib.itemnbtapi.NBTListCompound; import me.skymc.taboolib.itemnbtapi.NBTListCompound;
import me.skymc.taboolib.itemnbtapi.NBTType; import me.skymc.taboolib.itemnbtapi.NBTType;
import me.skymc.taboolib.other.NumberUtils; import me.skymc.taboolib.other.NumberUtils;
import me.skymc.taboolib.string.Language;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
@ -39,74 +39,59 @@ import java.util.stream.IntStream;
*/ */
public class ItemUtils { public class ItemUtils {
private static FileConfiguration itemdir = null;
private static FileConfiguration itemCache = null;
private static File finalItemsFolder; private static File finalItemsFolder;
private static FileConfiguration itemDir;
private static LinkedHashMap<String, String> itemlib = new LinkedHashMap<>(); 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> itemCaches = new LinkedHashMap<>();
private static LinkedHashMap<String, ItemStack> itemCachesFinal = new LinkedHashMap<>(); private static LinkedHashMap<String, ItemStack> itemCachesFinal = new LinkedHashMap<>();
public static FileConfiguration getItemdir() { public static void init() {
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() {
try { try {
reloadItemDir();
reloadItemName(); reloadItemName();
reloadItemCache(); reloadItemCache();
itemdir = YamlConfiguration.loadConfiguration(new File(Main.getInst().getConfig().getString("DATAURL.ITEMDIR")));
} catch (Exception e) { } catch (Exception e) {
TLocale.Logger.error("ITEM-UTILS.FAIL-LOAD-ITEMS", e.toString()); 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) { public static void loadItemsFile(File file, boolean finalFile) {
FileConfiguration conf = ConfigUtils.load(Main.getInst(), file); FileConfiguration conf = ConfigUtils.load(Main.getInst(), file);
for (String name : conf.getConfigurationSection("").getKeys(false)) { for (String name : conf.getConfigurationSection("").getKeys(false)) {
@ -120,33 +105,22 @@ public class ItemUtils {
} }
} }
public static void reloadItemCache() { // *********************************
itemCaches.clear(); //
itemCachesFinal.clear(); // API
loadItemsFile(getItemCacheFile(), false); //
// 创建固定物品库 // *********************************
finalItemsFolder = new File(Main.getInst().getDataFolder(), "FinalItems");
if (!finalItemsFolder.exists()) { public static boolean isExists(String name) {
finalItemsFolder.mkdir(); return itemCachesFinal.containsKey(name) || itemCaches.containsKey(name);
}
// 检查固定物品库中的物品
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 void reloadItemName() { public static ItemStack getCacheItem(String name) {
FileConfiguration conf = new Language("ITEM_NAME", Main.getInst(), true).getConfiguration(); return itemCachesFinal.containsKey(name) ? itemCachesFinal.get(name) : itemCaches.get(name);
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 File getItemCacheFile() { public static ItemStack getItemFromDir(String name) {
File itemCacheFile = new File(Main.getInst().getDataFolder(), "items.yml"); return itemDir != null ? itemDir.getItemStack("item." + name) : null;
if (!itemCacheFile.exists()) {
Main.getInst().saveResource("items.yml", true);
}
return itemCacheFile;
} }
public static String getCustomName(ItemStack item) { public static String getCustomName(ItemStack item) {
@ -154,19 +128,7 @@ public class ItemUtils {
return TLocale.asString("ITEM-UTILS.EMPTY-ITEM"); return TLocale.asString("ITEM-UTILS.EMPTY-ITEM");
} }
int data = item.getType().getMaxDurability() == 0 ? item.getDurability() : 0; 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); 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);
} }
public static ItemStack setName(ItemStack i, String n) { public static ItemStack setName(ItemStack i, String n) {
@ -176,7 +138,7 @@ public class ItemUtils {
return i; 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(); ItemMeta meta = i.getItemMeta();
meta.addEnchant(e, l, false); meta.addEnchant(e, l, false);
i.setItemMeta(meta); i.setItemMeta(meta);
@ -203,10 +165,7 @@ public class ItemUtils {
} }
public static String asString(String args, Player placeholderPlayer) { public static String asString(String args, Player placeholderPlayer) {
if (placeholderPlayer == null) { return placeholderPlayer == null ? args.replace("&", "§") : PlaceholderAPI.setPlaceholders(placeholderPlayer, args.replace("&", "§"));
return args.replace("&", "§");
}
return PlaceholderAPI.setPlaceholders(placeholderPlayer, args.replace("&", "§"));
} }
public static List<String> asString(List<String> args, Player placeholderPlayer) { public static List<String> asString(List<String> args, Player placeholderPlayer) {
@ -281,58 +240,30 @@ public class ItemUtils {
} }
} }
/** 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 a 关键字
*/
public static boolean hasLore(ItemStack i, String a) { public static boolean hasLore(ItemStack i, String a) {
return isLored(i) && i.getItemMeta().getLore().toString().contains(a); return isLored(i) && i.getItemMeta().getLore().toString().contains(a);
} }
/**
* 如果已描述
*
* @param i
* @return
*/
public static boolean isLored(ItemStack i) { public static boolean isLored(ItemStack i) {
return i != null && i.getItemMeta() != null && i.getItemMeta().getLore() != null; return i != null && i.getItemMeta() != null && i.getItemMeta().getLore() != null;
} }
/**
* 如果已命名
*
* @param i
* @return
*/
public static boolean isNamed(ItemStack i) { public static boolean isNamed(ItemStack i) {
return i != null && i.getItemMeta() != null && i.getItemMeta().getDisplayName() != null; return i != null && i.getItemMeta() != null && i.getItemMeta().getDisplayName() != null;
} }
/** public static ItemStack addLore(ItemStack is, String line) {
* 添加描述
*
* @param is 物品
* @param lore 描述
*/
public static ItemStack addLore(ItemStack is, String lore) {
ItemMeta meta = is.getItemMeta(); ItemMeta meta = is.getItemMeta();
List<String> lore = meta.hasLore() ? meta.getLore() : Collections.emptyList();
List<String> _lore = meta.hasLore() ? meta.getLore() : Collections.emptyList(); lore.add(TLocale.Translate.setColored(line));
_lore.add(lore.replaceAll("&", "§"));
is.setItemMeta(meta); is.setItemMeta(meta);
return is; return is;
} }
/**
* 移除描述
*
* @param is 物品
* @param line 行数
*/
public static ItemStack delLore(ItemStack is, int line) { public static ItemStack delLore(ItemStack is, int line) {
ItemMeta meta = is.getItemMeta(); ItemMeta meta = is.getItemMeta();
if (meta.hasLore()) { if (meta.hasLore()) {
@ -346,40 +277,7 @@ public class ItemUtils {
return is; return is;
} }
/** public static ItemStack replaceLore(ItemStack i, String l1, String l2) {
* 获取介绍所在行数
*
* @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) {
if (!isLored(i)) { if (!isLored(i)) {
return i; return i;
} else { } else {
@ -392,6 +290,16 @@ public class ItemUtils {
return i; 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) { public static ItemStack loadItem(FileConfiguration f, String s) {
return loadItem(f, s, null); return loadItem(f, s, null);
} }
@ -552,6 +460,62 @@ public class ItemUtils {
return nbt; 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 @Deprecated
public static void putO(ItemStack item, Inventory inv, int i) { public static void putO(ItemStack item, Inventory inv, int i) {
inv.setItem(i, item); inv.setItem(i, item);

View File

@ -3,8 +3,10 @@ package me.skymc.taboolib.inventory.builder;
import com.ilummc.tlib.resources.TLocale; import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.string.ArrayUtils; import me.skymc.taboolib.string.ArrayUtils;
import org.bukkit.Bukkit;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.banner.Pattern; import org.bukkit.block.banner.Pattern;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
@ -20,7 +22,7 @@ import java.util.List;
/** /**
* @Author sky * @Author sky
* @Since 2018-08-22 11:37 * @Since 2018-08-22 11:37
* @BuilderVersion 1.0 * @BuilderVersion 1.1
*/ */
public class ItemBuilder { public class ItemBuilder {
@ -40,6 +42,11 @@ public class ItemBuilder {
itemMeta = itemStack.getItemMeta(); itemMeta = itemStack.getItemMeta();
} }
public ItemBuilder(OfflinePlayer player) {
this(Material.SKULL_ITEM, 1, 3);
this.skullOwner(player.getName());
}
public ItemBuilder material(int id) { public ItemBuilder material(int id) {
itemStack.setType(Material.getMaterial(id)); itemStack.setType(Material.getMaterial(id));
return this; return this;
@ -147,6 +154,13 @@ public class ItemBuilder {
return this; return this;
} }
public ItemBuilder skullOwner(String name) {
if (itemMeta instanceof SkullMeta) {
((SkullMeta) itemMeta).setOwner(name);
}
return this;
}
public ItemBuilder unbreakable(boolean value) { public ItemBuilder unbreakable(boolean value) {
if (TabooLib.getVersionNumber() >= 12000) { if (TabooLib.getVersionNumber() >= 12000) {
itemMeta.setUnbreakable(value); itemMeta.setUnbreakable(value);
@ -173,4 +187,14 @@ public class ItemBuilder {
} }
return buildItem; 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 com.google.common.base.Preconditions;
import me.skymc.taboolib.Main; import me.skymc.taboolib.Main;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.packet.PacketUtils; import me.skymc.taboolib.packet.PacketUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -132,8 +133,11 @@ public class TagDataHandler implements Listener {
entryTeam.addEntry(playerData.getNameDisplay()); entryTeam.addEntry(playerData.getNameDisplay());
entryTeam.setPrefix(playerData.getPrefix()); entryTeam.setPrefix(playerData.getPrefix());
entryTeam.setSuffix(playerData.getSuffix()); entryTeam.setSuffix(playerData.getSuffix());
// 傻逼 BedWarsRel 我草你妈的
if (TabooLib.instance().getConfig().getBoolean("TABLIST-AUTO-CLEAN-TEAM", true)) {
TagUtils.cleanEmptyTeamInScoreboard(scoreboard); TagUtils.cleanEmptyTeamInScoreboard(scoreboard);
} }
}
private void cancelPlayerVariable(Player player, TagPlayerData playerData) { private void cancelPlayerVariable(Player player, TagPlayerData playerData) {
if (playerData == null) { if (playerData == null) {
@ -142,9 +146,12 @@ public class TagDataHandler implements Listener {
for (Player online : Bukkit.getOnlinePlayers()) { for (Player online : Bukkit.getOnlinePlayers()) {
Scoreboard scoreboard = TagUtils.getScoreboardComputeIfAbsent(player); Scoreboard scoreboard = TagUtils.getScoreboardComputeIfAbsent(player);
TagUtils.cleanEntryInScoreboard(scoreboard, playerData.getNameDisplay()); TagUtils.cleanEntryInScoreboard(scoreboard, playerData.getNameDisplay());
// 傻逼 BedWarsRel 我草你妈的
if (TabooLib.instance().getConfig().getBoolean("TABLIST-AUTO-CLEAN-TEAM", true)) {
TagUtils.cleanEmptyTeamInScoreboard(scoreboard); TagUtils.cleanEmptyTeamInScoreboard(scoreboard);
} }
} }
}
// ********************************* // *********************************
// //

View File

@ -4,33 +4,30 @@ import com.ilummc.tlib.bungee.api.chat.*;
import com.ilummc.tlib.bungee.chat.ComponentSerializer; import com.ilummc.tlib.bungee.chat.ComponentSerializer;
import com.ilummc.tlib.logger.TLogger; import com.ilummc.tlib.logger.TLogger;
import com.ilummc.tlib.resources.TLocale; import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.inventory.ItemUtils;
import me.skymc.taboolib.methods.ReflectionUtils; import me.skymc.taboolib.methods.ReflectionUtils;
import me.skymc.taboolib.nms.NMSUtils; import me.skymc.taboolib.nms.NMSUtils;
import me.skymc.taboolib.other.NumberUtils;
import me.skymc.taboolib.string.ArrayUtils; import me.skymc.taboolib.string.ArrayUtils;
import me.skymc.taboolib.string.VariableFormatter;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.lang.reflect.Array;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.stream.Collectors;
/** /**
* @Author sky * @Author sky
* @Since 2018-05-26 14:42json * @Since 2018-05-26 14:42json
* @BuilderLevel 1.2
*/ */
public class TellrawJson { public class TellrawJson {
private BaseComponent[] components = TextComponent.fromLegacyText(""); private List<BaseComponent> components = new ArrayList<>();
private final Class<?> craftItemStackClazz = NMSUtils.getOBCClass("inventory.CraftItemStack"); private List<BaseComponent> componentsLatest = new ArrayList<>();
private final Class<?> nmsItemStackClazz = NMSUtils.getNMSClass("ItemStack"); private static final Class<?> craftItemStackClazz = NMSUtils.getOBCClass("inventory.CraftItemStack");
private final Class<?> nbtTagCompoundClazz = NMSUtils.getNMSClass("NBTTagCompound"); private static final Class<?> nmsItemStackClazz = NMSUtils.getNMSClass("ItemStack");
private final String INVALID_ITEM = "{id:stone,tag:{display:{Name:§c* Invalid ItemStack *}}}"; private static final Class<?> nbtTagCompoundClazz = NMSUtils.getNMSClass("NBTTagCompound");
private static final String INVALID_ITEM = "{id:stone,tag:{display:{Name:§c* Invalid ItemStack *}}}";
TellrawJson() { TellrawJson() {
} }
@ -39,12 +36,16 @@ public class TellrawJson {
return new TellrawJson(); return new TellrawJson();
} }
public void send(CommandSender sender) {
TLocale.Tellraw.send(sender, toRawMessage());
}
public String toRawMessage() { public String toRawMessage() {
return ComponentSerializer.toString(components); return ComponentSerializer.toString(getComponentsAll());
} }
public String toLegacyText() { public String toLegacyText() {
return TextComponent.toLegacyText(components); return TextComponent.toLegacyText(getComponentsAll());
} }
public TellrawJson newLine() { public TellrawJson newLine() {
@ -52,50 +53,51 @@ public class TellrawJson {
} }
public TellrawJson append(String text) { 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; return this;
} }
public TellrawJson append(TellrawJson json) { public TellrawJson append(TellrawJson json) {
BaseComponent[] newArray = new BaseComponent[components.length + json.components.length]; appendComponents();
System.arraycopy(components, 0, newArray, 0, components.length); componentsLatest.addAll(ArrayUtils.asList(json.getComponentsAll()));
System.arraycopy(json.components, 0, newArray, components.length, json.components.length);
components = newArray;
return this; return this;
} }
public TellrawJson hoverText(String text) { 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; return this;
} }
public TellrawJson hoverItem(ItemStack itemStack) { 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; return this;
} }
public TellrawJson clickCommand(String command) { 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; return this;
} }
public TellrawJson clickSuggest(String command) { 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; return this;
} }
public TellrawJson clickOpenURL(String url) { 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; return this;
} }
public TellrawJson clickChangePage(int page) { 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; return this;
} }
public void send(CommandSender sender) { public BaseComponent[] getComponentsAll() {
TLocale.Tellraw.send(sender, toRawMessage()); 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) { public String getItemComponent(ItemStack itemStack) {
@ -106,7 +108,7 @@ public class TellrawJson {
Object nmsItemStackObj = asNMSCopyMethod.invoke(null, itemStack); Object nmsItemStackObj = asNMSCopyMethod.invoke(null, itemStack);
return saveNmsItemStackMethod.invoke(nmsItemStackObj, nmsNbtTagCompoundObj).toString(); return saveNmsItemStackMethod.invoke(nmsItemStackObj, nmsNbtTagCompoundObj).toString();
} catch (Throwable t) { } 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; return INVALID_ITEM;
} }
} }
@ -117,12 +119,17 @@ public class TellrawJson {
// //
// ********************************* // *********************************
private BaseComponent getLatestComponent() { private List<BaseComponent> getLatestComponent() {
return components[components.length - 1]; return componentsLatest;
} }
private void setLatestComponent(BaseComponent component) { private void setLatestComponent(BaseComponent... component) {
components[components.length - 1] = 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) { 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; package me.skymc.taboolib.listener;
import com.ilummc.tlib.logger.TLogger;
import me.skymc.taboolib.Main; import me.skymc.taboolib.Main;
import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.database.PlayerDataManager; import me.skymc.taboolib.database.PlayerDataManager;
import me.skymc.taboolib.inventory.ItemUtils;
import me.skymc.taboolib.itemnbtapi.NBTItem; import me.skymc.taboolib.itemnbtapi.NBTItem;
import me.skymc.taboolib.json.tellraw.TellrawJson;
import me.skymc.taboolib.message.MsgUtils; import me.skymc.taboolib.message.MsgUtils;
import me.skymc.taboolib.permission.PermissionUtils; import me.skymc.taboolib.permission.PermissionUtils;
import me.skymc.taboolib.playerdata.DataUtils; 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.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.server.ServerCommandEvent; import org.bukkit.event.server.ServerCommandEvent;
/**
* @author sky
*/
@TListener @TListener
public class ListenerPlayerCommand implements Listener { public class ListenerPlayerCommand implements Listener {
@EventHandler @EventHandler
public void cmd(ServerCommandEvent e) { public void cmd(ServerCommandEvent e) {
if ("savefile".equals(e.getCommand())) { if (e.getCommand().equalsIgnoreCase("saveFiles")) {
if (TabooLib.getVerint() > 10700) { if (TabooLib.getVerint() > 10700) {
e.setCancelled(true); e.setCancelled(true);
} }
Bukkit.getScheduler().runTask(Main.getInst(), DataUtils::saveAllCaches); Bukkit.getScheduler().runTask(Main.getInst(), DataUtils::saveAllCaches);
Bukkit.getScheduler().runTask(Main.getInst(), () -> PlayerDataManager.saveAllCaches(true, false)); 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") @SuppressWarnings("deprecation")
@EventHandler @EventHandler
public void cmd(PlayerCommandPreprocessEvent e) { 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); e.setCancelled(true);
NBTItem nbt = new NBTItem(e.getPlayer().getItemInHand());
NBTItem nbti = new NBTItem(e.getPlayer().getItemInHand()); nbt.setInteger("Unbreakable", 1);
nbti.setInteger("Unbreakable", 1); e.getPlayer().setItemInHand(nbt.getItem());
e.getPlayer().setItemInHand(nbti.getItem());
MsgUtils.send(e.getPlayer(), "Success!"); 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; package me.skymc.taboolib.listener;
import com.ilummc.tlib.TLib;
import com.ilummc.tlib.inject.TConfigWatcher;
import com.ilummc.tlib.resources.TLocale; import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.Main; 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.MysqlUtils;
import me.skymc.taboolib.mysql.hikari.HikariHandler;
import me.skymc.taboolib.mysql.protect.MySQLConnection; import me.skymc.taboolib.mysql.protect.MySQLConnection;
import me.skymc.taboolib.timecycle.TimeCycleManager; import me.skymc.taboolib.timecycle.TimeCycleManager;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -11,33 +15,48 @@ import org.bukkit.event.Listener;
import org.bukkit.event.server.PluginDisableEvent; import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional;
/**
* @author sky
*/
@TListener @TListener
public class ListenerPluginDisable implements Listener { public class ListenerPluginDisable implements Listener {
@EventHandler @EventHandler
public void disable(PluginDisableEvent e) { public void disable(PluginDisableEvent e) {
TabooLib.debug("Plugin \"" + e.getPlugin().getName() + "\" was disabled.");
// 注销时间周期 // 注销时间周期
TimeCycleManager.cancel(e.getPlugin()); 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) { for (MySQLConnection conn : MysqlUtils.CONNECTIONS) {
if (conn.getPlugin().equals(e.getPlugin())) { if (conn.getPlugin().equals(e.getPlugin())) {
conns.add(conn); connection.add(conn);
MysqlUtils.CONNECTIONS.remove(conn); MysqlUtils.CONNECTIONS.remove(conn);
} }
} }
// 异步注销 // 异步注销
BukkitRunnable runnable = new BukkitRunnable() { BukkitRunnable runnable = new BukkitRunnable() {
@Override @Override
public void run() { public void run() {
int i = 0; int i = 0;
for (MySQLConnection conn : conns) { for (MySQLConnection conn : connection) {
conn.setFallReconnection(false); conn.setFallReconnection(false);
conn.closeConnection(); conn.closeConnection();
i++; i++;
@ -47,7 +66,6 @@ public class ListenerPluginDisable implements Listener {
} }
} }
}; };
// 如果插件关闭 // 如果插件关闭
try { try {
runnable.runTaskLater(Main.getInst(), 40); runnable.runTaskLater(Main.getInst(), 40);

View File

@ -2,7 +2,8 @@ package me.skymc.taboolib.listener;
import com.ilummc.tlib.util.Strings; import com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.TabooLib; 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.Bukkit;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
@ -28,7 +29,6 @@ public class TListenerHandler implements Listener {
*/ */
public static void setupListeners() { public static void setupListeners() {
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
if (plugin.equals(TabooLib.instance()) || plugin.getDescription().getDepend().contains("TabooLib")) {
try { try {
setupListener(plugin); setupListener(plugin);
} catch (Exception e) { } catch (Exception e) {
@ -36,7 +36,6 @@ public class TListenerHandler implements Listener {
} }
} }
} }
}
/** /**
* 初始化插件的所有监听器 * 初始化插件的所有监听器
@ -45,9 +44,9 @@ public class TListenerHandler implements Listener {
* @param plugin 插件 * @param plugin 插件
*/ */
public static void setupListener(Plugin plugin) { public static void setupListener(Plugin plugin) {
List<Class> classes = FileUtils.getClasses(plugin); TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> {
for (Class<?> pluginClass : classes) { for (Class<?> pluginClass : classes) {
if (Listener.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TListener.class)) { if (org.bukkit.event.Listener.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TListener.class)) {
try { try {
TListener tListener = pluginClass.getAnnotation(TListener.class); TListener tListener = pluginClass.getAnnotation(TListener.class);
// 检查注册条件 // 检查注册条件
@ -57,13 +56,15 @@ public class TListenerHandler implements Listener {
} }
} }
// 实例化监听器 // 实例化监听器
Listener listener = plugin.getClass().equals(pluginClass) ? (Listener) plugin : (Listener) pluginClass.newInstance(); Listener listener = plugin.getClass().equals(pluginClass) ? (Listener) plugin : (Listener) ReflectionUtils.instantiateObject(pluginClass);
listeners.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(listener); listeners.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(listener);
TabooLib.debug("Listener " + listener.getClass().getSimpleName() + " setup successfully. (" + plugin.getName() + ")");
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); TabooLib.debug("Listener setup failed: " + e.toString());
} }
} }
} }
});
} }
/** /**
@ -113,6 +114,7 @@ public class TListenerHandler implements Listener {
} }
// 注册监听 // 注册监听
Bukkit.getPluginManager().registerEvents(listener, plugin); 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 @EventHandler
public void onPluginEnable(PluginEnableEvent e) { public void onPluginEnable(PluginEnableEvent e) {
try { try {
@ -170,14 +176,4 @@ public class TListenerHandler implements Listener {
} catch (Exception ignored) { } 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.command.CommandSender;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@Deprecated
public class MsgUtils { public class MsgUtils {
public static void send(CommandSender sender, String s) { public static void send(CommandSender sender, String s) {

View File

@ -19,7 +19,7 @@ import java.util.Map;
* <li>Don't claim this class as your own * <li>Don't claim this class as your own
* <li>Don't remove this disclaimer * <li>Don't remove this disclaimer
* </ul> * </ul>
* <p> *
* <i>It would be nice if you provide credit to me if you use this class in a published project</i> * <i>It would be nice if you provide credit to me if you use this class in a published project</i>
* *
* @author DarkBlade12 * @author DarkBlade12
@ -27,7 +27,8 @@ import java.util.Map;
*/ */
public final class ReflectionUtils { public final class ReflectionUtils {
// Prevent accidental construction // Prevent accidental construction
private ReflectionUtils() {} private ReflectionUtils() {
}
/** /**
* Returns the constructor of a given class with the given parameter types * Returns the constructor of a given class with the given parameter types
@ -42,10 +43,11 @@ public final class ReflectionUtils {
*/ */
public static Constructor<?> getConstructor(Class<?> clazz, Class<?>... parameterTypes) throws NoSuchMethodException { public static Constructor<?> getConstructor(Class<?> clazz, Class<?>... parameterTypes) throws NoSuchMethodException {
Class<?>[] primitiveTypes = DataType.getPrimitive(parameterTypes); Class<?>[] primitiveTypes = DataType.getPrimitive(parameterTypes);
for (Constructor<?> constructor : clazz.getConstructors()) { for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
if (!DataType.compare(DataType.getPrimitive(constructor.getParameterTypes()), primitiveTypes)) { if (!DataType.compare(DataType.getPrimitive(constructor.getParameterTypes()), primitiveTypes)) {
continue; continue;
} }
constructor.setAccessible(true);
return constructor; return constructor;
} }
throw new NoSuchMethodException("There is no such constructor in this class with the specified parameter types"); throw new NoSuchMethodException("There is no such constructor in this class with the specified parameter types");
@ -114,10 +116,11 @@ public final class ReflectionUtils {
*/ */
public static Method getMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) throws NoSuchMethodException { public static Method getMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) throws NoSuchMethodException {
Class<?>[] primitiveTypes = DataType.getPrimitive(parameterTypes); Class<?>[] primitiveTypes = DataType.getPrimitive(parameterTypes);
for (Method method : clazz.getMethods()) { for (Method method : clazz.getDeclaredMethods()) {
if (!method.getName().equals(methodName) || !DataType.compare(DataType.getPrimitive(method.getParameterTypes()), primitiveTypes)) { if (!method.getName().equals(methodName) || !DataType.compare(DataType.getPrimitive(method.getParameterTypes()), primitiveTypes)) {
continue; continue;
} }
method.setAccessible(true);
return method; return method;
} }
throw new NoSuchMethodException("There is no such method in this class with the specified name and parameter types"); throw new NoSuchMethodException("There is no such method in this class with the specified name and parameter types");

View File

@ -29,6 +29,16 @@ public class SQLColumn {
this(columnType, 0, 0, columnName, null); this(columnType, 0, 0, columnName, null);
} }
/**
* 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); * new SQLColumn(SQLColumnType.TEXT, "username", SQLColumnOption.PRIMARY_KEY, SQLColumnOption.AUTO_INCREMENT);
@ -99,25 +109,25 @@ public class SQLColumn {
for (SQLColumnOption options : columnOptions) { for (SQLColumnOption options : columnOptions) {
switch (options) { switch (options) {
case NOTNULL: case NOTNULL:
builder.append(" not null"); builder.append(" NOT NULL");
break; break;
case PRIMARY_KEY: case PRIMARY_KEY:
builder.append(" primary key"); builder.append(" PRIMARY KEY");
break; break;
case AUTO_INCREMENT: case AUTO_INCREMENT:
builder.append(" auto_increment"); builder.append(" AUTO_INCREMENT");
break; break;
case UNIQUE_KEY: case UNIQUE_KEY:
builder.append(" unique key"); builder.append(" UNIQUE KEY");
break; break;
default: default:
} }
} }
if (defaultValue != null) { if (defaultValue != null) {
if (defaultValue instanceof String) { if (defaultValue instanceof String) {
builder.append(" default '").append(defaultValue).append("'"); builder.append(" DEFAULT '").append(defaultValue).append("'");
} else { } else {
builder.append(" default ").append(defaultValue); builder.append(" DEFAULT ").append(defaultValue);
} }
} }
return builder.toString(); 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.configuration.ConfigurationSection;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import java.text.MessageFormat;
import java.util.Objects; import java.util.Objects;
/** /**
@ -19,18 +18,28 @@ public class SQLHost {
private String password; private String password;
private String database; private String database;
private Plugin plugin; private Plugin plugin;
private boolean autoClose;
public SQLHost(ConfigurationSection section, Plugin plugin) { 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); 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) { 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.host = host;
this.user = user; this.user = user;
this.port = port; this.port = port;
this.password = password; this.password = password;
this.database = database; this.database = database;
this.plugin = plugin; this.plugin = plugin;
this.autoClose = false;
} }
public String getHost() { public String getHost() {
@ -57,6 +66,10 @@ public class SQLHost {
return plugin; return plugin;
} }
public boolean isAutoClose() {
return autoClose;
}
public String getConnectionUrl() { public String getConnectionUrl() {
return Strings.replaceWithOrder("jdbc:mysql://{0}:{1}/{2}?characterEncoding=utf-8&useSSL=false", this.host, this.port, this.database); 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; return false;
} }
SQLHost sqlHost = (SQLHost) o; 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(getUser(), sqlHost.getUser()) &&
Objects.equals(getPort(), sqlHost.getPort()) && Objects.equals(getPort(), sqlHost.getPort()) &&
Objects.equals(getPassword(), sqlHost.getPassword()) && Objects.equals(getPassword(), sqlHost.getPassword()) &&
Objects.equals(getDatabase(), sqlHost.getDatabase()); Objects.equals(getDatabase(), sqlHost.getDatabase()) &&
Objects.equals(getPlugin(), sqlHost.getPlugin());
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(getHost(), getUser(), getPort(), getPassword(), getDatabase()); return Objects.hash(getHost(), getUser(), getPort(), getPassword(), getDatabase(), getPlugin(), autoClose);
} }
@Override @Override
@ -95,6 +110,7 @@ public class SQLHost {
", password='" + password + '\'' + ", password='" + password + '\'' +
", database='" + database + '\'' + ", database='" + database + '\'' +
", plugin=" + plugin + ", plugin=" + plugin +
", autoClose=" + autoClose +
'}'; '}';
} }
} }

View File

@ -26,11 +26,7 @@ public class SQLTable {
} }
public SQLTable addColumn(SQLColumn sqlColumn) { public SQLTable addColumn(SQLColumn sqlColumn) {
if (columns == null) { columns = columns == null ? new SQLColumn[] {sqlColumn} : ArrayUtils.arrayAppend(columns, sqlColumn);
columns = new SQLColumn[] {sqlColumn};
} else {
columns = ArrayUtils.arrayAppend(columns, sqlColumn);
}
return this; return this;
} }
@ -52,6 +48,22 @@ public class SQLTable {
return Strings.replaceWithOrder("truncate table `{0}`", tableName); 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) { public RunnableUpdate executeUpdate(String query) {
return new RunnableUpdate(query); return new RunnableUpdate(query);
} }

View File

@ -6,10 +6,8 @@ import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariDataSource;
import me.skymc.taboolib.Main; import me.skymc.taboolib.Main;
import me.skymc.taboolib.fileutils.ConfigUtils; import me.skymc.taboolib.fileutils.ConfigUtils;
import me.skymc.taboolib.fileutils.FileUtils;
import me.skymc.taboolib.mysql.builder.SQLHost; import me.skymc.taboolib.mysql.builder.SQLHost;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -91,4 +89,18 @@ public class HikariHandler {
} }
return config; 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.text.DecimalFormat;
import java.util.Random; import java.util.Random;
/**
* @author sky
*/
public class NumberUtils { public class NumberUtils {
private static Random random = new Random(); 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 @Deprecated
public static Random getRand() { public static Random getRand() {
return random; return random;

View File

@ -30,7 +30,7 @@ public class PluginUtils {
} }
public static File getPluginFile(Plugin plugin) { 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")) { if (pluginFile.getName().endsWith(".jar")) {
try { try {
PluginDescriptionFile desc = Main.getInst().getPluginLoader().getPluginDescription(pluginFile); PluginDescriptionFile desc = Main.getInst().getPluginLoader().getPluginDescription(pluginFile);
@ -44,6 +44,21 @@ public class PluginUtils {
return null; 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) { public static void enable(Plugin plugin) {
if (plugin != null && !plugin.isEnabled()) { if (plugin != null && !plugin.isEnabled()) {
Bukkit.getPluginManager().enablePlugin(plugin); Bukkit.getPluginManager().enablePlugin(plugin);

View File

@ -1,36 +1,19 @@
package me.skymc.taboolib.skull; package me.skymc.taboolib.skull;
import org.bukkit.Bukkit; import me.skymc.taboolib.inventory.builder.ItemBuilder;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
@Deprecated
public class SkullUtils { public class SkullUtils {
public static ItemStack getItme(OfflinePlayer p) { public static ItemStack getItme(OfflinePlayer p) {
SkullMeta s = (SkullMeta) Bukkit.getItemFactory().getItemMeta(Material.SKULL_ITEM); return new ItemBuilder(p).build();
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) { public static ItemStack getOnlineItem(OfflinePlayer p) {
if (p.isOnline()) return p.isOnline() ? new ItemBuilder(p).build() : new ItemStack(Material.SKULL_ITEM);
{
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);
} }
} }

View File

@ -2,9 +2,13 @@ package me.skymc.taboolib.socket;
import com.ilummc.tlib.resources.TLocale; import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.commands.builder.SimpleCommandBuilder;
import me.skymc.taboolib.other.NumberUtils; import me.skymc.taboolib.other.NumberUtils;
import me.skymc.taboolib.socket.packet.Packet; import me.skymc.taboolib.socket.packet.Packet;
import me.skymc.taboolib.socket.packet.PacketSerializer; 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 org.bukkit.Bukkit;
import java.io.*; import java.io.*;
@ -83,6 +87,23 @@ public class TabooLibClient {
TLocale.sendToConsole("COMMUNICATION.FAILED-READING-PACKET", e.getMessage()); 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; package me.skymc.taboolib.socket;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.other.NumberUtils; import me.skymc.taboolib.other.NumberUtils;
import me.skymc.taboolib.socket.packet.Packet; import me.skymc.taboolib.socket.packet.Packet;
import me.skymc.taboolib.socket.packet.PacketSerializer; import me.skymc.taboolib.socket.packet.PacketSerializer;
@ -55,9 +56,13 @@ public class TabooLibServer {
/* /*
检测无效的客户端连接如果超过 5000 毫秒没有收到客户端的回应上一次心跳包的回应则注销链接 检测无效的客户端连接如果超过 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); }, 0, 1, TimeUnit.SECONDS);
/*
异步接收连接请求
*/
Executors.newSingleThreadScheduledExecutor().execute(() -> {
while (true) { while (true) {
try { try {
Socket socket = server.accept(); Socket socket = server.accept();
@ -69,6 +74,7 @@ public class TabooLibServer {
println("Client accept failed: " + e.toString()); println("Client accept failed: " + e.toString());
} }
} }
});
} }
public static void sendPacket(Packet packet) { public static void sendPacket(Packet packet) {
@ -76,7 +82,6 @@ public class TabooLibServer {
} }
public static void sendPacket(String origin) { public static void sendPacket(String origin) {
println("Packet sending: " + origin + ", online: " + client.size());
// 在服务端尝试解析动作并运行 // 在服务端尝试解析动作并运行
Optional.ofNullable(PacketSerializer.unSerialize(origin)).ifPresent(Packet::readOnServer); Optional.ofNullable(PacketSerializer.unSerialize(origin)).ifPresent(Packet::readOnServer);
// 将动作发送至所有客户端 // 将动作发送至所有客户端
@ -90,10 +95,9 @@ public class TabooLibServer {
} }
public static void println(Object obj) { 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) { public static Optional<Map.Entry<Integer, ClientConnection>> getConnection(int port) {
return client.entrySet().stream().filter(entry -> entry.getKey().equals(port)).findFirst(); 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 me.skymc.taboolib.fileutils.FileUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -31,6 +32,43 @@ public class PacketParser {
try { try {
Packet packetObject = (Packet) packetFind.get().getConstructor(Integer.TYPE).newInstance(json.get("port").getAsInt()); Packet packetObject = (Packet) packetFind.get().getConstructor(Integer.TYPE).newInstance(json.get("port").getAsInt());
packetObject.unSerialize(json); 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; return packetObject;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -3,22 +3,88 @@ package me.skymc.taboolib.socket.packet;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException; 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 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 * @Author sky
* @Since 2018-08-22 23:32 * @Since 2018-08-22 23:32
*/ */
public class PacketSerializer { @TListener
public class PacketSerializer implements Listener {
private static PacketParser parser = new PacketParser(); 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) { public static String serialize(Packet packet) {
JsonObject json = new JsonObject(); JsonObject json = new JsonObject();
packet.serialize(json);
json.addProperty("uid", packet.getUid()); json.addProperty("uid", packet.getUid());
json.addProperty("port", packet.getPort()); json.addProperty("port", packet.getPort());
json.addProperty("packet", packet.getClass().getAnnotation(PacketType.class).name()); 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(); 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.TabooLibClient;
import me.skymc.taboolib.socket.packet.Packet; import me.skymc.taboolib.socket.packet.Packet;
import me.skymc.taboolib.socket.packet.PacketType; import me.skymc.taboolib.socket.packet.PacketType;
import org.bukkit.Bukkit;
/** /**
* @Author sky * @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.TabooLibServer;
import me.skymc.taboolib.socket.packet.Packet; import me.skymc.taboolib.socket.packet.Packet;
import me.skymc.taboolib.socket.packet.PacketType; import me.skymc.taboolib.socket.packet.PacketType;
import me.skymc.taboolib.socket.packet.PacketValue;
import org.bukkit.Bukkit;
/** /**
* @Author sky * @Author sky
@ -13,6 +15,7 @@ import me.skymc.taboolib.socket.packet.PacketType;
@PacketType(name = "message") @PacketType(name = "message")
public class PacketMessage extends Packet { public class PacketMessage extends Packet {
@PacketValue
private String message; private String message;
public PacketMessage(int port) { public PacketMessage(int port) {
@ -24,23 +27,18 @@ public class PacketMessage extends Packet {
this.message = message; this.message = message;
} }
public PacketMessage(String message) {
super(Bukkit.getPort());
this.message = message;
}
@Override @Override
public void readOnServer() { public void readOnServer() {
TabooLibServer.println(message); TabooLibServer.println(getPort() + ": " + message);
} }
@Override @Override
public void readOnClient() { public void readOnClient() {
TLocale.sendToConsole("COMMUNICATION.PACKET-MESSAGE", String.valueOf(getPort()), message); 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; package me.skymc.taboolib.socket.packet.impl;
import com.google.gson.JsonObject;
import com.ilummc.tlib.resources.TLocale; import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.socket.TabooLibServer; import me.skymc.taboolib.socket.TabooLibServer;
import me.skymc.taboolib.socket.packet.Packet; import me.skymc.taboolib.socket.packet.Packet;
import me.skymc.taboolib.socket.packet.PacketType; import me.skymc.taboolib.socket.packet.PacketType;
import me.skymc.taboolib.socket.packet.PacketValue;
/** /**
* @Author sky * @Author sky
@ -13,6 +13,7 @@ import me.skymc.taboolib.socket.packet.PacketType;
@PacketType(name = "quit") @PacketType(name = "quit")
public class PacketQuit extends Packet { public class PacketQuit extends Packet {
@PacketValue
private String message; private String message;
public PacketQuit(int port) { public PacketQuit(int port) {
@ -43,14 +44,4 @@ public class PacketQuit extends Packet {
public void readOnClient() { public void readOnClient() {
TLocale.sendToConsole("COMMUNICATION.CLIENT-QUITED", String.valueOf(getPort())); 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) { } catch (Exception e) {
TabooLibServer.println("Client running failed: " + e.toString()); 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 com.ilummc.tlib.util.Strings;
import javax.annotation.Nullable;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
@ -20,15 +19,21 @@ import java.util.stream.IntStream;
*/ */
public class ArrayUtils { public class ArrayUtils {
public static String arrayJoin(String[] args, int start) { public static <T> int indexOf(T[] array, T obj) {
return IntStream.range(start, args.length).mapToObj(i -> args[i] + " ").collect(Collectors.joining()).trim(); 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 @SafeVarargs
public static <T> List<T> asList(T... args) { public static <T> T[] asArray(T... args) {
List<T> list = new ArrayList<>(); return args;
Collections.addAll(list, args); }
return list;
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) { public static <T> T[] arrayAppend(T[] array, T obj) {
@ -88,6 +93,13 @@ public class ArrayUtils {
return firstElement == null ? def : obj; 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 // Deprecated

View File

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

View File

@ -1,32 +1,26 @@
package me.skymc.taboolib.update; package me.skymc.taboolib.update;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.ilummc.tlib.resources.TLocale; import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.Main; import me.skymc.taboolib.Main;
import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.fileutils.FileUtils; 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.Bukkit;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import java.io.File;
/** /**
* @author sky * @author sky
* @since 2018年2月23日 下午10:39:14 * @since 2018年2月23日 下午10:39:14
*/ */
public class UpdateTask { public class UpdateTask {
private static boolean haveUpdate = false;
private static double newVersion = 0; private static double newVersion = 0;
public static boolean isHaveUpdate() {
return haveUpdate;
}
public static double getNewVersion() {
return newVersion;
}
public UpdateTask() { public UpdateTask() {
new BukkitRunnable() { new BukkitRunnable() {
@ -35,34 +29,53 @@ public class UpdateTask {
if (!Main.getInst().getConfig().getBoolean("UPDATE-CHECK")) { if (!Main.getInst().getConfig().getBoolean("UPDATE-CHECK")) {
return; return;
} }
String value = FileUtils.getStringFromURL("https://api.github.com/repos/Bkm016/TabooLib/tags", null); String value = FileUtils.getStringFromURL("https://api.github.com/repos/Bkm016/TabooLib/tags", null);
if (value == null) { if (value == null) {
TLocale.Logger.error("UPDATETASK.VERSION-FAIL"); TLocale.Logger.error("UPDATETASK.VERSION-FAIL");
return; return;
} }
JsonElement json = new JsonParser().parse(value); JsonElement json = new JsonParser().parse(value);
if (json.isJsonArray()) { if (json.isJsonArray()) {
JsonObject latestObject = json.getAsJsonArray().get(0).getAsJsonObject(); newVersion = json.getAsJsonArray().get(0).getAsJsonObject().get("name").getAsDouble();
newVersion = latestObject.get("name").getAsDouble();
if (TabooLib.getPluginVersion() >= newVersion) { if (TabooLib.getPluginVersion() >= newVersion) {
TLocale.Logger.info("UPDATETASK.VERSION-LATEST"); TLocale.Logger.info("UPDATETASK.VERSION-LATEST");
} else { } else {
haveUpdate = true;
TLocale.Logger.info("UPDATETASK.VERSION-OUTDATED", String.valueOf(TabooLib.getPluginVersion()), String.valueOf(newVersion)); TLocale.Logger.info("UPDATETASK.VERSION-OUTDATED", String.valueOf(TabooLib.getPluginVersion()), String.valueOf(newVersion));
Bukkit.getScheduler().runTask(TabooLib.instance(), () -> updatePlugin(true));
new BukkitRunnable() {
@Override
public void run() {
if (Main.getInst().getConfig().getBoolean("UPDATE-DOWNLOAD", false)) {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "taboolib updatePlugin");
}
}
}.runTask(Main.getInst());
} }
} }
} }
}.runTaskTimerAsynchronously(Main.getInst(), 100, 20 * 60 * 60 * 6); }.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,22 +1,26 @@
package me.skymc.tlm.command; 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.TLM;
import me.skymc.tlm.command.sub.TLMInvCommand; import me.skymc.tlm.command.sub.TLMInvCommand;
import me.skymc.tlm.command.sub.TLMKitCommand; import me.skymc.tlm.command.sub.TLMKitCommand;
import me.skymc.tlm.command.sub.TLMListCommand; import me.skymc.tlm.command.sub.TLMListCommand;
import me.skymc.tlm.command.sub.TLMReloadCommand; import me.skymc.tlm.command.sub.TLMReloadCommand;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
/** /**
* @author sky * @author sky
* @since 2018年2月18日 上午12:02:08 * @since 2018年2月18日 上午12:02:08
*/ */
public class TLMCommands implements CommandExecutor { @Instantiable("TLMCommands")
public class TLMCommands {
@Override public TLMCommands() {
public boolean onCommand(CommandSender sender, Command arg1, String arg2, String[] args) { SimpleCommandBuilder.create("taboolibrarymodule", TabooLib.instance())
.aliases("tlm")
.permission("tlm.use")
.execute((sender, args) -> {
if (args.length == 0 || "help".equalsIgnoreCase(args[0])) { if (args.length == 0 || "help".equalsIgnoreCase(args[0])) {
if (sender.hasPermission("taboolib.admin")) { if (sender.hasPermission("taboolib.admin")) {
TLM.getInst().getLanguage().get("COMMAND-HELP").send(sender); TLM.getInst().getLanguage().get("COMMAND-HELP").send(sender);
@ -59,5 +63,6 @@ public class TLMCommands implements CommandExecutor {
TLM.getInst().getLanguage().get("COMMAND-ERROR").send(sender); TLM.getInst().getLanguage().get("COMMAND-ERROR").send(sender);
} }
return true; return true;
}).build();
} }
} }

View File

@ -13,16 +13,6 @@ DATAURL:
# 物品数据(来自 ItemSave 插件) # 物品数据(来自 ItemSave 插件)
ITEMDIR: 'plugins/Skript/scripts/config/item.yml' ITEMDIR: 'plugins/Skript/scripts/config/item.yml'
# 是否启用调试模式
# 启用后将收到来自其他插件的调试信息
DEBUG: false
# 网络连接测试地址
TEST-URL: 'aliyun.com'
# 下载依赖时启用的线程数
DOWNLOAD-POOL-SIZE: 4
# 语言文件相关设置 # 语言文件相关设置
LOCALE: LOCALE:
# 加载语言文件的顺序 # 加载语言文件的顺序
@ -34,9 +24,28 @@ LOCALE:
# 如果需要开启仍然可以在语言文件中加入 papi: true # 如果需要开启仍然可以在语言文件中加入 papi: true
USE_PAPI: false USE_PAPI: false
# 玩家列表TAB是否根据前缀排序 # 是否注入 PluginManager关闭后可能会导致部分功能出错。
# 启用后将会导致部分通过计分板获取玩家数据的插件出错BedwarsRel、SkyWars PLUGIN-INJECTOR:
TABLIST-SORT: false 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 UPDATE-CHECK: true
@ -62,6 +71,7 @@ ENABLE-UUID: false
HIDE-NOTIFY: true HIDE-NOTIFY: true
# 数据库信息 # 数据库信息
# 该功能在当前版本下无法使用,请勿启用
MYSQL: MYSQL:
# 是否启用数据库 # 是否启用数据库
ENABLE: false ENABLE: false

View File

@ -3,6 +3,9 @@ TLIB:
INJECTION-FAILED: INJECTION-FAILED:
- '注入失败' - '注入失败'
- '&c提前加载依赖于 TabooLib 的所有插件的相关功能' - '&c提前加载依赖于 TabooLib 的所有插件的相关功能'
INJECTION-DISABLED:
- '关闭注入'
- '&c提前加载依赖于 TabooLib 的所有插件的相关功能'
LOAD-FAIL-OFFLINE: LOAD-FAIL-OFFLINE:
- '**********************************************' - '**********************************************'
- '** TabooLib-{0} 无法在您的服务器上使用' - '** TabooLib-{0} 无法在您的服务器上使用'
@ -28,6 +31,7 @@ DEPENDENCY:
LIBRARY-LOAD-SUCCESS: ' {0} 请求的库文件 {1} 加载成功' LIBRARY-LOAD-SUCCESS: ' {0} 请求的库文件 {1} 加载成功'
LIBRARY-LOAD-FAIL: ' {0} 请求的库文件 {1} 加载失败' LIBRARY-LOAD-FAIL: ' {0} 请求的库文件 {1} 加载失败'
LOAD-COMPLETE: '依赖加载完成' LOAD-COMPLETE: '依赖加载完成'
LOAD-CLASSES: '&7缓存 &f{0} &7插件的 &f{1} &7个类耗时&f {2} &7毫秒.'
CONFIG: CONFIG:
LOAD-FAIL-NO-ANNOTATION: '插件 {0} 的配置类 {1} 加载失败:没有 @Config 注解' LOAD-FAIL-NO-ANNOTATION: '插件 {0} 的配置类 {1} 加载失败:没有 @Config 注解'
@ -112,13 +116,6 @@ LANGUAGE2:
TIMECYCLE: TIMECYCLE:
FAIL-CYCLE-EXISTS: '注册周期管理器 &8{0}&c 失败, 原因: &4名称重复' FAIL-CYCLE-EXISTS: '注册周期管理器 &8{0}&c 失败, 原因: &4名称重复'
ANVIL-CONTAINER:
NAME-EXAMPLE: '在这里输入文本'
LORE-NORMAL:
- ''
- '&7在上方文本框内输入信息'
- '&7随后点击右侧输出物品'
UPDATETASK: UPDATETASK:
VERSION-FAIL: '&4更新记录获取失败, 请检查网络连接!' VERSION-FAIL: '&4更新记录获取失败, 请检查网络连接!'
VERSION-LATEST: '&7插件已是最新版, 无需更新!' VERSION-LATEST: '&7插件已是最新版, 无需更新!'
@ -162,8 +159,8 @@ COMMANDS:
ONLY-STORAGE-SQL: '&8[&3&lTabooLib&8] &4只有启用数据库储存时才能这么做' ONLY-STORAGE-SQL: '&8[&3&lTabooLib&8] &4只有启用数据库储存时才能这么做'
INTERNAL: INTERNAL:
TYPE-ERROR: '&8[&3&lTabooLib&8] &7指令 &f{0} &7只能由 &f{1} &7执行' TYPE-ERROR: '&8[&3&lTabooLib&8] &7指令 &f{0} &7只能由 &f{1} &7执行'
TYPE-PLAYER: 玩家 TYPE-PLAYER: '玩家'
TYPE-CONSOLE: 控制台 TYPE-CONSOLE: '控制台'
ERROR-USAGE: ERROR-USAGE:
- '&8[&3&lTabooLib&8] &7指令 &f{0} &7参数不足' - '&8[&3&lTabooLib&8] &7指令 &f{0} &7参数不足'
- '&8[&3&lTabooLib&8] &7正确用法:' - '&8[&3&lTabooLib&8] &7正确用法:'
@ -240,10 +237,9 @@ COMMANDS:
DESCRIPTION: '&4更新插件 &8(谨防非正规途径的插件获取方式)' DESCRIPTION: '&4更新插件 &8(谨防非正规途径的插件获取方式)'
UPDATE-NOT-FOUND: '&8[&3&lTabooLib&8] &7插件已是最新版, 无需更新!' UPDATE-NOT-FOUND: '&8[&3&lTabooLib&8] &7插件已是最新版, 无需更新!'
UPDATE-NOT-SUPPORT: '&8[&3&lTabooLib&8] &4您的服务器不支持在线更新!' UPDATE-NOT-SUPPORT: '&8[&3&lTabooLib&8] &4您的服务器不支持在线更新!'
UPDATE-SUCCESS: '&8[&3&lTabooLib&8] &7最新版下载完成, 服务器即将重启!'
FILE-NOT-FOUND: '&8[&3&lTabooLib&8] &4尚未寻找到插件文件' FILE-NOT-FOUND: '&8[&3&lTabooLib&8] &4尚未寻找到插件文件'
PLAYER-ONLINE: '&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: PLAYERTAG:
DESCRIPTION: DESCRIPTION:
DISPLAY: '设置玩家展示名称' DISPLAY: '设置玩家展示名称'
@ -533,7 +529,13 @@ COMMANDS:
1: '内容' 1: '内容'
INVALID-PLAYER-OFFLINE: '&8[&3&lTabooLib&8] &4玩家 &c{0} &4不在线.' INVALID-PLAYER-OFFLINE: '&8[&3&lTabooLib&8] &4玩家 &c{0} &4不在线.'
COMMAND: COMMAND:
DESCRIPTION: '使目标输入执行指令' DESCRIPTION: '使目标执行指令'
ARGUMENTS:
0: '目标'
1: '内容'
INVALID-TARGET-NOT-FOUND: '&8[&3&lTabooLib&8] &4目标 &c{0} &4不存在.'
COMMAND-AS-OP:
DESCRIPTION: '使目标以管理员身份执行指令'
ARGUMENTS: ARGUMENTS:
0: '目标' 0: '目标'
1: '内容' 1: '内容'
@ -569,6 +571,13 @@ COMMUNICATION:
FAILED-CONNECT-CLIENT: '§8[§3§lTabooLibClient§8] &4本地通讯网络连接出错: {0}' FAILED-CONNECT-CLIENT: '§8[§3§lTabooLibClient§8] &4本地通讯网络连接出错: {0}'
FAILED-READING-PACKET: '§8[§3§lTabooLibClient§8] &4本地通讯网络数据包读取失败: {0}' FAILED-READING-PACKET: '§8[§3§lTabooLibClient§8] &4本地通讯网络数据包读取失败: {0}'
SUCCESS-CONNECTED: '§8[§3§lTabooLibClient§8] &7本地通讯网络连接成功.' SUCCESS-CONNECTED: '§8[§3§lTabooLibClient§8] &7本地通讯网络连接成功.'
CLIENT-JOINED: '§8[§3§lTabooLibClient§8] &7服务器 &flocalhost:{0} &7加入本地通讯网络.' CLIENT-JOINED: '§8[§3§lTabooLibClient§8] &7服务器 &f{0} &7加入本地通讯网络.'
CLIENT-QUITED: '§8[§3§lTabooLibClient§8] &7服务器 &flocalhost:{0} &7退出本地通讯网络.' CLIENT-QUITED: '§8[§3§lTabooLibClient§8] &7服务器 &f{0} &7退出本地通讯网络.'
PACKET-MESSAGE: '§8[§3§lTabooLibClient§8] &7服务器 &flocalhost:{0} &7发送信息: &f{1}' 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

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