commit
2d68d8e2a8
@ -38,9 +38,9 @@
|
||||
---
|
||||
| 命令 | 作用 | 权限 |
|
||||
| --- | --- | --- |
|
||||
| /tabooliblocale | 语言文件 | taboolib.admin |
|
||||
| /taboolibplugin | 插件管理 | taboolib.admin |
|
||||
| /taboolibexecute | 命令执行 | taboolib.admin |
|
||||
| /tLocale | 语言文件 | taboolib.admin |
|
||||
| /tPlugin | 插件管理 | taboolib.admin |
|
||||
| /tExecute | 命令执行 | taboolib.admin |
|
||||
|
||||
<br>
|
||||
|
||||
|
13
build.gradle
13
build.gradle
@ -5,7 +5,7 @@ plugins {
|
||||
id 'com.github.johnrengelman.shadow' version '4.0.4'
|
||||
}
|
||||
group = 'me.skymc'
|
||||
version = '4.9'
|
||||
version = '5.0'
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
@ -28,14 +28,11 @@ dependencies {
|
||||
exclude(module: 'log4j')
|
||||
}
|
||||
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.8'
|
||||
shadow group: 'com.zaxxer', name: 'HikariCP', version: '3.1.0'
|
||||
shadow group: 'org.javalite', name: 'activejdbc', version: '2.0'
|
||||
compile group: 'org.ow2.asm', name: 'asm', version: '7.0-beta'
|
||||
compile group: 'com.google.code.gson', name: 'gson', version: '2.7'
|
||||
shadow group: 'com.h2database', name: 'h2', version: '1.4.197'
|
||||
shadow group: 'me.clip', name: 'placeholderapi', version: '2.8.4'
|
||||
shadow group: 'net.objecthunter', name: 'exp4j', version: '0.4.8'
|
||||
shadow group: 'com.zaxxer', name: 'HikariCP', version: '3.1.0'
|
||||
shadow group: 'org.scala-lang', name: 'scala-library', version: '2.12.8'
|
||||
shadow group: 'me.clip', name: 'placeholderapi', version: '2.8.4'
|
||||
shadow fileTree(dir: 'libs', includes: ['*.jar'])
|
||||
}
|
||||
|
||||
@ -48,11 +45,11 @@ processResources {
|
||||
inputs.property "version", project.version
|
||||
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
include 'plugin.yml'
|
||||
include 'version'
|
||||
expand 'version': project.version
|
||||
}
|
||||
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
exclude 'plugin.yml'
|
||||
exclude 'version'
|
||||
}
|
||||
}
|
76
cloud.json
76
cloud.json
@ -1,76 +0,0 @@
|
||||
{
|
||||
"plugins": {
|
||||
"TabooMenu": {
|
||||
"author": [
|
||||
"Bkm016",
|
||||
"filoghost"
|
||||
],
|
||||
"description": "一款高自由,高效率,功能丰富的菜单插件。",
|
||||
"detail": [
|
||||
"独创忽略大小写式节点判断",
|
||||
"保留 ChestCommands 载入格式,更换插件直接复制文件",
|
||||
"保留 ChestCommands 的大部分节点",
|
||||
"保留 ChestCommands 的 51 项物品别名",
|
||||
"保留 ChestCommands 的 cc 指令,直接更换也不会影响其他插件",
|
||||
"更简单的物品坐标写法",
|
||||
"更强大的指令功能,多达 7 种触发方式,17 种执行方式",
|
||||
"更强大的物品扣除功能,多达 6 种检测方式",
|
||||
"更直观的物品条件写法",
|
||||
"更智能的菜单刷新方式",
|
||||
"物品 ID 容错,智能匹配",
|
||||
"关闭菜单时自动打开其他菜单",
|
||||
"点击/查看物品时执行自定义脚本",
|
||||
"PlaceholderAPI 支持。",
|
||||
"独立权限控制",
|
||||
"在线模板编辑",
|
||||
"冷却时间",
|
||||
"..."
|
||||
],
|
||||
"version": "1.73",
|
||||
"last_update": "2018-7-4",
|
||||
"last_update_note": "修复优先级问题",
|
||||
"link": "https://gitee.com/bkm016/TabooLibCloud/raw/master/plugins/TabooMenu.jar"
|
||||
},
|
||||
"TabooScript": {
|
||||
"author": [
|
||||
"lzzelAliz",
|
||||
"Bkm016"
|
||||
],
|
||||
"description": "告别 Java 开启奔放脚本时代。",
|
||||
"detail": [
|
||||
"快速上手,写法自由,功能强大",
|
||||
"超强 Bukkit 脚本拓展"
|
||||
],
|
||||
"version": "1.3",
|
||||
"last_update": "2018-10-1",
|
||||
"last_update_note": "-",
|
||||
"link": "https://gitee.com/bkm016/TabooLibCloud/raw/master/plugins/TabooScript.jar"
|
||||
},
|
||||
"TabooLibBungeeSuite": {
|
||||
"author": [
|
||||
"Bkm016"
|
||||
],
|
||||
"description": "用于 BungeeCord 与 Bukkit 之间的快速交流工具。",
|
||||
"detail": [
|
||||
"本插件为前置依赖无详细介绍"
|
||||
],
|
||||
"version": "1.3",
|
||||
"last_update": "2018-6-21",
|
||||
"last_update_note": "-",
|
||||
"link": "https://gitee.com/bkm016/TabooLibCloud/raw/master/plugins/TabooLibBungeeSuite.jar"
|
||||
},
|
||||
"TabooSK": {
|
||||
"author": [
|
||||
"Bkm016"
|
||||
],
|
||||
"description": "Skript 扩展插件。",
|
||||
"detail": [
|
||||
"计分板、配置文件、时间戳等高性能语法。"
|
||||
],
|
||||
"version": "2.2",
|
||||
"last_update": "2018-8-14",
|
||||
"last_update_note": "更新了MythicMobs的物品获取语法",
|
||||
"link": "https://gitee.com/bkm016/TabooLibCloud/raw/master/plugins/TabooSK.jar"
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
@ -1,125 +0,0 @@
|
||||
# UTF-8
|
||||
|
||||
# 错误代码:
|
||||
# 0:语言文件不存在
|
||||
# 1:语言文本不存在
|
||||
# 10: 大标题语言类型识别异常
|
||||
# 11: 动作栏语言类型识别异常
|
||||
# 12: 动作栏重复次数异常
|
||||
# 20: JSON 空文本异常
|
||||
# 21: JSON 语言类型识别异常
|
||||
# 30: 大标题不兼容当前版本服务器
|
||||
# 31: 动作栏不兼容当前版本服务器
|
||||
# 40: 语言文件类型异常
|
||||
# 50: BOOK 语言类型指定 option 不存在
|
||||
# 51: BOOK 语言类型识别异常
|
||||
# 52: BOOK 语言类型 url 地址错误(http:// or https://)
|
||||
# 60: JSON2 语言类型指定 option 不存在
|
||||
# 61: JSON2 语言类型识别异常
|
||||
|
||||
# 正常提示
|
||||
TEXT: '&f正常的提示'
|
||||
|
||||
# 多行正常提示
|
||||
# 类型 [text] 可以省略不写
|
||||
TEXT-MULTI:
|
||||
- '[text]'
|
||||
- '&f正常的提示 - 1'
|
||||
- '&f正常的提示 - 2'
|
||||
|
||||
# JSON提示 + 占位符
|
||||
# 占位符注释需要追加到第一行类型末尾
|
||||
PAPI-TEXT:
|
||||
- '[json][papi]'
|
||||
- '&f变量提示, 玩家名称: %player_name%'
|
||||
|
||||
# JSON提示
|
||||
JSON-NORMAL-TEXT:
|
||||
- '[json]'
|
||||
- '提示信息 - 1'
|
||||
- ' text: 这是一个一般提示'
|
||||
|
||||
# JSON提示
|
||||
JSON-COMMAND-TEXT:
|
||||
- '[json]'
|
||||
- '提示信息 - 2'
|
||||
- ' text: 点击执行指令'
|
||||
- ' command: /say %player% 牛逼'
|
||||
|
||||
# JSON提示
|
||||
JSON-SUGGEST-TEXT:
|
||||
- '[json]'
|
||||
- '提示信息 - 3'
|
||||
- ' text: 点击打印指令'
|
||||
- ' suggest: /say %player% 牛逼'
|
||||
|
||||
# JSON提示
|
||||
# [breka] 注释为 JSON 提示类型中的换行符
|
||||
JSON-MULTILINE-TEXT:
|
||||
- '[json]'
|
||||
- '提示信息 - 4'
|
||||
- ' text: 这是一段换行提示1'
|
||||
- '&a (单行追加内容)'
|
||||
- '[break]'
|
||||
- '提示信息 - 6'
|
||||
- ' text: 这是一段换行提示3'
|
||||
- '&a (单行追加内容)'
|
||||
|
||||
# 大标题提示
|
||||
TITLE-TEXT:
|
||||
- '[title]'
|
||||
- ' title: 大标题'
|
||||
- ' subtitle: 小标题'
|
||||
- ' stay: 10|40|10'
|
||||
|
||||
# 动作栏提示
|
||||
ACTION-TEXT:
|
||||
- '[action]'
|
||||
- ' text: 动作栏提示'
|
||||
- ' repeat: 10'
|
||||
|
||||
# 多类型混合
|
||||
TITLE-ACTION-TEXT:
|
||||
- '[title]'
|
||||
- ' title: 大标题'
|
||||
- ' subtitle: 小标题'
|
||||
- ' stay: 10|40|10'
|
||||
- '[action]'
|
||||
- ' text: 动作栏提示'
|
||||
- ' repeat: 10'
|
||||
|
||||
# 音效 + 文本提示
|
||||
SOUND-TEXT:
|
||||
- '[text]'
|
||||
- '单行文本 - 1'
|
||||
- '单行文本 - 2'
|
||||
- '[sound]'
|
||||
- 'BLOCK_ANVIL_USE-1-1'
|
||||
|
||||
# 书本界面
|
||||
BOOK-TEXT:
|
||||
- '[book]'
|
||||
- '书本单行文本'
|
||||
- '&4书本单行文本'
|
||||
- '&4&l书本单行文本'
|
||||
- '[page]'
|
||||
- '<@1>'
|
||||
- '<@1> | <@1> 单行重复变量'
|
||||
- '<@1> | <@2> 单行不同变量'
|
||||
- '@option:1'
|
||||
- ' text: 文本'
|
||||
- ' command: 执行命令'
|
||||
- ' showtext: 显示文本'
|
||||
- '@option:2'
|
||||
- ' text: 测试'
|
||||
- ' command: 执行命令'
|
||||
- ' showtext: 显示文本'
|
||||
|
||||
# JSON2
|
||||
JSON-NEW:
|
||||
- '[json2]'
|
||||
- '新 <@1> 内容 - 1'
|
||||
- '新 <@1> 内容 - 2'
|
||||
- '@option:1'
|
||||
- ' text: JSON'
|
||||
- ' showtext: 展示文本'
|
@ -1,66 +0,0 @@
|
||||
COMMAND-ERROR: '&8[&3&lTLM&8] &4指令错误'
|
||||
COMMAND-HELP:
|
||||
- ''
|
||||
- '&b&l----- &3&lTaooLibraryModule Commands &b&l-----'
|
||||
- ''
|
||||
- '&f /tlm kit list &6- &e列出所有礼包'
|
||||
- '&f /tlm kit reward &8[&7名称] &8<&7名称&8> &6- &e领取礼包'
|
||||
- '&f /tlm kit reset &8[&7名称] &8<&7玩家&8> &6- &e刷新礼包'
|
||||
- ''
|
||||
- '&f /tlm inv list &6- &e列出所有保存的背包'
|
||||
- '&f /tlm inv info &8[&7名称] &6- &e查看保存背包'
|
||||
- '&f /tlm inv save &8[&7名称] &6- &e保存当前背包'
|
||||
- '&f /tlm inv paste &8[&7名称] &8<&7玩家&8> &8<&7-b|a&8> &6- &e覆盖背包'
|
||||
- '&f /tlm inv delete &8[&7名称] &6- &e删除保存背包'
|
||||
- ''
|
||||
- '&f /tlm list &6- &e列出所有模块'
|
||||
- ''
|
||||
- '&f /tlm reload &8[&7模块名|TLM|ALL&8] &6- &e列出所有模块'
|
||||
- ''
|
||||
|
||||
# 3.58 增加
|
||||
NOPERMISSION-HELP: '&8[&3&lTLM&8] &4你没有权限列出帮助命令'
|
||||
NOPERMISSION-LIST: '&8[&3&lTLM&8] &4你没有权限这么做'
|
||||
NOPERMISSION-RELOAD: '&8[&3&lTLM&8] &4你没有权限这么做'
|
||||
NOPERMISSION-KIT-REWARD: '&8[&3&lTLM&8] &4你没有权限这么做'
|
||||
NOPERMISSION-KIT-RESET: '&8[&3&lTLM&8] &4你没有权限这么做'
|
||||
|
||||
# 3.60 新增
|
||||
NOPERMISSION-KIT-LIST: '&8[&3&lTLM&8] &4你没有权限这么做'
|
||||
NOPERMISSION-INV: '&8[&3&lTLM&8] &4你没有权限这么做'
|
||||
|
||||
# 3.59 增加
|
||||
KIT-EMPTY: '&8[&3&lTLM&8] &4参数错误'
|
||||
KIT-NAME: '&8[&3&lTLM&8] &4请输入正确的礼包名称'
|
||||
KIT-DISABLE: '&8[&3&lTLM&8] &4该模块尚未在配置文件中启用'
|
||||
KIT-NOTFOUND: '&8[&3&lTLM&8] &4礼包 &c$kit &4不存在'
|
||||
KIT-OFFLINE: '&8[&3&lTLM&8] &4玩家 &c$name &4不在线'
|
||||
KIT-CONSOLE: '&8[&3&lTLM&8] &4后台不允许输入这个指令'
|
||||
KIT-COOLDOWN: '&8[&3&lTLM&8] &4礼包 &c$kit &4正在冷却中'
|
||||
KIT-DISPOSABLE: '&8[&3&lTLM&8] &4礼包 &c$kit &4只能领取一次'
|
||||
KIT-RESET-ALL: '&8[&3&lTLM&8] &7礼包 &f$kit &7已刷新'
|
||||
KIT-RESET-PLAYER: '&8[&3&lTLM&8] &7玩家 &f$player &7的礼包 &f$kit &7已刷新'
|
||||
KIT-SUCCESS: '&8[&3&lTLM&8] &7礼包 &f$kit &7已领取'
|
||||
KIT-PLACEHOLDER:
|
||||
0: '&4模块未启用'
|
||||
1: '&4礼包不存在'
|
||||
2: '&8已领取'
|
||||
3: '&a可领取'
|
||||
4: '&4冷却中'
|
||||
5: '&4无权限'
|
||||
|
||||
# 3.60 新增
|
||||
KIT-LIST: '&8[&3&lTLM&8] &7当前礼包: &f$kits'
|
||||
|
||||
# 3.60 增加
|
||||
INV-EMPTY: '&8[&3&lTLM&8] &4参数错误'
|
||||
INV-DISABLE: '&8[&3&lTLM&8] &4该模块尚未在配置文件中启用'
|
||||
INV-CONSOLE: '&8[&3&lTLM&8] &4该命令不允许控制台执行'
|
||||
INV-NAME: '&8[&3&lTLM&8] &4请输入正确的背包名称'
|
||||
INV-LIST: '&8[&3&lTLM&8] &7当前已保存背包: &f$name'
|
||||
INV-NOTFOUND: '&8[&3&lTLM&8] &4背包 &c$name &4不存在'
|
||||
INV-INFO-TITLE: '背包信息: $name'
|
||||
INV-SAVE: '&8[&3&lTLM&8] &7背包 &f$name &7已保存!'
|
||||
INV-OFFLINE: '&8[&3&lTLM&8] &4玩家 &c$name &4不在线'
|
||||
INV-PASTE: '&8[&3&lTLM&8] &7背包 &f$name &7已覆盖到玩家 &f$player&7!'
|
||||
INV-DELETE: '&8[&3&lTLM&8] &4背包 &c$name &4已删除'
|
@ -1,14 +0,0 @@
|
||||
# 指令配置
|
||||
Commands:
|
||||
# 配置序号(不可重复)
|
||||
test:
|
||||
# 输入命令
|
||||
Input: '/kit'
|
||||
# 替换命令
|
||||
Replace: '/tlm kit'
|
||||
# 替换模式(省略默认全部)
|
||||
# ---------- #
|
||||
# CONSOLE = 后台
|
||||
# PLAYER = 玩家
|
||||
# ---------- #
|
||||
ReplaceMode: 'PLAYER'
|
@ -1,34 +0,0 @@
|
||||
# 礼包配置
|
||||
Kits:
|
||||
# 礼包名
|
||||
kit_name:
|
||||
# 礼包刷新时间
|
||||
# ---------- #
|
||||
# 1d = 1天
|
||||
# 1h = 1小时
|
||||
# 1m = 1分钟
|
||||
# 1s = 1秒钟
|
||||
# 时间之间用 ";" 分隔, 例如 1小时30分钟 = "1h;30m"
|
||||
# ---------- #
|
||||
Cooldown: '1d'
|
||||
|
||||
# 背包空间不足时物品是否掉落
|
||||
FullDrop: true
|
||||
|
||||
# 是否只能领取一次
|
||||
Disposable: false
|
||||
|
||||
# 礼包领取权限
|
||||
Permission: 'taboolib.kit.kit_name'
|
||||
|
||||
# 礼包领取权限提示
|
||||
Permission-message: '&4你没有权限领取这个礼包'
|
||||
|
||||
# 礼包内容
|
||||
# 空格左侧为物品名,右侧为物品数量
|
||||
Items:
|
||||
- 'UnlimitSword 1'
|
||||
|
||||
# 礼包命令
|
||||
Commands:
|
||||
- 'say $player 领取了礼包 kit_name!'
|
@ -1,35 +0,0 @@
|
||||
# 时间检查器
|
||||
TimeCycle:
|
||||
# 检查器名称
|
||||
cycle_name:
|
||||
# 检查器周期
|
||||
# ---------- #
|
||||
# 1d = 1天
|
||||
# 1h = 1小时
|
||||
# 1m = 1分钟
|
||||
# 1s = 1秒钟
|
||||
# 时间之间用 ";" 分隔, 例如 1小时30分钟 = "1h;30m"
|
||||
# ---------- #
|
||||
Cycle: '1d'
|
||||
|
||||
# 更新配置
|
||||
UpdateCommand:
|
||||
- 'say 检查器 cycle_name 更新!'
|
||||
|
||||
# 初始化配置
|
||||
Initialise:
|
||||
# 初始化时间
|
||||
# 特殊时间
|
||||
# - DAY_OF_WEEK = 本周第几天 (最小:1)
|
||||
# - DAY_OF_MONTH = 本月第几天 (最小:1)
|
||||
InitialiseDate:
|
||||
# 初始化时将小时设置为 0
|
||||
- 'HOUR_OF_DAY=0'
|
||||
# 初始化时将分钟设置为 0
|
||||
- 'MINUTE=0'
|
||||
# 初始化时将秒钟设置为 0
|
||||
- 'SECOND=0'
|
||||
|
||||
# 初始化命令
|
||||
InitialiseCommand:
|
||||
- 'say 检查器 cycle_name 初始化完成!'
|
@ -1,5 +0,0 @@
|
||||
name: TabooLib
|
||||
main: me.skymc.taboolib.bungee.TabooLibBungee
|
||||
version: ${project.version}
|
||||
|
||||
author: [lzzelAliz, 坏黑]
|
@ -1,98 +0,0 @@
|
||||
# 权限不足时提示
|
||||
NO-PERMISSION-MESSAGE: '&f&l(&4&l?&f&l) &c你没有权利这么做'
|
||||
# 不满足条件时提示
|
||||
NO-CLAIM-MESSAGE: '&f&l(&4&l?&f&l) &c你现在还不能这么做 &7(%s%&7)'
|
||||
|
||||
# 数据储存地址
|
||||
# 该配置将在启用数据库储存时失效
|
||||
DATAURL:
|
||||
# 玩家数据
|
||||
PLAYER-DATA: 'plugins/TabooLib/playerdata/'
|
||||
# 插件数据
|
||||
SERVER-DATA: 'plugins/TabooLib/serverdata/'
|
||||
# 物品数据(来自 ItemSave 插件)
|
||||
ITEMDIR: 'plugins/Skript/scripts/config/item.yml'
|
||||
|
||||
# 语言文件相关设置
|
||||
LOCALE:
|
||||
# 加载语言文件的顺序
|
||||
PRIORITY:
|
||||
- zh_CN
|
||||
- en_US
|
||||
# 默认是否启用语言文件中 PlaceholderAPI 的替换功能
|
||||
# 关闭可提升性能
|
||||
# 如果需要开启仍然可以在语言文件中加入 papi: true
|
||||
USE_PAPI: false
|
||||
|
||||
# 是否注入 PluginManager,关闭后可能会导致部分功能出错。
|
||||
PLUGIN-INJECTOR:
|
||||
ENABLE: true
|
||||
# 检测下面的插件并自动关闭注入
|
||||
DISABLE-ON-PLUGIN-EXISTS:
|
||||
- LuckPerms
|
||||
|
||||
# 是否在当前服务器启用交流网终端
|
||||
# 启用后将会收到大量调试信息, 不建议使用
|
||||
SERVER: false
|
||||
|
||||
# 网络连接测试地址
|
||||
TEST-URL: 'aliyun.com'
|
||||
|
||||
# 玩家列表(TAB-API)是否根据前缀排序
|
||||
TABLIST-SORT: true
|
||||
|
||||
# 玩家列表(TAB-API)是否自动清理没有成员的队伍
|
||||
TABLIST-AUTO-CLEAN-TEAM: true
|
||||
|
||||
# 是否启用发包(禁用后会影响 tagDisplay() 方法的使用)
|
||||
TABLIST-PACKET: true
|
||||
|
||||
# 是否启用更新检测
|
||||
UPDATE-CHECK: true
|
||||
|
||||
# 是否启用自动更新
|
||||
UPDATE-DOWNLOAD: false
|
||||
|
||||
# 是否启用附属插件异常拦截
|
||||
EXCEPTION-MIRROR: true
|
||||
|
||||
# 是否在关闭服务器时清理玩家数据
|
||||
# 该配置将在启用数据库储存时失效
|
||||
DELETE-DATA: false
|
||||
|
||||
# 是否在服务器关闭时清理无效变量
|
||||
# 该配置仅在启用数据库储存时有效
|
||||
# 该方法可能会导致数据丢失?
|
||||
# 不建议开启
|
||||
DELETE-VARIABLE: false
|
||||
|
||||
# 是否以 UUID 的形式创建玩家数据
|
||||
# 不建议开启!除非用 TabooLib 储存的插件支持新版储存方式!
|
||||
ENABLE-UUID: false
|
||||
|
||||
# 是否隐藏保存数据的提示
|
||||
HIDE-NOTIFY: true
|
||||
|
||||
# 数据库信息
|
||||
# 该功能在当前版本下无法使用,请勿启用
|
||||
MYSQL:
|
||||
# 是否启用数据库
|
||||
ENABLE: false
|
||||
# 数据库地址
|
||||
HOST: 'localhost'
|
||||
# 数据库端口
|
||||
PORT: 3306
|
||||
# 数据库用户
|
||||
USER: root
|
||||
# 数据库密码
|
||||
PASSWORD: ''
|
||||
# 数据库名称
|
||||
DATABASE: 'test'
|
||||
# 数据表前缀
|
||||
PREFIX: 'taboolib'
|
||||
|
||||
# 全局变量信息
|
||||
PluginData:
|
||||
# 检查更新间隔(单位:秒)
|
||||
# 检查变量是否被其他服务器更新
|
||||
CHECK-DELAY: 5
|
@ -1,51 +0,0 @@
|
||||
UnlimitSword:
|
||||
material: DIAMOND_SWORD
|
||||
name: '&b&nUnlimitSword'
|
||||
lore:
|
||||
- ''
|
||||
- '&8&oAn sword of infinitely durable'
|
||||
- '&8&oAnd hide attributes lore'
|
||||
- ''
|
||||
flags:
|
||||
- HIDE_ATTRIBUTES
|
||||
nbt:
|
||||
Unbreakable: 1
|
||||
|
||||
ColorLeather:
|
||||
material: LEATHER_CHESTPLATE
|
||||
name: '&aLe&2at&3he&4r C&5he&6st&7pl&8at&9e'
|
||||
lore:
|
||||
- ''
|
||||
- '&8&oA chestplate of colored'
|
||||
- '&8&oAnd enchanted with &7DURABILITY I'
|
||||
- ''
|
||||
enchants:
|
||||
DURABILITY: 1
|
||||
color: 255-0-0
|
||||
|
||||
SpeedPotion:
|
||||
material: POTION
|
||||
name: '&1&nSpeed Potion'
|
||||
lore:
|
||||
- ''
|
||||
- '&8&oA potion of &7SPEED I'
|
||||
- '&8&oAnd not have Particles'
|
||||
- ''
|
||||
potions:
|
||||
SPEED: 200-5
|
||||
|
||||
KingsAxe:
|
||||
material: GOLD_AXE
|
||||
name: '&e&nKingsAxe'
|
||||
lore:
|
||||
- ''
|
||||
- '&6&o100 damage !!!'
|
||||
- '&6&o30% speed !!!'
|
||||
- ''
|
||||
- '&e&oA knife a pupil !!!'
|
||||
- ''
|
||||
attributes:
|
||||
mainhand:
|
||||
damage: 100
|
||||
speed: 30%
|
||||
|
@ -1,8 +1,7 @@
|
||||
TRY-LOADING-LANG: '插件 {0} 尝试加载 {1} 作为语言文件'
|
||||
SUCCESS-LOADING-LANG-NORMAL: '成功加载 {0} 插件的 {1} 语言文件, 共 {2} 项'
|
||||
SUCCESS-LOADING-LANG-UPDATE: '成功加载 {0} 插件的 {1} 语言文件, 共 {2} 项, 及 {3} 项新条目'
|
||||
TRY-LOADING-LANG: '尝试为 {0} 加载 {1} 语言文件'
|
||||
SUCCESS-LOADING-LANG-NORMAL: '成功为 {0} 加载 {1} 语言文件, 共 {2} 项'
|
||||
SUCCESS-LOADING-LANG-UPDATE: '成功为 {0} 加载 {1} 语言文件, 共 {2} 项, 及 {3} 项新条目'
|
||||
ERROR-LOADING-LANG: '加载 {0} 插件的语言文件时发生异常:{1}'
|
||||
RELOADING-LANG: '正在重新载入 {0} 插件的语言文件'
|
||||
FETCH-LOCALE-ERROR: '语言文件获取失败:{0}'
|
||||
SEND-LOCALE-ERROR: '语言文件发送失败:{0}'
|
||||
LOCALE-ERROR-REASON: '原因:{0}'
|
||||
|
@ -1,21 +1,3 @@
|
||||
TLIB:
|
||||
INJECTION-SUCCESS: '注入成功'
|
||||
INJECTION-FAILED:
|
||||
- '注入失败'
|
||||
- '&c提前加载依赖于 TabooLib 的所有插件的相关功能'
|
||||
INJECTION-DISABLED:
|
||||
- '关闭注入'
|
||||
- '&c提前加载依赖于 TabooLib 的所有插件的相关功能'
|
||||
LOAD-FAIL-OFFLINE:
|
||||
- '**********************************************'
|
||||
- '** TabooLib-{0} 无法在您的服务器上使用'
|
||||
- '**'
|
||||
- '** 您的服务器尚未连接互联网导致本插件无法正常载入'
|
||||
- '** 请使用离线版本或是手动下载依赖库文件'
|
||||
- '**'
|
||||
- '** 详情查阅: https://github.com/Bkm016/TabooLib'
|
||||
- '**********************************************'
|
||||
|
||||
DEPENDENCY:
|
||||
DOWNLOAD-OFFLINE: '已启用离线模式, 将不会下载第三方依赖库'
|
||||
DOWNLOAD-CONNECTED: ' 正在下载 {0} 大小 {1}'
|
||||
@ -27,38 +9,7 @@ DEPENDENCY:
|
||||
PLUGIN-AUTOLOAD-FAIL: '{0} 所依赖的插件 {1} 尝试自动加载失败,请尝试手动下载'
|
||||
PLUGIN-LOAD-SUCCESS: ' {0} 请求的插件 {1} 加载成功'
|
||||
PLUGIN-LOAD-FAIL: ' {0} 请求的插件 {1} 加载失败'
|
||||
LOADING-START: '正在加载 {0} 插件所需的依赖'
|
||||
# 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 注解'
|
||||
LOAD-FAIL-NO-FILE: '插件 {0} 的配置类 {1} 加载失败:没有 @Config 注解或文件不存在'
|
||||
LOAD-SUCCESS: '插件 {0} 的 {1} 配置文件成功加载'
|
||||
SAVE-FAIL-NO-ANNOTATION: '插件 {0} 的配置类 {1} 序列化失败:没有 @Config 注解'
|
||||
SAVE-FAIL: '插件 {0} 的配置类 {1} 加载失败:没有 @Config 注解'
|
||||
SAVE-SUCCESS: '插件 {0} 的配置 {1} 已保存'
|
||||
RELOAD-SUCCESS: '插件 {0} 的配置 {1} 成功重载'
|
||||
RELOAD-FAIL: '插件 {0} 的配置 {1} 成功重载'
|
||||
LISTEN-START: '开始监听 {0} 插件的 {1} 配置文件'
|
||||
|
||||
NOTIFY:
|
||||
ERROR-SERVER-KEY: '&4检测到本服序列号与其他服务器相同, 已重新生成!'
|
||||
ERROR-CONNECTION-FAIL: '&4数据库连接失败, 请检查配置是否正确!'
|
||||
SUCCESS-LOADED:
|
||||
- '§7插件载入完成!'
|
||||
- '§7插件作者: §f{0}'
|
||||
- '§7插件版本: §f{1}'
|
||||
- '§7游戏版本: §f{2}'
|
||||
SUCCESS-DISABLE:
|
||||
- '&c插件已卸载, 感谢您使用&4禁忌书库'
|
||||
- '&c插件作者: &4坏黑'
|
||||
FAIL-DISABLE:
|
||||
- '&c插件尚未启动完成, 已跳过卸载代码'
|
||||
- '&c插件作者: &4坏黑'
|
||||
|
||||
LOCALE:
|
||||
TITLE-SEND-TO-NON-PLAYER: '该语言类型只能发送给玩家:{0}'
|
||||
@ -74,27 +25,10 @@ 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}'
|
||||
@ -106,53 +40,14 @@ ITEM-UTILS:
|
||||
FAIL-LOAD-POTION: '&c{0} &4不是一个有效的药水名称, 输入 &c/tlib potions&4 查看所有药水'
|
||||
FAIL-LOAD-FLAG: '&c{0} &4不是一个有效的标签名称, 输入 &c/tlib flags&4 查看所有标签'
|
||||
FAIL-SAVE-EXISTS: '无法载入载入物品 &4{0}&c, 因为它已经存在了'
|
||||
# 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名称重复'
|
||||
|
||||
UPDATETASK:
|
||||
VERSION-FAIL: '&4更新记录获取失败, 请检查网络连接!'
|
||||
VERSION-LATEST: '&7插件已是最新版, 无需更新!'
|
||||
VERSION-OUTDATED:
|
||||
- '&8####################################################'
|
||||
- '&7 检测到有新的版本更新!'
|
||||
- '&7 当前版本: &f{0}'
|
||||
- '&7 最新版本: &f{1}'
|
||||
- '&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驱动器获取失败, 无法连接到数据库'
|
||||
FAIL-NOTFOUND-CONNECTION: '&7警告! 数据库尚未连接, 请检查配置文件后重启服务器! ({0})'
|
||||
FAIL-COMMAND-NORMAL: '&4数据库命令执行出错, 错误原因: &c{0}'
|
||||
FAIL-COMMAND-DETAIL: '&4数据库命令执行出错, 错误代码: &c{0}&4, 错误原因: &c{1}'
|
||||
FAIL-EXECUTE-TASK: '异步任务失败, 执行方式改为同步执行'
|
||||
SUCCESS-REGISTERED: '&7插件 &f{0}&7 注册新的数据库连接'
|
||||
SUCCESS-REGISTERED-EXISTS: '&7插件 &f{0}&7 引用插件 &f{1}&7 注册的数据库连接'
|
||||
SUCCESS-REGISTERED-LISTENER: '&7启动数据库连接监控'
|
||||
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控制台无法这么做'
|
||||
@ -169,9 +64,7 @@ COMMANDS:
|
||||
- '&8[&3&lTabooLib&8] &7指令 &f{0} &7不存在'
|
||||
- '&8[&3&lTabooLib&8] &7你可能想要:'
|
||||
- '&8[&3&lTabooLib&8] &7{1}'
|
||||
COMMAND-CREATE-FAILED: '&7插件 &f{0} &7的 &f{1} &7命令注册失败: &c{2}'
|
||||
# COMMAND-CREATE: '&7自动为插件 &f{0} &7的 &f{1} &7命令注册到服务器'
|
||||
# COMMAND-REGISTER: '&7自动为插件 &f{0} &7的 &f{1} &7命令注册 &f{2} &7条子命令'
|
||||
COMMAND-CREATE-FAILED: '&c插件 &7{0} &c的 &7{1} &c命令注册失败: &7{2}'
|
||||
COMMAND-HELP: ' §f/{0} {1} {2}§6- §e{3}'
|
||||
COMMAND-HELP-EMPTY: ' §f/{0} {1} {2}'
|
||||
COMMAND-ARGUMENT: '§7<§8{0}§7>'
|
||||
@ -179,285 +72,6 @@ COMMANDS:
|
||||
PARAMETER:
|
||||
UNKNOWN: '&8[&3&lTabooLib&8] &4指令错误'
|
||||
INSUFFICIENT: '&8[&3&lTabooLib&8] &4参数不足'
|
||||
RELOAD:
|
||||
LOADING: '&8[&3&lTabooLib&8] &7重载中...'
|
||||
SUCCESS-NORMAL: '&8[&3&lTabooLib&8] &7重载成功'
|
||||
SUCCESS-ELAPSED-TIME: '&8[&3&lTabooLib&8] &7重载成功, 耗时: &f{0} ms'
|
||||
TABOOLIB:
|
||||
COMMAND-TITLE: '&e&l----- &6&lTabooLib Commands &e&l-----'
|
||||
SAVE:
|
||||
DESCRIPTION: '载入插件'
|
||||
ARGUMENTS:
|
||||
0: '名称'
|
||||
INVALID-NAME: '&8[&3&lTabooLib&8] &4请输入正确的名称'
|
||||
INVALID-ITEM: '&8[&3&lTabooLib&8] &4请手持正确的物品'
|
||||
INVALID-ITEM-FINAL-EXISTS: '&8[&3&lTabooLib&8] &4该名称所对应的物品保存于固定物品库中, 无法覆盖'
|
||||
GUIDE-EXISTS: '&8[&3&lTabooLib&8] &4你有一个正在进行的聊天引导, 请完成后在这么做'
|
||||
GUIDE-BEFORE: '&8[&3&lTabooLib&8] &7物品 &f{0}&7 已存在, 如果你想要覆盖它, 请在聊天框中输入 "&fYES&7"'
|
||||
GUIDE-QUIT: '&8[&3&lTabooLib&8] &7退出引导'
|
||||
SUCCESS: '&8[&3&lTabooLib&8] &7物品 &f{0} &7已替换'
|
||||
ITEM:
|
||||
DESCRIPTION: '给予玩家物品'
|
||||
ARGUMENTS:
|
||||
0: '名称'
|
||||
1: '玩家'
|
||||
2: '数量'
|
||||
INVALID-NAME: '&8[&3&lTabooLib&8] &4请输入正确的名称'
|
||||
INVALID-ITEM: '&8[&3&lTabooLib&8] &4物品 &c{0} &4不存在'
|
||||
INVALID-PLAYER: '&8[&3&lTabooLib&8] &4玩家 &c{0} &4不在线'
|
||||
INVALID-NUMBER: '&8[&3&lTabooLib&8] &4数量必须大于0'
|
||||
SUCCESS: '&8[&3&lTabooLib&8] &7物品已发送至玩家 &f{0} &7的背包中'
|
||||
ITEMRELOAD:
|
||||
DESCRIPTION: '重载物品缓存'
|
||||
SUCCESS-RELOAD: '&8[&3&lTabooLib&8] &7重载成功'
|
||||
VARIABLE:
|
||||
DESCRIPTION:
|
||||
GET: '查看变量'
|
||||
SET: '设置变量'
|
||||
ARGUMENTS:
|
||||
GET:
|
||||
0: '-s|-a'
|
||||
1: '键'
|
||||
SET:
|
||||
0: '-s|-a'
|
||||
1: '键'
|
||||
2: '值'
|
||||
WRITE-ERROR-TYPE: '&8[&3&lTabooLib&8] &4请输入正确的写入方式: &c-s&4、&c-a'
|
||||
WRITE-SUCCESS: '&8[&3&lTabooLib&8] &7写入完成, 耗时: &f{0} &7(ms)'
|
||||
READ-ERROR-TYPE: '&8[&3&lTabooLib&8] &4请输入正确的写入方式: &c-s&4、&c-a'
|
||||
READ-RESULT: '&8[&3&lTabooLib&8] &7变量 &f{0} &7的值为: &f{1}'
|
||||
READ-SUCCESS: '&8[&3&lTabooLib&8] &7写入完成, 耗时: &f{0} &7(ms)'
|
||||
IMPORTDATA:
|
||||
DESCRIPTION: '&4向数据库导入本地数据 &8(该操作将会清空数据库)'
|
||||
CLEARING: '&8[&3&lTabooLib&8] &7正在清空数据库...'
|
||||
EMPTYDATA: '&8[&3&lTabooLib&8] &4没有玩家数据可以导入'
|
||||
IMPORTING-START: '&8[&3&lTabooLib&8] &7开始导入 &f{0} &7项玩家数据'
|
||||
IMPORTING-PROGRESS: '&8[&3&lTabooLib&8] &7导入玩家数据: &f{0} &7进度: &f{1}/{2}'
|
||||
SUCCESS: '&8[&3&lTabooLib&8] &7导入完成'
|
||||
UPDATEPLUGIN:
|
||||
DESCRIPTION: '&4更新插件 &8(谨防非正规途径的插件获取方式)'
|
||||
UPDATE-NOT-FOUND: '&8[&3&lTabooLib&8] &7插件已是最新版, 无需更新!'
|
||||
UPDATE-NOT-FOUND-SIZE: '&8[&3&lTabooLib&8] &4文件长度获取失败.'
|
||||
UPDATE-NOT-SUPPORT: '&8[&3&lTabooLib&8] &4您的服务器不支持在线更新!'
|
||||
UPDATE-SUCCESS: '&8[&3&lTabooLib&8] &7最新版下载完成, 服务器即将重启!'
|
||||
UPDATE-FAILED: '&8[&3&lTabooLib&8] &4最新版下载失败.'
|
||||
FILE-NOT-FOUND: '&8[&3&lTabooLib&8] &4尚未寻找到插件文件.'
|
||||
PLAYER-ONLINE: '&8[&3&lTabooLib&8] &4服务器有玩家在线无法更新插件.'
|
||||
ARGUMENTS:
|
||||
0: '-f'
|
||||
PLAYERTAG:
|
||||
DESCRIPTION:
|
||||
DISPLAY: '设置玩家展示名称'
|
||||
PREFIX: '设置玩家头顶前缀'
|
||||
SUFFIX: '设置玩家头顶后缀'
|
||||
DELETE: '删除玩家称号数据'
|
||||
ARGUMENTS:
|
||||
DISPLAY:
|
||||
0: '玩家'
|
||||
1: '文本'
|
||||
PREFIX:
|
||||
0: '玩家'
|
||||
1: '文本'
|
||||
SUFFIX:
|
||||
0: '玩家'
|
||||
1: '文本'
|
||||
DELETE:
|
||||
0: '玩家'
|
||||
INVALID-PLAYER: '&8[&3&lTabooLib&8] &4玩家 &c{0} &4不在线'
|
||||
SUCCESS-DISPLAY-SET: '&8[&3&lTabooLib&8] &7设置玩家 &f{0} &7的名称为 &f{1}'
|
||||
SUCCESS-PREFIX-SET: '&8[&3&lTabooLib&8] &7设置玩家 &f{0} &7的前缀为 &f{1}'
|
||||
SUCCESS-SUFFIX-SET: '&8[&3&lTabooLib&8] &7设置玩家 &f{0} &7的后缀为 &f{1}'
|
||||
SUCCESS-DELETE: '&8[&3&lTabooLib&8] &7删除玩家 &f{0} &7的称号数据'
|
||||
LAGSERVER:
|
||||
DESCRIPTION: '休眠主线程'
|
||||
ARGUMENTS:
|
||||
0: '毫秒'
|
||||
INVALID-TIME: '&8[&3&lTabooLib&8] &4休眠时间不可超过 &c30000 &4毫秒'
|
||||
START: '&8[&3&lTabooLib&8] &7线程休眠开始.'
|
||||
STOP: '&8[&3&lTabooLib&8] &7线程休眠结束.'
|
||||
INFO:
|
||||
DESCRIPTION: '查看物品信息'
|
||||
INVALID-ITEM: '&8[&3&lTabooLib&8] &4请手持正确的物品'
|
||||
ITEM-INFO:
|
||||
- ==: JSON
|
||||
text:
|
||||
- ''
|
||||
- '&b&l----- &3&lItemStack Info &b&l-----'
|
||||
- ''
|
||||
- '&7 - 物品材质: &f<{0}@type>'
|
||||
- '&7 - 物品名称: &f<{1}@name>'
|
||||
- '&7 - 物品序号: &f<{2}@id>'
|
||||
- '&7 - 物品数据: &f<NBT@nbt>'
|
||||
- ''
|
||||
args:
|
||||
type:
|
||||
hover: '&f点击复制'
|
||||
suggest: '{0}'
|
||||
name:
|
||||
hover: '&f点击复制'
|
||||
suggest: '{1}'
|
||||
id:
|
||||
hover: '&f点击复制'
|
||||
suggest: '{2}'
|
||||
nbt:
|
||||
hover: '{3}'
|
||||
ITEMLIST:
|
||||
DESCRIPTION: '查看所有物品'
|
||||
MENU:
|
||||
TITLE: '物品库 {0}'
|
||||
NEXT: '&f上一页'
|
||||
BACK: '&f下一页'
|
||||
LORE:
|
||||
- ''
|
||||
- '&f&m '
|
||||
- '&f序列号: &8{0}'
|
||||
SOUNDS:
|
||||
DESCRIPTION: '查看所有音效'
|
||||
MENU:
|
||||
TITLE: '音效库 {0}'
|
||||
NEXT: '&f上一页'
|
||||
BACK: '&f下一页'
|
||||
LORE:
|
||||
- ''
|
||||
- '&fQ键: &70 音调'
|
||||
- '&f左键: &71 音调'
|
||||
- '&f右键: &72 音调'
|
||||
- '&f中键: &7复制名称'
|
||||
RESULT:
|
||||
SEARCH:
|
||||
- '&7查询名称: &f{0}'
|
||||
- '&7查询结果: &f{1}'
|
||||
COPY:
|
||||
- ==: JSON
|
||||
text: '&7点击复制: <&f&n{0}@sound>'
|
||||
args:
|
||||
sound:
|
||||
hover: 点击复制音效
|
||||
suggest: '{0}'
|
||||
TIMECYCLE:
|
||||
DESCRIPTION:
|
||||
LIST: '列出所有时间检查器'
|
||||
INFO: '查询检查器信息'
|
||||
RESET: '初始化时间检查器'
|
||||
UPDATE: '更新时间检查器'
|
||||
ARGUMENTS:
|
||||
INFO:
|
||||
0: '名称'
|
||||
RESET:
|
||||
0: '名称'
|
||||
UPDATE:
|
||||
0: '名称'
|
||||
INVALID-CYCLE: '&8[&3&lTabooLib&8] &4检查器 &c{0} &4不存在'
|
||||
CYCLE-UPDATE: '&8[&3&lTabooLib&8] &7检查器 &f{0} &7已更新'
|
||||
CYCLE-RESET: '&8[&3&lTabooLib&8] &7检查器 &f{0} &7初始化完成'
|
||||
CYCLE-INFO:
|
||||
- ''
|
||||
- '&b&l----- &3&lTimeCycle Info &b&l-----'
|
||||
- ''
|
||||
- ' &f- &7注册周期: &f{0}'
|
||||
- ' &f- &7注册插件: &f{1}'
|
||||
- ' &f- &7上次刷新时间: &f{2}'
|
||||
- ' &f- &7下次刷新时间: &f{3}'
|
||||
- ''
|
||||
LIST:
|
||||
HEAD:
|
||||
- ''
|
||||
- '&b&l----- &3&lTimeCycle List &b&l-----'
|
||||
- ''
|
||||
BODY:
|
||||
- ==: JSON
|
||||
text: ' &7- &f{0} <&8(点击复制)@copy>'
|
||||
args:
|
||||
copy:
|
||||
hover: '&f点击复制'
|
||||
suggest: '{0}'
|
||||
FOOT:
|
||||
- ''
|
||||
ATTRIBUTES:
|
||||
DESCRIPTION: '查看所有属性'
|
||||
HEAD:
|
||||
- ''
|
||||
- '&b&l----- &3&lItemStack Attributes &b&l-----'
|
||||
- ''
|
||||
BODY:
|
||||
- ==: JSON
|
||||
text: ' &7- &f{0} <&8(点击复制)@copy>'
|
||||
args:
|
||||
copy:
|
||||
hover: '&f点击复制'
|
||||
suggest: '{0}'
|
||||
FOOT:
|
||||
- ''
|
||||
ENCHANTS:
|
||||
DESCRIPTION: '查看所有附魔'
|
||||
HEAD:
|
||||
- ''
|
||||
- '&b&l----- &3&lItemStack Enchantments &b&l-----'
|
||||
- ''
|
||||
BODY:
|
||||
- ==: JSON
|
||||
text: ' &7- &f{0}. {1} <&8(点击复制)@copy>'
|
||||
args:
|
||||
copy:
|
||||
hover: '&f点击复制'
|
||||
suggest: '{1}'
|
||||
FOOT:
|
||||
- ''
|
||||
POTIONS:
|
||||
DESCRIPTION: '查看所有药水'
|
||||
HEAD:
|
||||
- ''
|
||||
- '&b&l----- &3&lItemStack PotionEffects &b&l-----'
|
||||
- ''
|
||||
BODY:
|
||||
- ==: JSON
|
||||
text: ' &7- &f{0}. {1} <&8(点击复制)@copy>'
|
||||
args:
|
||||
copy:
|
||||
hover: '&f点击复制'
|
||||
suggest: '{1}'
|
||||
FOOT:
|
||||
- ''
|
||||
FLAGS:
|
||||
DESCRIPTION: '查看所有标签'
|
||||
HEAD:
|
||||
- ''
|
||||
- '&b&l----- &3&lItemStack Flags &b&l-----'
|
||||
- ''
|
||||
BODY:
|
||||
- ==: JSON
|
||||
text: ' &7- &f{0} <&8(点击复制)@copy>'
|
||||
args:
|
||||
copy:
|
||||
hover: '&f点击复制'
|
||||
suggest: '{0}'
|
||||
FOOT:
|
||||
- ''
|
||||
SLOTS:
|
||||
DESCRIPTION: '查看所有部位'
|
||||
HEAD:
|
||||
- ''
|
||||
- '&b&l----- &3&lItemStack Slots &b&l-----'
|
||||
- ''
|
||||
BODY:
|
||||
- ==: JSON
|
||||
text: ' &7- &f{0} <&8(点击复制)@copy>'
|
||||
args:
|
||||
copy:
|
||||
hover: '&f点击复制'
|
||||
suggest: '{0}'
|
||||
FOOT:
|
||||
- ''
|
||||
LANGUAGE2:
|
||||
INVALID-PLAYER: '&8[&3&lTabooLib&8] &4玩家 &c{0} &4不在线'
|
||||
SUCCESS-SEND: '&8[&3&lTabooLib&8] &7信息已发送, 耗时&f: {0}'
|
||||
HELP:
|
||||
- ''
|
||||
- '&e&l----- &6&lLanguage2 Commands &e&l-----'
|
||||
- ''
|
||||
- '&f /{0} send &8[&7玩家/ALL&8] &8[&7语言&8] &8<&7变量&8> &6- &e发送语言提示'
|
||||
- '&f /{0} reload &6- &e重载语言库'
|
||||
- ''
|
||||
TLOCALE:
|
||||
COMMAND-TITLE: '&e&l----- &6&lTabooLibLoacle Commands &e&l-----'
|
||||
SEND:
|
||||
@ -517,15 +131,6 @@ COMMANDS:
|
||||
INVALID-PLUGIN: '&8[&3&lTabooLib&8] &4插件 &c{0} &4不存在'
|
||||
INVALID-PLUGIN-IGNORED: '&8[&3&lTabooLib&8] &4插件 &c{0} &4无法操作'
|
||||
TRY-RELOAD: '&8[&3&lTabooLib&8] &7尝试重载插件...'
|
||||
TRANSLATE-UUID:
|
||||
COMMAND-TITLE: '&e&l----- &6&lTranslateUUID Commands &e&l-----'
|
||||
IMPORTLOCAL:
|
||||
DESCRIPTION: '导入本地数据到数据库'
|
||||
DISABLED: '&8[&3&lTabooLib&8] &4该功能尚未启用'
|
||||
SUCCESS: '&8[&3&lTabooLib&8] &7请求已发送, 详细信息请查看控制台'
|
||||
RELOAD:
|
||||
DESCRIPTION: '重载配置及数据库'
|
||||
SUCCESS: '&8[&3&lTabooLib&8] &7请求已发送, 详细信息请查看控制台'
|
||||
TEXECUTE:
|
||||
COMMAND-TITLE: '&e&l----- &6&lTabooLibExecute Commands &e&l-----'
|
||||
CHAT:
|
||||
@ -566,81 +171,6 @@ COMMANDS:
|
||||
0: '目录'
|
||||
1: '内容'
|
||||
SUCCESS: '&8[&3&lTabooLib&8] &7写入完成.'
|
||||
TCLOUD:
|
||||
COMMAND-TITLE: '&e&l----- &6&lTabooLibCloud Commands &e&l-----'
|
||||
REFRESH:
|
||||
DESCRIPTION: '刷新扩展列表'
|
||||
SUCCESS: '&8[&3&lTabooLib&8] &7请求已发送. &8(详细信息请在控制台查看)'
|
||||
STATUS:
|
||||
DESCRIPTION: '查看扩展统计'
|
||||
STATUS:
|
||||
- '&8[&3&lTabooLib&8] &7当前总共 &f{0} &7项扩展被 &fTCLOUD &7录入, 其中包含:'
|
||||
- '&8[&3&lTabooLib&8] &7内置扩展 &f{1} &7项'
|
||||
- '&8[&3&lTabooLib&8] &7插件扩展 &f{2} &7项'
|
||||
CONNECT-FAILED: '&8[&3&lTabooLib&8] &c尚未获取扩展列表.'
|
||||
INFO:
|
||||
DESCRIPTION: '查看扩展信息'
|
||||
ARGUMENTS:
|
||||
0: '名称'
|
||||
EXPANSION-NOT-FOUND: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c不存在.'
|
||||
EXPANSION-INFO:
|
||||
- '&8[&3&lTabooLib&8] &7扩展 &f{0} &7信息:'
|
||||
- '&8[&3&lTabooLib&8] &7作者 &f{1}'
|
||||
- '&8[&3&lTabooLib&8] &7版本 &f{2}'
|
||||
- '&8[&3&lTabooLib&8] &7描述 &f{3}'
|
||||
- '&8[&3&lTabooLib&8] &7最后更新时间 &f{4}'
|
||||
- '&8[&3&lTabooLib&8] &7最后更新内容 &f{5}'
|
||||
EXPANSION-INFO-DETAIL:
|
||||
0: '&8[&3&lTabooLib&8] &7详细描述'
|
||||
1: '&8[&3&lTabooLib&8] &7- &f{0}'
|
||||
DOWNLOAD:
|
||||
DESCRIPTION: '下载扩展'
|
||||
ARGUMENTS:
|
||||
0: '名称'
|
||||
EXPANSION-NOT-FOUND: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c不存在.'
|
||||
EXPANSION-EXISTS: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c已存在.'
|
||||
EXPANSION-VERSION: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c需要 &4TabooLib v{1}&c 版本才可以使用!'
|
||||
DOWNLOAD-START:
|
||||
- '&8[&3&lTabooLib&8] &7扩展 &f{0} &7开始下载:'
|
||||
- '&8[&3&lTabooLib&8] &7地址 &f{1}'
|
||||
DOWNLOAD-SUCCESS: '&8[&3&lTabooLib&8] &7扩展 &f{0} &7下载完成, 请重启服务器.'
|
||||
UPDATE:
|
||||
DESCRIPTION: '更新扩展'
|
||||
ARGUMENTS:
|
||||
0: '名称'
|
||||
EXPANSION-NOT-FOUND: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c不存在.'
|
||||
EXPANSION-NOT-EXISTS: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c尚未下载.'
|
||||
EXPANSION-NO-UPDATE: '&8[&3&lTabooLib&8] &7扩展 &f{0} &7已是最新版本.'
|
||||
EXPANSION-VERSION: '&8[&3&lTabooLib&8] &c扩展 &4{0} &c需要 &4TabooLib v{1}&c 版本才可以使用!'
|
||||
UPDATE-START:
|
||||
- '&8[&3&lTabooLib&8] &7扩展 &f{0} &7开始更新:'
|
||||
- '&8[&3&lTabooLib&8] &7版本 &f{1}'
|
||||
- '&8[&3&lTabooLib&8] &7地址 &f{2}'
|
||||
UPDATE-SUCCESS: '&8[&3&lTabooLib&8] &7扩展 &f{0} &7更新完成, 请重启服务器.'
|
||||
LIST:
|
||||
DESCRIPTION: '查看扩展列表'
|
||||
ARGUMENTS:
|
||||
0: 'PLUGINS/INTERNAL'
|
||||
1: '页数'
|
||||
INVALID-TYPE:
|
||||
0: '&8[&3&lTabooLib&8] &c错误的扩展类型. &4(PLUGINS、INTERNAL)'
|
||||
1: '&8[&3&lTabooLib&8] &c错误的页数.'
|
||||
LIST-HEAD:
|
||||
- ''
|
||||
- '&e&l----- &6&lTabooLibCloud Expansions : &f{0} &6&l: &f{1}/{2} &e&l-----'
|
||||
- ''
|
||||
LIST-EXPANSION:
|
||||
0: ' &f{0}. &8{1} &7{2}'
|
||||
1: ' &f{0}. &c{1} &7{2}'
|
||||
2: ' &f{0}. &a{1} &7{2}'
|
||||
LIST-BOTTOM:
|
||||
- ''
|
||||
- ' &f> &8[未安装] &a[已安装] &c[可更新]'
|
||||
- ''
|
||||
|
||||
DATABASE:
|
||||
CONNECTION-ESTABLISHED: '成功连接到 {0} 数据库,连接池大小 {1}'
|
||||
CONNECTION-ERROR: '连接到数据库错误:{0}'
|
||||
|
||||
COMMUNICATION:
|
||||
FAILED-LOAD-SETTINGS: '§8[§3§lTabooLibClient§8] &4配置载入失败: {0}'
|
||||
@ -657,43 +187,4 @@ UTIL:
|
||||
DOWNLOAD-CONNECTED: '开始下载文件 {0} 大小 {1}'
|
||||
DOWNLOAD-PROGRESS: ' 下载速度 {0} 进度 {1}'
|
||||
DOWNLOAD-SUCCESS: '下载 {0} 完成!'
|
||||
DOWNLOAD-FAILED: '下载 {0} 失败!'
|
||||
|
||||
TCLOUD:
|
||||
LIST-LOAD-SUCCESS: '载入 &fTCLOUD &7扩展列表完成! 耗时 &f{0} &7毫秒'
|
||||
LIST-LOAD-FAILED: '载入 &4{0} &c扩展数据失败: &4{1}'
|
||||
LIST-PARSE-FAILED: '读取 &4TCLOUD &c扩展列表失败: &4{0}'
|
||||
LIST-CONNECT-FAILED: '获取 &4TCLOUD &c扩展列表失败!'
|
||||
|
||||
TFILTER:
|
||||
EXCEPTION-MIRROR:
|
||||
EVENT:
|
||||
HEAD:
|
||||
- '&c插件 &4{0} &c执行事件时出现异常! &7(处理耗时: {1}ms)'
|
||||
- '&c异常事件: &4{2}'
|
||||
- '&c异常类型: &4{3}'
|
||||
- '&c异常内容: &4{4}'
|
||||
- '&c异常位置:'
|
||||
STACK-TRACE: '&7 {0}. &4{1}'
|
||||
COMMAND:
|
||||
HEAD:
|
||||
- '&c插件 &4{0} &c执行命令时出现异常! &7(处理耗时: {1}ms)'
|
||||
- '&c异常命令: &4{2}'
|
||||
- '&c异常类型: &4{3}'
|
||||
- '&c异常内容: &4{4}'
|
||||
- '&c异常位置:'
|
||||
STACK-TRACE: '&7 {0}. &4{1}'
|
||||
SCHEDULE:
|
||||
HEAD:
|
||||
- '&c插件 &4{0} &c执行任务时出现异常! &7(处理耗时: {1}ms)'
|
||||
- '&c异常类型: &4{2}'
|
||||
- '&c异常内容: &4{3}'
|
||||
- '&c异常位置:'
|
||||
STACK-TRACE: '&7 {0}. &4{1}'
|
||||
OTHER:
|
||||
HEAD:
|
||||
- '&c插件 &4{0} &c运行时出现异常! &7(处理耗时: {1}ms)'
|
||||
- '&c异常类型: &4{2}'
|
||||
- '&c异常内容: &4{3}'
|
||||
- '&c异常位置:'
|
||||
STACK-TRACE: '&7 {0}. &4{1}'
|
||||
DOWNLOAD-FAILED: '下载 {0} 失败!'
|
@ -1,10 +0,0 @@
|
||||
# 语言文件
|
||||
Language: 'zh_CN'
|
||||
|
||||
# 启用模块
|
||||
# 该配置需要重启服务器才会生效
|
||||
EnableModule:
|
||||
#- 'Kits'
|
||||
#- 'TimeCycle'
|
||||
#- 'CommandChanger'
|
||||
#- 'InventorySave'
|
@ -1,14 +0,0 @@
|
||||
name: TabooLib
|
||||
main: me.skymc.taboolib.Main
|
||||
version: ${version}
|
||||
api-version: 1.13
|
||||
|
||||
authors:
|
||||
- 坏黑
|
||||
- lzzelAliz
|
||||
|
||||
softdepend:
|
||||
- Vault
|
||||
- PlaceholderAPI
|
||||
- Skript
|
||||
- MassiveLag
|
29
src/main/resources/settings.yml
Normal file
29
src/main/resources/settings.yml
Normal file
@ -0,0 +1,29 @@
|
||||
# 语言文件相关设置
|
||||
LOCALE:
|
||||
# 加载语言文件的顺序
|
||||
PRIORITY:
|
||||
- zh_CN
|
||||
- en_US
|
||||
# 默认是否启用语言文件中 PlaceholderAPI 的替换功能
|
||||
# 关闭可提升性能
|
||||
# 如果需要开启仍然可以在语言文件中加入 papi: true
|
||||
USE_PAPI: false
|
||||
|
||||
# 玩家数据储存位置
|
||||
# 如果服务器存在 TabooLib 的插件版本
|
||||
# 请设置相同路径
|
||||
LOCAL-PLAYER: 'plugins/TabooLib/playerdata/'
|
||||
|
||||
# 是否以 UUID 的形式创建玩家数据
|
||||
# 如果服务器存在 TabooLib 的插件版本则不建议开启
|
||||
LOCAL-PLAYER-UUID: false
|
||||
|
||||
# 是否在当前服务器启用交流网终端
|
||||
# 启用后将会收到大量调试信息, 不建议使用
|
||||
SERVER: false
|
||||
|
||||
# 玩家列表(TAB-API)是否根据前缀排序
|
||||
TABLIST-SORT: true
|
||||
|
||||
# 玩家列表(TAB-API)是否自动清理没有成员的队伍
|
||||
TABLIST-AUTO-CLEAN-TEAM: true
|
@ -1,11 +0,0 @@
|
||||
# 是否启用
|
||||
Enable: false
|
||||
|
||||
# 数据库地址
|
||||
Database:
|
||||
host: 'localhost'
|
||||
port: '3306'
|
||||
user: 'root'
|
||||
password: ''
|
||||
database: 'test'
|
||||
table: 'taboolib_translate_uuid_database'
|
1
src/main/resources/version
Normal file
1
src/main/resources/version
Normal file
@ -0,0 +1 @@
|
||||
${version}
|
@ -1,5 +0,0 @@
|
||||
package com.ilummc.eagletdl;
|
||||
|
||||
public class AlreadyStartException extends RuntimeException {
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.ilummc.eagletdl;
|
||||
|
||||
public class CompleteEvent {
|
||||
private EagletTask task;
|
||||
private boolean success;
|
||||
|
||||
CompleteEvent(EagletTask task, boolean success) {
|
||||
this.task = task;
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public EagletTask getTask() {
|
||||
return task;
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package com.ilummc.eagletdl;
|
||||
|
||||
public class ConnectedEvent {
|
||||
|
||||
private long contentLength;
|
||||
private EagletTask task;
|
||||
|
||||
public ConnectedEvent(long length, EagletTask task) {
|
||||
this.contentLength = length;
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of the download task.
|
||||
* <p>
|
||||
* If the length is -1, this task cannot be downloaded in multiple threads.
|
||||
*
|
||||
* @return length
|
||||
*/
|
||||
public long getContentLength() {
|
||||
return contentLength;
|
||||
}
|
||||
|
||||
public EagletTask getTask() {
|
||||
return task;
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
package com.ilummc.eagletdl;
|
||||
|
||||
public class DoNotSupportMultipleThreadException extends RuntimeException {
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
package com.ilummc.eagletdl;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface EagletHandler<T> {
|
||||
|
||||
void handle(T event) ;
|
||||
|
||||
}
|
@ -1,477 +0,0 @@
|
||||
package com.ilummc.eagletdl;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class EagletTask {
|
||||
|
||||
private ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
Map<String, String> httpHeader = new ConcurrentHashMap<>();
|
||||
|
||||
private URL url;
|
||||
|
||||
EagletHandler<ErrorEvent> onError = event -> event.getException().printStackTrace();
|
||||
|
||||
private EagletHandler<StartEvent> onStart;
|
||||
|
||||
private EagletHandler<CompleteEvent> onComplete;
|
||||
|
||||
private EagletHandler<ConnectedEvent> onConnected;
|
||||
|
||||
private EagletHandler<ProgressEvent> onProgress;
|
||||
|
||||
private Proxy proxy;
|
||||
|
||||
private String md5, sha1, sha256;
|
||||
|
||||
String requestMethod = "GET";
|
||||
|
||||
private int threadAmount = 1;
|
||||
|
||||
int connectionTimeout = 7000;
|
||||
int readTimeout = 7000;
|
||||
int maxRetry = 5;
|
||||
|
||||
private File dest;
|
||||
|
||||
private transient boolean running = false;
|
||||
private transient long contentLength, maxBlockingTime = 7000;
|
||||
private transient ExecutorService executorService;
|
||||
private transient Thread monitor;
|
||||
|
||||
public EagletTask() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop this task forcefully, and the target file will not be removed.
|
||||
*/
|
||||
public void stop() {
|
||||
executorService.shutdownNow();
|
||||
monitor.interrupt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the download file
|
||||
* <p>
|
||||
* 开始下载文件
|
||||
*/
|
||||
public EagletTask start() {
|
||||
// create thread pool for download
|
||||
executorService = Executors.newFixedThreadPool(threadAmount);
|
||||
// check if is already running
|
||||
if (running) {
|
||||
throw new AlreadyStartException();
|
||||
}
|
||||
// start the monitor thread
|
||||
monitor = new Thread(() -> {
|
||||
lock.lock();
|
||||
// fire a new start event
|
||||
if (onStart != null) {
|
||||
onStart.handle(new StartEvent(this));
|
||||
}
|
||||
try {
|
||||
// create the target file
|
||||
if (!dest.exists()) {
|
||||
dest.createNewFile();
|
||||
}
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
// set the connection properties
|
||||
httpHeader.forEach(connection::addRequestProperty);
|
||||
connection.setRequestMethod(requestMethod);
|
||||
connection.setConnectTimeout(30000);
|
||||
connection.setReadTimeout(30000);
|
||||
connection.connect();
|
||||
contentLength = connection.getContentLengthLong();
|
||||
// fire a new connected event
|
||||
// contains connection properties
|
||||
if (onConnected != null) {
|
||||
onConnected.handle(new ConnectedEvent(contentLength, this));
|
||||
}
|
||||
// if this is an unknown length task
|
||||
if (contentLength == -1 || threadAmount == 1) {
|
||||
// pass the connection instance to this new thread
|
||||
SingleThreadDownload download = new SingleThreadDownload(connection, dest, this);
|
||||
executorService.execute(download);
|
||||
long last = 0;
|
||||
do {
|
||||
Thread.sleep(500);
|
||||
// check the progress
|
||||
long progress = download.getCurrentProgress();
|
||||
// fire a new progress event
|
||||
if (onProgress != null) {
|
||||
onProgress.handle(new ProgressEvent(progress - last < 0 ? 0 : progress - last, this, ((double) progress) / Math.max((double) contentLength, 0D)));
|
||||
}
|
||||
last = progress;
|
||||
// check complete
|
||||
} while (last != contentLength && !download.isComplete());
|
||||
// close the thread pool, DoNotSupportMultipleThreadExceptionrelease resources
|
||||
executorService.shutdown();
|
||||
// change the running flag to false
|
||||
running = false;
|
||||
} else {
|
||||
List<SplitDownload> splitDownloads = new ArrayList<>();
|
||||
// Assign download task length
|
||||
long blockSize = contentLength / threadAmount;
|
||||
for (int threadId = 0; threadId < threadAmount; threadId++) {
|
||||
long startIndex = threadId * blockSize;
|
||||
long endIndex = (threadId + 1) * blockSize - 1;
|
||||
if (threadId == (threadAmount - 1)) {
|
||||
endIndex = contentLength - 1;
|
||||
}
|
||||
SplitDownload download = new SplitDownload(url, startIndex, endIndex, dest, this);
|
||||
// Start downloading
|
||||
executorService.execute(download);
|
||||
splitDownloads.add(download);
|
||||
}
|
||||
long last = 0;
|
||||
do {
|
||||
Thread.sleep(500);
|
||||
long progress = 0;
|
||||
// Collect download progress
|
||||
for (SplitDownload splitDownload : splitDownloads) {
|
||||
progress += splitDownload.getCurrentIndex() - splitDownload.startIndex;
|
||||
// blocked then restart from current index
|
||||
if (!splitDownload.isComplete() && System.currentTimeMillis() - splitDownload.getLastUpdateTime() > maxBlockingTime) {
|
||||
splitDownload.setStartIndex(splitDownload.getCurrentIndex());
|
||||
if (splitDownload.getRetry() <= maxRetry) {
|
||||
executorService.execute(splitDownload);
|
||||
} else {
|
||||
throw new RetryFailedException(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fire a progress event
|
||||
if (onProgress != null) {
|
||||
onProgress.handle(new ProgressEvent(progress - last, this,
|
||||
((double) progress) / ((double) contentLength)));
|
||||
}
|
||||
last = progress;
|
||||
// check complete
|
||||
} while (last < contentLength);
|
||||
// close the thread pool, release resources
|
||||
executorService.shutdown();
|
||||
// change the running flag to false
|
||||
running = false;
|
||||
}
|
||||
// check hash
|
||||
if (md5 != null && !md5.equalsIgnoreCase(HashUtil.md5(dest))) {
|
||||
throw new HashNotMatchException();
|
||||
}
|
||||
if (sha1 != null && !sha1.equalsIgnoreCase(HashUtil.sha1(dest))) {
|
||||
throw new HashNotMatchException();
|
||||
}
|
||||
if (sha256 != null && !sha256.equalsIgnoreCase(HashUtil.sha256(dest))) {
|
||||
throw new HashNotMatchException();
|
||||
}
|
||||
if (onComplete != null) {
|
||||
onComplete.handle(new CompleteEvent(this, true));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
onError.handle(new ErrorEvent(e, this));
|
||||
executorService.shutdown();
|
||||
if (onComplete != null) {
|
||||
onComplete.handle(new CompleteEvent(this, false));
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}, "EagletTaskMonitor");
|
||||
monitor.start();
|
||||
return this;
|
||||
}
|
||||
|
||||
public EagletTask waitUntil() {
|
||||
while (lock.tryLock()) {
|
||||
lock.unlock();
|
||||
}
|
||||
lock.lock();
|
||||
lock.unlock();
|
||||
return this;
|
||||
}
|
||||
|
||||
public EagletTask waitFor(long timeout, TimeUnit unit) {
|
||||
while (lock.tryLock()) {
|
||||
lock.unlock();
|
||||
}
|
||||
try {
|
||||
lock.tryLock(timeout, unit);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public EagletTask maxRetry(int maxRetry) {
|
||||
this.maxRetry = maxRetry;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the sha256 hash of the download file. Case is not sensitive.
|
||||
* <p>
|
||||
* If the hash check failed, an error event will be fired.
|
||||
*
|
||||
* @param sha256 file sha1
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask sha256(String sha256) {
|
||||
this.sha256 = sha256;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the sha1 hash of the download file. Case is not sensitive.
|
||||
* <p>
|
||||
* If the hash check failed, an error event will be fired.
|
||||
*
|
||||
* @param sha1 file sha1
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask sha1(String sha1) {
|
||||
this.sha1 = sha1;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the md5 hash of the download file. Case is not sensitive.
|
||||
* <p>
|
||||
* If the hash check failed, an error event will be fired.
|
||||
*
|
||||
* @param md5 file md5
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask md5(String md5) {
|
||||
this.md5 = md5;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the max blocked time per download thread.
|
||||
* <p>
|
||||
* If the thread blocks exceeded the provided time, this thread will re-start the task.
|
||||
*
|
||||
* @param maxBlockingTime time
|
||||
* @return task instance
|
||||
*/
|
||||
private EagletTask maxBlocking(long maxBlockingTime) {
|
||||
this.maxBlockingTime = maxBlockingTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the progress handler
|
||||
* <p>
|
||||
* This handler will be called every 1000 milli seconds.
|
||||
* <p>
|
||||
* 设置处理进度的时间监听器。该监听器的 handle 方法每秒调用一次。
|
||||
*
|
||||
* @param onProgress handler
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask setOnProgress(EagletHandler<ProgressEvent> onProgress) {
|
||||
this.onProgress = onProgress;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the download file
|
||||
*
|
||||
* @param file the file's absolute path
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask file(String file) {
|
||||
this.dest = new File(file);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the download file
|
||||
*
|
||||
* @param file the file
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask file(File file) {
|
||||
this.dest = file;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connected handler
|
||||
* <p>
|
||||
* This will be called when the connection is established
|
||||
* <p>
|
||||
* Async call
|
||||
*
|
||||
* @param onConnected onConnected event handler
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask setOnConnected(EagletHandler<ConnectedEvent> onConnected) {
|
||||
this.onConnected = onConnected;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the read timeout, default is 7000
|
||||
*
|
||||
* @param timeout timeout
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask readTimeout(int timeout) {
|
||||
this.readTimeout = timeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connection timeout, default is 7000
|
||||
*
|
||||
* @param timeout timeout
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask connectionTimeout(int timeout) {
|
||||
this.connectionTimeout = timeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the request method, default is <code>GET</code>
|
||||
*
|
||||
* @param requestMethod the request method
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask requestMethod(String requestMethod) {
|
||||
this.requestMethod = requestMethod;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the complete event handler
|
||||
* <p>
|
||||
* This handler will be called when everything is complete, and the downloaded file is available
|
||||
* <p>
|
||||
* Async call
|
||||
*
|
||||
* @param onComplete the handler
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask setOnComplete(EagletHandler<CompleteEvent> onComplete) {
|
||||
this.onComplete = onComplete;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the start handler
|
||||
* <p>
|
||||
* This handler will be called when the <code>start</code> method is called
|
||||
* <p>
|
||||
* Async call
|
||||
*
|
||||
* @param onStart the handler
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask setOnStart(EagletHandler<StartEvent> onStart) {
|
||||
this.onStart = onStart;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the network proxy
|
||||
*
|
||||
* @param proxy the proxy
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask proxy(Proxy proxy) {
|
||||
this.proxy = proxy;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the error handler, default is to print the stack trace
|
||||
* <p>
|
||||
* This handler will be called when an exception is thrown
|
||||
* <p>
|
||||
* Async call
|
||||
*
|
||||
* @param onError the handler
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask setOnError(EagletHandler<ErrorEvent> onError) {
|
||||
this.onError = onError;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set how much thread should be used to download, default is 1
|
||||
*
|
||||
* @param i thread amount
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask setThreads(int i) {
|
||||
if (i < 1) {
|
||||
throw new RuntimeException("Thread amount cannot be zero or negative!");
|
||||
}
|
||||
threadAmount = i;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the download source
|
||||
*
|
||||
* @param url the url
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask url(URL url) {
|
||||
this.url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the download source
|
||||
*
|
||||
* @param url the url
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask url(String url) {
|
||||
try {
|
||||
this.url = new URL(url);
|
||||
} catch (MalformedURLException e) {
|
||||
onError.handle(new ErrorEvent(e, this));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the http header field
|
||||
*
|
||||
* @return task instance
|
||||
*/
|
||||
public EagletTask clearHeaders() {
|
||||
httpHeader.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the header field of the http request
|
||||
*
|
||||
* @param key header key
|
||||
* @param value header value
|
||||
* @return builder instance
|
||||
*/
|
||||
public EagletTask header(String key, String value) {
|
||||
httpHeader.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package com.ilummc.eagletdl;
|
||||
|
||||
public class ErrorEvent {
|
||||
|
||||
private Throwable e;
|
||||
private EagletTask task;
|
||||
|
||||
public ErrorEvent(Throwable e, EagletTask task) {
|
||||
this.e = e;
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
public EagletTask getTask() {
|
||||
return task;
|
||||
}
|
||||
|
||||
public Throwable getException() {
|
||||
return e;
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
package com.ilummc.eagletdl;
|
||||
|
||||
public class HashNotMatchException extends RuntimeException {
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
package com.ilummc.eagletdl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class HashUtil {
|
||||
|
||||
public static String sha256(File file) {
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
MessageDigest md = MessageDigest.getInstance("SHA256");
|
||||
byte[] buffer = new byte[1024];
|
||||
int length = -1;
|
||||
while ((length = fis.read(buffer, 0, 1024)) != -1) {
|
||||
md.update(buffer, 0, length);
|
||||
}
|
||||
BigInteger bigInt = new BigInteger(1, md.digest());
|
||||
return bigInt.toString(16);
|
||||
} catch (NoSuchAlgorithmException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String sha1(File file) {
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
MessageDigest md = MessageDigest.getInstance("SHA1");
|
||||
byte[] buffer = new byte[1024];
|
||||
int length = -1;
|
||||
while ((length = fis.read(buffer, 0, 1024)) != -1) {
|
||||
md.update(buffer, 0, length);
|
||||
}
|
||||
BigInteger bigInt = new BigInteger(1, md.digest());
|
||||
return bigInt.toString(16);
|
||||
} catch (NoSuchAlgorithmException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String md5(File file) {
|
||||
try {
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] buffer = new byte[1024];
|
||||
int length = -1;
|
||||
while ((length = fis.read(buffer, 0, 1024)) != -1) {
|
||||
md.update(buffer, 0, length);
|
||||
}
|
||||
BigInteger bigInt = new BigInteger(1, md.digest());
|
||||
return bigInt.toString(16);
|
||||
} catch (NoSuchAlgorithmException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package com.ilummc.eagletdl;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class ProgressEvent {
|
||||
|
||||
private long speed;
|
||||
private EagletTask task;
|
||||
private double percentage;
|
||||
|
||||
ProgressEvent(long speed, EagletTask task, double percentage) {
|
||||
this.speed = speed;
|
||||
this.task = task;
|
||||
this.percentage = percentage;
|
||||
}
|
||||
|
||||
public EagletTask getTask() {
|
||||
return task;
|
||||
}
|
||||
|
||||
public long getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
public double getPercentage() {
|
||||
return percentage;
|
||||
}
|
||||
|
||||
public String getPercentageFormatted() {
|
||||
return formatDouble(percentage * 100D) + " %";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the speed with format like <code>X.00 MiB</code>, <code>Y.50 GiB</code>, etc.
|
||||
*
|
||||
* @return formatted speed string
|
||||
*/
|
||||
public String getSpeedFormatted() {
|
||||
return format(getSpeed());
|
||||
}
|
||||
|
||||
private static String formatDouble(double d) {
|
||||
return new DecimalFormat("0.00").format(d);
|
||||
}
|
||||
|
||||
public static String format(long l) {
|
||||
if (l < 1024) return l + " B";
|
||||
if (l < 1024 * 1024) return formatDouble((double) l / 1024D) + " KiB";
|
||||
if (l < 1024 * 1024 * 1024) return formatDouble((double) l / (1024D * 1024D)) + " MiB";
|
||||
if (l < 1024 * 1024 * 1024 * 1024L) return formatDouble((double) l / (1024D * 1024D * 1024)) + " GiB";
|
||||
return "";
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package com.ilummc.eagletdl;
|
||||
|
||||
public class RetryFailedException extends RuntimeException {
|
||||
|
||||
private EagletTask task;
|
||||
|
||||
RetryFailedException(EagletTask task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
public EagletTask getTask() {
|
||||
return task;
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package com.ilummc.eagletdl;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
|
||||
class SingleThreadDownload implements Runnable {
|
||||
|
||||
private HttpURLConnection connection;
|
||||
private File target;
|
||||
private EagletTask task;
|
||||
|
||||
private transient long currentProgress = 0, lastUpdateTime = System.currentTimeMillis();
|
||||
|
||||
private transient boolean complete = false;
|
||||
|
||||
SingleThreadDownload(HttpURLConnection connection, File target, EagletTask task) {
|
||||
this.connection = connection;
|
||||
this.target = target;
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
long getLastUpdateTime() {
|
||||
return lastUpdateTime;
|
||||
}
|
||||
|
||||
long getCurrentProgress() {
|
||||
return currentProgress;
|
||||
}
|
||||
|
||||
public boolean isComplete() {
|
||||
return complete;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
byte[] buf = new byte[1024];
|
||||
int len = 0;
|
||||
try (BufferedInputStream stream = new BufferedInputStream(connection.getInputStream()); BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(target))) {
|
||||
while ((len = stream.read(buf)) > 0) {
|
||||
outputStream.write(buf, 0, len);
|
||||
currentProgress += len;
|
||||
lastUpdateTime = System.currentTimeMillis();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
task.onError.handle(new ErrorEvent(e, task));
|
||||
}
|
||||
complete = true;
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
package com.ilummc.eagletdl;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
class SplitDownload implements Runnable {
|
||||
|
||||
private URL url;
|
||||
long startIndex, endIndex;
|
||||
private File target;
|
||||
private EagletTask task;
|
||||
|
||||
private transient long currentIndex, lastUpdateTime = System.currentTimeMillis(), tmpStart;
|
||||
private transient int retry = 0;
|
||||
private transient boolean complete;
|
||||
|
||||
SplitDownload(URL url, long startIndex, long endIndex, File dest, EagletTask task) {
|
||||
this.url = url;
|
||||
tmpStart = this.startIndex = this.currentIndex = startIndex;
|
||||
this.endIndex = endIndex;
|
||||
target = dest;
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
void setStartIndex(long index) {
|
||||
this.tmpStart = index;
|
||||
}
|
||||
|
||||
long getLastUpdateTime() {
|
||||
return lastUpdateTime;
|
||||
}
|
||||
|
||||
long getCurrentIndex() {
|
||||
return currentIndex;
|
||||
}
|
||||
|
||||
int getRetry() {
|
||||
return retry;
|
||||
}
|
||||
|
||||
boolean isComplete() {
|
||||
return complete || currentIndex == endIndex + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
complete = false;
|
||||
currentIndex = tmpStart;
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
// set the connection properties
|
||||
task.httpHeader.forEach(connection::addRequestProperty);
|
||||
connection.setRequestMethod(task.requestMethod);
|
||||
connection.setConnectTimeout(task.connectionTimeout);
|
||||
connection.setReadTimeout(task.readTimeout);
|
||||
// set the download range
|
||||
connection.setRequestProperty("Range", "bytes=" + tmpStart + "-" + endIndex);
|
||||
connection.connect();
|
||||
// if response code not equals 206, it means that the server do not support multi thread downloading
|
||||
if (connection.getResponseCode() == 206) {
|
||||
RandomAccessFile file = new RandomAccessFile(target, "rwd");
|
||||
file.seek(tmpStart);
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
try (BufferedInputStream stream = new BufferedInputStream(connection.getInputStream())) {
|
||||
while ((len = stream.read(buf)) > 0) {
|
||||
file.write(buf, 0, len);
|
||||
lastUpdateTime = System.currentTimeMillis();
|
||||
currentIndex += len;
|
||||
// some mysterious error occurred while downloading
|
||||
if (currentIndex >= endIndex + 2) {
|
||||
currentIndex = tmpStart;
|
||||
lastUpdateTime = 0;
|
||||
retry++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
complete = true;
|
||||
}
|
||||
file.close();
|
||||
} else {
|
||||
throw new DoNotSupportMultipleThreadException();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
task.onError.handle(new ErrorEvent(e, task));
|
||||
retry++;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package com.ilummc.eagletdl;
|
||||
|
||||
public class StartEvent {
|
||||
|
||||
private EagletTask task;
|
||||
|
||||
StartEvent(EagletTask task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
public EagletTask getTask() {
|
||||
return task;
|
||||
}
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
package com.ilummc.tlib;
|
||||
|
||||
import com.ilummc.tlib.annotations.TConfig;
|
||||
import com.ilummc.tlib.bean.Property;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.lang.management.GarbageCollectorMXBean;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.MemoryMXBean;
|
||||
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());
|
||||
System.out.println(bean.getNonHeapMemoryUsage().toString());
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (GarbageCollectorMXBean mxBean : ManagementFactory.getGarbageCollectorMXBeans()) {
|
||||
System.out.println(mxBean.getName());
|
||||
System.out.println(mxBean.getCollectionCount());
|
||||
System.out.println(mxBean.getCollectionTime());
|
||||
for (String s : mxBean.getMemoryPoolNames()) {
|
||||
System.out.println(s);
|
||||
}
|
||||
System.out.println(mxBean.getObjectName().toString());
|
||||
}
|
||||
System.gc();
|
||||
}
|
||||
for (String s : ManagementFactory.getRuntimeMXBean().getInputArguments()) {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
update.addListener(((oldVal, newVal) -> {
|
||||
Bukkit.getLogger().info("配置项 enableUpdate 的值由 " + oldVal + " 变为了 " + newVal);
|
||||
if (newVal) {
|
||||
Updater.start();
|
||||
} else {
|
||||
Updater.stop();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private static class Updater {
|
||||
public static void start() {
|
||||
|
||||
}
|
||||
|
||||
public static void stop() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static class CD {
|
||||
|
||||
final long start, period;
|
||||
final TimeUnit unit;
|
||||
final Runnable onStart, onFinish, onTimer;
|
||||
|
||||
CD(long start, long period, TimeUnit unit, Runnable onStart, Runnable onFinish, Runnable onTimer) {
|
||||
this.start = start;
|
||||
this.period = period;
|
||||
this.unit = unit;
|
||||
this.onStart = onStart;
|
||||
this.onFinish = onFinish;
|
||||
this.onTimer = onTimer;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
CD.builder().setOnStart(() -> {
|
||||
}).setOnFinish(() -> {
|
||||
}).setOnTimer(1000, TimeUnit.MILLISECONDS, () -> {
|
||||
}).build();
|
||||
}
|
||||
|
||||
public static CdBuilder builder() {
|
||||
return new CdBuilder();
|
||||
}
|
||||
|
||||
private static class CdBuilder {
|
||||
private long start, period;
|
||||
private TimeUnit unit;
|
||||
private Runnable onStart, onFinish, onTimer;
|
||||
|
||||
public CdBuilder setOnStart(Runnable runnable) {
|
||||
this.onStart = runnable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CdBuilder setOnFinish(Runnable runnable) {
|
||||
this.onFinish = runnable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CdBuilder setOnTimer(long period, TimeUnit timeUnit, Runnable runnable) {
|
||||
this.period = period;
|
||||
this.unit = timeUnit;
|
||||
this.onTimer = runnable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CD build() {
|
||||
return new CD(start, period, unit, onStart, onFinish, onTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
package com.ilummc.tlib;
|
||||
|
||||
import com.ilummc.tlib.annotations.Dependency;
|
||||
import com.ilummc.tlib.compat.PlaceholderHook;
|
||||
import com.ilummc.tlib.config.TLibConfig;
|
||||
import com.ilummc.tlib.db.Pool;
|
||||
import com.ilummc.tlib.inject.TConfigWatcher;
|
||||
import com.ilummc.tlib.inject.TDependencyInjector;
|
||||
import com.ilummc.tlib.inject.TPluginManager;
|
||||
import com.ilummc.tlib.logger.TLogger;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import com.ilummc.tlib.resources.TLocaleLoader;
|
||||
import com.ilummc.tlib.util.IO;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
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 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")
|
||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.javalite:activejdbc:2.0")
|
||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.javalite:javalite-common:2.0")
|
||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.javalite:app-config:2.0")
|
||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.codehaus.jackson:jackson-mapper-asl:1.9.13")
|
||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.codehaus.jackson:jackson-core-asl:1.9.13")
|
||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "jaxen:jaxen:1.1.6")
|
||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "dom4j:dom4j:1.6.1")
|
||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "xml-apis:xml-apis:1.0.b2")
|
||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.ehcache:ehcache:3.5.2")
|
||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "com.h2database:h2:1.4.197")
|
||||
public class TLib {
|
||||
|
||||
private static TLib tLib;
|
||||
private static YamlConfiguration internalLanguage;
|
||||
private TLogger logger = new TLogger("§8[§3§lTabooLib§8][§r{1}§8] §f{2}", Main.getInst(), TLogger.FINE);
|
||||
private TLibConfig config;
|
||||
private TConfigWatcher configWatcher = new TConfigWatcher();
|
||||
private File libsFolder;
|
||||
|
||||
private TLib() {
|
||||
libsFolder = new File(Main.getInst().getDataFolder(), "/libs");
|
||||
if (!libsFolder.exists()) {
|
||||
libsFolder.mkdirs();
|
||||
}
|
||||
try {
|
||||
String yamlText = new String(IO.readFully(FileUtils.getResource("lang/internal.yml")), Charset.forName("utf-8"));
|
||||
internalLanguage = new YamlConfiguration();
|
||||
internalLanguage.loadFromString(yamlText);
|
||||
} catch (IOException | InvalidConfigurationException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
tLib = new TLib();
|
||||
|
||||
TLocaleLoader.init();
|
||||
PlaceholderHook.init();
|
||||
TLocaleLoader.load(Main.getInst(), false);
|
||||
}
|
||||
|
||||
public static void initPost() {
|
||||
TDependencyInjector.inject(Main.getInst(), TLib.getTLib());
|
||||
try {
|
||||
Pool.init();
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public static void unload() {
|
||||
try {
|
||||
Pool.unload();
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
tLib.getConfigWatcher().unregisterAll();
|
||||
TDependencyInjector.eject(Main.getInst(), tLib);
|
||||
|
||||
}
|
||||
|
||||
public static void injectPluginManager() {
|
||||
if (!tLib.isInjectEnabled() || tLib.isBlackListPluginExists()) {
|
||||
TLocale.Logger.warn("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);
|
||||
field.set(Bukkit.getServer(), new TPluginManager());
|
||||
TLocale.Logger.info("TLIB.INJECTION-SUCCESS");
|
||||
} catch (NoSuchFieldException | IllegalAccessException | IllegalArgumentException ignored) {
|
||||
TLocale.Logger.error("TLIB.INJECTION-FAILED");
|
||||
Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> !TabooLib.isTabooLib(plugin)).forEach(plugin -> TDependencyInjector.inject(plugin, plugin));
|
||||
}
|
||||
}
|
||||
|
||||
public static TLib getTLib() {
|
||||
return tLib;
|
||||
}
|
||||
|
||||
public static YamlConfiguration getInternalLanguage() {
|
||||
return internalLanguage;
|
||||
}
|
||||
|
||||
public TLogger getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
public TLibConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public TConfigWatcher getConfigWatcher() {
|
||||
return configWatcher;
|
||||
}
|
||||
|
||||
public File getLibsFolder() {
|
||||
return libsFolder;
|
||||
}
|
||||
|
||||
public boolean isInjectEnabled() {
|
||||
return Main.getInst().getConfig().getBoolean("PLUGIN-INJECTOR.ENABLE", true);
|
||||
}
|
||||
|
||||
public boolean isBlackListPluginExists() {
|
||||
return Main.getInst().getConfig().getStringList("PLUGIN-INJECTOR.DISABLE-ON-PLUGIN-EXISTS").stream().anyMatch(PluginUtils::isPluginExists);
|
||||
}
|
||||
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package com.ilummc.tlib.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Logger {
|
||||
|
||||
String value() default "[{0}|{1}§f] {2}";
|
||||
|
||||
int level() default com.ilummc.tlib.logger.TLogger.INFO;
|
||||
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package com.ilummc.tlib.annotations;
|
||||
|
||||
import com.ilummc.tlib.util.Ref;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TConfig {
|
||||
|
||||
String name() default "config.yml";
|
||||
|
||||
boolean fromJar() default false;
|
||||
|
||||
boolean saveOnExit() default false;
|
||||
|
||||
boolean readOnly() default true;
|
||||
|
||||
String charset() default "UTF-8";
|
||||
|
||||
boolean listenChanges() default false;
|
||||
|
||||
int excludeModifiers() default Modifier.STATIC | Modifier.TRANSIENT | Ref.ACC_SYNTHETIC | Ref.ACC_BRIDGE;
|
||||
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package com.ilummc.tlib.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TLocalePlugin {
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package com.ilummc.tlib.annotations.clr;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Repeatable(CommandHandlers.class)
|
||||
public @interface CommandHandler {
|
||||
|
||||
/**
|
||||
* Name of the command
|
||||
*
|
||||
* @return Name of the command
|
||||
*/
|
||||
String value();
|
||||
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package com.ilummc.tlib.annotations.clr;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface CommandHandlers {
|
||||
|
||||
CommandHandler[] value();
|
||||
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package com.ilummc.tlib.annotations.clr;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Sub {
|
||||
|
||||
String value();
|
||||
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package com.ilummc.tlib.annotations.db;
|
||||
|
||||
public @interface Database {
|
||||
|
||||
boolean sharedPool() default true;
|
||||
|
||||
int poolSize() default 8;
|
||||
|
||||
Class<?> configClass();
|
||||
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
package com.ilummc.tlib.annotations.db;
|
||||
|
||||
public @interface DatabasePassword {
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
package com.ilummc.tlib.annotations.db;
|
||||
|
||||
public @interface DatabaseType {
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
package com.ilummc.tlib.annotations.db;
|
||||
|
||||
public @interface DatabaseUrl {
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
package com.ilummc.tlib.annotations.db;
|
||||
|
||||
public @interface DatabaseUser {
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package com.ilummc.tlib.annotations.db;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface SQLTable {
|
||||
|
||||
String value();
|
||||
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package com.ilummc.tlib.bean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class Property<T> {
|
||||
|
||||
private Property(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private List<BiConsumer<T, T>> consumers;
|
||||
|
||||
private T value;
|
||||
|
||||
public void set(T value) {
|
||||
if (value != this.value) {
|
||||
if (consumers != null) {
|
||||
for (BiConsumer<T, T> consumer : consumers) {
|
||||
consumer.accept(this.value, value);
|
||||
}
|
||||
}
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public T get() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void addListener(BiConsumer<T, T> consumer) {
|
||||
if (consumers == null) {
|
||||
consumers = new ArrayList<>();
|
||||
}
|
||||
consumers.add(consumer);
|
||||
}
|
||||
|
||||
public static <T> Property<T> of(T value) {
|
||||
return new Property<>(value);
|
||||
}
|
||||
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package com.ilummc.tlib.bean;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class PropertyTypeAdaptor implements JsonDeserializer<Property> {
|
||||
|
||||
@Override
|
||||
public Property deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) throws JsonParseException {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package com.ilummc.tlib.clr;
|
||||
|
||||
public class CommandLineResolver {
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
package com.ilummc.tlib.config;
|
||||
|
||||
import com.ilummc.tlib.annotations.TConfig;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author sky
|
||||
* @since 2018-04-22 14:31:11
|
||||
*/
|
||||
@TConfig(name = "tlib.yml")
|
||||
public class TLibConfig {
|
||||
|
||||
private String dataSourceClassName;
|
||||
|
||||
private String jdbcUrl = "jdbc:h2:file:~/plugins/TabooLib/h2";
|
||||
|
||||
private String driverClassName;
|
||||
|
||||
private String username = "";
|
||||
|
||||
private String password = "";
|
||||
|
||||
private int maximumPoolSize = 4;
|
||||
|
||||
private Map<String, Object> settings = new HashMap<String, Object>() {{
|
||||
put("cachePrepStmts", true);
|
||||
put("useServerPrepStmts", true);
|
||||
}};
|
||||
|
||||
public String getDataSourceClassName() {
|
||||
return dataSourceClassName;
|
||||
}
|
||||
|
||||
public String getJdbcUrl() {
|
||||
return jdbcUrl;
|
||||
}
|
||||
|
||||
public String getDriverClassName() {
|
||||
return driverClassName;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public int getMaximumPoolSize() {
|
||||
return maximumPoolSize;
|
||||
}
|
||||
|
||||
public Map<String, Object> getSettings() {
|
||||
return settings;
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
package com.ilummc.tlib.db;
|
||||
|
||||
import com.ilummc.tlib.TLib;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import org.javalite.activejdbc.Base;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public final class Pool extends ThreadPoolExecutor {
|
||||
|
||||
private static final AtomicInteger number = new AtomicInteger(1);
|
||||
|
||||
private static final Pool singleton = new Pool();
|
||||
|
||||
private final TLibDataSource dataSource;
|
||||
|
||||
private Pool() {
|
||||
super(TLib.getTLib().getConfig().getMaximumPoolSize(),
|
||||
TLib.getTLib().getConfig().getMaximumPoolSize(),
|
||||
0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
|
||||
try {
|
||||
dataSource = new TLibDataSource();
|
||||
this.setThreadFactory(r -> new Thread(() -> {
|
||||
Base.open(dataSource.getDataSource());
|
||||
r.run();
|
||||
}, "TabooLib-DbPool-" + number.getAndIncrement()));
|
||||
prestartAllCoreThreads();
|
||||
TLocale.sendToConsole("DATABASE.CONNECTION-ESTABLISHED", dataSource.getDataSource().getConnection().getMetaData().getDatabaseProductName(),
|
||||
String.valueOf(TLib.getTLib().getConfig().getMaximumPoolSize()));
|
||||
} catch (Exception e) {
|
||||
TLocale.sendToConsole("DATABASE.CONNECTION-ERROR", e.toString());
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
public static void run(Runnable runnable) {
|
||||
instance().execute(runnable);
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
|
||||
}
|
||||
|
||||
public static void unload() {
|
||||
instance().dataSource.disconnect();
|
||||
instance().shutdown();
|
||||
}
|
||||
|
||||
public static Pool instance() {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterExecute(Runnable r, Throwable t) {
|
||||
if (t != null) {
|
||||
Base.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package com.ilummc.tlib.db;
|
||||
|
||||
import com.ilummc.tlib.TLib;
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.javalite.activejdbc.Base;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Properties;
|
||||
|
||||
public class TLibDataSource {
|
||||
|
||||
private final HikariDataSource dataSource;
|
||||
|
||||
TLibDataSource() {
|
||||
Properties properties = new Properties();
|
||||
properties.put("jdbcUrl", TLib.getTLib().getConfig().getJdbcUrl());
|
||||
properties.put("username", TLib.getTLib().getConfig().getUsername());
|
||||
properties.put("password", TLib.getTLib().getConfig().getPassword());
|
||||
properties.put("dataSourceClassName", TLib.getTLib().getConfig().getDataSourceClassName());
|
||||
properties.put("driverClassName", TLib.getTLib().getConfig().getDriverClassName());
|
||||
TLib.getTLib().getConfig().getSettings().forEach((k, v) -> properties.put("dataSource." + k, v));
|
||||
dataSource = new HikariDataSource(new HikariConfig(properties));
|
||||
Base.open(dataSource);
|
||||
}
|
||||
|
||||
public DataSource getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
Base.close();
|
||||
}
|
||||
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
package com.ilummc.tlib.dependency;
|
||||
|
||||
import com.ilummc.eagletdl.EagletTask;
|
||||
import com.ilummc.eagletdl.ProgressEvent;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.Main;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class TDependency {
|
||||
|
||||
// 阿里 http://maven.aliyun.com/nexus/content/groups/public
|
||||
// Maven Central
|
||||
public static final String MAVEN_REPO = "http://repo1.maven.org/maven2";
|
||||
|
||||
/**
|
||||
* 请求一个插件作为依赖,这个插件将会在所有已经添加的 Jenkins 仓库、Maven 仓库寻找
|
||||
* <p>
|
||||
* 阻塞线程进行下载/加载
|
||||
*
|
||||
* @param args 插件名称,下载地址(可选)
|
||||
* @return 是否成功加载了依赖
|
||||
*/
|
||||
public static boolean requestPlugin(String... args) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求一个库作为依赖,这个库将会在 Maven Central、oss.sonatype 以及自定义的 Maven 仓库寻找
|
||||
* <p>
|
||||
* 阻塞线程进行下载/加载
|
||||
*
|
||||
* @param type 依赖名,格式为 groupId:artifactId:version
|
||||
* @return 是否成功加载库,如果加载成功,插件将可以任意调用使用的类
|
||||
*/
|
||||
public static boolean requestLib(String type, String repo, String url) {
|
||||
if (type.matches(".*:.*:.*")) {
|
||||
String[] arr = type.split(":");
|
||||
File file = new File(Main.getInst().getDataFolder(), "/libs/" + String.join("-", arr) + ".jar");
|
||||
if (file.exists()) {
|
||||
TDependencyLoader.addToPath(Main.getInst(), file);
|
||||
return true;
|
||||
} else {
|
||||
if (downloadMaven(repo, arr[0], arr[1], arr[2], file, url)) {
|
||||
TDependencyLoader.addToPath(Main.getInst(), file);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean downloadMaven(String url, String groupId, String artifactId, String version, File target, String dl) {
|
||||
if (Main.isOfflineVersion()) {
|
||||
TLocale.Logger.warn("DEPENDENCY.DOWNLOAD-OFFLINE");
|
||||
return false;
|
||||
}
|
||||
AtomicBoolean failed = new AtomicBoolean(false);
|
||||
String link = dl.length() == 0 ? url + "/" + groupId.replace('.', '/') + "/" + artifactId + "/" + version + "/" + artifactId + "-" + version + ".jar" : dl;
|
||||
new EagletTask()
|
||||
.url(link)
|
||||
.file(target)
|
||||
.setThreads(1)
|
||||
.setOnError(event -> event.getException().printStackTrace())
|
||||
.setOnConnected(event -> TLocale.Logger.info("DEPENDENCY.DOWNLOAD-CONNECTED", String.join(":", new String[] {groupId, artifactId, version}), ProgressEvent.format(event.getContentLength())))
|
||||
.setOnProgress(event -> TLocale.Logger.info("DEPENDENCY.DOWNLOAD-PROGRESS", event.getSpeedFormatted(), event.getPercentageFormatted()))
|
||||
.setOnComplete(event -> {
|
||||
if (event.isSuccess()) {
|
||||
TLocale.Logger.info("DEPENDENCY.DOWNLOAD-SUCCESS", String.join(":", new String[] {groupId, artifactId, version}));
|
||||
} else {
|
||||
failed.set(true);
|
||||
TLocale.Logger.error("DEPENDENCY.DOWNLOAD-FAILED", String.join(":", new String[] {groupId, artifactId, version}), link, target.getName());
|
||||
}
|
||||
}).start().waitUntil();
|
||||
return !failed.get();
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
package com.ilummc.tlib.filter;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.ilummc.tlib.filter.impl.FilterConfiguration;
|
||||
import com.ilummc.tlib.filter.impl.FilterInvalidPluginLoader;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Filter;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* @author Bkm016
|
||||
* @since 2018-04-22
|
||||
*/
|
||||
public class TLoggerFilter implements Filter {
|
||||
|
||||
private Filter filter;
|
||||
private Logger logger;
|
||||
private static List<TLoggerFilterHandler> handlers = Lists.newLinkedList();
|
||||
private static Map<String, TLoggerFilter> pluginFilter = Maps.newHashMap();
|
||||
private static TLoggerFilter globalFilter;
|
||||
private static String playerConnectionName;
|
||||
|
||||
static {
|
||||
handlers.add(new FilterConfiguration());
|
||||
handlers.add(new FilterInvalidPluginLoader());
|
||||
// handlers.add(new FilterExceptionMirror());
|
||||
}
|
||||
|
||||
public static void preInit() {
|
||||
inject(new TLoggerFilter(), Bukkit.getLogger());
|
||||
inject(new TLoggerFilter(), TabooLib.instance().getLogger());
|
||||
try {
|
||||
playerConnectionName = Class.forName("net.minecraft.server." + TabooLib.getVersion() + ".PlayerConnection").getName();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public static void postInit() {
|
||||
Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(TabooLib::isDependTabooLib).forEach(plugin -> inject(new TLoggerFilter(), plugin.getLogger()));
|
||||
}
|
||||
|
||||
public static void inject0() {
|
||||
inject(new TLoggerFilter(), Logger.getLogger(playerConnectionName));
|
||||
}
|
||||
|
||||
public static void inject(TLoggerFilter filter, Logger logger) {
|
||||
if (!(logger.getFilter() instanceof TLoggerFilter)) {
|
||||
try {
|
||||
filter.filter = logger.getFilter();
|
||||
filter.logger = logger;
|
||||
logger.setFilter(filter);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void eject(Plugin plugin) {
|
||||
try {
|
||||
if (plugin.getLogger().getFilter() instanceof TLoggerFilter) {
|
||||
((TLoggerFilter) plugin.getLogger().getFilter()).filter = null;
|
||||
((TLoggerFilter) plugin.getLogger().getFilter()).logger = null;
|
||||
plugin.getLogger().setFilter(null);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static TLoggerFilter getGlobalFilter() {
|
||||
return globalFilter;
|
||||
}
|
||||
|
||||
public static Map<String, TLoggerFilter> getPluginFilter() {
|
||||
return pluginFilter;
|
||||
}
|
||||
|
||||
public static List<TLoggerFilterHandler> getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public Filter getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
public Logger getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoggable(LogRecord e) {
|
||||
return handlers.stream().allMatch(filter -> filter.isLoggable(e)) && (filter == null || filter.isLoggable(e));
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
package com.ilummc.tlib.filter;
|
||||
|
||||
import java.util.logging.LogRecord;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-11-29 11:42
|
||||
*/
|
||||
public abstract class TLoggerFilterHandler {
|
||||
|
||||
abstract public boolean isLoggable(LogRecord e);
|
||||
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package com.ilummc.tlib.filter.impl;
|
||||
|
||||
import com.ilummc.tlib.filter.TLoggerFilterHandler;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.logging.LogRecord;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-11-29 11:47
|
||||
*/
|
||||
public class FilterConfiguration extends TLoggerFilterHandler {
|
||||
|
||||
@Override
|
||||
public boolean isLoggable(LogRecord e) {
|
||||
if (String.valueOf(e.getMessage()).contains("Cannot load configuration from stream")) {
|
||||
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
|
||||
for (StackTraceElement element : elements) {
|
||||
if (element.getClassName().contains("ConfigUtils")) {
|
||||
// Bukkit 拦截异常?我再扔一个
|
||||
System.out.println(Arrays.asList(e.getParameters()));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
package com.ilummc.tlib.filter.impl;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.ilummc.tlib.filter.TLoggerFilterHandler;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import org.bukkit.command.CommandException;
|
||||
import org.bukkit.event.EventException;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-11-29 11:42
|
||||
*/
|
||||
public class FilterExceptionMirror extends TLoggerFilterHandler {
|
||||
|
||||
interface ArgumentsCallback {
|
||||
|
||||
String[] run();
|
||||
}
|
||||
|
||||
private static Pattern patternEvent = Pattern.compile("Could not pass event (.+?) to (.+?)");
|
||||
private static Pattern patternCommand = Pattern.compile("Unhandled exception executing command '(.+?)' in plugin (.+?)");
|
||||
|
||||
/**
|
||||
* 判断是否为调度器异常
|
||||
*/
|
||||
public boolean isScheduleException(LogRecord log) {
|
||||
return String.valueOf(log.getMessage()).contains("generated an exception");
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为可捕捉异常
|
||||
*/
|
||||
public boolean isValidException(Throwable throwable) {
|
||||
return throwable.getCause() != null && throwable.getCause().getStackTrace() != null && throwable.getCause().getStackTrace().length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 向控制台打印捕捉到的异常
|
||||
*
|
||||
* @param stackTraceElements 堆栈
|
||||
* @param message 信息类型
|
||||
* @param args 信息参数
|
||||
* @return 是否成功捕捉并打印
|
||||
*/
|
||||
public boolean printException(AtomicReference<Plugin> plugin, StackTraceElement[] stackTraceElements, String message, ArgumentsCallback args) {
|
||||
Set<Plugin> plugins = Sets.newHashSet();
|
||||
List<StackTraceElement> stackTraces = Lists.newLinkedList();
|
||||
for (StackTraceElement stack : stackTraceElements) {
|
||||
try {
|
||||
plugins.add(JavaPlugin.getProvidingPlugin(Class.forName(stack.getClassName())));
|
||||
stackTraces.add(stack);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
if (!plugins.isEmpty() && plugins.stream().allMatch(p -> TabooLib.isTabooLib(p) || TabooLib.isDependTabooLib(p))) {
|
||||
plugin.set(plugins.iterator().next());
|
||||
TLocale.Logger.error("TFILTER.EXCEPTION-MIRROR." + message + ".HEAD", args.run());
|
||||
for (int i = 0; i < stackTraces.size(); i++) {
|
||||
StackTraceElement stack = stackTraces.get(i);
|
||||
TLocale.Logger.error("TFILTER.EXCEPTION-MIRROR." + message + ".STACK-TRACE", String.valueOf(i), stack.toString());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoggable(LogRecord e) {
|
||||
if (!Main.getInst().getConfig().getBoolean("EXCEPTION-MIRROR", true) || e.getThrown() == null) {
|
||||
return true;
|
||||
}
|
||||
// 是否为调度器异常
|
||||
if (isScheduleException(e)) {
|
||||
long time = System.currentTimeMillis();
|
||||
AtomicReference<Plugin> plugin = new AtomicReference<>();
|
||||
return !printException(plugin, e.getThrown().getStackTrace(), "SCHEDULE", () -> new String[] {plugin.get().getName(), String.valueOf(System.currentTimeMillis() - time), e.getThrown().getClass().getSimpleName(), String.valueOf(e.getThrown().getMessage())});
|
||||
}
|
||||
// 是否为其他可捕捉异常
|
||||
else if (isValidException(e.getThrown())) {
|
||||
// 事件异常
|
||||
if (e.getThrown() instanceof EventException) {
|
||||
Matcher matcher = patternEvent.matcher(e.getMessage());
|
||||
if (matcher.find()) {
|
||||
long time = System.currentTimeMillis();
|
||||
AtomicReference<Plugin> plugin = new AtomicReference<>();
|
||||
return !printException(plugin, e.getThrown().getCause().getStackTrace(), "EVENT", () -> new String[] {plugin.get().getName(), String.valueOf(System.currentTimeMillis() - time), matcher.group(1), e.getThrown().getCause().getClass().getSimpleName(), String.valueOf(e.getThrown().getCause().getMessage())});
|
||||
}
|
||||
}
|
||||
// 命令异常
|
||||
else if (e.getThrown() instanceof CommandException) {
|
||||
Matcher matcher = patternCommand.matcher(e.getThrown().getMessage());
|
||||
if (matcher.find()) {
|
||||
long time = System.currentTimeMillis();
|
||||
AtomicReference<Plugin> plugin = new AtomicReference<>();
|
||||
return !printException(plugin, e.getThrown().getCause().getStackTrace(), "COMMAND", () -> new String[] {plugin.get().getName(), String.valueOf(System.currentTimeMillis() - time), matcher.group(1), e.getThrown().getCause().getClass().getSimpleName(), String.valueOf(e.getThrown().getCause().getMessage())});
|
||||
}
|
||||
}
|
||||
// 其他异常
|
||||
else {
|
||||
long time = System.currentTimeMillis();
|
||||
AtomicReference<Plugin> plugin = new AtomicReference<>();
|
||||
return !printException(plugin, e.getThrown().getCause().getStackTrace(), "OTHER", () -> new String[] {plugin.get().getName(), String.valueOf(System.currentTimeMillis() - time), e.getThrown().getCause().getClass().getSimpleName(), String.valueOf(e.getThrown().getCause().getMessage())});
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package com.ilummc.tlib.filter.impl;
|
||||
|
||||
import com.ilummc.tlib.filter.TLoggerFilterHandler;
|
||||
|
||||
import java.util.logging.LogRecord;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-11-29 11:47
|
||||
*/
|
||||
public class FilterInvalidPluginLoader extends TLoggerFilterHandler {
|
||||
|
||||
@Override
|
||||
public boolean isLoggable(LogRecord e) {
|
||||
// 屏蔽插件加载器注入导致的警告信息
|
||||
return !String.valueOf(e.getMessage()).contains("Enabled plugin with unregistered PluginClassLoader");
|
||||
}
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
package com.ilummc.tlib.inject;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.ilummc.tlib.annotations.TConfig;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.fileutils.ConfigUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class TConfigInjector {
|
||||
|
||||
public static void fixUnicode(YamlConfiguration configuration) {
|
||||
try {
|
||||
Field field = YamlConfiguration.class.getDeclaredField("yamlOptions");
|
||||
field.setAccessible(true);
|
||||
field.set(configuration, NoUnicodeDumperOption.INSTANCE);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static final class NoUnicodeDumperOption extends DumperOptions {
|
||||
|
||||
private static final NoUnicodeDumperOption INSTANCE = new NoUnicodeDumperOption();
|
||||
|
||||
@Override
|
||||
public void setAllowUnicode(boolean allowUnicode) {
|
||||
super.setAllowUnicode(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowUnicode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLineBreak(LineBreak lineBreak) {
|
||||
super.setLineBreak(LineBreak.getPlatformLineBreak());
|
||||
}
|
||||
}
|
||||
|
||||
public static Object loadConfig(Plugin plugin, Class<?> clazz) {
|
||||
try {
|
||||
TConfig config = clazz.getAnnotation(TConfig.class);
|
||||
Validate.notNull(config);
|
||||
File file = new File(plugin.getDataFolder(), config.name());
|
||||
if (!file.exists()) {
|
||||
if (config.fromJar()) {
|
||||
plugin.saveResource(config.name(), true);
|
||||
} else {
|
||||
saveConfig(plugin, clazz.newInstance());
|
||||
}
|
||||
}
|
||||
Object obj = unserialize(plugin, clazz);
|
||||
if (config.readOnly()) {
|
||||
saveConfig(plugin, obj);
|
||||
}
|
||||
return obj;
|
||||
} catch (NullPointerException e) {
|
||||
TLocale.Logger.warn("CONFIG.LOAD-FAIL-NO-ANNOTATION", plugin.toString(), clazz.getSimpleName());
|
||||
} catch (Exception e) {
|
||||
TLocale.Logger.warn("CONFIG.LOAD-FAIL", plugin.toString(), clazz.getSimpleName());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void reloadConfig(Plugin plugin, Object object) {
|
||||
try {
|
||||
TConfig config = object.getClass().getAnnotation(TConfig.class);
|
||||
Validate.notNull(config);
|
||||
File file = new File(plugin.getDataFolder(), config.name());
|
||||
Map<String, Object> map = ConfigUtils.confToMap(ConfigUtils.loadYaml(plugin, file));
|
||||
Object obj = ConfigUtils.mapToObj(map, object);
|
||||
if (config.readOnly()) {
|
||||
saveConfig(plugin, obj);
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
TLocale.Logger.warn("CONFIG.LOAD-FAIL-NO-ANNOTATION", plugin.toString(), object.getClass().getSimpleName());
|
||||
} catch (Exception e) {
|
||||
TLocale.Logger.warn("CONFIG.LOAD-FAIL", plugin.toString(), object.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
public static Object unserialize(Plugin plugin, Class<?> clazz) {
|
||||
try {
|
||||
TConfig config = clazz.getAnnotation(TConfig.class);
|
||||
Validate.notNull(config);
|
||||
return ConfigUtils.confToObj(
|
||||
ConfigUtils.mapToConf(
|
||||
ConfigUtils.yamlToMap(
|
||||
Files.toString(new File(plugin.getDataFolder(), config.name()), Charset.forName(config.charset())))), clazz);
|
||||
} catch (NullPointerException e) {
|
||||
TLocale.Logger.warn("CONFIG.LOAD-FAIL-NO-FILE", plugin.toString(), clazz.getSimpleName());
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
return clazz.newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException e1) {
|
||||
TLocale.Logger.warn("CONFIG.LOAD-FAIL", plugin.toString(), clazz.getSimpleName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, Object> serialize(Plugin plugin, Object object) {
|
||||
try {
|
||||
TConfig config = object.getClass().getAnnotation(TConfig.class);
|
||||
Validate.notNull(config);
|
||||
return ConfigUtils.objToMap(ConfigUtils.objToConf(object).getValues(false), config.excludeModifiers());
|
||||
} catch (NullPointerException e) {
|
||||
TLocale.Logger.warn("CONFIG.SAVE-FAIL-NO-ANNOTATION", plugin.toString(), object.getClass().getSimpleName());
|
||||
} catch (Exception e) {
|
||||
TLocale.Logger.warn("CONFIG.SAVE-FAIL", plugin.toString(), object.getClass().getSimpleName());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void saveConfig(Plugin plugin, Object object) throws IOException, NullPointerException {
|
||||
TConfig config = object.getClass().getAnnotation(TConfig.class);
|
||||
Validate.notNull(config);
|
||||
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
|
||||
Map map = gson.fromJson(gson.toJson(object), HashMap.class);
|
||||
YamlConfiguration configuration = (YamlConfiguration) ConfigUtils.mapToConf(map);
|
||||
File target = new File(plugin.getDataFolder(), config.name());
|
||||
if (!target.exists()) {
|
||||
target.createNewFile();
|
||||
}
|
||||
byte[] arr = configuration.saveToString().getBytes(config.charset());
|
||||
Files.write(arr, target);
|
||||
}
|
||||
|
||||
}
|
@ -1,188 +0,0 @@
|
||||
package com.ilummc.tlib.inject;
|
||||
|
||||
import com.ilummc.tlib.TLib;
|
||||
import com.ilummc.tlib.annotations.*;
|
||||
import com.ilummc.tlib.dependency.TDependency;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import com.ilummc.tlib.resources.TLocaleLoader;
|
||||
import com.ilummc.tlib.util.Ref;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Izzel_Aliz
|
||||
*/
|
||||
public class TDependencyInjector {
|
||||
|
||||
private static List<String> injected = new ArrayList<>();
|
||||
|
||||
static void injectOnEnable(Plugin plugin) {
|
||||
inject(plugin, plugin);
|
||||
}
|
||||
|
||||
static void ejectOnDisable(Plugin plugin) {
|
||||
eject(plugin, plugin);
|
||||
}
|
||||
|
||||
public static boolean injected(Plugin plugin) {
|
||||
return injected.contains(plugin.getName());
|
||||
}
|
||||
|
||||
public static void inject(Plugin plugin, Object o) {
|
||||
if (!injected.contains(plugin.getName())) {
|
||||
injected.add(plugin.getName());
|
||||
TLocaleLoader.load(plugin, true);
|
||||
injectDependencies(plugin, o);
|
||||
injectLogger(plugin, o);
|
||||
injectConfig(plugin, o);
|
||||
injectPluginInstance(plugin, o);
|
||||
}
|
||||
}
|
||||
|
||||
public static void eject(Plugin plugin, Object o) {
|
||||
try {
|
||||
injected.remove(plugin.getName());
|
||||
ejectConfig(plugin, o);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public static Dependency[] getDependencies(Object o) {
|
||||
Dependency[] dependencies = new Dependency[0];
|
||||
Dependencies d = o.getClass().getAnnotation(Dependencies.class);
|
||||
if (d != null) {
|
||||
dependencies = d.value();
|
||||
}
|
||||
Dependency d2 = o.getClass().getAnnotation(Dependency.class);
|
||||
if (d2 != null) {
|
||||
dependencies = new Dependency[] {d2};
|
||||
}
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
private static void ejectConfig(Plugin plugin, Object o) {
|
||||
for (Field field : Ref.getDeclaredFields(o.getClass())) {
|
||||
TConfig config;
|
||||
if ((config = field.getType().getAnnotation(TConfig.class)) != null && config.saveOnExit()) {
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
TConfigInjector.saveConfig(plugin, field.get(o));
|
||||
TLocale.Logger.info("CONFIG.SAVE-SUCCESS", plugin.toString(), config.name());
|
||||
} catch (Exception e) {
|
||||
TLocale.Logger.warn("CONFIG.SAVE-FAIL", plugin.toString(), config.name());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void injectConfig(Plugin plugin, Object o) {
|
||||
for (Field field : Ref.getDeclaredFields(o.getClass())) {
|
||||
try {
|
||||
TConfig config;
|
||||
if ((config = field.getType().getAnnotation(TConfig.class)) != null) {
|
||||
field.setAccessible(true);
|
||||
Object obj = TConfigInjector.loadConfig(plugin, field.getType());
|
||||
if (obj != null) {
|
||||
TLocale.Logger.info("CONFIG.LOAD-SUCCESS", plugin.toString(), config.name());
|
||||
field.set(o, obj);
|
||||
if (config.listenChanges()) {
|
||||
TLocale.Logger.info("CONFIG.LISTEN-START", plugin.toString(), config.name());
|
||||
TLib.getTLib().getConfigWatcher().addOnListen(
|
||||
new File(plugin.getDataFolder(), config.name()),
|
||||
obj,
|
||||
object -> {
|
||||
try {
|
||||
TConfigInjector.reloadConfig(plugin, object);
|
||||
TLocale.Logger.info("CONFIG.RELOAD-SUCCESS", plugin.toString(), config.name());
|
||||
} catch (Exception ignored) {
|
||||
TLocale.Logger.warn("CONFIG.RELOAD-FAIL", plugin.toString(), config.name());
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void injectLogger(Plugin plugin, Object o) {
|
||||
for (Field field : Ref.getDeclaredFields(o.getClass())) {
|
||||
try {
|
||||
Logger logger;
|
||||
if ((logger = field.getAnnotation(Logger.class)) != null) {
|
||||
field.getType().asSubclass(com.ilummc.tlib.logger.TLogger.class);
|
||||
com.ilummc.tlib.logger.TLogger tLogger = new com.ilummc.tlib.logger.TLogger(logger.value(), plugin, logger.level());
|
||||
if (!field.isAccessible()) {
|
||||
field.setAccessible(true);
|
||||
}
|
||||
field.set(o, tLogger);
|
||||
TLoggerManager.setDefaultLogger(plugin, tLogger);
|
||||
}
|
||||
} catch (Exception ignored2) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void injectPluginInstance(Plugin plugin, Object o) {
|
||||
for (Field field : Ref.getDeclaredFields(o.getClass())) {
|
||||
try {
|
||||
PluginInstance instance;
|
||||
if ((instance = field.getAnnotation(PluginInstance.class)) != null) {
|
||||
if (!field.isAccessible()) {
|
||||
field.setAccessible(true);
|
||||
}
|
||||
field.getType().asSubclass(JavaPlugin.class);
|
||||
Plugin pl;
|
||||
if ((pl = Bukkit.getPluginManager().getPlugin(instance.value())) == null) {
|
||||
if (!TDependency.requestPlugin(instance.value())) {
|
||||
TLocale.Logger.warn("PLUGIN-AUTOLOAD-FAIL", plugin.getName(), instance.value());
|
||||
return;
|
||||
} else {
|
||||
pl = Bukkit.getPluginManager().getPlugin(instance.value());
|
||||
}
|
||||
}
|
||||
if (pl != null) {
|
||||
field.set(o, pl);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void injectDependencies(Plugin plugin, Object o) {
|
||||
Dependency[] dependencies = getDependencies(o);
|
||||
if (dependencies.length != 0) {
|
||||
TLocale.Logger.info("DEPENDENCY.LOADING-START", plugin.getName());
|
||||
for (Dependency dependency : dependencies) {
|
||||
if (dependency.type() == Dependency.Type.PLUGIN) {
|
||||
if (TDependency.requestPlugin(dependency.plugin())) {
|
||||
TabooLib.debug(" Loaded " + dependency.plugin() + " (" + plugin.getName() + ")");
|
||||
// TLocale.Logger.info("DEPENDENCY.PLUGIN-LOAD-SUCCESS", plugin.getName(), dependency.plugin());
|
||||
} else {
|
||||
TLocale.Logger.warn("DEPENDENCY.PLUGIN-LOAD-FAIL", plugin.getName(), dependency.plugin());
|
||||
}
|
||||
}
|
||||
if (dependency.type() == Dependency.Type.LIBRARY) {
|
||||
if (TDependency.requestLib(dependency.maven(), dependency.mavenRepo(), dependency.url())) {
|
||||
TabooLib.debug(" Loaded " + String.join(":", dependency.maven()) + " (" + plugin.getName() + ")");
|
||||
// TLocale.Logger.info("DEPENDENCY.LIBRARY-LOAD-SUCCESS", plugin.getName(), String.join(":", dependency.maven()));
|
||||
} else {
|
||||
TLocale.Logger.warn("DEPENDENCY.LIBRARY-LOAD-FAIL", plugin.getName(), String.join(":", dependency.maven()));
|
||||
}
|
||||
}
|
||||
}
|
||||
TLocale.Logger.info("DEPENDENCY.LOAD-COMPLETE");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,231 +0,0 @@
|
||||
package com.ilummc.tlib.inject;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.Main;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.SimpleCommandMap;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.plugin.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class TPluginManager implements PluginManager {
|
||||
|
||||
private static TPluginManager singleton;
|
||||
private final PluginManager instance;
|
||||
private final Main main = (Main) Main.getInst();
|
||||
private static File updateDirectory = null;
|
||||
private Server server;
|
||||
private Map<Pattern, PluginLoader> fileAssociations = new HashMap<>();
|
||||
private List<Plugin> plugins = new ArrayList<>();
|
||||
private Map<String, Plugin> lookupNames = new HashMap<>();
|
||||
private SimpleCommandMap commandMap;
|
||||
private Map<String, Permission> permissions = new HashMap<>();
|
||||
private Map<Boolean, Set<Permission>> defaultPerms = new LinkedHashMap<>();
|
||||
private Map<String, Map<Permissible, Boolean>> permSubs = new HashMap<>();
|
||||
private Map<Boolean, Map<Permissible, Boolean>> defSubs = new HashMap<>();
|
||||
private boolean useTimings = false;
|
||||
private List<Plugin> delayedDisable = new ArrayList<>();
|
||||
|
||||
public static void delayDisable(Plugin plugin) {
|
||||
if (!singleton.delayedDisable.contains(plugin)) {
|
||||
singleton.delayedDisable.add(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
public TPluginManager() {
|
||||
instance = Bukkit.getPluginManager();
|
||||
// clone all Field in SimplePluginManager
|
||||
cloneField("updateDirectory");
|
||||
cloneField("server");
|
||||
cloneField("fileAssociations");
|
||||
cloneField("plugins");
|
||||
cloneField("lookupNames");
|
||||
cloneField("commandMap");
|
||||
cloneField("permissions");
|
||||
cloneField("defaultPerms");
|
||||
cloneField("permSubs");
|
||||
cloneField("defSubs");
|
||||
cloneField("useTimings");
|
||||
singleton = this;
|
||||
}
|
||||
|
||||
private void cloneField(String bukkitName) {
|
||||
try {
|
||||
Field bukkitField = instance.getClass().getDeclaredField(bukkitName);
|
||||
Field thisFiled = this.getClass().getDeclaredField(bukkitName);
|
||||
if (bukkitField == null || thisFiled == null) {
|
||||
TLocale.Logger.warn("MISC.FIELD-COPY-FAILED", bukkitName);
|
||||
return;
|
||||
}
|
||||
bukkitField.setAccessible(true);
|
||||
thisFiled.setAccessible(true);
|
||||
thisFiled.set(this, bukkitField.get(instance));
|
||||
} catch (Exception e) {
|
||||
TLocale.Logger.error("MISC.FIELD-COPY-ERROR", bukkitName, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerInterface(Class<? extends PluginLoader> aClass) throws IllegalArgumentException {
|
||||
instance.registerInterface(aClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin getPlugin(String s) {
|
||||
return instance.getPlugin(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin[] getPlugins() {
|
||||
return instance.getPlugins();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPluginEnabled(String s) {
|
||||
return instance.isPluginEnabled(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPluginEnabled(Plugin plugin) {
|
||||
return instance.isPluginEnabled(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException {
|
||||
return instance.loadPlugin(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin[] loadPlugins(File file) {
|
||||
return instance.loadPlugins(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disablePlugins() {
|
||||
for (Plugin plugin : getPlugins()) {
|
||||
if (plugin != main && !delayedDisable.contains(plugin)) {
|
||||
disablePlugin(plugin);
|
||||
}
|
||||
}
|
||||
Collections.reverse(delayedDisable);
|
||||
delayedDisable.forEach(singleton::disablePlugin);
|
||||
disablePlugin(main);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearPlugins() {
|
||||
instance.clearPlugins();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void callEvent(Event event) throws IllegalStateException {
|
||||
instance.callEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEvents(Listener listener, Plugin plugin) {
|
||||
instance.registerEvents(listener, plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEvent(Class<? extends Event> aClass, Listener listener, EventPriority eventPriority, EventExecutor eventExecutor, Plugin plugin) {
|
||||
instance.registerEvent(aClass, listener, eventPriority, eventExecutor, plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEvent(Class<? extends Event> aClass, Listener listener, EventPriority eventPriority, EventExecutor eventExecutor, Plugin plugin, boolean b) {
|
||||
instance.registerEvent(aClass, listener, eventPriority, eventExecutor, plugin, b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enablePlugin(Plugin plugin) {
|
||||
TDependencyInjector.injectOnEnable(plugin);
|
||||
instance.enablePlugin(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disablePlugin(Plugin plugin) {
|
||||
TDependencyInjector.ejectOnDisable(plugin);
|
||||
instance.disablePlugin(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Permission getPermission(String s) {
|
||||
return instance.getPermission(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPermission(Permission permission) {
|
||||
instance.addPermission(permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePermission(Permission permission) {
|
||||
instance.removePermission(permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePermission(String s) {
|
||||
instance.removePermission(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Permission> getDefaultPermissions(boolean b) {
|
||||
return instance.getDefaultPermissions(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recalculatePermissionDefaults(Permission permission) {
|
||||
instance.recalculatePermissionDefaults(permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribeToPermission(String s, Permissible permissible) {
|
||||
instance.subscribeToPermission(s, permissible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribeFromPermission(String s, Permissible permissible) {
|
||||
instance.unsubscribeFromPermission(s, permissible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Permissible> getPermissionSubscriptions(String s) {
|
||||
return instance.getPermissionSubscriptions(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribeToDefaultPerms(boolean b, Permissible permissible) {
|
||||
instance.subscribeToDefaultPerms(b, permissible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribeFromDefaultPerms(boolean b, Permissible permissible) {
|
||||
instance.unsubscribeFromDefaultPerms(b, permissible);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Permissible> getDefaultPermSubscriptions(boolean b) {
|
||||
return instance.getDefaultPermSubscriptions(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Permission> getPermissions() {
|
||||
return instance.getPermissions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useTimings() {
|
||||
return instance.useTimings();
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package com.ilummc.tlib.nms;
|
||||
|
||||
import com.ilummc.tlib.util.asm.AsmClassTransformer;
|
||||
import me.skymc.taboolib.TabooLib;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public abstract class ActionBar {
|
||||
|
||||
private static ActionBar instance;
|
||||
|
||||
static {
|
||||
if (TabooLib.getVerint() > 11100) {
|
||||
instance = (ActionBar) AsmClassTransformer.builder().from(Impl_1_12.class).fromVersion("v1_12_R1")
|
||||
.toVersion(Bukkit.getServer().getClass().getName().split("\\.")[3]).build().transform();
|
||||
} else {
|
||||
instance = (ActionBar) AsmClassTransformer.builder().from(Impl_1_8.class).fromVersion("v1_8_R3")
|
||||
.toVersion(Bukkit.getServer().getClass().getName().split("\\.")[3]).build().transform();
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendActionBar(Player player, String text) {
|
||||
instance.send(player, text);
|
||||
}
|
||||
|
||||
public abstract void send(Player player, String text);
|
||||
|
||||
public static class Impl_1_8 extends ActionBar {
|
||||
|
||||
@Override
|
||||
public void send(Player player, String text) {
|
||||
net.minecraft.server.v1_8_R3.ChatComponentText component = new net.minecraft.server.v1_8_R3.ChatComponentText(text);
|
||||
net.minecraft.server.v1_8_R3.PacketPlayOutChat packet = new net.minecraft.server.v1_8_R3.PacketPlayOutChat(component, (byte) 2);
|
||||
((org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Impl_1_12 extends 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));
|
||||
((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package com.ilummc.tlib.resources;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-12 13:58
|
||||
*/
|
||||
public interface TLocaleSender {
|
||||
|
||||
/**
|
||||
* 发送信息
|
||||
*
|
||||
* @param sender 发送目标
|
||||
* @param args 参数
|
||||
*/
|
||||
void sendTo(CommandSender sender, String... args);
|
||||
|
||||
/**
|
||||
* 获取文本
|
||||
*
|
||||
* @param args 参数
|
||||
* @return 文本
|
||||
*/
|
||||
String asString(String... args);
|
||||
|
||||
/**
|
||||
* 获取文本集合
|
||||
*
|
||||
* @param args 参数
|
||||
* @return 文本集合
|
||||
*/
|
||||
List<String> asStringList(String... args);
|
||||
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package com.ilummc.tlib.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class IO {
|
||||
|
||||
public static byte[] readFully(InputStream inputStream) throws IOException {
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
byte[] buf = new byte[1024];
|
||||
int len = 0;
|
||||
while ((len = inputStream.read(buf)) > 0) {
|
||||
stream.write(buf, 0, len);
|
||||
}
|
||||
return stream.toByteArray();
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package com.ilummc.tlib.util;
|
||||
|
||||
public class Strings {
|
||||
|
||||
public static boolean isBlank(String var) {
|
||||
return var == null || var.trim().isEmpty();
|
||||
}
|
||||
|
||||
public static boolean isEmpty(CharSequence var) {
|
||||
return var == null || var.length() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 优化过的 String#replace,比默认快了大概 5 倍
|
||||
*
|
||||
* @param template 模板替换文件
|
||||
* @param args 替换的参数
|
||||
* @return 替换好的字符串
|
||||
*/
|
||||
public static String replaceWithOrder(String template, Object... args) {
|
||||
if (args.length == 0 || template.length() == 0) {
|
||||
return template;
|
||||
}
|
||||
char[] arr = template.toCharArray();
|
||||
StringBuilder stringBuilder = new StringBuilder(template.length());
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
if (arr[i] == '{' && Character.isDigit(arr[Math.min(i + 1, arr.length - 1)])
|
||||
&& arr[Math.min(i + 1, arr.length - 1)] - '0' < args.length
|
||||
&& arr[Math.min(i + 2, arr.length - 1)] == '}') {
|
||||
stringBuilder.append(args[arr[i + 1] - '0']);
|
||||
i += 2;
|
||||
} else {
|
||||
stringBuilder.append(arr[i]);
|
||||
}
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Deprecated
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public static String replaceWithOrder(String template, String... args) {
|
||||
return replaceWithOrder(template, (Object[]) args);
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package com.ilummc.tlibscala.runtime
|
||||
|
||||
import me.skymc.taboolib.Main
|
||||
import me.skymc.taboolib.economy.EcoUtils
|
||||
import me.skymc.taboolib.inventory.builder.ItemBuilder
|
||||
import org.bukkit.OfflinePlayer
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
class RichOfflinePlayer(private val offlinePlayer: OfflinePlayer) {
|
||||
|
||||
def getSkullItem: ItemStack = new ItemBuilder(offlinePlayer).build()
|
||||
|
||||
def getMoney: Double = EcoUtils.get(offlinePlayer)
|
||||
|
||||
def withdraw(x: Double): Boolean = Main.getEconomy.withdrawPlayer(offlinePlayer, x).transactionSuccess
|
||||
|
||||
def deposit(x: Double): Boolean = Main.getEconomy.depositPlayer(offlinePlayer, x).transactionSuccess
|
||||
|
||||
def hasMoney(x: Double): Boolean = Main.getEconomy.has(offlinePlayer, x)
|
||||
|
||||
}
|
||||
|
||||
|
||||
object RichOfflinePlayer {
|
||||
|
||||
implicit def player2rich(player: OfflinePlayer): RichOfflinePlayer = new RichOfflinePlayer(player)
|
||||
|
||||
implicit def rich2player(player: RichOfflinePlayer): OfflinePlayer = player.offlinePlayer
|
||||
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package com.ilummc.tlibscala.runtime
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale
|
||||
import me.skymc.taboolib.anvil.AnvilContainerAPI
|
||||
import me.skymc.taboolib.display.{ActionUtils, TitleUtils}
|
||||
import me.skymc.taboolib.permission.PermissionUtils
|
||||
import me.skymc.taboolib.player.PlayerUtils
|
||||
import me.skymc.taboolib.scoreboard.ScoreboardUtil
|
||||
import me.skymc.taboolib.sign.SignUtils
|
||||
import org.bukkit.block.Block
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
|
||||
class RichPlayer(private val player: Player) extends RichOfflinePlayer(player) {
|
||||
|
||||
def sendActionBar(x: String): Unit = ActionUtils.send(player, x)
|
||||
|
||||
def getFishTicks: Int = PlayerUtils.getFishingTicks(PlayerUtils.getPlayerHookedFish(player))
|
||||
|
||||
def setFishTicks(x: Int): Unit = PlayerUtils.setFishingTicks(PlayerUtils.getPlayerHookedFish(player), x)
|
||||
|
||||
def resetData(): Unit = PlayerUtils.resetData(player, false)
|
||||
|
||||
def resetData(scoreboard: Boolean): Unit = PlayerUtils.resetData(player, scoreboard)
|
||||
|
||||
def displaySidebar(title: String, elements: Map[String, Integer]): Unit = ScoreboardUtil.rankedSidebarDisplay(player, title, mapAsJavaMap(elements))
|
||||
|
||||
def displaySidebarUnranked(title: String, elements: Array[String]): Unit = ScoreboardUtil.unrankedSidebarDisplay(player, elements: _*)
|
||||
|
||||
def displaySidebarUnranked(title: String, elements: List[String]): Unit = ScoreboardUtil.unrankedSidebarDisplay(player, elements: _*)
|
||||
|
||||
def displaySidebarUnranked(title: String, elements: String*): Unit = ScoreboardUtil.unrankedSidebarDisplay(player, elements: _*)
|
||||
|
||||
def openSign(block: Block): Unit = SignUtils.openSign(player, block)
|
||||
|
||||
def openSign(lines: Array[String], id: String): Unit = SignUtils.openSign(player, lines, id)
|
||||
|
||||
//todo TagDataHandler
|
||||
|
||||
def addPermission(perm: String): Unit = PermissionUtils.addPermission(player, perm)
|
||||
|
||||
def removePermission(perm: String): Unit = PermissionUtils.removePermission(player, perm)
|
||||
|
||||
def sendTitle(title: String, subtitle: String, fadein: Int, stay: Int, fadeout: Int): Unit = TitleUtils.sendTitle(player, title, subtitle, fadein, stay, fadeout)
|
||||
|
||||
def sendTitle(p: Player, title: String, fadeint: Int, stayt: Int, fadeoutt: Int, subtitle: String, fadeinst: Int, stayst: Int, fadeoutst: Int): Unit = TitleUtils.sendTitle(p, title, fadeint, stayt, fadeoutt, subtitle, fadeinst, stayst, fadeoutst)
|
||||
|
||||
def openAnvil(): Unit = AnvilContainerAPI.openAnvil(player)
|
||||
|
||||
def sendLocalizedMessage(node: String, params: String*): Unit = TLocale.sendTo(player, node, params: _*)
|
||||
|
||||
def locale(node: String, params: String*): Unit = sendLocalizedMessage(node, params: _*)
|
||||
|
||||
def <<(text: String): RichPlayer = {
|
||||
player.sendMessage(text)
|
||||
this
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object RichPlayer {
|
||||
|
||||
implicit def player2rich(player: Player): RichPlayer = new RichPlayer(player)
|
||||
|
||||
implicit def rich2player(player: RichPlayer): Player = player.player
|
||||
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
package me.skymc.taboolib.bstats;
|
||||
package io.izzel.taboolib;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
@ -55,7 +55,7 @@ public class Metrics {
|
||||
}
|
||||
|
||||
// The plugin
|
||||
private final JavaPlugin plugin;
|
||||
private final Plugin plugin;
|
||||
|
||||
// A list with all custom charts
|
||||
private final List<CustomChart> charts = new ArrayList<>();
|
||||
@ -65,7 +65,7 @@ public class Metrics {
|
||||
*
|
||||
* @param plugin The plugin which stats should be submitted.
|
||||
*/
|
||||
public Metrics(JavaPlugin plugin) {
|
||||
public Metrics(Plugin plugin) {
|
||||
if (plugin == null) {
|
||||
throw new IllegalArgumentException("Plugin cannot be null!");
|
||||
}
|
||||
@ -78,27 +78,17 @@ public class Metrics {
|
||||
|
||||
// Check if the config file exists
|
||||
if (!config.isSet("serverUuid")) {
|
||||
|
||||
// Add default values
|
||||
config.addDefault("enabled", true);
|
||||
// Every server gets it's unique random id.
|
||||
config.addDefault("serverUuid", UUID.randomUUID().toString());
|
||||
// Should failed request be logged?
|
||||
config.addDefault("logFailedRequests", false);
|
||||
|
||||
// Inform the server owners about bStats
|
||||
config.options().header(
|
||||
"bStats collects some data for plugin authors like how many servers are using their plugins.\n" +
|
||||
"To honor their work, you should not disable it.\n" +
|
||||
"This has nearly no effect on the server performance!\n" +
|
||||
"Check out https://bStats.org/ to learn more :)"
|
||||
).copyDefaults(true);
|
||||
try {
|
||||
config.save(configFile);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
// Load the data
|
||||
serverUUID = config.getString("serverUuid");
|
||||
logFailedRequests = config.getBoolean("logFailedRequests", false);
|
117
src/main/scala/io/izzel/taboolib/PluginLoader.java
Normal file
117
src/main/scala/io/izzel/taboolib/PluginLoader.java
Normal file
@ -0,0 +1,117 @@
|
||||
package io.izzel.taboolib;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import io.izzel.taboolib.module.command.TCommandHandler;
|
||||
import io.izzel.taboolib.module.config.TConfig;
|
||||
import io.izzel.taboolib.module.config.TConfigWatcher;
|
||||
import io.izzel.taboolib.module.db.IHost;
|
||||
import io.izzel.taboolib.module.db.local.Local;
|
||||
import io.izzel.taboolib.module.db.source.DBSource;
|
||||
import io.izzel.taboolib.module.dependency.TDependencyInjector;
|
||||
import io.izzel.taboolib.module.inject.TListenerHandler;
|
||||
import io.izzel.taboolib.module.inject.TScheduleLoader;
|
||||
import io.izzel.taboolib.module.locale.TLocaleLoader;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2019-07-05 15:14
|
||||
*/
|
||||
public abstract class PluginLoader {
|
||||
|
||||
private static List<PluginLoader> registerLoader = Lists.newArrayList();
|
||||
private static Set<String> plugins = Sets.newHashSet();
|
||||
|
||||
static {
|
||||
registerLoader.add(new PluginLoader() {
|
||||
|
||||
@Override
|
||||
public void onLoading(Plugin plugin) {
|
||||
// 加载语言文件
|
||||
TLocaleLoader.load(plugin, false);
|
||||
// 注入依赖
|
||||
TDependencyInjector.inject(plugin, plugin.getClass());
|
||||
// 读取插件类
|
||||
TabooLibLoader.setupClasses(plugin);
|
||||
// 加载插件类
|
||||
TabooLibLoader.getPluginClassSafely(plugin).forEach(c -> TabooLibLoader.preLoadClass(plugin, c));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStarting(Plugin plugin) {
|
||||
// 加载监听器
|
||||
TListenerHandler.setupListener(plugin);
|
||||
// 加载插件类
|
||||
TabooLibLoader.getPluginClassSafely(plugin).forEach(c -> TabooLibLoader.postLoadClass(plugin, c));
|
||||
// 注册插件命令
|
||||
TCommandHandler.registerCommand(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivated(Plugin plugin) {
|
||||
// 注册监听器
|
||||
TListenerHandler.registerListener(plugin);
|
||||
// 注册调度器
|
||||
TScheduleLoader.run(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopping(Plugin plugin) {
|
||||
// 卸载语言文件
|
||||
TLocaleLoader.unload(plugin);
|
||||
// 保存数据
|
||||
Local.saveFiles(plugin.getName());
|
||||
Local.clearFiles(plugin.getName());
|
||||
// 注销监听器
|
||||
TListenerHandler.cancelListener(plugin);
|
||||
// 注销插件类
|
||||
TabooLibLoader.getPluginClassSafely(plugin).forEach(c -> TabooLibLoader.unloadClass(plugin, c));
|
||||
// 注销数据库连接
|
||||
Sets.newHashSet(DBSource.getDataSource().keySet()).stream().filter(IHost::isAutoClose).forEach(DBSource::closeDataSource);
|
||||
// 释放文检动态读取
|
||||
Optional.ofNullable(TConfig.getFiles().remove(plugin.getName())).ifPresent(files -> files.forEach(file -> TConfigWatcher.getInst().removeListener(file)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onLoading(Plugin plugin) {
|
||||
}
|
||||
|
||||
public void onStarting(Plugin plugin) {
|
||||
}
|
||||
|
||||
public void onActivated(Plugin plugin) {
|
||||
}
|
||||
|
||||
public void onStopping(Plugin plugin) {
|
||||
}
|
||||
|
||||
public static void addPlugin(Plugin plugin) {
|
||||
plugins.add(plugin.getName());
|
||||
}
|
||||
|
||||
public static void load(Plugin plugin) {
|
||||
registerLoader.forEach(loader -> loader.onLoading(plugin));
|
||||
}
|
||||
|
||||
public static void start(Plugin plugin) {
|
||||
registerLoader.forEach(loader -> loader.onStarting(plugin));
|
||||
}
|
||||
|
||||
public static void active(Plugin plugin) {
|
||||
registerLoader.forEach(loader -> loader.onActivated(plugin));
|
||||
}
|
||||
|
||||
public static void stop(Plugin plugin) {
|
||||
registerLoader.forEach(loader -> loader.onStopping(plugin));
|
||||
}
|
||||
|
||||
public static boolean isPlugin(Plugin plugin) {
|
||||
return plugins.contains(plugin.getName());
|
||||
}
|
||||
}
|
109
src/main/scala/io/izzel/taboolib/TabooLib.java
Normal file
109
src/main/scala/io/izzel/taboolib/TabooLib.java
Normal file
@ -0,0 +1,109 @@
|
||||
package io.izzel.taboolib;
|
||||
|
||||
import io.izzel.taboolib.common.plugin.InternalPlugin;
|
||||
import io.izzel.taboolib.module.config.TConfig;
|
||||
import io.izzel.taboolib.module.config.TConfigWatcher;
|
||||
import io.izzel.taboolib.module.db.local.Local;
|
||||
import io.izzel.taboolib.module.db.local.LocalPlayer;
|
||||
import io.izzel.taboolib.module.db.source.DBSource;
|
||||
import io.izzel.taboolib.module.dependency.Dependency;
|
||||
import io.izzel.taboolib.module.locale.TLocaleLoader;
|
||||
import io.izzel.taboolib.module.locale.logger.TLogger;
|
||||
import io.izzel.taboolib.module.nms.NMS;
|
||||
import io.izzel.taboolib.util.Files;
|
||||
import io.izzel.taboolib.util.IO;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.util.NumberConversions;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2019-07-05 10:39
|
||||
* <p>
|
||||
* 注意与 TabooLib4.x 版本的兼容
|
||||
* 可能存在同时运行的情况
|
||||
*/
|
||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.slf4j:slf4j-api:1.7.25", url = "https://skymc.oss-cn-shanghai.aliyuncs.com/libs/org.slf4j-slf4j-api-1.7.25.jar")
|
||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "com.zaxxer:HikariCP:3.1.0", url = "https://skymc.oss-cn-shanghai.aliyuncs.com/libs/com.zaxxer-HikariCP-3.1.0.jar")
|
||||
@Dependency(type = Dependency.Type.LIBRARY, maven = "org.scala-lang:scala-library:2.12.8", url = "https://skymc.oss-cn-shanghai.aliyuncs.com/libs/scala-library-2.12.8.jar")
|
||||
public class TabooLib {
|
||||
|
||||
private static TabooLib inst = new TabooLib();
|
||||
private static TLogger logger;
|
||||
private static TConfig config;
|
||||
|
||||
// 当前运行版本
|
||||
private static double version;
|
||||
|
||||
// 内部语言文件
|
||||
private YamlConfiguration internal = new YamlConfiguration();
|
||||
|
||||
public TabooLib() {
|
||||
inst = this;
|
||||
logger = TLogger.getUnformatted("TabooLib");
|
||||
// 配置文件从 config.yml 修改为 settings.yml 防止与老版本插件冲突
|
||||
config = TConfig.create(getPlugin(), "settings.yml");
|
||||
// 加载版本号
|
||||
try {
|
||||
version = NumberConversions.toDouble(IO.readFully(Files.getResource("version"), Charset.forName("utf-8")));
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
// 加载内部语言文件
|
||||
try {
|
||||
internal.loadFromString(IO.readFully(Files.getResource("lang/internal.yml"), Charset.forName("utf-8")));
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
// 加载 TabooLib 语言文件
|
||||
TLocaleLoader.load(getPlugin(), false);
|
||||
// 加载 TabooLib
|
||||
TabooLibLoader.init();
|
||||
// 创建线程检测服务器是否关闭
|
||||
Executors.newSingleThreadExecutor().submit(() -> {
|
||||
while (NMS.handle().isRunning()) {
|
||||
}
|
||||
// 保存数据
|
||||
Local.saveFiles();
|
||||
LocalPlayer.saveFiles();
|
||||
// 关闭文件监听
|
||||
TConfigWatcher.getInst().unregisterAll();
|
||||
// 关闭连接池
|
||||
DBSource.closeDataSourceForce();
|
||||
// 关闭插件
|
||||
PluginLoader.stop(getPlugin());
|
||||
});
|
||||
}
|
||||
|
||||
public static InternalPlugin getPlugin() {
|
||||
return InternalPlugin.getPlugin();
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Getter and Setter
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public static TabooLib getInst() {
|
||||
return inst;
|
||||
}
|
||||
|
||||
public static TLogger getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
public static TConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public static double getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public YamlConfiguration getInternal() {
|
||||
return internal;
|
||||
}
|
||||
}
|
91
src/main/scala/io/izzel/taboolib/TabooLibAPI.java
Normal file
91
src/main/scala/io/izzel/taboolib/TabooLibAPI.java
Normal file
@ -0,0 +1,91 @@
|
||||
package io.izzel.taboolib;
|
||||
|
||||
import io.izzel.taboolib.module.db.local.Local;
|
||||
import io.izzel.taboolib.module.nms.NMS;
|
||||
import io.izzel.taboolib.util.Strings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.event.server.ServerCommandEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2019-07-05 14:31
|
||||
*/
|
||||
public class TabooLibAPI {
|
||||
|
||||
private static boolean bukkit;
|
||||
private static boolean originLoaded;
|
||||
|
||||
static {
|
||||
try {
|
||||
// 判断是否基于 Bukkit 运行
|
||||
bukkit = Class.forName("org.bukkit.Bukkit") != null;
|
||||
// 获取 TabooLib4.x 版本是否载入
|
||||
originLoaded = Bukkit.getPluginManager().getPlugin("TabooLib") != null;
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isBukkit() {
|
||||
return bukkit;
|
||||
}
|
||||
|
||||
public static boolean isOriginLoaded() {
|
||||
return originLoaded;
|
||||
}
|
||||
|
||||
public static boolean isDependTabooLib(Plugin plugin) {
|
||||
return PluginLoader.isPlugin(plugin);
|
||||
}
|
||||
|
||||
public static double[] getTPS() {
|
||||
return NMS.handle().getTPS();
|
||||
}
|
||||
|
||||
public static boolean isDebug() {
|
||||
return Local.get().get("data").getBoolean("debug");
|
||||
}
|
||||
|
||||
public static void setDebug(boolean debug) {
|
||||
Local.get().get("data").set("debug", debug);
|
||||
}
|
||||
|
||||
public static void debug(String... args) {
|
||||
debug(TabooLib.getPlugin(), args);
|
||||
}
|
||||
|
||||
public static void debug(Plugin plugin, String... args) {
|
||||
if (!isDebug()) {
|
||||
return;
|
||||
}
|
||||
for (String line : args) {
|
||||
Bukkit.getConsoleSender().sendMessage("§4[" + plugin.getName() + "][DEBUG] §c" + line);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean dispatchCommand(CommandSender sender, String command) {
|
||||
try {
|
||||
if ((sender instanceof Player)) {
|
||||
PlayerCommandPreprocessEvent e = new PlayerCommandPreprocessEvent((Player) sender, "/" + command);
|
||||
Bukkit.getPluginManager().callEvent(e);
|
||||
if (e.isCancelled() || Strings.isBlank(e.getMessage()) || !e.getMessage().startsWith("/")) {
|
||||
return false;
|
||||
}
|
||||
return Bukkit.dispatchCommand(e.getPlayer(), e.getMessage().substring(1));
|
||||
} else {
|
||||
ServerCommandEvent e = new ServerCommandEvent(sender, command);
|
||||
Bukkit.getPluginManager().callEvent(e);
|
||||
if (e.isCancelled() || Strings.isBlank(e.getCommand())) {
|
||||
return false;
|
||||
}
|
||||
return Bukkit.dispatchCommand(e.getSender(), e.getCommand());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
151
src/main/scala/io/izzel/taboolib/TabooLibLoader.java
Normal file
151
src/main/scala/io/izzel/taboolib/TabooLibLoader.java
Normal file
@ -0,0 +1,151 @@
|
||||
package io.izzel.taboolib;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import io.izzel.taboolib.client.TabooLibClient;
|
||||
import io.izzel.taboolib.client.TabooLibServer;
|
||||
import io.izzel.taboolib.module.dependency.TDependencyInjector;
|
||||
import io.izzel.taboolib.module.inject.TSchedule;
|
||||
import io.izzel.taboolib.util.Files;
|
||||
import io.izzel.taboolib.util.Reflection;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2019-07-05 15:30
|
||||
*/
|
||||
public class TabooLibLoader {
|
||||
|
||||
static Map<String, List<Class>> pluginClasses = Maps.newHashMap();
|
||||
static List<Loader> loaders = Lists.newArrayList();
|
||||
|
||||
@TSchedule
|
||||
static void start() {
|
||||
PluginLoader.active(TabooLib.getPlugin());
|
||||
// 通讯网络服务器
|
||||
if (TabooLib.getConfig().getBoolean("SERVER")) {
|
||||
TabooLibServer.main(new String[0]);
|
||||
}
|
||||
// 通讯网络客户端
|
||||
TabooLibClient.init();
|
||||
}
|
||||
|
||||
static void init() {
|
||||
// 加载依赖
|
||||
TDependencyInjector.inject("TabooLib", TabooLib.class);
|
||||
// 插件统计
|
||||
Metrics metrics = new Metrics(TabooLib.getPlugin());
|
||||
metrics.addCustomChart(new Metrics.SingleLineChart("plugins_using_taboolib", () -> Math.toIntExact(Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(TabooLibAPI::isDependTabooLib).count())));
|
||||
// 读取插件类
|
||||
setupClasses(TabooLib.getPlugin());
|
||||
// 读取加载器
|
||||
pluginClasses.get("TabooLib").stream().filter(TabooLibLoader::isLoader).forEach(pluginClass -> {
|
||||
try {
|
||||
loaders.add((Loader) Reflection.instantiateObject(pluginClass));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
loaders.sort(Comparator.comparingInt(Loader::priority));
|
||||
});
|
||||
// 加载插件
|
||||
PluginLoader.load(TabooLib.getPlugin());
|
||||
PluginLoader.start(TabooLib.getPlugin());
|
||||
}
|
||||
|
||||
public static Optional<List<Class>> getPluginClasses(Plugin plugin) {
|
||||
return Optional.ofNullable(pluginClasses.get(plugin.getName()));
|
||||
}
|
||||
|
||||
public static List<Class> getPluginClassSafely(Plugin plugin) {
|
||||
List<Class> classes = pluginClasses.get(plugin.getName());
|
||||
return classes == null ? new ArrayList<>() : new ArrayList<>(classes);
|
||||
}
|
||||
|
||||
static boolean isLoader(Class pluginClass) {
|
||||
return !Loader.class.equals(pluginClass) && Loader.class.isAssignableFrom(pluginClass);
|
||||
}
|
||||
|
||||
static void setupClasses(Plugin plugin) {
|
||||
try {
|
||||
long time = System.currentTimeMillis();
|
||||
List<Class> classes;
|
||||
IgnoreClasses annotation = plugin.getClass().getAnnotation(IgnoreClasses.class);
|
||||
if (annotation != null) {
|
||||
classes = Files.getClasses(plugin, annotation.value());
|
||||
} else {
|
||||
classes = Files.getClasses(plugin);
|
||||
}
|
||||
if (plugin.getName().equals("TabooLib")) {
|
||||
classes = classes.stream().filter(c -> c.getName().startsWith("io.izzel")).collect(Collectors.toList());
|
||||
}
|
||||
TabooLibAPI.debug("Saved " + classes.size() + " classes (" + plugin.getName() + ") (" + (System.currentTimeMillis() - time) + "ms)");
|
||||
pluginClasses.put(plugin.getName(), classes);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
static void preLoadClass(Plugin plugin, Class<?> loadClass) {
|
||||
loaders.forEach(loader -> {
|
||||
try {
|
||||
loader.preLoad(plugin, loadClass);
|
||||
} catch (NoClassDefFoundError ignore) {
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void postLoadClass(Plugin plugin, Class<?> loadClass) {
|
||||
loaders.forEach(loader -> {
|
||||
try {
|
||||
loader.postLoad(plugin, loadClass);
|
||||
} catch (NoClassDefFoundError ignore) {
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void unloadClass(Plugin plugin, Class<?> loadClass) {
|
||||
loaders.forEach(loader -> {
|
||||
try {
|
||||
loader.unload(plugin, loadClass);
|
||||
} catch (NoClassDefFoundError ignore) {
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public interface Loader {
|
||||
|
||||
default void preLoad(org.bukkit.plugin.Plugin plugin, Class<?> loadClass) {
|
||||
}
|
||||
|
||||
default void postLoad(org.bukkit.plugin.Plugin plugin, Class<?> loadClass) {
|
||||
}
|
||||
|
||||
default void unload(Plugin plugin, Class<?> cancelClass) {
|
||||
}
|
||||
|
||||
default int priority() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface IgnoreClasses {
|
||||
|
||||
String[] value();
|
||||
|
||||
}
|
||||
}
|
57
src/main/scala/io/izzel/taboolib/Version.java
Normal file
57
src/main/scala/io/izzel/taboolib/Version.java
Normal file
@ -0,0 +1,57 @@
|
||||
package io.izzel.taboolib;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2019-07-05 14:42
|
||||
*/
|
||||
public enum Version {
|
||||
|
||||
v1_7(10700), v1_8(10800), v1_9(10900), v1_10(11000), v1_11(11100), v1_12(11200), v1_13(11300), v1_14(11400), vNull(0);
|
||||
|
||||
private int versionInt;
|
||||
|
||||
Version(int versionInt) {
|
||||
this.versionInt = versionInt;
|
||||
}
|
||||
|
||||
public int getVersionInt() {
|
||||
return versionInt;
|
||||
}
|
||||
|
||||
public static boolean isAfter(Version in) {
|
||||
return getCurrentVersion().getVersionInt() >= in.getVersionInt();
|
||||
}
|
||||
|
||||
public static boolean isBefore(Version in) {
|
||||
return getCurrentVersion().getVersionInt() < in.getVersionInt();
|
||||
}
|
||||
|
||||
public static String getBukkitVersion() {
|
||||
return Bukkit.getServer().getClass().getName().split("\\.")[3];
|
||||
}
|
||||
|
||||
public static Version getCurrentVersion() {
|
||||
String nmsVersion = getBukkitVersion();
|
||||
if (nmsVersion.startsWith("v1_7")) {
|
||||
return v1_7;
|
||||
} else if (nmsVersion.startsWith("v1_8")) {
|
||||
return v1_8;
|
||||
} else if (nmsVersion.startsWith("v1_9")) {
|
||||
return v1_9;
|
||||
} else if (nmsVersion.startsWith("v1_10")) {
|
||||
return v1_10;
|
||||
} else if (nmsVersion.startsWith("v1_11")) {
|
||||
return v1_11;
|
||||
} else if (nmsVersion.startsWith("v1_12")) {
|
||||
return v1_12;
|
||||
} else if (nmsVersion.startsWith("v1_13")) {
|
||||
return v1_13;
|
||||
} else if (nmsVersion.startsWith("v1_14")) {
|
||||
return v1_14;
|
||||
} else {
|
||||
return vNull;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,15 +1,15 @@
|
||||
package me.skymc.taboolib.socket;
|
||||
package io.izzel.taboolib.client;
|
||||
|
||||
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 io.izzel.taboolib.TabooLib;
|
||||
import io.izzel.taboolib.client.packet.Packet;
|
||||
import io.izzel.taboolib.client.packet.impl.PacketCommand;
|
||||
import io.izzel.taboolib.client.packet.impl.PacketMessage;
|
||||
import io.izzel.taboolib.module.locale.TLocale;
|
||||
import io.izzel.taboolib.module.command.lite.CommandBuilder;
|
||||
import io.izzel.taboolib.client.packet.PacketSerializer;
|
||||
import io.izzel.taboolib.util.ArrayUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.util.NumberConversions;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.Socket;
|
||||
@ -34,7 +34,7 @@ public class TabooLibClient {
|
||||
public static void init() {
|
||||
if (TabooLibSettings.load()) {
|
||||
connect();
|
||||
Bukkit.getScheduler().runTaskTimerAsynchronously(TabooLib.instance(), TabooLibClient::reconnect, 0, 100);
|
||||
Bukkit.getScheduler().runTaskTimerAsynchronously(TabooLib.getPlugin(), TabooLibClient::reconnect, 0, 100);
|
||||
} else {
|
||||
TLocale.sendToConsole("COMMUNICATION.FAILED-LOAD-SETTINGS", TabooLibSettings.getThrowable().toString());
|
||||
}
|
||||
@ -45,7 +45,7 @@ public class TabooLibClient {
|
||||
}
|
||||
|
||||
public static void reconnect() {
|
||||
if (System.currentTimeMillis() - latestResponse > NumberUtils.getInteger(TabooLibSettings.getSettings().getProperty("channel.timeout"))) {
|
||||
if (System.currentTimeMillis() - latestResponse > NumberConversions.toInt(TabooLibSettings.getSettings().getProperty("channel.timeout"))) {
|
||||
connect();
|
||||
}
|
||||
}
|
||||
@ -59,7 +59,7 @@ public class TabooLibClient {
|
||||
}
|
||||
|
||||
try {
|
||||
socket = new Socket("localhost", NumberUtils.getInteger(TabooLibSettings.getSettings().getProperty("channel.port")));
|
||||
socket = new Socket("localhost", NumberConversions.toInt(TabooLibSettings.getSettings().getProperty("channel.port")));
|
||||
reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), TabooLibSettings.getCharset()));
|
||||
writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), TabooLibSettings.getCharset()), true);
|
||||
notify = false;
|
||||
@ -81,7 +81,7 @@ public class TabooLibClient {
|
||||
}
|
||||
});
|
||||
|
||||
SimpleCommandBuilder.create("TabooLibClient", TabooLib.instance())
|
||||
CommandBuilder.create("TabooLibClient", TabooLib.getPlugin())
|
||||
.aliases("tclient")
|
||||
.permission("*")
|
||||
.execute((sender, args) -> {
|
||||
@ -89,13 +89,12 @@ public class TabooLibClient {
|
||||
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)));
|
||||
sendPacket(new PacketMessage(ArrayUtil.arrayJoin(args, 1)));
|
||||
} else if (args[0].equalsIgnoreCase("command") && args.length > 1) {
|
||||
sendPacket(new PacketCommand(ArrayUtils.arrayJoin(args, 1)));
|
||||
sendPacket(new PacketCommand(ArrayUtil.arrayJoin(args, 1)));
|
||||
} else {
|
||||
sender.sendMessage("§c[TabooLibClient] §7指令错误.");
|
||||
}
|
||||
return true;
|
||||
}).build();
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
package me.skymc.taboolib.socket;
|
||||
package io.izzel.taboolib.client;
|
||||
|
||||
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;
|
||||
import me.skymc.taboolib.socket.packet.impl.PacketHeartbeat;
|
||||
import me.skymc.taboolib.socket.packet.impl.PacketQuit;
|
||||
import me.skymc.taboolib.socket.server.ClientConnection;
|
||||
import io.izzel.taboolib.TabooLibAPI;
|
||||
import io.izzel.taboolib.client.packet.Packet;
|
||||
import io.izzel.taboolib.client.packet.PacketSerializer;
|
||||
import io.izzel.taboolib.client.packet.impl.PacketHeartbeat;
|
||||
import io.izzel.taboolib.client.server.ClientConnection;
|
||||
import io.izzel.taboolib.client.packet.impl.PacketQuit;
|
||||
import org.bukkit.util.NumberConversions;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
@ -41,7 +41,7 @@ public class TabooLibServer {
|
||||
}
|
||||
|
||||
try {
|
||||
server = new ServerSocket(NumberUtils.getInteger(TabooLibSettings.getSettings().getProperty("channel.port")));
|
||||
server = new ServerSocket(NumberConversions.toInt(TabooLibSettings.getSettings().getProperty("channel.port")));
|
||||
println("Starting TabooLib server on " + server.getInetAddress().getHostName() + ":" + server.getLocalPort());
|
||||
} catch (IOException e) {
|
||||
println("Server starting failed: " + e.toString());
|
||||
@ -95,7 +95,7 @@ public class TabooLibServer {
|
||||
}
|
||||
|
||||
public static void println(Object obj) {
|
||||
System.out.println(TabooLib.isSpigot() ? obj : "[" + infoFormat.format(System.currentTimeMillis()) + " INFO]: " + obj);
|
||||
System.out.println(TabooLibAPI.isBukkit() ? obj : "[" + infoFormat.format(System.currentTimeMillis()) + " INFO]: " + obj);
|
||||
}
|
||||
|
||||
public static Optional<Map.Entry<Integer, ClientConnection>> getConnection(int port) {
|
@ -1,4 +1,4 @@
|
||||
package me.skymc.taboolib.socket;
|
||||
package io.izzel.taboolib.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
@ -1,4 +1,4 @@
|
||||
package me.skymc.taboolib.socket.packet;
|
||||
package io.izzel.taboolib.client.packet;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
@ -1,7 +1,8 @@
|
||||
package me.skymc.taboolib.socket.packet;
|
||||
package io.izzel.taboolib.client.packet;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import me.skymc.taboolib.fileutils.FileUtils;
|
||||
import io.izzel.taboolib.TabooLib;
|
||||
import io.izzel.taboolib.util.Files;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -17,7 +18,7 @@ public class PacketParser {
|
||||
private List<Class<?>> packets = new ArrayList<>();
|
||||
|
||||
public PacketParser() {
|
||||
FileUtils.getClasses(PacketParser.class).stream().filter(clazz -> clazz.isAnnotationPresent(PacketType.class)).forEach(clazz -> packets.add(clazz));
|
||||
Files.getClasses(TabooLib.getPlugin()).stream().filter(clazz -> clazz.isAnnotationPresent(PacketType.class)).forEach(clazz -> packets.add(clazz));
|
||||
}
|
||||
|
||||
public Packet parser(JsonObject json) {
|
@ -1,12 +1,12 @@
|
||||
package me.skymc.taboolib.socket.packet;
|
||||
package io.izzel.taboolib.client.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 io.izzel.taboolib.TabooLibAPI;
|
||||
import io.izzel.taboolib.TabooLibLoader;
|
||||
import io.izzel.taboolib.client.packet.impl.PacketEmpty;
|
||||
import io.izzel.taboolib.module.inject.TListener;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
@ -14,7 +14,6 @@ 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;
|
||||
|
||||
/**
|
||||
@ -45,7 +44,7 @@ public class PacketSerializer implements Listener {
|
||||
}
|
||||
|
||||
public static void loadPacket(Plugin plugin) {
|
||||
if (TabooLib.isTabooLib(plugin) || TabooLib.isDependTabooLib(plugin)) {
|
||||
if (plugin.getName().equals("TabooLib") || TabooLibAPI.isDependTabooLib(plugin)) {
|
||||
TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> classes.stream().filter(pluginClass -> pluginClass.isAnnotationPresent(PacketType.class)).forEach(pluginClass -> parser.getPackets().add(pluginClass)));
|
||||
}
|
||||
}
|
||||
@ -55,7 +54,7 @@ public class PacketSerializer implements Listener {
|
||||
}
|
||||
|
||||
public static void unloadPacket(Plugin plugin) {
|
||||
if (TabooLib.isTabooLib(plugin) || TabooLib.isDependTabooLib(plugin)) {
|
||||
if (plugin.getName().equals("TabooLib") || TabooLibAPI.isDependTabooLib(plugin)) {
|
||||
TabooLibLoader.getPluginClasses(plugin).ifPresent(classes -> classes.stream().filter(pluginClass -> pluginClass.isAnnotationPresent(PacketType.class)).forEach(pluginClass -> parser.getPackets().remove(pluginClass)));
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package me.skymc.taboolib.socket.packet;
|
||||
package io.izzel.taboolib.client.packet;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
@ -1,4 +1,4 @@
|
||||
package me.skymc.taboolib.socket.packet;
|
||||
package io.izzel.taboolib.client.packet;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
@ -1,8 +1,8 @@
|
||||
package me.skymc.taboolib.socket.packet.impl;
|
||||
package io.izzel.taboolib.client.packet.impl;
|
||||
|
||||
import me.skymc.taboolib.socket.TabooLibServer;
|
||||
import me.skymc.taboolib.socket.packet.Packet;
|
||||
import me.skymc.taboolib.socket.packet.PacketType;
|
||||
import io.izzel.taboolib.client.TabooLibServer;
|
||||
import io.izzel.taboolib.client.packet.Packet;
|
||||
import io.izzel.taboolib.client.packet.PacketType;
|
||||
|
||||
/**
|
||||
* @Author sky
|
@ -1,9 +1,9 @@
|
||||
package me.skymc.taboolib.socket.packet.impl;
|
||||
package io.izzel.taboolib.client.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 io.izzel.taboolib.client.TabooLibServer;
|
||||
import io.izzel.taboolib.client.packet.Packet;
|
||||
import io.izzel.taboolib.client.packet.PacketType;
|
||||
import io.izzel.taboolib.client.packet.PacketValue;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
/**
|
@ -1,7 +1,7 @@
|
||||
package me.skymc.taboolib.socket.packet.impl;
|
||||
package io.izzel.taboolib.client.packet.impl;
|
||||
|
||||
import me.skymc.taboolib.socket.packet.Packet;
|
||||
import me.skymc.taboolib.socket.packet.PacketType;
|
||||
import io.izzel.taboolib.client.packet.Packet;
|
||||
import io.izzel.taboolib.client.packet.PacketType;
|
||||
|
||||
/**
|
||||
* @Author sky
|
@ -1,9 +1,8 @@
|
||||
package me.skymc.taboolib.socket.packet.impl;
|
||||
package io.izzel.taboolib.client.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;
|
||||
import io.izzel.taboolib.client.TabooLibClient;
|
||||
import io.izzel.taboolib.client.packet.Packet;
|
||||
import io.izzel.taboolib.client.packet.PacketType;
|
||||
|
||||
/**
|
||||
* @Author sky
|
@ -1,9 +1,9 @@
|
||||
package me.skymc.taboolib.socket.packet.impl;
|
||||
package io.izzel.taboolib.client.packet.impl;
|
||||
|
||||
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 io.izzel.taboolib.client.TabooLibServer;
|
||||
import io.izzel.taboolib.client.packet.Packet;
|
||||
import io.izzel.taboolib.client.packet.PacketType;
|
||||
import io.izzel.taboolib.module.locale.TLocale;
|
||||
|
||||
/**
|
||||
* @Author sky
|
@ -1,11 +1,10 @@
|
||||
package me.skymc.taboolib.socket.packet.impl;
|
||||
package io.izzel.taboolib.client.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;
|
||||
import io.izzel.taboolib.module.locale.TLocale;
|
||||
import io.izzel.taboolib.client.TabooLibServer;
|
||||
import io.izzel.taboolib.client.packet.Packet;
|
||||
import io.izzel.taboolib.client.packet.PacketType;
|
||||
import io.izzel.taboolib.client.packet.PacketValue;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
/**
|
@ -1,10 +1,10 @@
|
||||
package me.skymc.taboolib.socket.packet.impl;
|
||||
package io.izzel.taboolib.client.packet.impl;
|
||||
|
||||
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 io.izzel.taboolib.client.TabooLibServer;
|
||||
import io.izzel.taboolib.client.packet.Packet;
|
||||
import io.izzel.taboolib.client.packet.PacketType;
|
||||
import io.izzel.taboolib.client.packet.PacketValue;
|
||||
import io.izzel.taboolib.module.locale.TLocale;
|
||||
|
||||
/**
|
||||
* @Author sky
|
@ -1,10 +1,10 @@
|
||||
package me.skymc.taboolib.socket.server;
|
||||
package io.izzel.taboolib.client.server;
|
||||
|
||||
import me.skymc.taboolib.other.NumberUtils;
|
||||
import me.skymc.taboolib.socket.TabooLibServer;
|
||||
import me.skymc.taboolib.socket.TabooLibSettings;
|
||||
import me.skymc.taboolib.socket.packet.impl.PacketJoin;
|
||||
import me.skymc.taboolib.socket.packet.impl.PacketQuit;
|
||||
import io.izzel.taboolib.client.TabooLibServer;
|
||||
import io.izzel.taboolib.client.TabooLibSettings;
|
||||
import io.izzel.taboolib.client.packet.impl.PacketJoin;
|
||||
import io.izzel.taboolib.client.packet.impl.PacketQuit;
|
||||
import org.bukkit.util.NumberConversions;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
@ -53,7 +53,7 @@ public class ClientConnection implements Runnable {
|
||||
}
|
||||
|
||||
public boolean isAlive() {
|
||||
return System.currentTimeMillis() - latestResponse < NumberUtils.getInteger(TabooLibSettings.getSettings().getProperty("channel.timeout"));
|
||||
return System.currentTimeMillis() - latestResponse < NumberConversions.toInt(TabooLibSettings.getSettings().getProperty("channel.timeout"));
|
||||
}
|
||||
|
||||
// *********************************
|
@ -0,0 +1,149 @@
|
||||
package io.izzel.taboolib.common.command;
|
||||
|
||||
import io.izzel.taboolib.TabooLibAPI;
|
||||
import io.izzel.taboolib.module.locale.TLocale;
|
||||
import io.izzel.taboolib.module.command.base.BaseMainCommand;
|
||||
import io.izzel.taboolib.module.command.base.BaseSubCommand;
|
||||
import io.izzel.taboolib.module.command.base.BaseCommand;
|
||||
import io.izzel.taboolib.module.command.base.Argument;
|
||||
import io.izzel.taboolib.module.command.base.SubCommand;
|
||||
import io.izzel.taboolib.util.ArrayUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-07-04 21:32
|
||||
*/
|
||||
@BaseCommand(
|
||||
name = "tExecute",
|
||||
permission = "taboolib.admin"
|
||||
)
|
||||
public class TabooLibExecuteCommand extends BaseMainCommand {
|
||||
|
||||
@Override
|
||||
public String getCommandTitle() {
|
||||
return TLocale.asString("COMMANDS.TEXECUTE.COMMAND-TITLE");
|
||||
}
|
||||
|
||||
@SubCommand(priority = 1)
|
||||
BaseSubCommand chat = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "chat";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TEXECUTE.CHAT.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Argument[] getArguments() {
|
||||
return new Argument[] {
|
||||
new Argument(TLocale.asString("COMMANDS.TEXECUTE.CHAT.ARGUMENTS.0")),
|
||||
new Argument(TLocale.asString("COMMANDS.TEXECUTE.CHAT.ARGUMENTS.1"))
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
Player player = Bukkit.getPlayerExact(args[0]);
|
||||
if (player == null) {
|
||||
TLocale.sendTo(sender, "INVALID-PLAYER-OFFLINE", args[0]);
|
||||
return;
|
||||
}
|
||||
player.chat(ArrayUtil.arrayJoin(args, 1));
|
||||
}
|
||||
};
|
||||
|
||||
@SubCommand(priority = 1)
|
||||
BaseSubCommand command = new BaseSubCommand() {
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "command";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAliases() {
|
||||
return new String[] {"cmd"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TEXECUTE.COMMAND.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Argument[] getArguments() {
|
||||
return new Argument[] {
|
||||
new Argument(TLocale.asString("COMMANDS.TEXECUTE.COMMAND.ARGUMENTS.0")),
|
||||
new Argument(TLocale.asString("COMMANDS.TEXECUTE.COMMAND.ARGUMENTS.1"))
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (args[0].equalsIgnoreCase("console")) {
|
||||
TabooLibAPI.dispatchCommand(Bukkit.getConsoleSender(), ArrayUtil.arrayJoin(args, 1));
|
||||
return;
|
||||
}
|
||||
Player player = Bukkit.getPlayerExact(args[0]);
|
||||
if (player == null) {
|
||||
TLocale.sendTo(sender, "INVALID-TARGET-NOT-FOUND", args[0]);
|
||||
return;
|
||||
}
|
||||
TabooLibAPI.dispatchCommand(player, ArrayUtil.arrayJoin(args, 1));
|
||||
}
|
||||
};
|
||||
|
||||
@SubCommand(priority = 2)
|
||||
BaseSubCommand commandAsOp = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return "commandAsOp";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAliases() {
|
||||
return new String[] {"op"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return TLocale.asString("COMMANDS.TEXECUTE.COMMAND-AS-OP.DESCRIPTION");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Argument[] getArguments() {
|
||||
return new Argument[] {
|
||||
new Argument(TLocale.asString("COMMANDS.TEXECUTE.COMMAND-AS-OP.ARGUMENTS.0")),
|
||||
new Argument(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")) {
|
||||
TabooLibAPI.dispatchCommand(Bukkit.getConsoleSender(), ArrayUtil.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 {
|
||||
TabooLibAPI.dispatchCommand(player, ArrayUtil.arrayJoin(args, 1));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
player.setOp(isOp);
|
||||
}
|
||||
};
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
package me.skymc.taboolib.commands.locale;
|
||||
package io.izzel.taboolib.common.command;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import com.ilummc.tlib.resources.TLocaleLoader;
|
||||
import me.skymc.taboolib.commands.internal.BaseMainCommand;
|
||||
import me.skymc.taboolib.commands.internal.BaseSubCommand;
|
||||
import me.skymc.taboolib.commands.internal.TCommand;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandArgument;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandRegister;
|
||||
import io.izzel.taboolib.module.locale.TLocale;
|
||||
import io.izzel.taboolib.module.locale.TLocaleLoader;
|
||||
import io.izzel.taboolib.module.command.base.BaseMainCommand;
|
||||
import io.izzel.taboolib.module.command.base.BaseSubCommand;
|
||||
import io.izzel.taboolib.module.command.base.BaseCommand;
|
||||
import io.izzel.taboolib.module.command.base.Argument;
|
||||
import io.izzel.taboolib.module.command.base.SubCommand;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -21,9 +21,8 @@ import java.util.stream.IntStream;
|
||||
* @author sky
|
||||
* @since 2018-04-22 14:36:28
|
||||
*/
|
||||
@TCommand(
|
||||
name = "tabooliblocale",
|
||||
aliases = {"taboolocale", "tlocale"},
|
||||
@BaseCommand(
|
||||
name = "tLocale",
|
||||
permission = "taboolib.admin"
|
||||
)
|
||||
public class TabooLibLocaleCommand extends BaseMainCommand {
|
||||
@ -33,7 +32,7 @@ public class TabooLibLocaleCommand extends BaseMainCommand {
|
||||
return TLocale.asString("COMMANDS.TLOCALE.COMMAND-TITLE");
|
||||
}
|
||||
|
||||
@CommandRegister
|
||||
@SubCommand
|
||||
BaseSubCommand send = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
@ -47,11 +46,11 @@ public class TabooLibLocaleCommand extends BaseMainCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[] {
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TLOCALE.SEND.ARGUMENTS.0")),
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TLOCALE.SEND.ARGUMENTS.1")),
|
||||
new CommandArgument(TLocale.asString("COMMANDS.TLOCALE.SEND.ARGUMENTS.2"), false)
|
||||
public Argument[] getArguments() {
|
||||
return new Argument[] {
|
||||
new Argument(TLocale.asString("COMMANDS.TLOCALE.SEND.ARGUMENTS.0")),
|
||||
new Argument(TLocale.asString("COMMANDS.TLOCALE.SEND.ARGUMENTS.1")),
|
||||
new Argument(TLocale.asString("COMMANDS.TLOCALE.SEND.ARGUMENTS.2"), false)
|
||||
};
|
||||
}
|
||||
|
@ -1,17 +1,18 @@
|
||||
package me.skymc.taboolib.commands.plugin;
|
||||
package io.izzel.taboolib.common.command;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.commands.internal.BaseMainCommand;
|
||||
import me.skymc.taboolib.commands.internal.BaseSubCommand;
|
||||
import me.skymc.taboolib.commands.internal.TCommand;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandArgument;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandRegister;
|
||||
import me.skymc.taboolib.plugin.PluginLoadState;
|
||||
import me.skymc.taboolib.plugin.PluginLoadStateType;
|
||||
import me.skymc.taboolib.plugin.PluginUnloadState;
|
||||
import me.skymc.taboolib.plugin.PluginUtils;
|
||||
import me.skymc.taboolib.string.ArrayUtils;
|
||||
import io.izzel.taboolib.TabooLibAPI;
|
||||
import io.izzel.taboolib.module.locale.TLocale;
|
||||
import io.izzel.taboolib.module.command.base.BaseCommand;
|
||||
import io.izzel.taboolib.module.command.base.BaseMainCommand;
|
||||
import io.izzel.taboolib.module.command.base.BaseSubCommand;
|
||||
import io.izzel.taboolib.module.command.base.Argument;
|
||||
import io.izzel.taboolib.module.command.base.SubCommand;
|
||||
import io.izzel.taboolib.util.plugin.PluginLoadState;
|
||||
import io.izzel.taboolib.util.plugin.PluginLoadStateType;
|
||||
import io.izzel.taboolib.util.plugin.PluginUnloadState;
|
||||
import io.izzel.taboolib.util.plugin.PluginUtils;
|
||||
import io.izzel.taboolib.util.ArrayUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -25,9 +26,8 @@ import java.util.stream.Collectors;
|
||||
* @Author sky
|
||||
* @Since 2018-05-07 20:14
|
||||
*/
|
||||
@TCommand(
|
||||
name = "taboolibplugin",
|
||||
aliases = {"tabooplugin", "tplugin"},
|
||||
@BaseCommand(
|
||||
name = "tPlugin",
|
||||
permission = "taboolib.admin"
|
||||
)
|
||||
public class TabooLibPluginCommand extends BaseMainCommand {
|
||||
@ -37,18 +37,7 @@ public class TabooLibPluginCommand extends BaseMainCommand {
|
||||
return TLocale.asString("COMMANDS.TPLUGIN.COMMAND-TITLE");
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String[] args) {
|
||||
// if (args.length == 1) {
|
||||
// return getSubCommands().stream().filter(internalCommandExecutor -> internalCommandExecutor != null && (args[0].isEmpty() || internalCommandExecutor.getLabel().toLowerCase().startsWith(args[0].toLowerCase()))).map(BaseSubCommand::getLabel).collect(Collectors.toList());
|
||||
// } else if (args.length > 1 && isPluginCommand(args[0])) {
|
||||
// return Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(x -> !PluginUtils.isIgnored(x)).collect(Collectors.toList()).stream().filter(plugin -> args[1].isEmpty() || plugin.getName().toLowerCase().startsWith(args[1].toLowerCase())).map(Plugin::getName).collect(Collectors.toList());
|
||||
// } else {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
|
||||
@CommandRegister(priority = 1)
|
||||
@SubCommand(priority = 1)
|
||||
BaseSubCommand load = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
@ -62,13 +51,13 @@ public class TabooLibPluginCommand extends BaseMainCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[] {new CommandArgument(TLocale.asString("COMMANDS.TPLUGIN.LOAD.ARGUMENTS.0"), true)};
|
||||
public Argument[] getArguments() {
|
||||
return new Argument[] {new Argument(TLocale.asString("COMMANDS.TPLUGIN.LOAD.ARGUMENTS.0"), true)};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
String name = ArrayUtils.arrayJoin(args, 0);
|
||||
String name = ArrayUtil.arrayJoin(args, 0);
|
||||
if (PluginUtils.getPluginByName(name) != null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.LOAD.INVALID-PLUGIN", name, name + " already loaded!");
|
||||
} else {
|
||||
@ -98,7 +87,7 @@ public class TabooLibPluginCommand extends BaseMainCommand {
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 2)
|
||||
@SubCommand(priority = 2)
|
||||
BaseSubCommand unload = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
@ -112,15 +101,15 @@ public class TabooLibPluginCommand extends BaseMainCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[] {new CommandArgument(TLocale.asString("COMMANDS.TPLUGIN.UNLOAD.ARGUMENTS.0"), true, () -> {
|
||||
return Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName).collect(Collectors.toList());
|
||||
public Argument[] getArguments() {
|
||||
return new Argument[] {new Argument(TLocale.asString("COMMANDS.TPLUGIN.UNLOAD.ARGUMENTS.0"), true, () -> {
|
||||
return java.util.Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName).collect(Collectors.toList());
|
||||
})};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
String name = ArrayUtils.arrayJoin(args, 0);
|
||||
String name = ArrayUtil.arrayJoin(args, 0);
|
||||
Plugin plugin = PluginUtils.getPluginByName(name);
|
||||
if (plugin == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.UNLOAD.INVALID-PLUGIN", name);
|
||||
@ -142,7 +131,7 @@ public class TabooLibPluginCommand extends BaseMainCommand {
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 3)
|
||||
@SubCommand(priority = 3)
|
||||
BaseSubCommand reload = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
@ -156,28 +145,28 @@ public class TabooLibPluginCommand extends BaseMainCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[] {new CommandArgument(TLocale.asString("COMMANDS.TPLUGIN.RELOAD.ARGUMENTS.0"), true, () -> {
|
||||
public Argument[] getArguments() {
|
||||
return new Argument[] {new Argument(TLocale.asString("COMMANDS.TPLUGIN.RELOAD.ARGUMENTS.0"), true, () -> {
|
||||
return Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName).collect(Collectors.toList());
|
||||
})};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
String name = ArrayUtils.arrayJoin(args, 0);
|
||||
String name = ArrayUtil.arrayJoin(args, 0);
|
||||
Plugin plugin = PluginUtils.getPluginByName(name);
|
||||
if (plugin == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.RELOAD.INVALID-PLUGIN", name);
|
||||
} else if (PluginUtils.isIgnored(plugin)) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.RELOAD.INVALID-PLUGIN-IGNORED", name);
|
||||
} else {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.RELOAD.TRY-RELOAD");
|
||||
PluginUtils.reload(plugin);
|
||||
TabooLibAPI.dispatchCommand(sender, "taboolibplugin unload " + plugin.getName());
|
||||
TabooLibAPI.dispatchCommand(sender, "taboolibplugin load " + plugin.getName());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 4)
|
||||
@SubCommand(priority = 4)
|
||||
BaseSubCommand info = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
@ -191,13 +180,15 @@ public class TabooLibPluginCommand extends BaseMainCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[] {new CommandArgument(TLocale.asString("COMMANDS.TPLUGIN.INFO.ARGUMENTS.0"), true)};
|
||||
public Argument[] getArguments() {
|
||||
return new Argument[] {new Argument(TLocale.asString("COMMANDS.TPLUGIN.INFO.ARGUMENTS.0"), true, () -> {
|
||||
return Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName).collect(Collectors.toList());
|
||||
})};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
String name = ArrayUtils.arrayJoin(args, 0);
|
||||
String name = ArrayUtil.arrayJoin(args, 0);
|
||||
Plugin plugin = PluginUtils.getPluginByName(name);
|
||||
if (plugin == null) {
|
||||
TLocale.sendTo(sender, "COMMANDS.TPLUGIN.INFO.INVALID-PLUGIN", name);
|
||||
@ -220,7 +211,7 @@ public class TabooLibPluginCommand extends BaseMainCommand {
|
||||
}
|
||||
};
|
||||
|
||||
@CommandRegister(priority = 5)
|
||||
@SubCommand(priority = 5)
|
||||
BaseSubCommand list = new BaseSubCommand() {
|
||||
|
||||
@Override
|
||||
@ -234,8 +225,8 @@ public class TabooLibPluginCommand extends BaseMainCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandArgument[] getArguments() {
|
||||
return new CommandArgument[0];
|
||||
public Argument[] getArguments() {
|
||||
return new Argument[0];
|
||||
}
|
||||
|
||||
@Override
|
@ -1,4 +1,4 @@
|
||||
package me.skymc.taboolib.events;
|
||||
package io.izzel.taboolib.common.event;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
@ -1,4 +1,4 @@
|
||||
package me.skymc.taboolib.events;
|
||||
package io.izzel.taboolib.common.event;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
@ -1,7 +1,6 @@
|
||||
package me.skymc.taboolib.listener;
|
||||
package io.izzel.taboolib.common.listener;
|
||||
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.message.MsgUtils;
|
||||
import io.izzel.taboolib.module.inject.TListener;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
@ -14,11 +13,9 @@ import pw.yumc.Yum.events.PluginNetworkEvent;
|
||||
@TListener(depend = "YUM")
|
||||
public class ListenerNetWork implements Listener {
|
||||
|
||||
public static final String GG = "本监听只是为了防止本插件的更新检测被 YUM 插件阻止,别无它用。";
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onNetWork(PluginNetworkEvent e) {
|
||||
if (e.getPlugin() != null && e.getPlugin().equals(Main.getInst())) {
|
||||
if (e.getPlugin() != null && e.getPlugin().getName().equals("TabooLib")) {
|
||||
e.setCancelled(false);
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package io.izzel.taboolib.common.listener;
|
||||
|
||||
import io.izzel.taboolib.TabooLibAPI;
|
||||
import io.izzel.taboolib.Version;
|
||||
import io.izzel.taboolib.module.db.local.Local;
|
||||
import io.izzel.taboolib.module.db.local.LocalPlayer;
|
||||
import io.izzel.taboolib.module.inject.TListener;
|
||||
import io.izzel.taboolib.module.locale.logger.TLogger;
|
||||
import io.izzel.taboolib.module.tellraw.TellrawJson;
|
||||
import io.izzel.taboolib.util.item.Items;
|
||||
import org.bukkit.event.EventHandler;
|
||||
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 (e.getCommand().equalsIgnoreCase("saveFiles")) {
|
||||
if (Version.isAfter(Version.v1_8)) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
Local.saveFiles();
|
||||
LocalPlayer.saveFiles();
|
||||
TLogger.getGlobalLogger().info("Successfully.");
|
||||
} else if (e.getCommand().equalsIgnoreCase("tDebug")) {
|
||||
if (Version.isAfter(Version.v1_8)) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
if (TabooLibAPI.isDebug()) {
|
||||
TabooLibAPI.setDebug(false);
|
||||
TLogger.getGlobalLogger().info("&cDisabled.");
|
||||
} else {
|
||||
TabooLibAPI.setDebug(true);
|
||||
TLogger.getGlobalLogger().info("&aEnabled.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void cmd(PlayerCommandPreprocessEvent e) {
|
||||
if (e.getMessage().equals("/tellrawTest") && e.getPlayer().hasPermission("taboolib.tellraw")) {
|
||||
e.setCancelled(true);
|
||||
TellrawJson.create()
|
||||
.append("§8[§3§lTabooLib§8] §7TellrawJson Test: §f[")
|
||||
.append(Items.getName(e.getPlayer().getItemInHand())).hoverItem(e.getPlayer().getItemInHand())
|
||||
.append("§f]")
|
||||
.send(e.getPlayer());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package me.skymc.taboolib.listener;
|
||||
package io.izzel.taboolib.common.listener;
|
||||
|
||||
import me.skymc.taboolib.events.PlayerJumpEvent;
|
||||
import io.izzel.taboolib.module.inject.TListener;
|
||||
import io.izzel.taboolib.common.event.PlayerJumpEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
@ -30,15 +31,14 @@ public class ListenerPlayerJump implements Listener {
|
||||
PlayerJumpEvent evt = new PlayerJumpEvent(event.isCancelled(), event.getPlayer());
|
||||
Bukkit.getPluginManager().callEvent(evt);
|
||||
if (evt.isCancelled()) {
|
||||
event.setCancelled(true);
|
||||
event.setTo(event.getFrom());
|
||||
}
|
||||
} else if (this.cooldown.get(event.getPlayer()) <= System.currentTimeMillis()) {
|
||||
this.cooldown.put(event.getPlayer(), System.currentTimeMillis() + 350L);
|
||||
PlayerJumpEvent evt = new PlayerJumpEvent(event.isCancelled(), event.getPlayer());
|
||||
|
||||
Bukkit.getPluginManager().callEvent(evt);
|
||||
if (evt.isCancelled()) {
|
||||
event.setCancelled(true);
|
||||
event.setTo(event.getFrom());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package io.izzel.taboolib.common.plugin;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2019-07-05 14:13
|
||||
*/
|
||||
public class InternalJavaPlugin extends JavaPlugin {
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user