Merge branch 'master' of https://github.com/Bkm016/TabooLib
This commit is contained in:
commit
cd8bf36df4
120
README.md
120
README.md
@ -1,68 +1,76 @@
|
||||
# TabooLib
|
||||
<h1 align="center">
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
TabooLib
|
||||
<h4 align="center">
|
||||
<a href="#function">插件功能</a>
|
||||
<a href="#document">插件文档</a>
|
||||
<a href="#commands">插件命令</a>
|
||||
<a href="#download">插件下载</a>
|
||||
<a href="#mcbbs">MCBBS</a>
|
||||
</h4>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
</h1>
|
||||
|
||||
> Bukkit 开发工具库集合
|
||||
<a name="function"></a>
|
||||
插件功能
|
||||
---
|
||||
本插件包含大量常用开发工具及扩展工具,可以帮助入门开发者完成一些繁琐或是复杂的操作,在你没有自己的工具库时,这些工具可以大量提升你的而开发速度,本插件自带的大部分计算都是异步处理,不会影响服务器的正常运行,你只要不去使用我标注为过时的工具,那么我可以向你保证工具的运行效率。插件在 3.55 版本后开始逐渐将一些常用的工具添加到配置文件中, 来让不会开发的服主使用。
|
||||
|
||||
[![](http://ci.pcd.ac.cn/job/TabooLib/badge/icon)](http://ci.pcd.ac.cn/job/TabooLib)
|
||||
<br>
|
||||
|
||||
<a name="document"></a>
|
||||
插件文档
|
||||
---
|
||||
| 文档(更新中) | 地址 |
|
||||
| --- | --- |
|
||||
| 主文档 | https://bkm016.github.io/TabooLib/#/ |
|
||||
|
||||
<br>
|
||||
|
||||
<a name="commands"></a>
|
||||
插件命令
|
||||
---
|
||||
| 命令 | 作用 | 权限 |
|
||||
| --- | --- | --- |
|
||||
| /taboolib | 插件主命令 | taboolib.admin |
|
||||
| /tabooliblocale | TLocale 工具主命令 | taboolib.admin |
|
||||
| /taboolibplugin | TPlugin 工具主命令 | taboolib.admin |
|
||||
| /taboolibexecute | TExecute 工具主命令 | taboolib.admin |
|
||||
| /tabooliblogs | TLogs 工具主命令 | taboolib.admin |
|
||||
| /taboolibrarymodule | TLM 模块主命令 | tlm.use |
|
||||
| /language2 | Language2 工具主命令 | taboolib.admin |
|
||||
| /translateuuid | TranslateUUID 工具主命令 | taboolib.admin |
|
||||
|
||||
<br>
|
||||
|
||||
<a name="download"></a>
|
||||
插件下载
|
||||
---
|
||||
[![](http://jenkins.mirez.cc/buildStatus/icon?job=TabooLib)](http://jenkins.mirez.cc/job/TabooLib/)
|
||||
[![](https://img.shields.io/github/downloads/Bkm016/TabooLib/total.svg)](https://github.com/Bkm016/TabooLib/releases)
|
||||
[![](https://img.shields.io/github/release/Bkm016/TabooLib.svg)](https://github.com/Bkm016/TabooLib/tags)
|
||||
[![](https://img.shields.io/github/stars/Bkm016/TabooLib.svg?style=flat-square&label=Stars)](https://github.com/Bkm016/TabooLib)
|
||||
[![](https://jitpack.io/v/Bkm016/TabooLib.svg)](https://jitpack.io/#Bkm016/TabooLib)
|
||||
|
||||
## 插件文档
|
||||
你可以在 [**这里**](https://github.com/Bkm016/TabooLib/releases) 下载正式版本
|
||||
如果你的服务器没有连接互联网(内网跨服),请下载 **libs.rar** 文件并手动解压至服务端目录
|
||||
|
||||
[TabooLib 文档](https://bkm016.github.io/TabooLib/#/)
|
||||
如果你无法连接到 Github,可以在由 **Mirez** 服务器提供的 [**构建站**](http://jenkins.15imc.com:8080/job/TabooLib/) 下载最新版本
|
||||
该网站下载到的插件有可能是 **正在测试** 的不稳定版本,最新版本以 Github 为准
|
||||
|
||||
## 下载 TabooLib 插件
|
||||
从 **4.0** 版本起,不再对 **1.7.10** 进行支持与维护,部分功能在该版本可能会失效
|
||||
如果你需要在 1.7.10 安装本插件,请在 [**这里**](https://pcd.ac.cn/2018/05/19/71/) 修复因 **SpecialSource** 版本过低导致插件无法载入的问题。
|
||||
|
||||
在 [这里](https://github.com/bkm016/TabooLib/releases) 根据您服务器的网络状态下载**在线**或**离线**版本
|
||||
离线版为 **offline** 结尾的 **jar** 文件
|
||||
|
||||
如果你的服务器是 **1.7.10** 版本,在 [这里](https://pcd.ac.cn/2018/05/19/71/) 修复因 **SpecialSource** 版本过低导致插件无法载入的问题
|
||||
|
||||
## 添加 TabooLib 为库
|
||||
|
||||
### Maven
|
||||
|
||||
```xml
|
||||
<build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependency>
|
||||
<groupId>com.github.Bkm016</groupId>
|
||||
<artifactId>TabooLib</artifactId>
|
||||
<version>JitPack版本</version>
|
||||
</dependency>
|
||||
</build>
|
||||
```
|
||||
|
||||
### Gradle
|
||||
|
||||
```groovy
|
||||
repositories {
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
dependencies {
|
||||
compile 'com.github.Bkm016:TabooLib:JitPack版本'
|
||||
}
|
||||
```
|
||||
|
||||
### sbt
|
||||
|
||||
```scala
|
||||
resolvers += "jitpack" at "https://jitpack.io"
|
||||
libraryDependencies += "com.github.Bkm016" % "TabooLib" % "JitPack版本"
|
||||
```
|
||||
|
||||
在添加依赖后,你还需要在 `plugin.yml` 中添加 `softdepend` 或者 `depend` 才能享受到 TabooLib 的全部功能。
|
||||
<br>
|
||||
|
||||
<a name="mcbbs"></a>
|
||||
MCBBS
|
||||
---
|
||||
**3.56** 版本开始 `com.sun.tools.jar` 不再和插件一起发布。
|
||||
|
||||
如果需要启用 *JavaShell* 功能请将 [com.sun.tools.jar](http://skymc.oss-cn-shanghai.aliyuncs.com/plugins/com.sun.tools.jar) 放入 *"TabooLib/JavaShell/lib"* 文件夹中。
|
||||
|
||||
---
|
||||
**3.832** 版本后开源协议更改为 `MIT`
|
||||
本插件仅在 [**MCBBS**](http://www.mcbbs.net/thread-773065-1-1.html) 发布
|
||||
<hr>
|
||||
|
2
pom.xml
2
pom.xml
@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>me.skymc</groupId>
|
||||
<artifactId>TabooLib</artifactId>
|
||||
<version>4.2</version>
|
||||
<version>4.325</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
@ -13,6 +13,8 @@ import java.util.concurrent.TimeUnit;
|
||||
@TConfig(name = "cfg.yml", charset = "GBK")
|
||||
public class ExampleMain extends JavaPlugin {
|
||||
|
||||
private Property<Boolean> update = Property.of(false);
|
||||
|
||||
public static void main(String[] args) {
|
||||
MemoryMXBean bean = ManagementFactory.getMemoryMXBean();
|
||||
System.out.println(bean.getHeapMemoryUsage().toString());
|
||||
@ -34,8 +36,6 @@ public class ExampleMain extends JavaPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
private Property<Boolean> update = Property.of(false);
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
update.addListener(((oldVal, newVal) -> {
|
||||
|
@ -14,15 +14,16 @@ import com.ilummc.tlib.resources.TLocaleLoader;
|
||||
import com.ilummc.tlib.util.IO;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.fileutils.FileUtils;
|
||||
import me.skymc.taboolib.plugin.PluginUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "com.zaxxer:HikariCP:3.1.0")
|
||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.slf4j:slf4j-api:1.7.25")
|
||||
@ -58,14 +59,6 @@ public class TLib {
|
||||
}
|
||||
}
|
||||
|
||||
public static TLib getTLib() {
|
||||
return tLib;
|
||||
}
|
||||
|
||||
public static YamlConfiguration getInternalLanguage() {
|
||||
return internalLanguage;
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
tLib = new TLib();
|
||||
|
||||
@ -94,6 +87,11 @@ public class TLib {
|
||||
}
|
||||
|
||||
public static void injectPluginManager() {
|
||||
if (!tLib.isInjectEnabled() || tLib.isBlackListPluginExists()) {
|
||||
TLocale.Logger.fatal("TLIB.INJECTION-DISABLED");
|
||||
Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin != Main.getInst()).forEach(plugin -> TDependencyInjector.inject(plugin, plugin));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Field field = Bukkit.getServer().getClass().getDeclaredField("pluginManager");
|
||||
field.setAccessible(true);
|
||||
@ -101,14 +99,18 @@ public class TLib {
|
||||
TLocale.Logger.info("TLIB.INJECTION-SUCCESS");
|
||||
} catch (NoSuchFieldException | IllegalAccessException | IllegalArgumentException ignored) {
|
||||
TLocale.Logger.fatal("TLIB.INJECTION-FAILED");
|
||||
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
if (plugin != Main.getInst()) {
|
||||
TDependencyInjector.inject(plugin, plugin);
|
||||
}
|
||||
}
|
||||
Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin != Main.getInst()).forEach(plugin -> TDependencyInjector.inject(plugin, plugin));
|
||||
}
|
||||
}
|
||||
|
||||
public static TLib getTLib() {
|
||||
return tLib;
|
||||
}
|
||||
|
||||
public static YamlConfiguration getInternalLanguage() {
|
||||
return internalLanguage;
|
||||
}
|
||||
|
||||
public TLogger getLogger() {
|
||||
return logger;
|
||||
}
|
||||
@ -124,4 +126,18 @@ public class TLib {
|
||||
public File getLibsFolder() {
|
||||
return libsFolder;
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Private Methods
|
||||
//
|
||||
// *********************************
|
||||
|
||||
private boolean isInjectEnabled() {
|
||||
return Main.getInst().getConfig().getBoolean("PLUGIN-INJECTOR.ENABLE", true);
|
||||
}
|
||||
|
||||
private boolean isBlackListPluginExists() {
|
||||
return Main.getInst().getConfig().getStringList("PLUGIN-INJECTOR.DISABLE-ON-PLUGIN-EXISTS").stream().anyMatch(PluginUtils::isPluginExists);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
package com.ilummc.tlib.logger;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import com.ilummc.tlib.util.Strings;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import net.md_5.bungee.BungeeCord;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class TLogger {
|
||||
@ -12,7 +15,7 @@ public class TLogger {
|
||||
|
||||
private static TLogger globalLogger = new TLogger("§8[§3§lTabooLib§8][§r{1}§8] §f{2}", Main.getInst(), TLogger.FINE);
|
||||
private final String pattern;
|
||||
private Plugin plugin;
|
||||
private String name;
|
||||
private int level;
|
||||
|
||||
public static TLogger getGlobalLogger() {
|
||||
@ -23,8 +26,8 @@ public class TLogger {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
public Plugin getPlugin() {
|
||||
return plugin;
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
@ -37,49 +40,83 @@ public class TLogger {
|
||||
|
||||
public TLogger(String pattern, Plugin plugin, int level) {
|
||||
this.pattern = pattern;
|
||||
this.plugin = plugin;
|
||||
this.name = plugin.getName();
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public TLogger(String pattern, String name, int level) {
|
||||
this.pattern = pattern;
|
||||
this.name = name;
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public void verbose(String msg) {
|
||||
if (level <= VERBOSE) {
|
||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§f全部", ChatColor.translateAlternateColorCodes('&', msg)));
|
||||
if (TabooLib.isSpigot()) {
|
||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§f全部", TLocale.Translate.setColored(msg)));
|
||||
} else {
|
||||
BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§f全部", TLocale.Translate.setColored(msg))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void finest(String msg) {
|
||||
if (level <= FINEST) {
|
||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§e良好", ChatColor.translateAlternateColorCodes('&', msg)));
|
||||
if (TabooLib.isSpigot()) {
|
||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§e良好", TLocale.Translate.setColored(msg)));
|
||||
} else {
|
||||
BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§e良好", TLocale.Translate.setColored(msg))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void fine(String msg) {
|
||||
if (level <= FINE) {
|
||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§a正常", ChatColor.translateAlternateColorCodes('&', msg)));
|
||||
if (TabooLib.isSpigot()) {
|
||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§a正常", TLocale.Translate.setColored(msg)));
|
||||
} else {
|
||||
BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§a正常", TLocale.Translate.setColored(msg))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void info(String msg) {
|
||||
if (level <= INFO) {
|
||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§b信息", ChatColor.translateAlternateColorCodes('&', msg)));
|
||||
if (TabooLib.isSpigot()) {
|
||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§b信息", TLocale.Translate.setColored(msg)));
|
||||
} else {
|
||||
BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§b信息", TLocale.Translate.setColored(msg))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void warn(String msg) {
|
||||
if (level <= WARN) {
|
||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§6警告", "§6" + ChatColor.translateAlternateColorCodes('&', msg)));
|
||||
if (TabooLib.isSpigot()) {
|
||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§6警告", "§6" + TLocale.Translate.setColored(msg)));
|
||||
} else {
|
||||
BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§6警告", "§6" + TLocale.Translate.setColored(msg))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void error(String msg) {
|
||||
if (level <= ERROR) {
|
||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§c错误", "§c" + ChatColor.translateAlternateColorCodes('&', msg)));
|
||||
if (TabooLib.isSpigot()) {
|
||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§c错误", "§c" + TLocale.Translate.setColored(msg)));
|
||||
} else {
|
||||
BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§c错误", "§c" + TLocale.Translate.setColored(msg))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void fatal(String msg) {
|
||||
if (level <= FATAL) {
|
||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§4致命错误", "§4" + ChatColor.translateAlternateColorCodes('&', msg)));
|
||||
if (TabooLib.isSpigot()) {
|
||||
Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, name, "§4致命错误", "§4" + TLocale.Translate.setColored(msg)));
|
||||
} else {
|
||||
BungeeCord.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Strings.replaceWithOrder(pattern, name, "§4致命错误", "§4" + TLocale.Translate.setColored(msg))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,4 +124,7 @@ public class TLogger {
|
||||
return new TLogger("§8[§3§l{0}§8][§r{1}§8] §f{2}", plugin, TLogger.FINE);
|
||||
}
|
||||
|
||||
public static TLogger getUnformatted(String name) {
|
||||
return new TLogger("§8[§3§l{0}§8][§r{1}§8] §f{2}", name, TLogger.FINE);
|
||||
}
|
||||
}
|
||||
|
@ -40,10 +40,8 @@ public abstract class ActionBar {
|
||||
@Override
|
||||
public void send(Player player, String text) {
|
||||
net.minecraft.server.v1_12_R1.ChatComponentText component = new net.minecraft.server.v1_12_R1.ChatComponentText(text);
|
||||
net.minecraft.server.v1_12_R1.PacketPlayOutChat packet = new net.minecraft.server.v1_12_R1.PacketPlayOutChat(component,
|
||||
net.minecraft.server.v1_12_R1.ChatMessageType.a((byte) 2));
|
||||
net.minecraft.server.v1_12_R1.PacketPlayOutChat packet = new net.minecraft.server.v1_12_R1.PacketPlayOutChat(component, net.minecraft.server.v1_12_R1.ChatMessageType.a((byte) 2));
|
||||
((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,16 +13,15 @@ import java.util.Map;
|
||||
public class AsmClassTransformer extends ClassVisitor implements Opcodes {
|
||||
|
||||
private final Class<?> from;
|
||||
|
||||
private final String fromVer, toVer;
|
||||
|
||||
private final String fromVer;
|
||||
private final String toVer;
|
||||
private final ClassWriter writer;
|
||||
|
||||
private String newClassName, prevName;
|
||||
private String newClassName;
|
||||
private String prevName;
|
||||
|
||||
private AsmClassTransformer(Class<?> from, String fromVer, String toVer, ClassWriter classWriter) {
|
||||
super(Opcodes.ASM6, classWriter);
|
||||
writer = classWriter;
|
||||
super(Opcodes.ASM5, classWriter);
|
||||
this.writer = classWriter;
|
||||
this.from = from;
|
||||
this.fromVer = fromVer;
|
||||
this.toVer = toVer;
|
||||
@ -51,6 +50,10 @@ public class AsmClassTransformer extends ClassVisitor implements Opcodes {
|
||||
return new Builder().toVersion(Bukkit.getServer().getClass().getName().split("\\.")[3]);
|
||||
}
|
||||
|
||||
public static Builder builder(String ver) {
|
||||
return new Builder().toVersion(ver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
|
||||
MethodVisitor visitor = super.visitMethod(access, name, replace(descriptor), replace(signature), replace(exceptions));
|
||||
@ -67,9 +70,15 @@ public class AsmClassTransformer extends ClassVisitor implements Opcodes {
|
||||
super.visitInnerClass(replace(name), outerName, replace(name).substring(outerName.length() + 1), access);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
|
||||
super.visit(version, access, newClassName.replace('.', '/'), replace(signature), replace(superName), replace(interfaces));
|
||||
}
|
||||
|
||||
private String replace(String text) {
|
||||
if (text != null) {
|
||||
return text.replace("net/minecraft/server/" + fromVer, "net/minecraft/server/" + toVer)
|
||||
return text
|
||||
.replace("net/minecraft/server/" + fromVer, "net/minecraft/server/" + toVer)
|
||||
.replace("org/bukkit/craftbukkit/" + fromVer, "org/bukkit/craftbukkit/" + toVer)
|
||||
.replace(prevName, newClassName.replace('.', '/'));
|
||||
} else {
|
||||
@ -88,16 +97,10 @@ public class AsmClassTransformer extends ClassVisitor implements Opcodes {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
|
||||
super.visit(version, access, newClassName.replace('.', '/'), replace(signature),
|
||||
replace(superName), replace(interfaces));
|
||||
}
|
||||
|
||||
private class AsmMethodTransformer extends MethodVisitor {
|
||||
|
||||
AsmMethodTransformer(MethodVisitor visitor) {
|
||||
super(Opcodes.ASM6, visitor);
|
||||
super(Opcodes.ASM5, visitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -4,6 +4,7 @@ import com.ilummc.tlib.TLib;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import com.ilummc.tlib.util.IO;
|
||||
import com.ilummc.tlib.util.Strings;
|
||||
import me.skymc.taboolib.common.function.TFunctionLoader;
|
||||
import me.skymc.taboolib.database.GlobalDataManager;
|
||||
import me.skymc.taboolib.database.PlayerDataManager;
|
||||
import me.skymc.taboolib.economy.EcoUtils;
|
||||
@ -22,6 +23,7 @@ import me.skymc.taboolib.permission.PermissionUtils;
|
||||
import me.skymc.taboolib.playerdata.DataUtils;
|
||||
import me.skymc.taboolib.skript.SkriptHandler;
|
||||
import me.skymc.taboolib.socket.TabooLibClient;
|
||||
import me.skymc.taboolib.socket.TabooLibServer;
|
||||
import me.skymc.taboolib.string.language2.Language2;
|
||||
import me.skymc.taboolib.support.SupportPlaceholder;
|
||||
import me.skymc.taboolib.timecycle.TimeCycleManager;
|
||||
@ -111,7 +113,7 @@ public class Main extends JavaPlugin {
|
||||
// 载入权限
|
||||
PermissionUtils.loadRegisteredServiceProvider();
|
||||
// 物品名称
|
||||
ItemUtils.LoadLib();
|
||||
ItemUtils.init();
|
||||
// 低层工具
|
||||
DabItemUtils.getInstance();
|
||||
// 载入周期管理器
|
||||
@ -162,6 +164,10 @@ public class Main extends JavaPlugin {
|
||||
}
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
// 本地通讯网络终端
|
||||
if (getConfig().getBoolean("SERVER")) {
|
||||
TabooLibServer.main(new String[0]);
|
||||
}
|
||||
// 本地通讯网络
|
||||
TabooLibClient.init();
|
||||
}
|
||||
@ -198,6 +204,8 @@ public class Main extends JavaPlugin {
|
||||
HikariHandler.closeDataSourceForce();
|
||||
// 注销监听器
|
||||
TListenerHandler.cancelListeners();
|
||||
// 注销子模块
|
||||
TFunctionLoader.unloadFunction();
|
||||
// 结束数据库储存方法
|
||||
if (getStorageType() == StorageType.SQL) {
|
||||
GlobalDataManager.SQLMethod.cancelSQLMethod();
|
||||
|
@ -1,5 +1,6 @@
|
||||
package me.skymc.taboolib;
|
||||
|
||||
import me.skymc.taboolib.nms.NMSUtils;
|
||||
import me.skymc.taboolib.other.NumberUtils;
|
||||
import me.skymc.taboolib.playerdata.DataUtils;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
@ -18,41 +19,128 @@ public class TabooLib {
|
||||
|
||||
static {
|
||||
try {
|
||||
spigot = Bukkit.getConsoleSender() != null;
|
||||
Class.forName("org.bukkit.Bukkit");
|
||||
spigot = true;
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取主类对象,因 Main 名称容易造成混淆所以转移至此
|
||||
*
|
||||
* @return {@link Main}
|
||||
*/
|
||||
public static Main instance() {
|
||||
return (Main) Main.getInst();
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件是否为 TabooLib(沙雕方法)
|
||||
*
|
||||
* @param plugin 插件
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isTabooLib(Plugin plugin) {
|
||||
return plugin.equals(instance()) || plugin.getName().equals("TabooLib");
|
||||
}
|
||||
|
||||
/**
|
||||
* 插件是否依赖于 TabooLib(依赖或软兼容)
|
||||
*
|
||||
* @param plugin 插件
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isDependTabooLib(Plugin plugin) {
|
||||
return plugin.getDescription().getDepend().contains("TabooLib") || plugin.getDescription().getSoftDepend().contains("TabooLib");
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为 Spigot 核心,因 TabooLib 可在 BungeeCord 上运行所以添加此方法
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isSpigot() {
|
||||
return spigot;
|
||||
}
|
||||
|
||||
public static boolean isDebug() {
|
||||
return Main.getInst().getConfig().getBoolean("DEBUG");
|
||||
}
|
||||
|
||||
public static void debug(Plugin plugin, String... args) {
|
||||
if (Main.getInst().getConfig().getBoolean("DEBUG")) {
|
||||
Arrays.stream(args).forEach(var -> Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "[TabooLib - DEBUG][" + plugin.getName() + "] " + ChatColor.RED + var));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 TabooLib 插件版本
|
||||
*
|
||||
* @return double
|
||||
*/
|
||||
public static double getPluginVersion() {
|
||||
return NumberUtils.getDouble(Main.getInst().getDescription().getVersion());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务端版本
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public static String getVersion() {
|
||||
return Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
|
||||
return Bukkit.getServer().getClass().getName().split("\\.")[3];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务端版本数字
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static int getVersionNumber() {
|
||||
return getVerint();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置服务器序列号
|
||||
*/
|
||||
public static void resetServerUID() {
|
||||
DataUtils.getPluginData("TabooLibrary", null).set("serverUID", UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为调试模式
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isDebug() {
|
||||
return DataUtils.getPluginData("TabooLibrary", instance()).getBoolean("debug");
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换调试模式
|
||||
*
|
||||
* @param debug 值
|
||||
*/
|
||||
public static void setDebug(boolean debug) {
|
||||
DataUtils.getPluginData("TabooLibrary", instance()).set("debug", debug);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送调试信息
|
||||
*
|
||||
* @param args 内容
|
||||
*/
|
||||
public static void debug(String... args) {
|
||||
debug(instance(), args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送调试信息
|
||||
*
|
||||
* @param plugin 插件名
|
||||
* @param args 内容
|
||||
*/
|
||||
public static void debug(Plugin plugin, String... args) {
|
||||
if (TabooLib.isDebug()) {
|
||||
Arrays.stream(args).forEach(var -> Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "[TabooLib - DEBUG][" + plugin.getName() + "] " + ChatColor.RED + var));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务器序列号
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public static String getServerUID() {
|
||||
if (!DataUtils.getPluginData("TabooLibrary", null).contains("serverUID")) {
|
||||
DataUtils.getPluginData("TabooLibrary", null).set("serverUID", UUID.randomUUID().toString());
|
||||
@ -60,8 +148,19 @@ public class TabooLib {
|
||||
return DataUtils.getPluginData("TabooLibrary", null).getString("serverUID");
|
||||
}
|
||||
|
||||
public static void resetServerUID() {
|
||||
DataUtils.getPluginData("TabooLibrary", null).set("serverUID", UUID.randomUUID().toString());
|
||||
/**
|
||||
* 获取服务器 TPS
|
||||
*
|
||||
* @return double[3]
|
||||
*/
|
||||
public static double[] getTPS() {
|
||||
try {
|
||||
Class<?> minecraftServer = NMSUtils.getNMSClass("MinecraftServer");
|
||||
Object server = minecraftServer.getMethod("getServer").invoke(null);
|
||||
return (double[]) server.getClass().getField("recentTps").get(server);
|
||||
} catch (Exception e) {
|
||||
return new double[] {0, 0, 0};
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
|
@ -5,25 +5,34 @@ import com.ilummc.tlib.annotations.Dependency;
|
||||
import com.ilummc.tlib.inject.TDependencyInjector;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.bstats.Metrics;
|
||||
import me.skymc.taboolib.commands.language.Language2Command;
|
||||
import me.skymc.taboolib.fileutils.FileUtils;
|
||||
import me.skymc.taboolib.listener.TListener;
|
||||
import me.skymc.taboolib.listener.TListenerHandler;
|
||||
import me.skymc.taboolib.playerdata.DataUtils;
|
||||
import me.skymc.tlm.command.TLMCommands;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.event.server.PluginEnableEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-08-23 17:04
|
||||
*/
|
||||
class TabooLibLoader {
|
||||
@TListener
|
||||
public class TabooLibLoader implements Listener {
|
||||
|
||||
static HashMap<String, List<Class>> pluginClasses = new HashMap<>();
|
||||
|
||||
static void setup() {
|
||||
testInternet();
|
||||
@ -33,11 +42,21 @@ class TabooLibLoader {
|
||||
}
|
||||
|
||||
static void register() {
|
||||
setupClasses();
|
||||
registerListener();
|
||||
registerCommands();
|
||||
registerMetrics();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件所有被读取到的类
|
||||
*
|
||||
* @param plugin 插件
|
||||
* @return List
|
||||
*/
|
||||
public static Optional<List<Class>> getPluginClasses(Plugin plugin) {
|
||||
return Optional.ofNullable(pluginClasses.get(plugin.getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化插件文件夹
|
||||
*/
|
||||
@ -46,6 +65,40 @@ class TabooLibLoader {
|
||||
Main.setServerDataFolder(FileUtils.folder(Main.getInst().getConfig().getString("DATAURL.SERVER-DATA")));
|
||||
}
|
||||
|
||||
/**
|
||||
* 载入插件数据库
|
||||
*/
|
||||
static void setupDatabase() {
|
||||
DataUtils.addPluginData("TabooLibrary", null);
|
||||
// 检查是否启用数据库
|
||||
Main.setStorageType(Main.getInst().getConfig().getBoolean("MYSQL.ENABLE") ? Main.StorageType.SQL : Main.StorageType.LOCAL);
|
||||
// 初始化数据库
|
||||
TabooLibDatabase.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取插件类
|
||||
*/
|
||||
static void setupClasses() {
|
||||
Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(TabooLibLoader::setupClasses);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取插件类
|
||||
*/
|
||||
static void setupClasses(Plugin plugin) {
|
||||
if (!(TabooLib.isTabooLib(plugin) || TabooLib.isDependTabooLib(plugin))) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
long time = System.currentTimeMillis();
|
||||
List<Class> classes = FileUtils.getClasses(plugin);
|
||||
TLocale.Logger.info("DEPENDENCY.LOAD-CLASSES", plugin.getName(), String.valueOf(classes.size()), String.valueOf(System.currentTimeMillis() - time));
|
||||
pluginClasses.put(plugin.getName(), classes);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化插件依赖库
|
||||
*/
|
||||
@ -85,25 +138,6 @@ class TabooLibLoader {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 载入插件数据库
|
||||
*/
|
||||
static void setupDatabase() {
|
||||
DataUtils.addPluginData("TabooLibrary", null);
|
||||
// 检查是否启用数据库
|
||||
Main.setStorageType(Main.getInst().getConfig().getBoolean("MYSQL.ENABLE") ? Main.StorageType.SQL : Main.StorageType.LOCAL);
|
||||
// 初始化数据库
|
||||
TabooLibDatabase.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 载入插件命令
|
||||
*/
|
||||
static void registerCommands() {
|
||||
Bukkit.getPluginCommand("language2").setExecutor(new Language2Command());
|
||||
Bukkit.getPluginCommand("taboolibrarymodule").setExecutor(new TLMCommands());
|
||||
}
|
||||
|
||||
/**
|
||||
* 载入插件监听
|
||||
*/
|
||||
@ -120,7 +154,15 @@ class TabooLibLoader {
|
||||
static void registerMetrics() {
|
||||
Metrics metrics = new Metrics(TabooLib.instance());
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("plugins_using_taboolib", () -> Math.toIntExact(Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin.getDescription().getDepend().contains("TabooLib")).count())));
|
||||
metrics.addCustomChart(new Metrics.AdvancedPie("plugins_using_taboolib_name", () -> Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin.getDescription().getDepend().contains("TabooLib")).collect(Collectors.toMap(Plugin::getName, plugin -> 1, (a, b) -> b))));
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onEnable(PluginEnableEvent e) {
|
||||
setupClasses(e.getPlugin());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onDisable(PluginDisableEvent e) {
|
||||
pluginClasses.remove(e.getPlugin().getName());
|
||||
}
|
||||
}
|
||||
|
@ -1,78 +1,29 @@
|
||||
package me.skymc.taboolib.anvil;
|
||||
|
||||
import me.skymc.taboolib.nms.NMSUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @Author sky
|
||||
* @Since 2018-09-08 15:47
|
||||
*/
|
||||
public class AnvilContainer {
|
||||
public class AnvilContainer extends net.minecraft.server.v1_12_R1.ContainerAnvil {
|
||||
|
||||
// private static IAnvilContainer instance;
|
||||
public AnvilContainer(net.minecraft.server.v1_12_R1.EntityHuman player) {
|
||||
super(player.inventory, player.world, new net.minecraft.server.v1_12_R1.BlockPosition(0, 0, 0), player);
|
||||
}
|
||||
|
||||
private static Class<?> ChatMessage = NMSUtils.getNMSClass("ChatMessage");
|
||||
private static Class<?> PacketPlayOutOpenWindow = NMSUtils.getNMSClass("PacketPlayOutOpenWindow");
|
||||
private static Class<?> IChatBaseComponent = NMSUtils.getNMSClass("IChatBaseComponent");
|
||||
private static Class<?> Packet = NMSUtils.getNMSClass("Packet");
|
||||
|
||||
// public static IAnvilContainer getInstance() {
|
||||
// return instance;
|
||||
// }
|
||||
//
|
||||
// static {
|
||||
// /*
|
||||
// * 玩不懂玩不懂... 似乎不会更改父类的包名?
|
||||
// */
|
||||
// instance = (IAnvilContainer) AsmClassTransformer.builder()
|
||||
// .from(AnvilContainerImpl.class)
|
||||
// .fromVersion("v1_12_R1")
|
||||
// .toVersion(Bukkit.getServer().getClass().getName().split("\\.")[3])
|
||||
// .build()
|
||||
// .transform();
|
||||
// }
|
||||
@Override
|
||||
public boolean a(net.minecraft.server.v1_12_R1.EntityHuman player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void openAnvil(Player p) {
|
||||
try {
|
||||
Object player = p.getClass().getMethod("getHandle").invoke(p);
|
||||
int c = (int) player.getClass().getMethod("nextContainerCounter").invoke(player);
|
||||
Object chatMessage = ChatMessage.getConstructor(String.class, Object[].class).newInstance("Repairing", new Object[0]);
|
||||
Object packetPlayOutOpenWindow = PacketPlayOutOpenWindow.getConstructor(Integer.TYPE, String.class, IChatBaseComponent, Integer.TYPE).newInstance(c, "minecraft:anvil", chatMessage, 0);
|
||||
Object playerConnection = player.getClass().getDeclaredField("playerConnection").get(player);
|
||||
playerConnection.getClass().getMethod("sendPacket", Packet).invoke(playerConnection, packetPlayOutOpenWindow);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
net.minecraft.server.v1_12_R1.EntityPlayer player = ((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) p).getHandle();
|
||||
AnvilContainer container = new AnvilContainer(player);
|
||||
int c = player.nextContainerCounter();
|
||||
player.playerConnection.sendPacket(new net.minecraft.server.v1_12_R1.PacketPlayOutOpenWindow(c, "minecraft:anvil", new net.minecraft.server.v1_12_R1.ChatMessage("Repairing"), 0));
|
||||
player.activeContainer = container;
|
||||
player.activeContainer.windowId = c;
|
||||
player.activeContainer.addSlotListener(player);
|
||||
}
|
||||
}
|
||||
|
||||
//interface IAnvilContainer {
|
||||
//
|
||||
// /**
|
||||
// * 打开铁砧界面
|
||||
// *
|
||||
// * @param player 玩家
|
||||
// */
|
||||
// void openAnvil(Player player);
|
||||
//}
|
||||
//
|
||||
//class AnvilContainerImpl extends net.minecraft.server.v1_12_R1.ContainerAnvil implements IAnvilContainer {
|
||||
//
|
||||
// public AnvilContainerImpl(net.minecraft.server.v1_12_R1.EntityHuman player) {
|
||||
// super(player.inventory, player.world, new net.minecraft.server.v1_12_R1.BlockPosition(0, 0, 0), player);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void openAnvil(Player p) {
|
||||
// net.minecraft.server.v1_12_R1.EntityPlayer player = ((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) p).getHandle();
|
||||
// AnvilContainerImpl container = new AnvilContainerImpl(player);
|
||||
// int c = player.nextContainerCounter();
|
||||
// player.playerConnection.sendPacket(new net.minecraft.server.v1_12_R1.PacketPlayOutOpenWindow(c, "minecraft:anvil", new net.minecraft.server.v1_12_R1.ChatMessage("Repairing"), 0));
|
||||
// player.activeContainer = container;
|
||||
// player.activeContainer.windowId = c;
|
||||
// player.activeContainer.addSlotListener(player);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean a(net.minecraft.server.v1_12_R1.EntityHuman player) {
|
||||
// return true;
|
||||
// }
|
||||
//}
|
||||
}
|
@ -1,105 +1,44 @@
|
||||
package me.skymc.taboolib.anvil;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.listener.TListener;
|
||||
import com.ilummc.tlib.util.asm.AsmClassLoader;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.object.Instantiable;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
@TListener
|
||||
/**
|
||||
* @author sky
|
||||
*/
|
||||
@Instantiable("AnvilContainerAPI")
|
||||
public class AnvilContainerAPI implements Listener {
|
||||
|
||||
public static List<String> list = new ArrayList<>();
|
||||
public static ItemStack item = new ItemStack(Material.NAME_TAG);
|
||||
public static HashMap<String, String> isOpen = new HashMap<>();
|
||||
public static AnvilContainerAPIEvent event;
|
||||
private static Class<?> impl;
|
||||
|
||||
public static void send(Player p, String type, String str, List<String> lorelist) {
|
||||
isOpen.put(p.getName(), type);
|
||||
|
||||
AnvilContainer.openAnvil(p);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
list.clear();
|
||||
if (lorelist == null) {
|
||||
list.addAll(TLocale.asStringList("ANVIL-CONTAINER.LORE-NORMAL"));
|
||||
} else {
|
||||
list = lorelist;
|
||||
}
|
||||
|
||||
meta.setLore(list);
|
||||
meta.setDisplayName(str);
|
||||
item.setItemMeta(meta);
|
||||
|
||||
p.getOpenInventory().getTopInventory().setItem(0, item);
|
||||
p.playSound(p.getLocation(), Sound.BLOCK_ANVIL_PLACE, 1, 1);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void close(InventoryCloseEvent e) {
|
||||
if (isOpen.containsKey(e.getPlayer().getName())) {
|
||||
isOpen.remove(e.getPlayer().getName());
|
||||
if (e.getInventory().getType() == InventoryType.ANVIL) {
|
||||
e.getInventory().clear();
|
||||
}
|
||||
public AnvilContainerAPI() {
|
||||
try {
|
||||
impl = AsmClassLoader.createNewClass("me.skymc.taboolib.anvil.AnvilContainer", AnvilContainerGenerator.generate());
|
||||
Bukkit.getPluginManager().registerEvents(this, TabooLib.instance());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void click(InventoryClickEvent e) {
|
||||
if (!isOpen.containsKey(e.getWhoClicked().getName())) {
|
||||
return;
|
||||
}
|
||||
if (e.getInventory().getType() != InventoryType.ANVIL) {
|
||||
return;
|
||||
}
|
||||
e.setCancelled(true);
|
||||
|
||||
int slot = e.getRawSlot();
|
||||
if (slot != 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
Inventory inv = e.getInventory();
|
||||
if (inv.getItem(2) == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (inv.getItem(2).getItemMeta().hasDisplayName()) {
|
||||
event = new AnvilContainerAPIEvent(e, isOpen.get(e.getWhoClicked().getName()), inv.getItem(2).getItemMeta().getDisplayName());
|
||||
e.getWhoClicked().closeInventory();
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
public static void openAnvil(Player player) {
|
||||
try {
|
||||
impl.getMethod("openAnvil", Player.class).invoke(impl, player);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void example(PlayerCommandPreprocessEvent e) {
|
||||
if ("/anvilexample".equals(e.getMessage())) {
|
||||
if (e.getPlayer().hasPermission("taboolib.admin")) {
|
||||
e.setCancelled(true);
|
||||
AnvilContainerAPI.send(e.getPlayer(), "EXAMPLE", TLocale.asString("ANVIL-CONTAINER.NAME-EXAMPLE"), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void example2(AnvilContainerAPIEvent e) {
|
||||
if ("EXAMPLE".equals(e.type)) {
|
||||
e.event.getWhoClicked().sendMessage(e.string);
|
||||
if (e.getMessage().equalsIgnoreCase("/anvilExample") && e.getPlayer().hasPermission("taboolib.admin")) {
|
||||
e.setCancelled(true);
|
||||
openAnvil(e.getPlayer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -17,13 +17,7 @@ import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
@ -36,13 +30,22 @@ import java.util.zip.GZIPOutputStream;
|
||||
*/
|
||||
public class Metrics {
|
||||
|
||||
// The version of this bStats class
|
||||
public static final int B_STATS_VERSION = 1;
|
||||
// The url to which the data is sent
|
||||
private static final String URL = "https://bStats.org/submitData/bukkit";
|
||||
// Should failed requests be logged?
|
||||
private static boolean logFailedRequests;
|
||||
// The uuid of the server
|
||||
private static String serverUUID;
|
||||
|
||||
static {
|
||||
// You can use the property to disable the check in your test environment
|
||||
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
|
||||
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
|
||||
final String defaultPackage = new String(
|
||||
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
|
||||
final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
||||
new byte[] {'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
|
||||
final String examplePackage = new String(new byte[] {'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
||||
// We want to make sure nobody just copy & pastes the example and use the wrong package names
|
||||
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) {
|
||||
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
||||
@ -50,18 +53,6 @@ public class Metrics {
|
||||
}
|
||||
}
|
||||
|
||||
// The version of this bStats class
|
||||
public static final int B_STATS_VERSION = 1;
|
||||
|
||||
// The url to which the data is sent
|
||||
private static final String URL = "https://bStats.org/submitData/bukkit";
|
||||
|
||||
// Should failed requests be logged?
|
||||
private static boolean logFailedRequests;
|
||||
|
||||
// The uuid of the server
|
||||
private static String serverUUID;
|
||||
|
||||
// The plugin
|
||||
private final JavaPlugin plugin;
|
||||
|
||||
@ -103,7 +94,8 @@ public class Metrics {
|
||||
).copyDefaults(true);
|
||||
try {
|
||||
config.save(configFile);
|
||||
} catch (IOException ignored) { }
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
// Load the data
|
||||
@ -117,7 +109,8 @@ public class Metrics {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
found = true; // We aren't the first
|
||||
break;
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
}
|
||||
}
|
||||
// Register our service
|
||||
Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
|
||||
@ -128,6 +121,61 @@ public class Metrics {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the data to the bStats server.
|
||||
*
|
||||
* @param data The data to send.
|
||||
* @throws Exception If the request failed.
|
||||
*/
|
||||
private static void sendData(JSONObject data) throws Exception {
|
||||
if (data == null) {
|
||||
throw new IllegalArgumentException("Data cannot be null!");
|
||||
}
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
throw new IllegalAccessException("This method must not be called from the main thread!");
|
||||
}
|
||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
|
||||
|
||||
// Compress the data to save bandwidth
|
||||
byte[] compressedData = compress(data.toString());
|
||||
|
||||
// Add headers
|
||||
connection.setRequestMethod("POST");
|
||||
connection.addRequestProperty("Accept", "application/json");
|
||||
connection.addRequestProperty("Connection", "close");
|
||||
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
|
||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
|
||||
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
|
||||
|
||||
// Send data
|
||||
connection.setDoOutput(true);
|
||||
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
|
||||
outputStream.write(compressedData);
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
||||
connection.getInputStream().close(); // We don't care about the response - Just send our data :)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gzips the given String.
|
||||
*
|
||||
* @param str The string to gzip.
|
||||
* @return The gzipped String.
|
||||
* @throws IOException If the compression failed.
|
||||
*/
|
||||
private static byte[] compress(final String str) throws IOException {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
|
||||
gzip.write(str.getBytes("UTF-8"));
|
||||
gzip.close();
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom chart.
|
||||
*
|
||||
@ -161,7 +209,7 @@ public class Metrics {
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 1000*60*5, 1000*60*30);
|
||||
}, 1000 * 60 * 5, 1000 * 60 * 30);
|
||||
// Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start
|
||||
// WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
|
||||
// WARNING: Just don't do it!
|
||||
@ -256,9 +304,11 @@ public class Metrics {
|
||||
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
|
||||
try {
|
||||
pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider()));
|
||||
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
|
||||
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {
|
||||
}
|
||||
}
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
data.put("plugins", pluginData);
|
||||
@ -280,61 +330,6 @@ public class Metrics {
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the data to the bStats server.
|
||||
*
|
||||
* @param data The data to send.
|
||||
* @throws Exception If the request failed.
|
||||
*/
|
||||
private static void sendData(JSONObject data) throws Exception {
|
||||
if (data == null) {
|
||||
throw new IllegalArgumentException("Data cannot be null!");
|
||||
}
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
throw new IllegalAccessException("This method must not be called from the main thread!");
|
||||
}
|
||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
|
||||
|
||||
// Compress the data to save bandwidth
|
||||
byte[] compressedData = compress(data.toString());
|
||||
|
||||
// Add headers
|
||||
connection.setRequestMethod("POST");
|
||||
connection.addRequestProperty("Accept", "application/json");
|
||||
connection.addRequestProperty("Connection", "close");
|
||||
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
|
||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
|
||||
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
|
||||
|
||||
// Send data
|
||||
connection.setDoOutput(true);
|
||||
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
|
||||
outputStream.write(compressedData);
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
||||
connection.getInputStream().close(); // We don't care about the response - Just send our data :)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gzips the given String.
|
||||
*
|
||||
* @param str The string to gzip.
|
||||
* @return The gzipped String.
|
||||
* @throws IOException If the compression failed.
|
||||
*/
|
||||
private static byte[] compress(final String str) throws IOException {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
|
||||
gzip.write(str.getBytes("UTF-8"));
|
||||
gzip.close();
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom chart.
|
||||
*/
|
||||
@ -388,7 +383,7 @@ public class Metrics {
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimplePie(String chartId, Callable<String> callable) {
|
||||
@ -419,7 +414,7 @@ public class Metrics {
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
@ -463,7 +458,7 @@ public class Metrics {
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
|
||||
@ -512,7 +507,7 @@ public class Metrics {
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SingleLineChart(String chartId, Callable<Integer> callable) {
|
||||
@ -544,7 +539,7 @@ public class Metrics {
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
@ -589,7 +584,7 @@ public class Metrics {
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
@ -627,7 +622,7 @@ public class Metrics {
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
|
||||
|
@ -97,6 +97,47 @@ public class TabooLibExecuteCommand extends BaseMainCommand {
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 2)
|
||||
BaseSubCommand commandAsOp = new BaseSubCommand() {
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "commandAsOp";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TEXECUTE.COMMAND-AS-OP.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[] {
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TEXECUTE.COMMAND-AS-OP.ARGUMENTS.0")),
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TEXECUTE.COMMAND-AS-OP.ARGUMENTS.1"))
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (args[0].equalsIgnoreCase("console")) {
|
||||
dispatchCommand(Bukkit.getConsoleSender(), ArrayUtils.arrayJoin(args, 1));
|
||||
return;
|
||||
}
|
||||
Player player = Bukkit.getPlayerExact(args[0]);
|
||||
if (player == null) {
|
||||
TLocale.sendTo(sender, "INVALID-TARGET-NOT-FOUND", args[0]);
|
||||
return;
|
||||
}
|
||||
boolean isOp = player.isOp();
|
||||
player.setOp(true);
|
||||
try {
|
||||
dispatchCommand(player, ArrayUtils.arrayJoin(args, 1));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
player.setOp(isOp);
|
||||
}
|
||||
};
|
||||
|
||||
public static boolean dispatchCommand(CommandSender sender, String command) {
|
||||
try {
|
||||
if ((sender instanceof Player)) {
|
||||
|
@ -779,39 +779,12 @@ public class TabooLibMainCommand extends BaseMainCommand {
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (!UpdateTask.isHaveUpdate()) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.UPDATEPLUGIN.UPDATE-NOT-FOUND");
|
||||
return;
|
||||
}
|
||||
UpdateTask.updatePlugin(true);
|
||||
}
|
||||
|
||||
File pluginFile = PluginUtils.getPluginFile(Main.getInst());
|
||||
if (pluginFile == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.UPDATEPLUGIN.FILE-NOT-FOUND");
|
||||
return;
|
||||
}
|
||||
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (PlayerUtils.getOnlinePlayers().size() > 0) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.UPDATEPLUGIN.PLAYER-ONLINE");
|
||||
return;
|
||||
}
|
||||
|
||||
String url = Strings.replaceWithOrder("https://github.com/Bkm016/TabooLib/releases/download/{0}/TabooLib-{0}.jar", UpdateTask.getNewVersion());
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.UPDATEPLUGIN.UPDATE-START", url);
|
||||
|
||||
File file = new File("plugins/update");
|
||||
if (file.exists()) {
|
||||
FileUtils.download(url, new File(file, pluginFile.getName()));
|
||||
TLocale.sendTo(sender, "COMMANDS.TABOOLIB.UPDATEPLUGIN.UPDATE-SUCCESS");
|
||||
} else {
|
||||
FileUtils.download(url, pluginFile);
|
||||
Bukkit.shutdown();
|
||||
}
|
||||
}
|
||||
}.runTaskAsynchronously(Main.getInst());
|
||||
@Override
|
||||
public CommandType getType() {
|
||||
return CommandType.CONSOLE;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package me.skymc.taboolib.commands.builder.type;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
* 为了防止与 CommandExecutor 混淆所以名称改为 CompleterCommand
|
||||
*
|
||||
* @author sky
|
||||
*/
|
||||
public interface CompleterCommand {
|
||||
|
||||
boolean execute(CommandSender sender, String[] args);
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package me.skymc.taboolib.commands.builder.type;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 为了防止与 TabExecutor 混淆所以名称改为 CompleterTab
|
||||
*
|
||||
* @author sky
|
||||
*/
|
||||
public interface CompleterTab {
|
||||
|
||||
List<String> execute(CommandSender sender, String[] args);
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -54,20 +54,20 @@ public class TCommandHandler implements Listener {
|
||||
return registerPluginCommand(plugin, command, "", "/" + command, new ArrayList<>(), null, null, commandExecutor, null);
|
||||
}
|
||||
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, CommandExecutor commandExecutor, TabExecutor tabExecutor) {
|
||||
return registerPluginCommand(plugin, command, "", "/" + command, new ArrayList<>(), null, null, commandExecutor, tabExecutor);
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, CommandExecutor commandExecutor, TabCompleter tabCompleter) {
|
||||
return registerPluginCommand(plugin, command, "", "/" + command, new ArrayList<>(), null, null, commandExecutor, tabCompleter);
|
||||
}
|
||||
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, String description, CommandExecutor commandExecutor, TabExecutor tabExecutor) {
|
||||
return registerPluginCommand(plugin, command, description, "/" + command, new ArrayList<>(), null, null, commandExecutor, tabExecutor);
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, String description, CommandExecutor commandExecutor, TabCompleter tabCompleter) {
|
||||
return registerPluginCommand(plugin, command, description, "/" + command, new ArrayList<>(), null, null, commandExecutor, tabCompleter);
|
||||
}
|
||||
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, CommandExecutor commandExecutor, TabExecutor tabExecutor) {
|
||||
return registerPluginCommand(plugin, command, description, usage, new ArrayList<>(), null, null, commandExecutor, tabExecutor);
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, CommandExecutor commandExecutor, TabCompleter tabCompleter) {
|
||||
return registerPluginCommand(plugin, command, description, usage, new ArrayList<>(), null, null, commandExecutor, tabCompleter);
|
||||
}
|
||||
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, List<String> aliases, CommandExecutor commandExecutor, TabExecutor tabExecutor) {
|
||||
return registerPluginCommand(plugin, command, description, usage, aliases, null, null, commandExecutor, tabExecutor);
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, List<String> aliases, CommandExecutor commandExecutor, TabCompleter tabCompleter) {
|
||||
return registerPluginCommand(plugin, command, description, usage, aliases, null, null, commandExecutor, tabCompleter);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -81,16 +81,16 @@ public class TCommandHandler implements Listener {
|
||||
* @param permission 权限
|
||||
* @param permissionMessage 权限提示
|
||||
* @param commandExecutor 命令执行器
|
||||
* @param tabExecutor 补全执行器
|
||||
* @param tabCompleter 补全执行器
|
||||
* @return 注册结果(boolean)
|
||||
*/
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, List<String> aliases, String permission, String permissionMessage, CommandExecutor commandExecutor, TabExecutor tabExecutor) {
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, List<String> aliases, String permission, String permissionMessage, CommandExecutor commandExecutor, TabCompleter tabCompleter) {
|
||||
try {
|
||||
Constructor<PluginCommand> constructor = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class);
|
||||
constructor.setAccessible(true);
|
||||
PluginCommand pluginCommand = constructor.newInstance(command, plugin);
|
||||
pluginCommand.setExecutor(commandExecutor);
|
||||
pluginCommand.setTabCompleter(tabExecutor);
|
||||
pluginCommand.setTabCompleter(tabCompleter);
|
||||
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "description", description);
|
||||
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "usageMessage", usage);
|
||||
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "aliases", aliases);
|
||||
@ -98,7 +98,9 @@ public class TCommandHandler implements Listener {
|
||||
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "permission", permission);
|
||||
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "permissionMessage", permissionMessage);
|
||||
commandMap.register(command, pluginCommand);
|
||||
TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE", plugin.getName(), command);
|
||||
if (!TabooLib.isTabooLib(plugin)) {
|
||||
TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE", plugin.getName(), command);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE-FAILED", plugin.getName(), command, e.getMessage());
|
||||
@ -134,12 +136,10 @@ public class TCommandHandler implements Listener {
|
||||
*/
|
||||
public static void registerCommands() {
|
||||
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
if (plugin.equals(TabooLib.instance()) || plugin.getDescription().getDepend().contains("TabooLib")) {
|
||||
try {
|
||||
registerCommand(plugin);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
registerCommand(plugin);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -150,6 +150,9 @@ public class TCommandHandler implements Listener {
|
||||
* @param plugin 插件
|
||||
*/
|
||||
public static void registerCommand(Plugin plugin) {
|
||||
if (!(plugin.equals(TabooLib.instance()) || TabooLib.isDependTabooLib(plugin))) {
|
||||
return;
|
||||
}
|
||||
for (Class pluginClass : FileUtils.getClasses(plugin)) {
|
||||
if (BaseMainCommand.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TCommand.class)) {
|
||||
TCommand tCommand = (TCommand) pluginClass.getAnnotation(TCommand.class);
|
||||
|
@ -2,11 +2,12 @@ package me.skymc.taboolib.commands.language;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.commands.builder.SimpleCommandBuilder;
|
||||
import me.skymc.taboolib.object.Instantiable;
|
||||
import me.skymc.taboolib.string.language2.Language2Value;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -14,18 +15,23 @@ import org.bukkit.entity.Player;
|
||||
* @author sky
|
||||
* @since 2018年2月13日 下午5:11:01
|
||||
*/
|
||||
public class Language2Command implements CommandExecutor {
|
||||
@Instantiable("Language2Command")
|
||||
public class Language2Command {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
|
||||
if (args.length == 0) {
|
||||
TLocale.sendTo(sender, "COMMANDS.LANGUAGE2.HELP", label);
|
||||
} else if ("reload".equalsIgnoreCase(args[0])) {
|
||||
reload(sender);
|
||||
} else if ("send".equalsIgnoreCase(args[0])) {
|
||||
send(sender, args);
|
||||
}
|
||||
return true;
|
||||
public Language2Command() {
|
||||
SimpleCommandBuilder.create("language2", TabooLib.instance())
|
||||
.aliases("lang2")
|
||||
.permission("taboolib.admin")
|
||||
.execute((sender, args) -> {
|
||||
if (args.length == 0) {
|
||||
TLocale.sendTo(sender, "COMMANDS.LANGUAGE2.HELP", "langauge2");
|
||||
} else if ("reload".equalsIgnoreCase(args[0])) {
|
||||
reload(sender);
|
||||
} else if ("send".equalsIgnoreCase(args[0])) {
|
||||
send(sender, args);
|
||||
}
|
||||
return true;
|
||||
}).build();
|
||||
}
|
||||
|
||||
private void send(CommandSender sender, String[] args) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package me.skymc.taboolib.common.function;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-08 14:01
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TFunction {
|
||||
|
||||
String enable() default "onEnable";
|
||||
String disable() default "onDisable";
|
||||
|
||||
}
|
@ -0,0 +1,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());
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package me.skymc.taboolib.common.pathfinder;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-21 13:06
|
||||
*/
|
||||
public interface PathfinderCreator {
|
||||
|
||||
Object createPathfinderGoal(SimpleAi ai);
|
||||
|
||||
}
|
@ -0,0 +1,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);
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package me.skymc.taboolib.common.pathfinder;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-19 19:42
|
||||
*/
|
||||
public abstract class SimpleAi {
|
||||
|
||||
public abstract boolean shouldExecute();
|
||||
|
||||
public boolean continueExecute() {
|
||||
return shouldExecute();
|
||||
}
|
||||
|
||||
public void startTask() {
|
||||
}
|
||||
|
||||
public void resetTask() {
|
||||
}
|
||||
|
||||
public void updateTask() {
|
||||
}
|
||||
}
|
@ -0,0 +1,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;
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package me.skymc.taboolib.common.pathfinder.internal;
|
||||
|
||||
import me.skymc.taboolib.common.pathfinder.PathfinderCreator;
|
||||
import me.skymc.taboolib.common.pathfinder.SimpleAi;
|
||||
|
||||
/**
|
||||
* 该类仅用作生成 ASM 代码,无任何意义
|
||||
*
|
||||
* @Author sky
|
||||
* @Since 2018-09-19 22:31
|
||||
*/
|
||||
public class InternalPathfinderCreator extends net.minecraft.server.v1_8_R3.PathfinderGoal implements PathfinderCreator {
|
||||
|
||||
private SimpleAi simpleAI;
|
||||
|
||||
public InternalPathfinderCreator() {
|
||||
}
|
||||
|
||||
public InternalPathfinderCreator(SimpleAi ai) {
|
||||
this.simpleAI = ai;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createPathfinderGoal(SimpleAi ai) {
|
||||
return new InternalPathfinderCreator(ai);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean a() {
|
||||
return simpleAI.shouldExecute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean b() {
|
||||
return simpleAI.continueExecute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void c() {
|
||||
simpleAI.startTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void d() {
|
||||
simpleAI.resetTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void e() {
|
||||
simpleAI.updateTask();
|
||||
}
|
||||
}
|
@ -0,0 +1,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);
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package me.skymc.taboolib.common.playercontainer;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
*/
|
||||
public class Container {
|
||||
|
||||
private final Object container;
|
||||
private final boolean uniqueId;
|
||||
|
||||
public Container(Object container, boolean uniqueId) {
|
||||
this.container = container;
|
||||
this.uniqueId = uniqueId;
|
||||
}
|
||||
|
||||
public Object getContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
public boolean isUniqueId() {
|
||||
return uniqueId;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package me.skymc.taboolib.common.playercontainer;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-09-14 23:45
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface PlayerContainer {
|
||||
|
||||
boolean uniqueId() default false;
|
||||
|
||||
}
|
@ -0,0 +1,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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -1,58 +1,44 @@
|
||||
package me.skymc.taboolib.damage;
|
||||
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
*/
|
||||
public class DamageUtils {
|
||||
|
||||
public static Player getAttackerInDamageEvent(EntityDamageByEntityEvent e) {
|
||||
if (e.getDamager() instanceof Player) {
|
||||
return (Player) e.getDamager();
|
||||
} else if (e.getDamager() instanceof Projectile && ((Projectile) e.getDamager()).getShooter() instanceof Player) {
|
||||
return (Player) ((Projectile) e.getDamager()).getShooter();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Deprecated
|
||||
//
|
||||
// *********************************
|
||||
|
||||
@Deprecated
|
||||
public static void damage(Player player, LivingEntity victim, double damage) {
|
||||
dmg(player, victim, damage);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void damage(Player player, Entity victim, double damage) {
|
||||
if (victim instanceof LivingEntity) {
|
||||
dmg(player, (LivingEntity) victim, damage);
|
||||
}
|
||||
dmg(player, (LivingEntity) victim, damage);
|
||||
}
|
||||
|
||||
public static void dmg(LivingEntity paramLivingEntity1, LivingEntity paramLivingEntity2, double paramDouble) {
|
||||
if ((paramLivingEntity2.hasMetadata("NPC")) || (paramLivingEntity1.hasMetadata("NPC"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object localObject1;
|
||||
try {
|
||||
localObject1 = paramLivingEntity1.getClass().getDeclaredMethod("getHandle").invoke(paramLivingEntity1);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException localIllegalAccessException1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object localObject2;
|
||||
try {
|
||||
localObject2 = paramLivingEntity2.getClass().getDeclaredMethod("getHandle").invoke(paramLivingEntity2);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException localIllegalAccessException2) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Class<?> DamageSource = nmsClass("DamageSource");
|
||||
Object localObject3 = DamageSource.getDeclaredMethod("playerAttack", nmsClass("EntityHuman")).invoke(DamageSource, localObject1);
|
||||
|
||||
localObject2.getClass().getDeclaredMethod("damageEntity", new Class[]{DamageSource, Float.TYPE}).invoke(localObject2, localObject3, (float) paramDouble);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private static Class<?> nmsClass(String paramString) {
|
||||
String str = "net.minecraft.server." + TabooLib.getVersion() + "." + paramString;
|
||||
try {
|
||||
return Class.forName(str);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
@Deprecated
|
||||
public static void dmg(LivingEntity attacker, LivingEntity victim, double damage) {
|
||||
attacker.damage(damage, victim);
|
||||
}
|
||||
}
|
||||
|
@ -4,19 +4,11 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
|
||||
@Deprecated
|
||||
public class GetDamager {
|
||||
|
||||
public static Player get(EntityDamageByEntityEvent e) {
|
||||
Player p = null;
|
||||
if (e.getDamager() instanceof Projectile) {
|
||||
Projectile arrow = (Projectile) e.getDamager();
|
||||
if (arrow.getShooter() instanceof Player) {
|
||||
p = (Player) arrow.getShooter();
|
||||
}
|
||||
} else if (e.getDamager() instanceof Player) {
|
||||
p = (Player) e.getDamager();
|
||||
}
|
||||
return p;
|
||||
return DamageUtils.getAttackerInDamageEvent(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,22 +1,13 @@
|
||||
package me.skymc.taboolib.damage;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
|
||||
@Deprecated
|
||||
public class GetKiller {
|
||||
|
||||
public static Player get(EntityDeathEvent e) {
|
||||
Player p = null;
|
||||
if (e.getEntity().getKiller() instanceof Projectile) {
|
||||
Projectile arrow = (Projectile) e.getEntity().getKiller();
|
||||
if (arrow.getShooter() instanceof Player) {
|
||||
p = (Player) arrow.getShooter();
|
||||
}
|
||||
} else if (e.getEntity().getKiller() != null) {
|
||||
p = e.getEntity().getKiller();
|
||||
}
|
||||
return p;
|
||||
return e.getEntity().getKiller();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ public class VectorUtils {
|
||||
|
||||
/**
|
||||
* 物品丢弃
|
||||
*
|
||||
* <p>
|
||||
* 常用参数:
|
||||
* itemDrop(player, itemStack, 0.2, 0.5)
|
||||
*
|
||||
@ -57,7 +57,7 @@ public class VectorUtils {
|
||||
|
||||
/**
|
||||
* 生物抛射
|
||||
*
|
||||
* <p>
|
||||
* 常用参数:
|
||||
* entityPush(entity, location, 15)
|
||||
*
|
||||
@ -69,17 +69,17 @@ public class VectorUtils {
|
||||
Location from = entity.getLocation();
|
||||
|
||||
Vector test = to.clone().subtract(from).toVector();
|
||||
Double elevation = test.getY();
|
||||
double elevation = test.getY();
|
||||
|
||||
Double launchAngle = calculateLaunchAngle(from, to, velocity, elevation, 20.0D);
|
||||
Double distance = Math.sqrt(Math.pow(test.getX(), 2.0D) + Math.pow(test.getZ(), 2.0D));
|
||||
double distance = Math.sqrt(Math.pow(test.getX(), 2.0D) + Math.pow(test.getZ(), 2.0D));
|
||||
if (distance == 0.0D) {
|
||||
return;
|
||||
}
|
||||
if (launchAngle == null) {
|
||||
launchAngle = Math.atan((40.0D * elevation + Math.pow(velocity, 2.0D)) / (40.0D * elevation + 2.0D * Math.pow(velocity, 2.0D)));
|
||||
}
|
||||
Double hangTime = calculateHangTime(launchAngle, velocity, elevation, 20.0D);
|
||||
double hangTime = calculateHangTime(launchAngle, velocity, elevation, 20.0D);
|
||||
|
||||
test.setY(Math.tan(launchAngle) * distance);
|
||||
test = normalizeVector(test);
|
||||
@ -113,7 +113,7 @@ public class VectorUtils {
|
||||
|
||||
private static Double calculateLaunchAngle(Location from, Location to, double v, double elevation, double g) {
|
||||
Vector vector = from.clone().subtract(to).toVector();
|
||||
Double distance = Math.sqrt(Math.pow(vector.getX(), 2.0D) + Math.pow(vector.getZ(), 2.0D));
|
||||
double distance = Math.sqrt(Math.pow(vector.getX(), 2.0D) + Math.pow(vector.getZ(), 2.0D));
|
||||
double v2 = Math.pow(v, 2.0D);
|
||||
double v4 = Math.pow(v, 4.0D);
|
||||
double check = g * (g * Math.pow(distance, 2.0D) + 2.0D * elevation * v2);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +1,15 @@
|
||||
package me.skymc.taboolib.fileutils;
|
||||
|
||||
import ch.njol.util.Closeable;
|
||||
import com.ilummc.eagletdl.EagletTask;
|
||||
import com.ilummc.eagletdl.ProgressEvent;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import com.ilummc.tlib.util.IO;
|
||||
import me.skymc.taboolib.Main;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
@ -133,13 +135,9 @@ public class FileUtils {
|
||||
public static InputStream getResource(Plugin plugin, String filename) {
|
||||
try {
|
||||
URL url = plugin.getClass().getClassLoader().getResource(filename);
|
||||
if (url == null) {
|
||||
return null;
|
||||
} else {
|
||||
URLConnection connection = url.openConnection();
|
||||
connection.setUseCaches(false);
|
||||
return connection.getInputStream();
|
||||
}
|
||||
URLConnection connection = url.openConnection();
|
||||
connection.setUseCaches(false);
|
||||
return connection.getInputStream();
|
||||
} catch (IOException ignored) {
|
||||
return null;
|
||||
}
|
||||
@ -409,35 +407,38 @@ public class FileUtils {
|
||||
/**
|
||||
* 下载文件
|
||||
*
|
||||
* @param downloadURL 下载地址
|
||||
* @param file 保存位置
|
||||
* @param url 下载地址
|
||||
* @param file 下载位置
|
||||
* @param async 是否异步
|
||||
*/
|
||||
public static void download(String downloadURL, File file) {
|
||||
HttpURLConnection conn = null;
|
||||
InputStream inputStream = null;
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
URL url = new URL(downloadURL);
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setConnectTimeout(5 * 1000);
|
||||
conn.setRequestProperty("User-Agent", "Mozilla/31.0 (compatible; MSIE 10.0; Windows NT; DigExt)");
|
||||
|
||||
inputStream = conn.getInputStream();
|
||||
byte[] data = read(inputStream);
|
||||
|
||||
fos = new FileOutputStream(createNewFile(file));
|
||||
fos.write(data);
|
||||
} catch (Exception ignored) {
|
||||
} finally {
|
||||
IOUtils.close(conn);
|
||||
IOUtils.closeQuietly(fos);
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
public static void download(String url, File file, boolean async) {
|
||||
EagletTask eagletTask = new EagletTask()
|
||||
.url(url)
|
||||
.file(file)
|
||||
.setThreads(8)
|
||||
.setOnError(event -> {
|
||||
})
|
||||
.setOnConnected(event -> TLocale.Logger.info("UTIL.DOWNLOAD-CONNECTED", file.getName(), ProgressEvent.format(event.getContentLength())))
|
||||
.setOnProgress(event -> TLocale.Logger.info("UTIL.DOWNLOAD-PROGRESS", event.getSpeedFormatted(), event.getPercentageFormatted()))
|
||||
.setOnComplete(event -> {
|
||||
if (event.isSuccess()) {
|
||||
TLocale.Logger.info("UTIL.DOWNLOAD-SUCCESS", file.getName());
|
||||
} else {
|
||||
TLocale.Logger.error("UTIL.DOWNLOAD-FAILED", file.getName());
|
||||
}
|
||||
}).start();
|
||||
if (!async) {
|
||||
eagletTask.waitUntil();
|
||||
}
|
||||
}
|
||||
|
||||
public static void download(String url, File file) {
|
||||
download(url, file, false);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void download(String downloadURL, String filename, File saveDir) {
|
||||
download(downloadURL, new File(saveDir, filename));
|
||||
public static void download(String url, String filename, File saveDir) {
|
||||
download(url, new File(saveDir, filename));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
|
@ -4,13 +4,13 @@ import com.ilummc.tlib.resources.TLocale;
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.common.configuration.TConfiguration;
|
||||
import me.skymc.taboolib.fileutils.ConfigUtils;
|
||||
import me.skymc.taboolib.itemnbtapi.NBTItem;
|
||||
import me.skymc.taboolib.itemnbtapi.NBTList;
|
||||
import me.skymc.taboolib.itemnbtapi.NBTListCompound;
|
||||
import me.skymc.taboolib.itemnbtapi.NBTType;
|
||||
import me.skymc.taboolib.other.NumberUtils;
|
||||
import me.skymc.taboolib.string.Language;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
@ -39,74 +39,59 @@ import java.util.stream.IntStream;
|
||||
*/
|
||||
public class ItemUtils {
|
||||
|
||||
private static FileConfiguration itemdir = null;
|
||||
|
||||
private static FileConfiguration itemCache = null;
|
||||
|
||||
private static File finalItemsFolder;
|
||||
|
||||
private static LinkedHashMap<String, String> itemlib = new LinkedHashMap<>();
|
||||
|
||||
private static FileConfiguration itemDir;
|
||||
private static FileConfiguration itemCache;
|
||||
private static TConfiguration itemName;
|
||||
private static LinkedHashMap<String, String> itemLib = new LinkedHashMap<>();
|
||||
private static LinkedHashMap<String, ItemStack> itemCaches = new LinkedHashMap<>();
|
||||
|
||||
private static LinkedHashMap<String, ItemStack> itemCachesFinal = new LinkedHashMap<>();
|
||||
|
||||
public static FileConfiguration getItemdir() {
|
||||
return itemdir;
|
||||
}
|
||||
|
||||
public static FileConfiguration getItemCache() {
|
||||
return itemCache;
|
||||
}
|
||||
|
||||
public static File getFinalItemsFolder() {
|
||||
return finalItemsFolder;
|
||||
}
|
||||
|
||||
public static LinkedHashMap<String, String> getItemlib() {
|
||||
return itemlib;
|
||||
}
|
||||
|
||||
public static LinkedHashMap<String, ItemStack> getItemCaches() {
|
||||
return itemCaches;
|
||||
}
|
||||
|
||||
public static LinkedHashMap<String, ItemStack> getItemCachesFinal() {
|
||||
return itemCachesFinal;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取物品缓存
|
||||
* 检测顺序:
|
||||
* 1. 固定物品库
|
||||
* 2. 动态物品库
|
||||
*
|
||||
* @param name 物品名称
|
||||
* @return
|
||||
*/
|
||||
public static ItemStack getCacheItem(String name) {
|
||||
// 检测固定物品库是否存在该物品
|
||||
if (itemCachesFinal.containsKey(name)) {
|
||||
return itemCachesFinal.get(name);
|
||||
}
|
||||
// 返回动态物品库
|
||||
return itemCaches.get(name);
|
||||
}
|
||||
|
||||
public static boolean isExists(String name) {
|
||||
return itemCachesFinal.containsKey(name) || itemCaches.containsKey(name);
|
||||
}
|
||||
|
||||
public static void LoadLib() {
|
||||
public static void init() {
|
||||
try {
|
||||
reloadItemDir();
|
||||
reloadItemName();
|
||||
reloadItemCache();
|
||||
itemdir = YamlConfiguration.loadConfiguration(new File(Main.getInst().getConfig().getString("DATAURL.ITEMDIR")));
|
||||
} catch (Exception e) {
|
||||
TLocale.Logger.error("ITEM-UTILS.FAIL-LOAD-ITEMS", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public static void reloadItemDir() {
|
||||
File file = new File(Main.getInst().getConfig().getString("DATAURL.ITEMDIR"));
|
||||
if (file.exists()) {
|
||||
itemDir = YamlConfiguration.loadConfiguration(file);
|
||||
}
|
||||
}
|
||||
|
||||
public static void reloadItemName() {
|
||||
itemName = TConfiguration.createInResource(Main.getInst(), "Language/ITEM_NAME.yml");
|
||||
itemName.listener(() -> {
|
||||
itemName.getConfigurationSection("").getKeys(false).forEach(a -> itemLib.put(a, itemName.getString(a)));
|
||||
TLocale.Logger.info("ITEM-UTILS.SUCCESS-LOAD-NAMES", String.valueOf(itemLib.size()));
|
||||
}).runListener();
|
||||
}
|
||||
|
||||
public static void reloadItemCache() {
|
||||
itemCaches.clear();
|
||||
itemCachesFinal.clear();
|
||||
loadItemsFile(getItemCacheFile(), false);
|
||||
finalItemsFolder = new File(Main.getInst().getDataFolder(), "FinalItems");
|
||||
if (!finalItemsFolder.exists()) {
|
||||
finalItemsFolder.mkdir();
|
||||
}
|
||||
Arrays.stream(finalItemsFolder.listFiles()).forEach(file -> loadItemsFile(file, true));
|
||||
TLocale.Logger.info("ITEM-UTILS.SUCCESS-LOAD-CACHES", String.valueOf(itemCaches.size() + itemCachesFinal.size()));
|
||||
}
|
||||
|
||||
public static File getItemCacheFile() {
|
||||
File itemCacheFile = new File(Main.getInst().getDataFolder(), "items.yml");
|
||||
if (!itemCacheFile.exists()) {
|
||||
Main.getInst().saveResource("items.yml", true);
|
||||
}
|
||||
return itemCacheFile;
|
||||
}
|
||||
|
||||
public static void loadItemsFile(File file, boolean finalFile) {
|
||||
FileConfiguration conf = ConfigUtils.load(Main.getInst(), file);
|
||||
for (String name : conf.getConfigurationSection("").getKeys(false)) {
|
||||
@ -120,33 +105,22 @@ public class ItemUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void reloadItemCache() {
|
||||
itemCaches.clear();
|
||||
itemCachesFinal.clear();
|
||||
loadItemsFile(getItemCacheFile(), false);
|
||||
// 创建固定物品库
|
||||
finalItemsFolder = new File(Main.getInst().getDataFolder(), "FinalItems");
|
||||
if (!finalItemsFolder.exists()) {
|
||||
finalItemsFolder.mkdir();
|
||||
}
|
||||
// 检查固定物品库中的物品
|
||||
Arrays.stream(finalItemsFolder.listFiles()).forEach(file -> loadItemsFile(file, true));
|
||||
TLocale.Logger.info("ITEM-UTILS.SUCCESS-LOAD-CACHES", String.valueOf(itemCaches.size() + itemCachesFinal.size()));
|
||||
// *********************************
|
||||
//
|
||||
// API
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public static boolean isExists(String name) {
|
||||
return itemCachesFinal.containsKey(name) || itemCaches.containsKey(name);
|
||||
}
|
||||
|
||||
public static void reloadItemName() {
|
||||
FileConfiguration conf = new Language("ITEM_NAME", Main.getInst(), true).getConfiguration();
|
||||
itemlib.clear();
|
||||
conf.getConfigurationSection("").getKeys(false).forEach(a -> itemlib.put(a, conf.getString(a)));
|
||||
TLocale.Logger.info("ITEM-UTILS.SUCCESS-LOAD-NAMES", String.valueOf(itemlib.size()));
|
||||
public static ItemStack getCacheItem(String name) {
|
||||
return itemCachesFinal.containsKey(name) ? itemCachesFinal.get(name) : itemCaches.get(name);
|
||||
}
|
||||
|
||||
public static File getItemCacheFile() {
|
||||
File itemCacheFile = new File(Main.getInst().getDataFolder(), "items.yml");
|
||||
if (!itemCacheFile.exists()) {
|
||||
Main.getInst().saveResource("items.yml", true);
|
||||
}
|
||||
return itemCacheFile;
|
||||
public static ItemStack getItemFromDir(String name) {
|
||||
return itemDir != null ? itemDir.getItemStack("item." + name) : null;
|
||||
}
|
||||
|
||||
public static String getCustomName(ItemStack item) {
|
||||
@ -154,19 +128,7 @@ public class ItemUtils {
|
||||
return TLocale.asString("ITEM-UTILS.EMPTY-ITEM");
|
||||
}
|
||||
int data = item.getType().getMaxDurability() == 0 ? item.getDurability() : 0;
|
||||
return item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName() : itemlib.get(item.getType() + ":" + data) == null ? item.getType().toString() : itemlib.get(item.getType() + ":" + data);
|
||||
}
|
||||
|
||||
public static ItemStack getItemFromDir(String name) {
|
||||
if (itemdir != null) {
|
||||
return itemdir.getItemStack("item." + name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static ItemStack item(int n, int a, int d) {
|
||||
return new ItemStack(n, a, (short) d);
|
||||
return item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName() : itemLib.get(item.getType() + ":" + data) == null ? item.getType().toString() : itemLib.get(item.getType() + ":" + data);
|
||||
}
|
||||
|
||||
public static ItemStack setName(ItemStack i, String n) {
|
||||
@ -176,7 +138,7 @@ public class ItemUtils {
|
||||
return i;
|
||||
}
|
||||
|
||||
public static ItemStack Enchant(ItemStack i, Enchantment e, int l) {
|
||||
public static ItemStack enchant(ItemStack i, Enchantment e, int l) {
|
||||
ItemMeta meta = i.getItemMeta();
|
||||
meta.addEnchant(e, l, false);
|
||||
i.setItemMeta(meta);
|
||||
@ -203,10 +165,7 @@ public class ItemUtils {
|
||||
}
|
||||
|
||||
public static String asString(String args, Player placeholderPlayer) {
|
||||
if (placeholderPlayer == null) {
|
||||
return args.replace("&", "§");
|
||||
}
|
||||
return PlaceholderAPI.setPlaceholders(placeholderPlayer, args.replace("&", "§"));
|
||||
return placeholderPlayer == null ? args.replace("&", "§") : PlaceholderAPI.setPlaceholders(placeholderPlayer, args.replace("&", "§"));
|
||||
}
|
||||
|
||||
public static List<String> asString(List<String> args, Player placeholderPlayer) {
|
||||
@ -281,58 +240,30 @@ public class ItemUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 包含介绍
|
||||
*
|
||||
* @param i 物品
|
||||
* @param a 关键字
|
||||
*/
|
||||
public static int getLore(ItemStack i, String a) {
|
||||
return isLored(i) ? IntStream.range(0, i.getItemMeta().getLore().size()).filter(j -> i.getItemMeta().getLore().get(j).contains(a)).findFirst().orElse(0) : 0;
|
||||
}
|
||||
|
||||
public static boolean hasLore(ItemStack i, String a) {
|
||||
return isLored(i) && i.getItemMeta().getLore().toString().contains(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果已描述
|
||||
*
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
public static boolean isLored(ItemStack i) {
|
||||
return i != null && i.getItemMeta() != null && i.getItemMeta().getLore() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果已命名
|
||||
*
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
public static boolean isNamed(ItemStack i) {
|
||||
return i != null && i.getItemMeta() != null && i.getItemMeta().getDisplayName() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加描述
|
||||
*
|
||||
* @param is 物品
|
||||
* @param lore 描述
|
||||
*/
|
||||
public static ItemStack addLore(ItemStack is, String lore) {
|
||||
public static ItemStack addLore(ItemStack is, String line) {
|
||||
ItemMeta meta = is.getItemMeta();
|
||||
|
||||
List<String> _lore = meta.hasLore() ? meta.getLore() : Collections.emptyList();
|
||||
_lore.add(lore.replaceAll("&", "§"));
|
||||
|
||||
List<String> lore = meta.hasLore() ? meta.getLore() : Collections.emptyList();
|
||||
lore.add(TLocale.Translate.setColored(line));
|
||||
is.setItemMeta(meta);
|
||||
return is;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除描述
|
||||
*
|
||||
* @param is 物品
|
||||
* @param line 行数
|
||||
*/
|
||||
public static ItemStack delLore(ItemStack is, int line) {
|
||||
ItemMeta meta = is.getItemMeta();
|
||||
if (meta.hasLore()) {
|
||||
@ -346,40 +277,7 @@ public class ItemUtils {
|
||||
return is;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取介绍所在行数
|
||||
*
|
||||
* @param i 物品
|
||||
* @param a 关键字
|
||||
*/
|
||||
public static int getLore(ItemStack i, String a) {
|
||||
return isLored(i) ? IntStream.range(0, i.getItemMeta().getLore().size()).filter(j -> i.getItemMeta().getLore().get(j).contains(a)).findFirst().orElse(0) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加耐久
|
||||
*
|
||||
* @param i 物品
|
||||
* @param d 耐久
|
||||
*/
|
||||
public static ItemStack addDurability(ItemStack i, int d) {
|
||||
i.setDurability((short) (i.getDurability() + d));
|
||||
int min = i.getDurability();
|
||||
int max = i.getType().getMaxDurability();
|
||||
if (min >= max) {
|
||||
i.setType(Material.AIR);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换描述
|
||||
*
|
||||
* @param i 物品
|
||||
* @param l1 关键字1
|
||||
* @param l2 关键字2
|
||||
*/
|
||||
public static ItemStack repalceLore(ItemStack i, String l1, String l2) {
|
||||
public static ItemStack replaceLore(ItemStack i, String l1, String l2) {
|
||||
if (!isLored(i)) {
|
||||
return i;
|
||||
} else {
|
||||
@ -392,6 +290,16 @@ public class ItemUtils {
|
||||
return i;
|
||||
}
|
||||
|
||||
public static ItemStack addDurability(ItemStack i, int d) {
|
||||
i.setDurability((short) (i.getDurability() + d));
|
||||
int min = i.getDurability();
|
||||
int max = i.getType().getMaxDurability();
|
||||
if (min >= max) {
|
||||
i.setType(Material.AIR);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
public static ItemStack loadItem(FileConfiguration f, String s) {
|
||||
return loadItem(f, s, null);
|
||||
}
|
||||
@ -552,6 +460,62 @@ public class ItemUtils {
|
||||
return nbt;
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Getter and Setter
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public static FileConfiguration getItemDir() {
|
||||
return itemDir;
|
||||
}
|
||||
|
||||
public static LinkedHashMap<String, String> getItemLib() {
|
||||
return itemLib;
|
||||
}
|
||||
|
||||
public static FileConfiguration getItemCache() {
|
||||
return itemCache;
|
||||
}
|
||||
|
||||
public static File getFinalItemsFolder() {
|
||||
return finalItemsFolder;
|
||||
}
|
||||
|
||||
public static LinkedHashMap<String, ItemStack> getItemCaches() {
|
||||
return itemCaches;
|
||||
}
|
||||
|
||||
public static LinkedHashMap<String, ItemStack> getItemCachesFinal() {
|
||||
return itemCachesFinal;
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Deprecated
|
||||
//
|
||||
// *********************************
|
||||
|
||||
@Deprecated
|
||||
public static FileConfiguration getItemdir() {
|
||||
return itemDir;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static LinkedHashMap<String, String> getItemlib() {
|
||||
return itemLib;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static ItemStack item(int n, int a, int d) {
|
||||
return new ItemStack(n, a, (short) d);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static ItemStack repalceLore(ItemStack i, String l1, String l2) {
|
||||
return replaceLore(i, l1, l2);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void putO(ItemStack item, Inventory inv, int i) {
|
||||
inv.setItem(i, item);
|
||||
|
@ -3,8 +3,10 @@ package me.skymc.taboolib.inventory.builder;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.string.ArrayUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.block.banner.Pattern;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.EntityType;
|
||||
@ -20,7 +22,7 @@ import java.util.List;
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-08-22 11:37
|
||||
* @BuilderVersion 1.0
|
||||
* @BuilderVersion 1.1
|
||||
*/
|
||||
public class ItemBuilder {
|
||||
|
||||
@ -40,6 +42,11 @@ public class ItemBuilder {
|
||||
itemMeta = itemStack.getItemMeta();
|
||||
}
|
||||
|
||||
public ItemBuilder(OfflinePlayer player) {
|
||||
this(Material.SKULL_ITEM, 1, 3);
|
||||
this.skullOwner(player.getName());
|
||||
}
|
||||
|
||||
public ItemBuilder material(int id) {
|
||||
itemStack.setType(Material.getMaterial(id));
|
||||
return this;
|
||||
@ -147,6 +154,13 @@ public class ItemBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder skullOwner(String name) {
|
||||
if (itemMeta instanceof SkullMeta) {
|
||||
((SkullMeta) itemMeta).setOwner(name);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemBuilder unbreakable(boolean value) {
|
||||
if (TabooLib.getVersionNumber() >= 12000) {
|
||||
itemMeta.setUnbreakable(value);
|
||||
@ -173,4 +187,14 @@ public class ItemBuilder {
|
||||
}
|
||||
return buildItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文本中获取物品(name:名字;lore:描述||描述;material:材质)
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static ItemStack fromString(String str) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package me.skymc.taboolib.itagapi;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.packet.PacketUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -132,7 +133,10 @@ public class TagDataHandler implements Listener {
|
||||
entryTeam.addEntry(playerData.getNameDisplay());
|
||||
entryTeam.setPrefix(playerData.getPrefix());
|
||||
entryTeam.setSuffix(playerData.getSuffix());
|
||||
TagUtils.cleanEmptyTeamInScoreboard(scoreboard);
|
||||
// 傻逼 BedWarsRel 我草你妈的
|
||||
if (TabooLib.instance().getConfig().getBoolean("TABLIST-AUTO-CLEAN-TEAM", true)) {
|
||||
TagUtils.cleanEmptyTeamInScoreboard(scoreboard);
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelPlayerVariable(Player player, TagPlayerData playerData) {
|
||||
@ -142,7 +146,10 @@ public class TagDataHandler implements Listener {
|
||||
for (Player online : Bukkit.getOnlinePlayers()) {
|
||||
Scoreboard scoreboard = TagUtils.getScoreboardComputeIfAbsent(player);
|
||||
TagUtils.cleanEntryInScoreboard(scoreboard, playerData.getNameDisplay());
|
||||
TagUtils.cleanEmptyTeamInScoreboard(scoreboard);
|
||||
// 傻逼 BedWarsRel 我草你妈的
|
||||
if (TabooLib.instance().getConfig().getBoolean("TABLIST-AUTO-CLEAN-TEAM", true)) {
|
||||
TagUtils.cleanEmptyTeamInScoreboard(scoreboard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,7 +164,7 @@ public class TagDataHandler implements Listener {
|
||||
downloadPlayerVariable(e.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler (priority = EventPriority.MONITOR)
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onQuit(PlayerQuitEvent e) {
|
||||
cancelPlayerVariable(e.getPlayer(), unregisterPlayerData(e.getPlayer()));
|
||||
}
|
||||
|
@ -4,33 +4,30 @@ import com.ilummc.tlib.bungee.api.chat.*;
|
||||
import com.ilummc.tlib.bungee.chat.ComponentSerializer;
|
||||
import com.ilummc.tlib.logger.TLogger;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.inventory.ItemUtils;
|
||||
import me.skymc.taboolib.methods.ReflectionUtils;
|
||||
import me.skymc.taboolib.nms.NMSUtils;
|
||||
import me.skymc.taboolib.other.NumberUtils;
|
||||
import me.skymc.taboolib.string.ArrayUtils;
|
||||
import me.skymc.taboolib.string.VariableFormatter;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-26 14:42json
|
||||
* @BuilderLevel 1.2
|
||||
*/
|
||||
public class TellrawJson {
|
||||
|
||||
private BaseComponent[] components = TextComponent.fromLegacyText("");
|
||||
private final Class<?> craftItemStackClazz = NMSUtils.getOBCClass("inventory.CraftItemStack");
|
||||
private final Class<?> nmsItemStackClazz = NMSUtils.getNMSClass("ItemStack");
|
||||
private final Class<?> nbtTagCompoundClazz = NMSUtils.getNMSClass("NBTTagCompound");
|
||||
private final String INVALID_ITEM = "{id:stone,tag:{display:{Name:§c* Invalid ItemStack *}}}";
|
||||
private List<BaseComponent> components = new ArrayList<>();
|
||||
private List<BaseComponent> componentsLatest = new ArrayList<>();
|
||||
private static final Class<?> craftItemStackClazz = NMSUtils.getOBCClass("inventory.CraftItemStack");
|
||||
private static final Class<?> nmsItemStackClazz = NMSUtils.getNMSClass("ItemStack");
|
||||
private static final Class<?> nbtTagCompoundClazz = NMSUtils.getNMSClass("NBTTagCompound");
|
||||
private static final String INVALID_ITEM = "{id:stone,tag:{display:{Name:§c* Invalid ItemStack *}}}";
|
||||
|
||||
TellrawJson() {
|
||||
}
|
||||
@ -39,12 +36,16 @@ public class TellrawJson {
|
||||
return new TellrawJson();
|
||||
}
|
||||
|
||||
public void send(CommandSender sender) {
|
||||
TLocale.Tellraw.send(sender, toRawMessage());
|
||||
}
|
||||
|
||||
public String toRawMessage() {
|
||||
return ComponentSerializer.toString(components);
|
||||
return ComponentSerializer.toString(getComponentsAll());
|
||||
}
|
||||
|
||||
public String toLegacyText() {
|
||||
return TextComponent.toLegacyText(components);
|
||||
return TextComponent.toLegacyText(getComponentsAll());
|
||||
}
|
||||
|
||||
public TellrawJson newLine() {
|
||||
@ -52,50 +53,51 @@ public class TellrawJson {
|
||||
}
|
||||
|
||||
public TellrawJson append(String text) {
|
||||
Arrays.stream(TextComponent.fromLegacyText(text)).forEach(component -> this.components = ArrayUtils.arrayAppend(this.components, component));
|
||||
appendComponents();
|
||||
componentsLatest.addAll(ArrayUtils.asList(TextComponent.fromLegacyText(text)));
|
||||
return this;
|
||||
}
|
||||
|
||||
public TellrawJson append(TellrawJson json) {
|
||||
BaseComponent[] newArray = new BaseComponent[components.length + json.components.length];
|
||||
System.arraycopy(components, 0, newArray, 0, components.length);
|
||||
System.arraycopy(json.components, 0, newArray, components.length, json.components.length);
|
||||
components = newArray;
|
||||
appendComponents();
|
||||
componentsLatest.addAll(ArrayUtils.asList(json.getComponentsAll()));
|
||||
return this;
|
||||
}
|
||||
|
||||
public TellrawJson hoverText(String text) {
|
||||
getLatestComponent().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(text).create()));
|
||||
getLatestComponent().forEach(component -> component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(text).create())));
|
||||
return this;
|
||||
}
|
||||
|
||||
public TellrawJson hoverItem(ItemStack itemStack) {
|
||||
getLatestComponent().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new ComponentBuilder(getItemComponent(itemStack)).create()));
|
||||
getLatestComponent().forEach(component -> component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new ComponentBuilder(getItemComponent(itemStack)).create())));
|
||||
return this;
|
||||
}
|
||||
|
||||
public TellrawJson clickCommand(String command) {
|
||||
getLatestComponent().setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command));
|
||||
getLatestComponent().forEach(component -> component.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command)));
|
||||
return this;
|
||||
}
|
||||
|
||||
public TellrawJson clickSuggest(String command) {
|
||||
getLatestComponent().setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command));
|
||||
getLatestComponent().forEach(component -> component.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command)));
|
||||
return this;
|
||||
}
|
||||
|
||||
public TellrawJson clickOpenURL(String url) {
|
||||
getLatestComponent().setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url));
|
||||
getLatestComponent().forEach(component -> component.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url)));
|
||||
return this;
|
||||
}
|
||||
|
||||
public TellrawJson clickChangePage(int page) {
|
||||
getLatestComponent().setClickEvent(new ClickEvent(ClickEvent.Action.CHANGE_PAGE, String.valueOf(page)));
|
||||
getLatestComponent().forEach(component -> component.setClickEvent(new ClickEvent(ClickEvent.Action.CHANGE_PAGE, String.valueOf(page))));
|
||||
return this;
|
||||
}
|
||||
|
||||
public void send(CommandSender sender) {
|
||||
TLocale.Tellraw.send(sender, toRawMessage());
|
||||
public BaseComponent[] getComponentsAll() {
|
||||
List<BaseComponent> components = this.components.stream().filter(component -> !(component instanceof TextComponent) || !((TextComponent) component).getText().isEmpty()).collect(Collectors.toList());
|
||||
this.componentsLatest.stream().filter(component -> !(component instanceof TextComponent) || !((TextComponent) component).getText().isEmpty()).forEach(components::add);
|
||||
return components.toArray(new BaseComponent[0]);
|
||||
}
|
||||
|
||||
public String getItemComponent(ItemStack itemStack) {
|
||||
@ -106,7 +108,7 @@ public class TellrawJson {
|
||||
Object nmsItemStackObj = asNMSCopyMethod.invoke(null, itemStack);
|
||||
return saveNmsItemStackMethod.invoke(nmsItemStackObj, nmsNbtTagCompoundObj).toString();
|
||||
} catch (Throwable t) {
|
||||
TLogger.getGlobalLogger().error("failed to serialize itemstack to nms item: " + t.toString());
|
||||
TLogger.getGlobalLogger().error("failed to serialize bukkit item to nms item: " + t.toString());
|
||||
return INVALID_ITEM;
|
||||
}
|
||||
}
|
||||
@ -117,12 +119,17 @@ public class TellrawJson {
|
||||
//
|
||||
// *********************************
|
||||
|
||||
private BaseComponent getLatestComponent() {
|
||||
return components[components.length - 1];
|
||||
private List<BaseComponent> getLatestComponent() {
|
||||
return componentsLatest;
|
||||
}
|
||||
|
||||
private void setLatestComponent(BaseComponent component) {
|
||||
components[components.length - 1] = component;
|
||||
private void setLatestComponent(BaseComponent... component) {
|
||||
componentsLatest.addAll(ArrayUtils.asList(component));
|
||||
}
|
||||
|
||||
private void appendComponents() {
|
||||
components.addAll(componentsLatest);
|
||||
componentsLatest.clear();
|
||||
}
|
||||
|
||||
// *********************************
|
||||
@ -131,12 +138,11 @@ public class TellrawJson {
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public BaseComponent[] getComponents() {
|
||||
return components;
|
||||
}
|
||||
|
||||
public void setComponents(BaseComponent[] components) {
|
||||
this.components = components;
|
||||
this.components = ArrayUtils.asList(components);
|
||||
}
|
||||
|
||||
public BaseComponent[] getComponents() {
|
||||
return components.toArray(new BaseComponent[0]);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
package me.skymc.taboolib.listener;
|
||||
|
||||
import com.ilummc.tlib.logger.TLogger;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.database.PlayerDataManager;
|
||||
import me.skymc.taboolib.inventory.ItemUtils;
|
||||
import me.skymc.taboolib.itemnbtapi.NBTItem;
|
||||
import me.skymc.taboolib.json.tellraw.TellrawJson;
|
||||
import me.skymc.taboolib.message.MsgUtils;
|
||||
import me.skymc.taboolib.permission.PermissionUtils;
|
||||
import me.skymc.taboolib.playerdata.DataUtils;
|
||||
@ -13,31 +16,51 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.event.server.ServerCommandEvent;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
*/
|
||||
@TListener
|
||||
public class ListenerPlayerCommand implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void cmd(ServerCommandEvent e) {
|
||||
if ("savefile".equals(e.getCommand())) {
|
||||
if (e.getCommand().equalsIgnoreCase("saveFiles")) {
|
||||
if (TabooLib.getVerint() > 10700) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
Bukkit.getScheduler().runTask(Main.getInst(), DataUtils::saveAllCaches);
|
||||
Bukkit.getScheduler().runTask(Main.getInst(), () -> PlayerDataManager.saveAllCaches(true, false));
|
||||
TLogger.getGlobalLogger().info("Successfully.");
|
||||
} else if (e.getCommand().equalsIgnoreCase("tDebug")) {
|
||||
if (TabooLib.getVerint() > 10700) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
if (TabooLib.isDebug()) {
|
||||
TabooLib.setDebug(false);
|
||||
TLogger.getGlobalLogger().info("&cDisabled.");
|
||||
} else {
|
||||
TabooLib.setDebug(true);
|
||||
TLogger.getGlobalLogger().info("&aEnabled.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@EventHandler
|
||||
public void cmd(PlayerCommandPreprocessEvent e) {
|
||||
if ("/unbreakable".equals(e.getMessage()) && PermissionUtils.hasPermission(e.getPlayer(), "taboolib.unbreakable")) {
|
||||
if (e.getMessage().equals("/unbreakable") && PermissionUtils.hasPermission(e.getPlayer(), "taboolib.unbreakable")) {
|
||||
e.setCancelled(true);
|
||||
|
||||
NBTItem nbti = new NBTItem(e.getPlayer().getItemInHand());
|
||||
nbti.setInteger("Unbreakable", 1);
|
||||
e.getPlayer().setItemInHand(nbti.getItem());
|
||||
|
||||
NBTItem nbt = new NBTItem(e.getPlayer().getItemInHand());
|
||||
nbt.setInteger("Unbreakable", 1);
|
||||
e.getPlayer().setItemInHand(nbt.getItem());
|
||||
MsgUtils.send(e.getPlayer(), "Success!");
|
||||
} else if (e.getMessage().equals("/tellrawTest") && PermissionUtils.hasPermission(e.getPlayer(), "taboolib.tellraw")) {
|
||||
e.setCancelled(true);
|
||||
TellrawJson.create()
|
||||
.append("§8[§3§lTabooLib§8] §7TellrawJson Test: §f[")
|
||||
.append(ItemUtils.getCustomName(e.getPlayer().getItemInHand())).hoverItem(e.getPlayer().getItemInHand())
|
||||
.append("§f]")
|
||||
.send(e.getPlayer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,13 @@
|
||||
package me.skymc.taboolib.listener;
|
||||
|
||||
import com.ilummc.tlib.TLib;
|
||||
import com.ilummc.tlib.inject.TConfigWatcher;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.message.MsgUtils;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.common.configuration.TConfiguration;
|
||||
import me.skymc.taboolib.mysql.MysqlUtils;
|
||||
import me.skymc.taboolib.mysql.hikari.HikariHandler;
|
||||
import me.skymc.taboolib.mysql.protect.MySQLConnection;
|
||||
import me.skymc.taboolib.timecycle.TimeCycleManager;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -11,33 +15,48 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
*/
|
||||
@TListener
|
||||
public class ListenerPluginDisable implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void disable(PluginDisableEvent e) {
|
||||
TabooLib.debug("Plugin \"" + e.getPlugin().getName() + "\" was disabled.");
|
||||
// 注销时间周期
|
||||
TimeCycleManager.cancel(e.getPlugin());
|
||||
|
||||
// 注销插件配置
|
||||
Optional.ofNullable(TConfiguration.getFiles().get(e.getPlugin().getName())).ifPresent(files -> {
|
||||
TConfigWatcher tConfigWatcher = TLib.getTLib().getConfigWatcher();
|
||||
for (File file : files) {
|
||||
tConfigWatcher.removeListener(file);
|
||||
TabooLib.debug("Remove TConfiguration \"" + file.getName() + "\" from Plugin \"" + e.getPlugin().getName() + "\"");
|
||||
}
|
||||
});
|
||||
// 注销数据库连接
|
||||
new HashSet<>(HikariHandler.getDataSource().keySet()).stream().filter(host -> e.getPlugin().equals(host.getPlugin()) && host.isAutoClose()).forEach(HikariHandler::closeDataSource);
|
||||
// 获取连接
|
||||
List<MySQLConnection> conns = new ArrayList<>();
|
||||
List<MySQLConnection> connection = new ArrayList<>();
|
||||
for (MySQLConnection conn : MysqlUtils.CONNECTIONS) {
|
||||
if (conn.getPlugin().equals(e.getPlugin())) {
|
||||
conns.add(conn);
|
||||
connection.add(conn);
|
||||
MysqlUtils.CONNECTIONS.remove(conn);
|
||||
}
|
||||
}
|
||||
|
||||
// 异步注销
|
||||
BukkitRunnable runnable = new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
int i = 0;
|
||||
for (MySQLConnection conn : conns) {
|
||||
for (MySQLConnection conn : connection) {
|
||||
conn.setFallReconnection(false);
|
||||
conn.closeConnection();
|
||||
i++;
|
||||
@ -47,7 +66,6 @@ public class ListenerPluginDisable implements Listener {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 如果插件关闭
|
||||
try {
|
||||
runnable.runTaskLater(Main.getInst(), 40);
|
||||
|
@ -2,7 +2,8 @@ package me.skymc.taboolib.listener;
|
||||
|
||||
import com.ilummc.tlib.util.Strings;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.fileutils.FileUtils;
|
||||
import me.skymc.taboolib.TabooLibLoader;
|
||||
import me.skymc.taboolib.methods.ReflectionUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
@ -28,12 +29,10 @@ public class TListenerHandler implements Listener {
|
||||
*/
|
||||
public static void setupListeners() {
|
||||
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
if (plugin.equals(TabooLib.instance()) || plugin.getDescription().getDepend().contains("TabooLib")) {
|
||||
try {
|
||||
setupListener(plugin);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
setupListener(plugin);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -45,25 +44,27 @@ public class TListenerHandler implements Listener {
|
||||
* @param plugin 插件
|
||||
*/
|
||||
public static void setupListener(Plugin plugin) {
|
||||
List<Class> classes = FileUtils.getClasses(plugin);
|
||||
for (Class<?> pluginClass : classes) {
|
||||
if (Listener.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TListener.class)) {
|
||||
try {
|
||||
TListener tListener = pluginClass.getAnnotation(TListener.class);
|
||||
// 检查注册条件
|
||||
if (tListener.depend().length > 0 && !Strings.isBlank(tListener.depend()[0])) {
|
||||
if (Arrays.stream(tListener.depend()).anyMatch(depend -> Bukkit.getPluginManager().getPlugin(depend) == null)) {
|
||||
continue;
|
||||
TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> {
|
||||
for (Class<?> pluginClass : classes) {
|
||||
if (org.bukkit.event.Listener.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TListener.class)) {
|
||||
try {
|
||||
TListener tListener = pluginClass.getAnnotation(TListener.class);
|
||||
// 检查注册条件
|
||||
if (tListener.depend().length > 0 && !Strings.isBlank(tListener.depend()[0])) {
|
||||
if (Arrays.stream(tListener.depend()).anyMatch(depend -> Bukkit.getPluginManager().getPlugin(depend) == null)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// 实例化监听器
|
||||
Listener listener = plugin.getClass().equals(pluginClass) ? (Listener) plugin : (Listener) ReflectionUtils.instantiateObject(pluginClass);
|
||||
listeners.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(listener);
|
||||
TabooLib.debug("Listener " + listener.getClass().getSimpleName() + " setup successfully. (" + plugin.getName() + ")");
|
||||
} catch (Exception e) {
|
||||
TabooLib.debug("Listener setup failed: " + e.toString());
|
||||
}
|
||||
// 实例化监听器
|
||||
Listener listener = plugin.getClass().equals(pluginClass) ? (Listener) plugin : (Listener) pluginClass.newInstance();
|
||||
listeners.computeIfAbsent(plugin.getName(), name -> new ArrayList<>()).add(listener);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,6 +114,7 @@ public class TListenerHandler implements Listener {
|
||||
}
|
||||
// 注册监听
|
||||
Bukkit.getPluginManager().registerEvents(listener, plugin);
|
||||
TabooLib.debug("Listener " + listener.getClass().getSimpleName() + " registered. (" + plugin.getName() + ")");
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -154,6 +156,10 @@ public class TListenerHandler implements Listener {
|
||||
});
|
||||
}
|
||||
|
||||
public static HashMap<String, List<Listener>> getListeners() {
|
||||
return listeners;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPluginEnable(PluginEnableEvent e) {
|
||||
try {
|
||||
@ -170,14 +176,4 @@ public class TListenerHandler implements Listener {
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Getter and Setter
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public static HashMap<String, List<Listener>> getListeners() {
|
||||
return listeners;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
@Deprecated
|
||||
public class MsgUtils {
|
||||
|
||||
public static void send(CommandSender sender, String s) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@ public class SQLColumn {
|
||||
private SQLColumnOption[] columnOptions;
|
||||
|
||||
/**
|
||||
* 文本类型常用构造器
|
||||
* 文本 类型常用构造器
|
||||
* new SQLColumn(SQLColumnType.TEXT, "username");
|
||||
*/
|
||||
public SQLColumn(SQLColumnType columnType, String columnName) {
|
||||
@ -30,7 +30,17 @@ public class SQLColumn {
|
||||
}
|
||||
|
||||
/**
|
||||
* 主键类型常用构造器
|
||||
* CHAR 类型常用构造器
|
||||
*
|
||||
* @param columnType
|
||||
* @param columnName
|
||||
*/
|
||||
public SQLColumn(SQLColumnType columnType, int m, String columnName) {
|
||||
this(columnType, m, 0, columnName, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 主键 类型常用构造器
|
||||
* new SQLColumn(SQLColumnType.TEXT, "username", SQLColumnOption.PRIMARY_KEY, SQLColumnOption.AUTO_INCREMENT);
|
||||
*/
|
||||
public SQLColumn(SQLColumnType columnType, String columnName, SQLColumnOption... columnOptions) {
|
||||
@ -38,7 +48,7 @@ public class SQLColumn {
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据类型常用构造器
|
||||
* 数据 类型常用构造器
|
||||
* new SQLColumn(SQLColumnType.TEXT, "player_group", "PLAYER");
|
||||
*/
|
||||
public SQLColumn(SQLColumnType columnType, String columnName, Object defaultValue) {
|
||||
@ -99,25 +109,25 @@ public class SQLColumn {
|
||||
for (SQLColumnOption options : columnOptions) {
|
||||
switch (options) {
|
||||
case NOTNULL:
|
||||
builder.append(" not null");
|
||||
builder.append(" NOT NULL");
|
||||
break;
|
||||
case PRIMARY_KEY:
|
||||
builder.append(" primary key");
|
||||
builder.append(" PRIMARY KEY");
|
||||
break;
|
||||
case AUTO_INCREMENT:
|
||||
builder.append(" auto_increment");
|
||||
builder.append(" AUTO_INCREMENT");
|
||||
break;
|
||||
case UNIQUE_KEY:
|
||||
builder.append(" unique key");
|
||||
builder.append(" UNIQUE KEY");
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
if (defaultValue != null) {
|
||||
if (defaultValue instanceof String) {
|
||||
builder.append(" default '").append(defaultValue).append("'");
|
||||
builder.append(" DEFAULT '").append(defaultValue).append("'");
|
||||
} else {
|
||||
builder.append(" default ").append(defaultValue);
|
||||
builder.append(" DEFAULT ").append(defaultValue);
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@ import com.ilummc.tlib.util.Strings;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@ -19,18 +18,28 @@ public class SQLHost {
|
||||
private String password;
|
||||
private String database;
|
||||
private Plugin plugin;
|
||||
private boolean autoClose;
|
||||
|
||||
public SQLHost(ConfigurationSection section, Plugin plugin) {
|
||||
this(section, plugin, false);
|
||||
}
|
||||
|
||||
public SQLHost(ConfigurationSection section, Plugin plugin, boolean autoClose) {
|
||||
this(section.getString("host", "localhost"), section.getString("user", "root"), section.getString("port", "3306"), section.getString("password", ""), section.getString("database", "test"), plugin);
|
||||
}
|
||||
|
||||
public SQLHost(String host, String user, String port, String password, String database, Plugin plugin) {
|
||||
this(host, user, port, password, database, plugin, false);
|
||||
}
|
||||
|
||||
public SQLHost(String host, String user, String port, String password, String database, Plugin plugin, boolean autoClose) {
|
||||
this.host = host;
|
||||
this.user = user;
|
||||
this.port = port;
|
||||
this.password = password;
|
||||
this.database = database;
|
||||
this.plugin = plugin;
|
||||
this.autoClose = false;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
@ -57,6 +66,10 @@ public class SQLHost {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
public boolean isAutoClose() {
|
||||
return autoClose;
|
||||
}
|
||||
|
||||
public String getConnectionUrl() {
|
||||
return Strings.replaceWithOrder("jdbc:mysql://{0}:{1}/{2}?characterEncoding=utf-8&useSSL=false", this.host, this.port, this.database);
|
||||
}
|
||||
@ -74,16 +87,18 @@ public class SQLHost {
|
||||
return false;
|
||||
}
|
||||
SQLHost sqlHost = (SQLHost) o;
|
||||
return Objects.equals(getHost(), sqlHost.getHost()) &&
|
||||
return autoClose == sqlHost.autoClose &&
|
||||
Objects.equals(getHost(), sqlHost.getHost()) &&
|
||||
Objects.equals(getUser(), sqlHost.getUser()) &&
|
||||
Objects.equals(getPort(), sqlHost.getPort()) &&
|
||||
Objects.equals(getPassword(), sqlHost.getPassword()) &&
|
||||
Objects.equals(getDatabase(), sqlHost.getDatabase());
|
||||
Objects.equals(getDatabase(), sqlHost.getDatabase()) &&
|
||||
Objects.equals(getPlugin(), sqlHost.getPlugin());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getHost(), getUser(), getPort(), getPassword(), getDatabase());
|
||||
return Objects.hash(getHost(), getUser(), getPort(), getPassword(), getDatabase(), getPlugin(), autoClose);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -95,6 +110,7 @@ public class SQLHost {
|
||||
", password='" + password + '\'' +
|
||||
", database='" + database + '\'' +
|
||||
", plugin=" + plugin +
|
||||
", autoClose=" + autoClose +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -26,11 +26,7 @@ public class SQLTable {
|
||||
}
|
||||
|
||||
public SQLTable addColumn(SQLColumn sqlColumn) {
|
||||
if (columns == null) {
|
||||
columns = new SQLColumn[] {sqlColumn};
|
||||
} else {
|
||||
columns = ArrayUtils.arrayAppend(columns, sqlColumn);
|
||||
}
|
||||
columns = columns == null ? new SQLColumn[] {sqlColumn} : ArrayUtils.arrayAppend(columns, sqlColumn);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -52,6 +48,22 @@ public class SQLTable {
|
||||
return Strings.replaceWithOrder("truncate table `{0}`", tableName);
|
||||
}
|
||||
|
||||
public RunnableUpdate executeInsert(String values) {
|
||||
return executeUpdate("insert into " + tableName + " values(" + values + ")");
|
||||
}
|
||||
|
||||
public RunnableQuery executeSelect(String where) {
|
||||
return executeQuery("select * from " + tableName + " where " + where);
|
||||
}
|
||||
|
||||
public RunnableQuery executeSelect() {
|
||||
return executeQuery("select * from " + tableName);
|
||||
}
|
||||
|
||||
public RunnableUpdate executeUpdate(String update, String where) {
|
||||
return executeUpdate("update " + tableName + " set " + update + " where " + where);
|
||||
}
|
||||
|
||||
public RunnableUpdate executeUpdate(String query) {
|
||||
return new RunnableUpdate(query);
|
||||
}
|
||||
|
@ -6,10 +6,8 @@ import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.fileutils.ConfigUtils;
|
||||
import me.skymc.taboolib.fileutils.FileUtils;
|
||||
import me.skymc.taboolib.mysql.builder.SQLHost;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -91,4 +89,18 @@ public class HikariHandler {
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Getter and Setter
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public static ConcurrentHashMap<SQLHost, MapDataSource> getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
public static FileConfiguration getSettings() {
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
|
18
src/main/java/me/skymc/taboolib/object/Instantiable.java
Normal file
18
src/main/java/me/skymc/taboolib/object/Instantiable.java
Normal 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();
|
||||
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
@ -3,6 +3,9 @@ package me.skymc.taboolib.other;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
*/
|
||||
public class NumberUtils {
|
||||
|
||||
private static Random random = new Random();
|
||||
@ -52,6 +55,22 @@ public class NumberUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static Boolean getBooleanAbbreviation(String str) {
|
||||
if (str == null || str.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (str.length() < 4) {
|
||||
char var = str.charAt(0);
|
||||
if (var == 'y' || var == 'Y' || var == 't' || var == 'T' || var == '1') {
|
||||
return true;
|
||||
}
|
||||
if (var == 'n' || var == 'N' || var == 'f' || var == 'F' || var == '0') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return getBoolean(str);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Random getRand() {
|
||||
return random;
|
||||
|
@ -30,7 +30,7 @@ public class PluginUtils {
|
||||
}
|
||||
|
||||
public static File getPluginFile(Plugin plugin) {
|
||||
for (File pluginFile : Objects.requireNonNull(new File("plugins").listFiles())) {
|
||||
for (File pluginFile : new File("plugins").listFiles()) {
|
||||
if (pluginFile.getName().endsWith(".jar")) {
|
||||
try {
|
||||
PluginDescriptionFile desc = Main.getInst().getPluginLoader().getPluginDescription(pluginFile);
|
||||
@ -44,6 +44,21 @@ public class PluginUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isPluginExists(String name) {
|
||||
for (File pluginFile : new File("plugins").listFiles()) {
|
||||
if (pluginFile.getName().endsWith(".jar")) {
|
||||
try {
|
||||
PluginDescriptionFile desc = Main.getInst().getPluginLoader().getPluginDescription(pluginFile);
|
||||
if (desc.getName().equalsIgnoreCase(name)) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void enable(Plugin plugin) {
|
||||
if (plugin != null && !plugin.isEnabled()) {
|
||||
Bukkit.getPluginManager().enablePlugin(plugin);
|
||||
|
@ -1,36 +1,19 @@
|
||||
package me.skymc.taboolib.skull;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import me.skymc.taboolib.inventory.builder.ItemBuilder;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
|
||||
@Deprecated
|
||||
public class SkullUtils {
|
||||
|
||||
public static ItemStack getItme(OfflinePlayer p ) {
|
||||
SkullMeta s = (SkullMeta) Bukkit.getItemFactory().getItemMeta(Material.SKULL_ITEM);
|
||||
s.setOwner(p.getName());
|
||||
|
||||
ItemStack i = new ItemStack(Material.SKULL_ITEM);
|
||||
i.setDurability((short) 3);
|
||||
i.setItemMeta(s);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public static ItemStack getOnlineItem(OfflinePlayer p ) {
|
||||
if (p.isOnline())
|
||||
{
|
||||
SkullMeta s = (SkullMeta) Bukkit.getItemFactory().getItemMeta(Material.SKULL_ITEM);
|
||||
s.setOwner(p.getName());
|
||||
|
||||
ItemStack i = new ItemStack(Material.SKULL_ITEM);
|
||||
i.setDurability((short) 3);
|
||||
i.setItemMeta(s);
|
||||
return i;
|
||||
}
|
||||
return new ItemStack(Material.SKULL_ITEM);
|
||||
}
|
||||
|
||||
public static ItemStack getItme(OfflinePlayer p) {
|
||||
return new ItemBuilder(p).build();
|
||||
}
|
||||
|
||||
public static ItemStack getOnlineItem(OfflinePlayer p) {
|
||||
return p.isOnline() ? new ItemBuilder(p).build() : new ItemStack(Material.SKULL_ITEM);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,9 +2,13 @@ package me.skymc.taboolib.socket;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.commands.builder.SimpleCommandBuilder;
|
||||
import me.skymc.taboolib.other.NumberUtils;
|
||||
import me.skymc.taboolib.socket.packet.Packet;
|
||||
import me.skymc.taboolib.socket.packet.PacketSerializer;
|
||||
import me.skymc.taboolib.socket.packet.impl.PacketCommand;
|
||||
import me.skymc.taboolib.socket.packet.impl.PacketMessage;
|
||||
import me.skymc.taboolib.string.ArrayUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.io.*;
|
||||
@ -83,6 +87,23 @@ public class TabooLibClient {
|
||||
TLocale.sendToConsole("COMMUNICATION.FAILED-READING-PACKET", e.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
SimpleCommandBuilder.create("TabooLibClient", TabooLib.instance())
|
||||
.aliases("tclient")
|
||||
.permission("*")
|
||||
.execute((sender, args) -> {
|
||||
if (args.length == 0) {
|
||||
sender.sendMessage("§c[TabooLibClient] §f/tclient message §7[TEXT] §8- §7发送测试信息");
|
||||
sender.sendMessage("§c[TabooLibClient] §f/tclient command §7[TEXT] §8- §7发送测试命令");
|
||||
} else if (args[0].equalsIgnoreCase("message") && args.length > 1) {
|
||||
sendPacket(new PacketMessage(ArrayUtils.arrayJoin(args, 1)));
|
||||
} else if (args[0].equalsIgnoreCase("command") && args.length > 1) {
|
||||
sendPacket(new PacketCommand(ArrayUtils.arrayJoin(args, 1)));
|
||||
} else {
|
||||
sender.sendMessage("§c[TabooLibClient] §7指令错误.");
|
||||
}
|
||||
return true;
|
||||
}).build();
|
||||
}
|
||||
|
||||
// *********************************
|
||||
|
@ -1,5 +1,6 @@
|
||||
package me.skymc.taboolib.socket;
|
||||
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.other.NumberUtils;
|
||||
import me.skymc.taboolib.socket.packet.Packet;
|
||||
import me.skymc.taboolib.socket.packet.PacketSerializer;
|
||||
@ -55,20 +56,25 @@ public class TabooLibServer {
|
||||
/*
|
||||
检测无效的客户端连接,如果超过 5000 毫秒没有收到客户端的回应(上一次心跳包的回应)则注销链接
|
||||
*/
|
||||
client.entrySet().stream().filter(connection -> connection.getValue().isAlive()).map(connection -> new PacketQuit(connection.getKey(), "Lost connection")).forEach(TabooLibServer::sendPacket);
|
||||
client.entrySet().stream().filter(connection -> !connection.getValue().isAlive()).map(connection -> new PacketQuit(connection.getKey(), "Lost connection")).forEach(TabooLibServer::sendPacket);
|
||||
}, 0, 1, TimeUnit.SECONDS);
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
Socket socket = server.accept();
|
||||
ClientConnection connection = new ClientConnection(socket);
|
||||
client.put(socket.getPort(), connection);
|
||||
executorService.execute(connection);
|
||||
println("Client accepted: " + socket.getPort() + " online: " + client.size());
|
||||
} catch (Exception e) {
|
||||
println("Client accept failed: " + e.toString());
|
||||
/*
|
||||
异步接收连接请求
|
||||
*/
|
||||
Executors.newSingleThreadScheduledExecutor().execute(() -> {
|
||||
while (true) {
|
||||
try {
|
||||
Socket socket = server.accept();
|
||||
ClientConnection connection = new ClientConnection(socket);
|
||||
client.put(socket.getPort(), connection);
|
||||
executorService.execute(connection);
|
||||
println("Client accepted: " + socket.getPort() + " online: " + client.size());
|
||||
} catch (Exception e) {
|
||||
println("Client accept failed: " + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void sendPacket(Packet packet) {
|
||||
@ -76,7 +82,6 @@ public class TabooLibServer {
|
||||
}
|
||||
|
||||
public static void sendPacket(String origin) {
|
||||
println("Packet sending: " + origin + ", online: " + client.size());
|
||||
// 在服务端尝试解析动作并运行
|
||||
Optional.ofNullable(PacketSerializer.unSerialize(origin)).ifPresent(Packet::readOnServer);
|
||||
// 将动作发送至所有客户端
|
||||
@ -90,10 +95,9 @@ public class TabooLibServer {
|
||||
}
|
||||
|
||||
public static void println(Object obj) {
|
||||
System.out.println("[" + infoFormat.format(System.currentTimeMillis()) + " INFO]: " + obj);
|
||||
System.out.println(TabooLib.isSpigot() ? obj : "[" + infoFormat.format(System.currentTimeMillis()) + " INFO]: " + obj);
|
||||
}
|
||||
|
||||
|
||||
public static Optional<Map.Entry<Integer, ClientConnection>> getConnection(int port) {
|
||||
return client.entrySet().stream().filter(entry -> entry.getKey().equals(port)).findFirst();
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import com.google.gson.JsonObject;
|
||||
import me.skymc.taboolib.fileutils.FileUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@ -31,6 +32,43 @@ public class PacketParser {
|
||||
try {
|
||||
Packet packetObject = (Packet) packetFind.get().getConstructor(Integer.TYPE).newInstance(json.get("port").getAsInt());
|
||||
packetObject.unSerialize(json);
|
||||
Arrays.stream(packetObject.getClass().getDeclaredFields()).filter(field -> field.isAnnotationPresent(PacketValue.class)).forEach(field -> {
|
||||
field.setAccessible(true);
|
||||
try {
|
||||
switch (field.getType().getSimpleName().toLowerCase()) {
|
||||
case "double":
|
||||
field.set(packetObject, json.get(field.getName()).getAsDouble());
|
||||
break;
|
||||
case "long":
|
||||
field.set(packetObject, json.get(field.getName()).getAsLong());
|
||||
break;
|
||||
case "short":
|
||||
field.set(packetObject, json.get(field.getName()).getAsShort());
|
||||
break;
|
||||
case "boolean":
|
||||
field.set(packetObject, json.get(field.getName()).getAsBoolean());
|
||||
break;
|
||||
case "string":
|
||||
field.set(packetObject, json.get(field.getName()).getAsString());
|
||||
break;
|
||||
case "number":
|
||||
field.set(packetObject, json.get(field.getName()).getAsNumber());
|
||||
break;
|
||||
case "int":
|
||||
case "integer":
|
||||
field.set(packetObject, json.get(field.getName()).getAsInt());
|
||||
break;
|
||||
case "char":
|
||||
case "character":
|
||||
field.set(packetObject, json.get(field.getName()).getAsCharacter());
|
||||
break;
|
||||
default:
|
||||
System.out.println("UnSerialize: Invalid packet value: " + field.getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
return packetObject;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
@ -3,22 +3,88 @@ package me.skymc.taboolib.socket.packet;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.TabooLibLoader;
|
||||
import me.skymc.taboolib.listener.TListener;
|
||||
import me.skymc.taboolib.socket.packet.impl.PacketEmpty;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.event.server.PluginEnableEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-08-22 23:32
|
||||
*/
|
||||
public class PacketSerializer {
|
||||
@TListener
|
||||
public class PacketSerializer implements Listener {
|
||||
|
||||
private static PacketParser parser = new PacketParser();
|
||||
|
||||
public PacketSerializer() {
|
||||
loadPacket();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEnable(PluginEnableEvent e) {
|
||||
loadPacket(e.getPlugin());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDisable(PluginDisableEvent e) {
|
||||
unloadPacket(e.getPlugin());
|
||||
}
|
||||
|
||||
public static void loadPacket() {
|
||||
Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(PacketSerializer::loadPacket);
|
||||
}
|
||||
|
||||
public static void loadPacket(Plugin plugin) {
|
||||
if (TabooLib.isTabooLib(plugin) || TabooLib.isDependTabooLib(plugin)) {
|
||||
TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> classes.stream().filter(pluginClass -> pluginClass.isAnnotationPresent(PacketType.class)).forEach(pluginClass -> parser.getPackets().add(pluginClass)));
|
||||
}
|
||||
}
|
||||
|
||||
public static void unloadPacket() {
|
||||
Arrays.stream(Bukkit.getPluginManager().getPlugins()).forEach(PacketSerializer::unloadPacket);
|
||||
}
|
||||
|
||||
public static void unloadPacket(Plugin plugin) {
|
||||
if (TabooLib.isTabooLib(plugin) || TabooLib.isDependTabooLib(plugin)) {
|
||||
TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> classes.stream().filter(pluginClass -> pluginClass.isAnnotationPresent(PacketType.class)).forEach(pluginClass -> parser.getPackets().remove(pluginClass)));
|
||||
}
|
||||
}
|
||||
|
||||
public static String serialize(Packet packet) {
|
||||
JsonObject json = new JsonObject();
|
||||
packet.serialize(json);
|
||||
json.addProperty("uid", packet.getUid());
|
||||
json.addProperty("port", packet.getPort());
|
||||
json.addProperty("packet", packet.getClass().getAnnotation(PacketType.class).name());
|
||||
packet.serialize(json);
|
||||
Arrays.stream(packet.getClass().getDeclaredFields()).filter(field -> field.isAnnotationPresent(PacketValue.class)).forEach(field -> {
|
||||
field.setAccessible(true);
|
||||
try {
|
||||
Object obj = field.get(packet);
|
||||
if (obj instanceof Number) {
|
||||
json.addProperty(field.getName(), (Number) obj);
|
||||
} else if (obj instanceof Boolean) {
|
||||
json.addProperty(field.getName(), (Boolean) obj);
|
||||
} else if (obj instanceof String) {
|
||||
json.addProperty(field.getName(), (String) obj);
|
||||
} else if (obj instanceof Character) {
|
||||
json.addProperty(field.getName(), (Character) obj);
|
||||
} else {
|
||||
System.out.println("Serialize: Invalid packet value: " + field.getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
return json.toString();
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
||||
}
|
@ -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."));
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ package me.skymc.taboolib.socket.packet.impl;
|
||||
import me.skymc.taboolib.socket.TabooLibClient;
|
||||
import me.skymc.taboolib.socket.packet.Packet;
|
||||
import me.skymc.taboolib.socket.packet.PacketType;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
|
@ -5,6 +5,8 @@ import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.socket.TabooLibServer;
|
||||
import me.skymc.taboolib.socket.packet.Packet;
|
||||
import me.skymc.taboolib.socket.packet.PacketType;
|
||||
import me.skymc.taboolib.socket.packet.PacketValue;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
@ -13,6 +15,7 @@ import me.skymc.taboolib.socket.packet.PacketType;
|
||||
@PacketType(name = "message")
|
||||
public class PacketMessage extends Packet {
|
||||
|
||||
@PacketValue
|
||||
private String message;
|
||||
|
||||
public PacketMessage(int port) {
|
||||
@ -24,23 +27,18 @@ public class PacketMessage extends Packet {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public PacketMessage(String message) {
|
||||
super(Bukkit.getPort());
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readOnServer() {
|
||||
TabooLibServer.println(message);
|
||||
TabooLibServer.println(getPort() + ": " + message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readOnClient() {
|
||||
TLocale.sendToConsole("COMMUNICATION.PACKET-MESSAGE", String.valueOf(getPort()), message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(JsonObject json) {
|
||||
json.addProperty("message", message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unSerialize(JsonObject json) {
|
||||
message = json.get("message").getAsString();
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
package me.skymc.taboolib.socket.packet.impl;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.socket.TabooLibServer;
|
||||
import me.skymc.taboolib.socket.packet.Packet;
|
||||
import me.skymc.taboolib.socket.packet.PacketType;
|
||||
import me.skymc.taboolib.socket.packet.PacketValue;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
@ -13,6 +13,7 @@ import me.skymc.taboolib.socket.packet.PacketType;
|
||||
@PacketType(name = "quit")
|
||||
public class PacketQuit extends Packet {
|
||||
|
||||
@PacketValue
|
||||
private String message;
|
||||
|
||||
public PacketQuit(int port) {
|
||||
@ -43,14 +44,4 @@ public class PacketQuit extends Packet {
|
||||
public void readOnClient() {
|
||||
TLocale.sendToConsole("COMMUNICATION.CLIENT-QUITED", String.valueOf(getPort()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(JsonObject json) {
|
||||
json.addProperty("message", message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unSerialize(JsonObject json) {
|
||||
message = json.get("message").getAsString();
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ public class ClientConnection implements Runnable {
|
||||
/*
|
||||
连接丢失,客户端退出
|
||||
*/
|
||||
TabooLibServer.sendPacket(new PacketQuit(socket.getPort(), e.getMessage()));
|
||||
TabooLibServer.sendPacket(new PacketQuit(socket.getPort(), "SocketException: " + e.getMessage()));
|
||||
} catch (Exception e) {
|
||||
TabooLibServer.println("Client running failed: " + e.toString());
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package me.skymc.taboolib.string;
|
||||
|
||||
import com.ilummc.tlib.util.Strings;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
@ -20,15 +19,21 @@ import java.util.stream.IntStream;
|
||||
*/
|
||||
public class ArrayUtils {
|
||||
|
||||
public static String arrayJoin(String[] args, int start) {
|
||||
return IntStream.range(start, args.length).mapToObj(i -> args[i] + " ").collect(Collectors.joining()).trim();
|
||||
public static <T> int indexOf(T[] array, T obj) {
|
||||
return array == null || array.length == 0 ? -1 : IntStream.range(0, array.length).filter(i -> array[i] != null && array[i].equals(obj)).findFirst().orElse(-1);
|
||||
}
|
||||
|
||||
public static <T> boolean contains(T[] array, T obj) {
|
||||
return indexOf(array, obj) != -1;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> List<T> asList(T... args) {
|
||||
List<T> list = new ArrayList<>();
|
||||
Collections.addAll(list, args);
|
||||
return list;
|
||||
public static <T> T[] asArray(T... args) {
|
||||
return args;
|
||||
}
|
||||
|
||||
public static String arrayJoin(String[] args, int start) {
|
||||
return IntStream.range(start, args.length).mapToObj(i -> args[i] + " ").collect(Collectors.joining()).trim();
|
||||
}
|
||||
|
||||
public static <T> T[] arrayAppend(T[] array, T obj) {
|
||||
@ -88,6 +93,13 @@ public class ArrayUtils {
|
||||
return firstElement == null ? def : obj;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> List<T> asList(T... args) {
|
||||
List<T> list = new ArrayList<>();
|
||||
Collections.addAll(list, args);
|
||||
return list;
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Deprecated
|
||||
|
@ -1,5 +1,6 @@
|
||||
package me.skymc.taboolib.support;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
@ -9,60 +10,59 @@ import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author AgarthaLib
|
||||
*/
|
||||
public class SupportWorldGuard {
|
||||
|
||||
String Source_code_from_AgarthaLib;
|
||||
private WorldGuardPlugin worldGuard;
|
||||
|
||||
public SupportWorldGuard() {
|
||||
final Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin("WorldGuard");
|
||||
if (plugin != null) {
|
||||
this.worldGuard = (WorldGuardPlugin) plugin;
|
||||
}
|
||||
Preconditions.checkNotNull(Bukkit.getServer().getPluginManager().getPlugin("WorldGuard"), "WorldGuard was not found.");
|
||||
worldGuard = WorldGuardPlugin.inst();
|
||||
}
|
||||
|
||||
public final WorldGuardPlugin getWorldGuard() {
|
||||
public WorldGuardPlugin getWorldGuard() {
|
||||
return this.worldGuard;
|
||||
}
|
||||
|
||||
public final RegionManager getRegionManager(final World world) {
|
||||
public RegionManager getRegionManager(World world) {
|
||||
return this.worldGuard.getRegionManager(world);
|
||||
}
|
||||
|
||||
public final boolean isRegionManagerExists(final World world) {
|
||||
public boolean isRegionManagerExists(World world) {
|
||||
return this.getRegionManager(world) != null;
|
||||
}
|
||||
|
||||
public final Collection<String> getRegionIDs(final World world) {
|
||||
final RegionManager regionManager = this.getRegionManager(world);
|
||||
return regionManager.getRegions().keySet();
|
||||
public Collection<String> getRegionIDs(World world) {
|
||||
return getRegionManager(world).getRegions().keySet();
|
||||
}
|
||||
|
||||
public final Collection<ProtectedRegion> getRegions(final World world) {
|
||||
final RegionManager regionManager = this.getRegionManager(world);
|
||||
return regionManager.getRegions().values();
|
||||
public Collection<ProtectedRegion> getRegions(World world) {
|
||||
return getRegionManager(world).getRegions().values();
|
||||
}
|
||||
|
||||
public final ProtectedRegion getRegion(final World world, final String id) {
|
||||
final RegionManager regionManager = this.getRegionManager(world);
|
||||
if (regionManager != null) {
|
||||
for (final String key : regionManager.getRegions().keySet()) {
|
||||
if (key.equalsIgnoreCase(id)) {
|
||||
return regionManager.getRegion(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
public List<String> getRegionsAtLocation(World world, Location location) {
|
||||
return getRegions(world).stream().filter(protectedRegion -> protectedRegion.contains(location.getBlockX(), location.getBlockY(), location.getBlockZ())).map(ProtectedRegion::getId).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public final boolean isRegionExists(final World world, final String id) {
|
||||
public ProtectedRegion getRegion(World world, String id) {
|
||||
RegionManager regionManager = this.getRegionManager(world);
|
||||
return regionManager != null ? regionManager.getRegions().keySet().stream().filter(key -> key.equalsIgnoreCase(id)).findFirst().map(regionManager::getRegion).orElse(null) : null;
|
||||
}
|
||||
|
||||
public boolean isRegionExists(World world, String id) {
|
||||
return this.getRegion(world, id) != null;
|
||||
}
|
||||
|
||||
public final boolean isPlayerInsideRegion(final ProtectedRegion region, final Player player) {
|
||||
final Location location = player.getLocation();
|
||||
public boolean isPlayerInsideRegion(ProtectedRegion region, Player player) {
|
||||
Location location = player.getLocation();
|
||||
return region.contains(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +1,26 @@
|
||||
package me.skymc.taboolib.update;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.fileutils.FileUtils;
|
||||
import me.skymc.taboolib.player.PlayerUtils;
|
||||
import me.skymc.taboolib.plugin.PluginUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018年2月23日 下午10:39:14
|
||||
*/
|
||||
public class UpdateTask {
|
||||
|
||||
private static boolean haveUpdate = false;
|
||||
private static double newVersion = 0;
|
||||
|
||||
public static boolean isHaveUpdate() {
|
||||
return haveUpdate;
|
||||
}
|
||||
|
||||
public static double getNewVersion() {
|
||||
return newVersion;
|
||||
}
|
||||
|
||||
public UpdateTask() {
|
||||
new BukkitRunnable() {
|
||||
|
||||
@ -35,34 +29,53 @@ public class UpdateTask {
|
||||
if (!Main.getInst().getConfig().getBoolean("UPDATE-CHECK")) {
|
||||
return;
|
||||
}
|
||||
|
||||
String value = FileUtils.getStringFromURL("https://api.github.com/repos/Bkm016/TabooLib/tags", null);
|
||||
if (value == null) {
|
||||
TLocale.Logger.error("UPDATETASK.VERSION-FAIL");
|
||||
return;
|
||||
}
|
||||
|
||||
JsonElement json = new JsonParser().parse(value);
|
||||
if (json.isJsonArray()) {
|
||||
JsonObject latestObject = json.getAsJsonArray().get(0).getAsJsonObject();
|
||||
newVersion = latestObject.get("name").getAsDouble();
|
||||
newVersion = json.getAsJsonArray().get(0).getAsJsonObject().get("name").getAsDouble();
|
||||
if (TabooLib.getPluginVersion() >= newVersion) {
|
||||
TLocale.Logger.info("UPDATETASK.VERSION-LATEST");
|
||||
} else {
|
||||
haveUpdate = true;
|
||||
TLocale.Logger.info("UPDATETASK.VERSION-OUTDATED", String.valueOf(TabooLib.getPluginVersion()), String.valueOf(newVersion));
|
||||
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (Main.getInst().getConfig().getBoolean("UPDATE-DOWNLOAD", false)) {
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "taboolib updatePlugin");
|
||||
}
|
||||
}
|
||||
}.runTask(Main.getInst());
|
||||
Bukkit.getScheduler().runTask(TabooLib.instance(), () -> updatePlugin(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}.runTaskTimerAsynchronously(Main.getInst(), 100, 20 * 60 * 60 * 6);
|
||||
}
|
||||
|
||||
public static boolean isHaveUpdate() {
|
||||
return newVersion > 0;
|
||||
}
|
||||
|
||||
public static double getNewVersion() {
|
||||
return newVersion;
|
||||
}
|
||||
|
||||
public static void updatePlugin(boolean shutdown) {
|
||||
if (!UpdateTask.isHaveUpdate()) {
|
||||
TLocale.Logger.info("COMMANDS.TABOOLIB.UPDATEPLUGIN.UPDATE-NOT-FOUND");
|
||||
return;
|
||||
}
|
||||
if (PlayerUtils.getOnlinePlayers().size() > 0) {
|
||||
TLocale.Logger.info("COMMANDS.TABOOLIB.UPDATEPLUGIN.PLAYER-ONLINE");
|
||||
return;
|
||||
}
|
||||
File pluginFile = PluginUtils.getPluginFile(Main.getInst());
|
||||
if (pluginFile == null) {
|
||||
TLocale.Logger.info("COMMANDS.TABOOLIB.UPDATEPLUGIN.FILE-NOT-FOUND");
|
||||
return;
|
||||
}
|
||||
Bukkit.getScheduler().runTaskAsynchronously(TabooLib.instance(), () -> {
|
||||
FileUtils.download("https://github.com/Bkm016/TabooLib/releases/download/" + newVersion + "/TabooLib-" + newVersion + ".jar", pluginFile);
|
||||
TLocale.Logger.info("COMMANDS.TABOOLIB.UPDATEPLUGIN.UPDATE-SUCCESS");
|
||||
if (shutdown) {
|
||||
Bukkit.shutdown();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,63 +1,68 @@
|
||||
package me.skymc.tlm.command;
|
||||
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import me.skymc.taboolib.commands.builder.SimpleCommandBuilder;
|
||||
import me.skymc.taboolib.object.Instantiable;
|
||||
import me.skymc.tlm.TLM;
|
||||
import me.skymc.tlm.command.sub.TLMInvCommand;
|
||||
import me.skymc.tlm.command.sub.TLMKitCommand;
|
||||
import me.skymc.tlm.command.sub.TLMListCommand;
|
||||
import me.skymc.tlm.command.sub.TLMReloadCommand;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018年2月18日 上午12:02:08
|
||||
*/
|
||||
public class TLMCommands implements CommandExecutor {
|
||||
@Instantiable("TLMCommands")
|
||||
public class TLMCommands {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command arg1, String arg2, String[] args) {
|
||||
if (args.length == 0 || "help".equalsIgnoreCase(args[0])) {
|
||||
if (sender.hasPermission("taboolib.admin")) {
|
||||
TLM.getInst().getLanguage().get("COMMAND-HELP").send(sender);
|
||||
} else {
|
||||
TLM.getInst().getLanguage().get("NOPERMISSION-HELP").send(sender);
|
||||
}
|
||||
}
|
||||
public TLMCommands() {
|
||||
SimpleCommandBuilder.create("taboolibrarymodule", TabooLib.instance())
|
||||
.aliases("tlm")
|
||||
.permission("tlm.use")
|
||||
.execute((sender, args) -> {
|
||||
if (args.length == 0 || "help".equalsIgnoreCase(args[0])) {
|
||||
if (sender.hasPermission("taboolib.admin")) {
|
||||
TLM.getInst().getLanguage().get("COMMAND-HELP").send(sender);
|
||||
} else {
|
||||
TLM.getInst().getLanguage().get("NOPERMISSION-HELP").send(sender);
|
||||
}
|
||||
}
|
||||
|
||||
// 重载
|
||||
else if ("reload".equalsIgnoreCase(args[0])) {
|
||||
if (sender.hasPermission("taboolib.admin")) {
|
||||
new TLMReloadCommand(sender, args);
|
||||
} else {
|
||||
TLM.getInst().getLanguage().get("NOPERMISSION-RELOAD").send(sender);
|
||||
}
|
||||
}
|
||||
// 重载
|
||||
else if ("reload".equalsIgnoreCase(args[0])) {
|
||||
if (sender.hasPermission("taboolib.admin")) {
|
||||
new TLMReloadCommand(sender, args);
|
||||
} else {
|
||||
TLM.getInst().getLanguage().get("NOPERMISSION-RELOAD").send(sender);
|
||||
}
|
||||
}
|
||||
|
||||
// 列出
|
||||
else if ("list".equalsIgnoreCase(args[0])) {
|
||||
if (sender.hasPermission("taboolib.admin")) {
|
||||
new TLMListCommand(sender, args);
|
||||
} else {
|
||||
TLM.getInst().getLanguage().get("NOPERMISSION-LIST").send(sender);
|
||||
}
|
||||
}
|
||||
// 列出
|
||||
else if ("list".equalsIgnoreCase(args[0])) {
|
||||
if (sender.hasPermission("taboolib.admin")) {
|
||||
new TLMListCommand(sender, args);
|
||||
} else {
|
||||
TLM.getInst().getLanguage().get("NOPERMISSION-LIST").send(sender);
|
||||
}
|
||||
}
|
||||
|
||||
// InventorySave 模块
|
||||
else if ("inv".equalsIgnoreCase(args[0])) {
|
||||
if (sender.hasPermission("taboolib.admin")) {
|
||||
new TLMInvCommand(sender, args);
|
||||
} else {
|
||||
TLM.getInst().getLanguage().get("NOPERMISSION-INV").send(sender);
|
||||
}
|
||||
}
|
||||
// InventorySave 模块
|
||||
else if ("inv".equalsIgnoreCase(args[0])) {
|
||||
if (sender.hasPermission("taboolib.admin")) {
|
||||
new TLMInvCommand(sender, args);
|
||||
} else {
|
||||
TLM.getInst().getLanguage().get("NOPERMISSION-INV").send(sender);
|
||||
}
|
||||
}
|
||||
|
||||
// Kit 模块
|
||||
else if ("kit".equalsIgnoreCase(args[0])) {
|
||||
new TLMKitCommand(sender, args);
|
||||
} else {
|
||||
TLM.getInst().getLanguage().get("COMMAND-ERROR").send(sender);
|
||||
}
|
||||
return true;
|
||||
// Kit 模块
|
||||
else if ("kit".equalsIgnoreCase(args[0])) {
|
||||
new TLMKitCommand(sender, args);
|
||||
} else {
|
||||
TLM.getInst().getLanguage().get("COMMAND-ERROR").send(sender);
|
||||
}
|
||||
return true;
|
||||
}).build();
|
||||
}
|
||||
}
|
||||
|
@ -12,16 +12,6 @@ DATAURL:
|
||||
SERVER-DATA: 'plugins/TabooLib/serverdata/'
|
||||
# 物品数据(来自 ItemSave 插件)
|
||||
ITEMDIR: 'plugins/Skript/scripts/config/item.yml'
|
||||
|
||||
# 是否启用调试模式
|
||||
# 启用后将收到来自其他插件的调试信息
|
||||
DEBUG: false
|
||||
|
||||
# 网络连接测试地址
|
||||
TEST-URL: 'aliyun.com'
|
||||
|
||||
# 下载依赖时启用的线程数
|
||||
DOWNLOAD-POOL-SIZE: 4
|
||||
|
||||
# 语言文件相关设置
|
||||
LOCALE:
|
||||
@ -33,10 +23,29 @@ LOCALE:
|
||||
# 关闭可提升性能
|
||||
# 如果需要开启仍然可以在语言文件中加入 papi: true
|
||||
USE_PAPI: false
|
||||
|
||||
# 玩家列表(TAB)是否根据前缀排序
|
||||
# 启用后将会导致部分通过计分板获取玩家数据的插件出错(BedwarsRel、SkyWars)
|
||||
TABLIST-SORT: false
|
||||
|
||||
# 是否注入 PluginManager,关闭后可能会导致部分功能出错。
|
||||
PLUGIN-INJECTOR:
|
||||
ENABLE: true
|
||||
# 检测下面的插件并自动关闭注入
|
||||
DISABLE-ON-PLUGIN-EXISTS:
|
||||
- LuckPerms
|
||||
|
||||
# 是否在当前服务器启用交流网终端
|
||||
# 启用后将会收到大量调试信息, 不建议使用
|
||||
SERVER: false
|
||||
|
||||
# 网络连接测试地址
|
||||
TEST-URL: 'aliyun.com'
|
||||
|
||||
# 下载依赖时启用的线程数
|
||||
DOWNLOAD-POOL-SIZE: 4
|
||||
|
||||
# 玩家列表(TAB-API)是否根据前缀排序
|
||||
TABLIST-SORT: true
|
||||
|
||||
# 玩家列表(TAB-API)是否自动清理没有成员的队伍
|
||||
TABLIST-AUTO-CLEAN-TEAM: true
|
||||
|
||||
# 是否启用更新检测
|
||||
UPDATE-CHECK: true
|
||||
@ -62,6 +71,7 @@ ENABLE-UUID: false
|
||||
HIDE-NOTIFY: true
|
||||
|
||||
# 数据库信息
|
||||
# 该功能在当前版本下无法使用,请勿启用
|
||||
MYSQL:
|
||||
# 是否启用数据库
|
||||
ENABLE: false
|
||||
@ -77,7 +87,7 @@ MYSQL:
|
||||
DATABASE: 'test'
|
||||
# 数据表前缀
|
||||
PREFIX: 'taboolib'
|
||||
|
||||
|
||||
# 全局变量信息
|
||||
PluginData:
|
||||
# 检查更新间隔(单位:秒)
|
||||
|
@ -1,8 +1,11 @@
|
||||
TLIB:
|
||||
INJECTION-SUCCESS: '注入成功'
|
||||
INJECTION-FAILED:
|
||||
- '注入失败'
|
||||
- '&c提前加载依赖于 TabooLib 的所有插件的相关功能'
|
||||
- '注入失败'
|
||||
- '&c提前加载依赖于 TabooLib 的所有插件的相关功能'
|
||||
INJECTION-DISABLED:
|
||||
- '关闭注入'
|
||||
- '&c提前加载依赖于 TabooLib 的所有插件的相关功能'
|
||||
LOAD-FAIL-OFFLINE:
|
||||
- '**********************************************'
|
||||
- '** TabooLib-{0} 无法在您的服务器上使用'
|
||||
@ -12,15 +15,15 @@ TLIB:
|
||||
- '**'
|
||||
- '** 详情查阅: https://github.com/Bkm016/TabooLib'
|
||||
- '**********************************************'
|
||||
|
||||
|
||||
DEPENDENCY:
|
||||
DOWNLOAD-OFFLINE: '已启用离线模式, 将不会下载第三方依赖库'
|
||||
DOWNLOAD-CONNECTED: ' 正在下载 {0} 大小 {1}'
|
||||
DOWNLOAD-PROGRESS: ' 下载速度 {0} 进度 {1}'
|
||||
DOWNLOAD-SUCCESS: ' 下载 {0} 完成'
|
||||
DOWNLOAD-FAILED:
|
||||
- ' 下载 {0} 失败'
|
||||
- ' 请手动下载 {1} 并重命名为 {2} 后放在 /{0}/libs 文件夹内'
|
||||
- ' 下载 {0} 失败'
|
||||
- ' 请手动下载 {1} 并重命名为 {2} 后放在 /{0}/libs 文件夹内'
|
||||
PLUGIN-AUTOLOAD-FAIL: '{0} 所依赖的插件 {1} 尝试自动加载失败,请尝试手动下载'
|
||||
PLUGIN-LOAD-SUCCESS: ' {0} 请求的插件 {1} 加载成功'
|
||||
PLUGIN-LOAD-FAIL: ' {0} 请求的插件 {1} 加载失败'
|
||||
@ -28,7 +31,8 @@ DEPENDENCY:
|
||||
LIBRARY-LOAD-SUCCESS: ' {0} 请求的库文件 {1} 加载成功'
|
||||
LIBRARY-LOAD-FAIL: ' {0} 请求的库文件 {1} 加载失败'
|
||||
LOAD-COMPLETE: '依赖加载完成'
|
||||
|
||||
LOAD-CLASSES: '&7缓存 &f{0} &7插件的 &f{1} &7个类耗时&f {2} &7毫秒.'
|
||||
|
||||
CONFIG:
|
||||
LOAD-FAIL-NO-ANNOTATION: '插件 {0} 的配置类 {1} 加载失败:没有 @Config 注解'
|
||||
LOAD-FAIL: '插件 {0} 的配置类 {1} 加载失败:没有 @Config 注解'
|
||||
@ -40,7 +44,7 @@ CONFIG:
|
||||
RELOAD-SUCCESS: '插件 {0} 的配置 {1} 成功重载'
|
||||
RELOAD-FAIL: '插件 {0} 的配置 {1} 成功重载'
|
||||
LISTEN-START: '开始监听 {0} 插件的 {1} 配置文件'
|
||||
|
||||
|
||||
NOTIFY:
|
||||
ERROR-SERVER-KEY: '&4检测到本服序列号与其他服务器相同, 已重新生成!'
|
||||
ERROR-CONNECTION-FAIL: '&4数据库连接失败, 请检查配置是否正确!'
|
||||
@ -55,7 +59,7 @@ NOTIFY:
|
||||
FAIL-DISABLE:
|
||||
- '&c插件尚未启动完成, 已跳过卸载代码'
|
||||
- '&c插件作者: &4坏黑'
|
||||
|
||||
|
||||
LOCALE:
|
||||
TITLE-SEND-TO-NON-PLAYER: '该语言类型只能发送给玩家:{0}'
|
||||
PLUGIN-NOT-FOUND: '无效的语言文件发送形式: &4{0}'
|
||||
@ -65,36 +69,36 @@ LOCALE:
|
||||
BAR-PLUGIN-NOT-FOUND: 'TLocaleBossBar 的依赖插件 BossBarAPI 不存在'
|
||||
CALLER-PLUGIN-NOT-FOUND: '{0} 不是一个由插件加载的类'
|
||||
STATIC-CLASS-LOADER: '{0} 由静态类加载器初始化,无法获得其从属的插件'
|
||||
|
||||
|
||||
MISC:
|
||||
FIELD-COPY-FAILED: '拷贝 {0} 对象失败'
|
||||
FIELD-COPY-ERROR: '拷贝 {0} 对象出错:{1}'
|
||||
|
||||
|
||||
COOLDOWNPACK:
|
||||
PACK-REGISTER: '注册冷却包: {0}, 时间: {1} 秒 ({2})'
|
||||
PACK-REGISTER-ANONYMOUS: '注册冷却包: {0}, 时间: {1} 秒 (匿名注册)'
|
||||
PACK-UNREGISTER: '注销冷却包: {0} (主动注销)'
|
||||
PACK-UNREGISTER-AUTO: '注销冷却包: {0} (自动注销)'
|
||||
|
||||
|
||||
GLOBAL-DATAMANAGER:
|
||||
ERROR-CHECK-VARIABLE: '&4变量 &c{0} &4载入异常: &c{1}'
|
||||
SUCCESS-LOADED-VARIABLE: '&7从数据库中获取 &f{0} &7个变量, 耗时: &f{1} &7(ms)'
|
||||
|
||||
|
||||
PLAYER-DATAMANAGER:
|
||||
ERROR-STORAGE-SQL: '不允许在储存模式为数据库的情况下获取离线玩家数据'
|
||||
ERROR-PLAYER-DATA: '&4玩家 &c{0} &4的数据载入出现异常: &c{1}'
|
||||
SUCCESS-SAVE-DATA: '&7保存 &f{0} &7条玩家数据, 耗时: &f{1} &7(ms)'
|
||||
|
||||
|
||||
ENTITY-UTILS:
|
||||
NOTFOUND-PROTOCOLLIB: '缺少前置插件 ProtocolLib'
|
||||
|
||||
|
||||
FILE-UTILS:
|
||||
FAIL-LOAD-CONFIGURATION: '&4配置文件载入失败!, 插件: &c{0}&4, 文件: &c{1}'
|
||||
|
||||
|
||||
DATA-UTILS:
|
||||
SUCCESS-SAVE-DATA: '&7保存 &f{0} &7条插件数据, 耗时: &f{1} &7(ms)'
|
||||
FAIL-SAVE-FILE: '&4文件 &c{0}&4 保存失败, 原因: &c{1}'
|
||||
|
||||
|
||||
ITEM-UTILS:
|
||||
FAIL-LOAD-ITEMS: '物品库载入失败: &4{0}'
|
||||
FAIL-LOAD-ATTRIBUTE: '&c{0} &4不是一个有效的属性名称, 输入 &c/tlib attributes&4 查看所有属性'
|
||||
@ -105,20 +109,13 @@ ITEM-UTILS:
|
||||
SUCCESS-LOAD-CACHES: '&7载入 &f{0} &7项缓存物品'
|
||||
SUCCESS-LOAD-NAMES: '&7载入 &f{0} &7项物品名称'
|
||||
EMPTY-ITEM: '空'
|
||||
|
||||
|
||||
LANGUAGE2:
|
||||
FAIL-NOTFOUND-FILE: '语言文件 {0} 不存在'
|
||||
|
||||
|
||||
TIMECYCLE:
|
||||
FAIL-CYCLE-EXISTS: '注册周期管理器 &8{0}&c 失败, 原因: &4名称重复'
|
||||
|
||||
ANVIL-CONTAINER:
|
||||
NAME-EXAMPLE: '在这里输入文本'
|
||||
LORE-NORMAL:
|
||||
- ''
|
||||
- '&7在上方文本框内输入信息'
|
||||
- '&7随后点击右侧输出物品'
|
||||
|
||||
|
||||
UPDATETASK:
|
||||
VERSION-FAIL: '&4更新记录获取失败, 请检查网络连接!'
|
||||
VERSION-LATEST: '&7插件已是最新版, 无需更新!'
|
||||
@ -130,7 +127,7 @@ UPDATETASK:
|
||||
- '&7 下载地址: &fhttp://www.mcbbs.net/thread-773065-1-1.html'
|
||||
- '&7 开源地址: &fhttps://github.com/Bkm016/TabooLib/'
|
||||
- '&8####################################################'
|
||||
|
||||
|
||||
MYSQL-CONNECTION:
|
||||
FAIL-CONNECT: '&4数据库 &c{0} &4连接失败, 原因: &c{0}'
|
||||
FAIL-NOTFOUND-DRIVE: '&7驱动器获取失败, 无法连接到数据库'
|
||||
@ -144,26 +141,26 @@ MYSQL-CONNECTION:
|
||||
SUCCESS-CONNECTION-CANCEL: '已停止插件 &f{0}&7 的 &f{1}&7 条数据库连接'
|
||||
NOTIFY-CONNECTING: '&7正在连接数据库, 地址: &f{0}'
|
||||
NOTIFY-CONNECTED: '&7数据库连接成功 ({0}ms)'
|
||||
|
||||
|
||||
MYSQL-HIKARI:
|
||||
CREATE-SUCCESS: '&7插件 &f{0}&7 注册新的数据库连接: &f{1}'
|
||||
CREATE-EXISTS: '&7插件 &f{0}&7 引用插件 &f{1}&7 注册的数据库连接'
|
||||
CLOSE-SUCCESS: '&7插件 &f{0} &7注册的数据库连接 &f{1} &7已被注销!'
|
||||
CLOSE-FAIL: '&7插件 &f{0} &7注册的数据库连接正在被 &f{1} &7个插件使用, 无法注销!'
|
||||
|
||||
|
||||
TABOOLIB-MODULE:
|
||||
SUCCESS-LOADED: '&7载入 &f{0} &7个 &fTLM &7模块'
|
||||
FAIL-LOADED: '&4模块载入异常: &c{0}&4, 模块: &c{1}&4, 位于: &c{2}'
|
||||
FAIL-RUNTIME: '&4模块运行异常: &c{0}&4, 模块: &c{1}&4, 位于: &c{2}'
|
||||
|
||||
|
||||
COMMANDS:
|
||||
GLOBAL:
|
||||
ONLY-PLAYER: '&8[&3&lTabooLib&8] &4控制台无法这么做'
|
||||
ONLY-STORAGE-SQL: '&8[&3&lTabooLib&8] &4只有启用数据库储存时才能这么做'
|
||||
INTERNAL:
|
||||
TYPE-ERROR: '&8[&3&lTabooLib&8] &7指令 &f{0} &7只能由 &f{1} &7执行'
|
||||
TYPE-PLAYER: 玩家
|
||||
TYPE-CONSOLE: 控制台
|
||||
TYPE-PLAYER: '玩家'
|
||||
TYPE-CONSOLE: '控制台'
|
||||
ERROR-USAGE:
|
||||
- '&8[&3&lTabooLib&8] &7指令 &f{0} &7参数不足'
|
||||
- '&8[&3&lTabooLib&8] &7正确用法:'
|
||||
@ -240,10 +237,9 @@ COMMANDS:
|
||||
DESCRIPTION: '&4更新插件 &8(谨防非正规途径的插件获取方式)'
|
||||
UPDATE-NOT-FOUND: '&8[&3&lTabooLib&8] &7插件已是最新版, 无需更新!'
|
||||
UPDATE-NOT-SUPPORT: '&8[&3&lTabooLib&8] &4您的服务器不支持在线更新!'
|
||||
UPDATE-SUCCESS: '&8[&3&lTabooLib&8] &7最新版下载完成, 服务器即将重启!'
|
||||
FILE-NOT-FOUND: '&8[&3&lTabooLib&8] &4尚未寻找到插件文件'
|
||||
PLAYER-ONLINE: '&8[&3&lTabooLib&8] &4服务器有玩家在线无法更新插件.'
|
||||
UPDATE-START: '&8[&3&lTabooLib&8] &7开始下载:&f {0}'
|
||||
UPDATE-SUCCESS: '&8[&3&lTabooLib&8] &7最新版下载完成, 服务器即将重启!'
|
||||
PLAYERTAG:
|
||||
DESCRIPTION:
|
||||
DISPLAY: '设置玩家展示名称'
|
||||
@ -385,7 +381,7 @@ COMMANDS:
|
||||
hover: '&f点击复制'
|
||||
suggest: '{0}'
|
||||
FOOT:
|
||||
- ''
|
||||
- ''
|
||||
ENCHANTS:
|
||||
DESCRIPTION: '查看所有附魔'
|
||||
HEAD:
|
||||
@ -430,7 +426,7 @@ COMMANDS:
|
||||
hover: '&f点击复制'
|
||||
suggest: '{0}'
|
||||
FOOT:
|
||||
- ''
|
||||
- ''
|
||||
SLOTS:
|
||||
DESCRIPTION: '查看所有部位'
|
||||
HEAD:
|
||||
@ -473,7 +469,7 @@ COMMANDS:
|
||||
COMMAND-TITLE: '&e&l----- &6&lTabooLibPlugin Commands &e&l-----'
|
||||
LIST:
|
||||
DESCRIPTION: '列出插件'
|
||||
LIST-PLUGIN:
|
||||
LIST-PLUGIN:
|
||||
- '&8[&3&lTabooLib&8] &7插件总数: &f{0}'
|
||||
- '&8[&3&lTabooLib&8] &7插件列表: &f{1}'
|
||||
INFO:
|
||||
@ -533,7 +529,13 @@ COMMANDS:
|
||||
1: '内容'
|
||||
INVALID-PLAYER-OFFLINE: '&8[&3&lTabooLib&8] &4玩家 &c{0} &4不在线.'
|
||||
COMMAND:
|
||||
DESCRIPTION: '使目标输入执行指令'
|
||||
DESCRIPTION: '使目标执行指令'
|
||||
ARGUMENTS:
|
||||
0: '目标'
|
||||
1: '内容'
|
||||
INVALID-TARGET-NOT-FOUND: '&8[&3&lTabooLib&8] &4目标 &c{0} &4不存在.'
|
||||
COMMAND-AS-OP:
|
||||
DESCRIPTION: '使目标以管理员身份执行指令'
|
||||
ARGUMENTS:
|
||||
0: '目标'
|
||||
1: '内容'
|
||||
@ -562,13 +564,20 @@ COMMANDS:
|
||||
DATABASE:
|
||||
CONNECTION-ESTABLISHED: '成功连接到 {0} 数据库,连接池大小 {1}'
|
||||
CONNECTION-ERROR: '连接到数据库错误:{0}'
|
||||
|
||||
|
||||
COMMUNICATION:
|
||||
FAILED-LOAD-SETTINGS: '§8[§3§lTabooLibClient§8] &4配置载入失败: {0}'
|
||||
FAILED-CONNECT-SERVER: '§8[§3§lTabooLibClient§8] &4本地通讯网络连接失败.'
|
||||
FAILED-CONNECT-CLIENT: '§8[§3§lTabooLibClient§8] &4本地通讯网络连接出错: {0}'
|
||||
FAILED-READING-PACKET: '§8[§3§lTabooLibClient§8] &4本地通讯网络数据包读取失败: {0}'
|
||||
SUCCESS-CONNECTED: '§8[§3§lTabooLibClient§8] &7本地通讯网络连接成功.'
|
||||
CLIENT-JOINED: '§8[§3§lTabooLibClient§8] &7服务器 &flocalhost:{0} &7加入本地通讯网络.'
|
||||
CLIENT-QUITED: '§8[§3§lTabooLibClient§8] &7服务器 &flocalhost:{0} &7退出本地通讯网络.'
|
||||
PACKET-MESSAGE: '§8[§3§lTabooLibClient§8] &7服务器 &flocalhost:{0} &7发送信息: &f{1}'
|
||||
CLIENT-JOINED: '§8[§3§lTabooLibClient§8] &7服务器 &f{0} &7加入本地通讯网络.'
|
||||
CLIENT-QUITED: '§8[§3§lTabooLibClient§8] &7服务器 &f{0} &7退出本地通讯网络.'
|
||||
PACKET-MESSAGE: '§8[§3§lTabooLibClient§8] &7服务器 &f{0} &7发送信息: &f{1}'
|
||||
PACKET-COMMAND: '§8[§3§lTabooLibClient§8] &7服务器 &f{0} &7运行命令: &f{1}'
|
||||
|
||||
UTIL:
|
||||
DOWNLOAD-CONNECTED: '开始下载文件 {0} 大小 {1}'
|
||||
DOWNLOAD-PROGRESS: ' 下载速度 {0} 进度 {1}'
|
||||
DOWNLOAD-SUCCESS: '下载 {0} 完成!'
|
||||
DOWNLOAD-FAILED: '下载 {0} 失败!'
|
@ -4,12 +4,4 @@ version: ${project.version}
|
||||
|
||||
author: [lzzelAliz, 坏黑]
|
||||
depend: [Vault]
|
||||
softdepend: [PlaceholderAPI, Skript, MassiveLag]
|
||||
|
||||
# 两个命令删除预定
|
||||
commands:
|
||||
language2:
|
||||
aliases: [lang2]
|
||||
permission: taboolib.admin
|
||||
taboolibrarymodule:
|
||||
aliases: [tlm]
|
||||
softdepend: [PlaceholderAPI, Skript, MassiveLag]
|
Loading…
Reference in New Issue
Block a user