From f5d1edc9e062c13a53df5f64ac6fe002b87705b5 Mon Sep 17 00:00:00 2001 From: Izzel_Aliz Date: Sun, 1 Apr 2018 14:49:02 +0800 Subject: [PATCH 01/44] Convert to Maven --- .gitignore | 5 + .gradle/4.5/fileChanges/last-build.bin | Bin 1 -> 0 bytes .../4.5/fileContent/annotation-processors.bin | Bin 18875 -> 0 bytes .gradle/4.5/fileContent/fileContent.lock | Bin 17 -> 0 bytes .gradle/4.5/fileHashes/fileHashes.bin | Bin 71365 -> 0 bytes .gradle/4.5/fileHashes/fileHashes.lock | Bin 17 -> 0 bytes .../4.5/fileHashes/resourceHashesCache.bin | Bin 19925 -> 0 bytes .gradle/4.5/taskHistory/taskHistory.bin | Bin 484987 -> 0 bytes .gradle/4.5/taskHistory/taskHistory.lock | Bin 17 -> 0 bytes .../buildOutputCleanup.lock | Bin 17 -> 0 bytes .gradle/buildOutputCleanup/cache.properties | 2 - .gradle/vcsWorkingDirs/gc.properties | 0 .idea/compiler.xml | 10 + .idea/gradle.xml | 19 -- ...Maven__com_google_code_gson_gson_2_2_4.xml | 13 ++ .../Maven__com_google_guava_guava_17_0.xml | 13 ++ ...oglecode_json_simple_json_simple_1_1_1.xml | 13 ++ .../Maven__commons_lang_commons_lang_2_6.xml | 13 ++ ..._javax_persistence_persistence_api_1_0.xml | 13 ++ .idea/libraries/Maven__junit_junit_4_10.xml | 13 ++ ...Maven__net_milkbowl_vault_VaultAPI_1_6.xml | 13 ++ .../Maven__org_avaje_ebean_2_8_1.xml | 13 ++ ...n__org_bukkit_bukkit_1_9_R0_1_SNAPSHOT.xml | 13 ++ .../Maven__org_hamcrest_hamcrest_core_1_1.xml | 13 ++ .../libraries/Maven__org_ow2_asm_asm_5_2.xml | 13 ++ .../Maven__org_yaml_snakeyaml_1_15.xml | 13 ++ .idea/modules/TabooLib_main.iml | 148 --------------- .idea/modules/TabooLib_test.iml | 150 --------------- .settings/org.eclipse.buildship.core.prefs | 2 - .settings/org.eclipse.core.resources.prefs | 3 - README.md | 6 + build.gradle | 39 ---- gradle/wrapper/gradle-wrapper.jar | Bin 54329 -> 0 bytes gradle/wrapper/gradle-wrapper.properties | 6 - gradlew | 172 ------------------ gradlew.bat | 84 --------- pom.xml | 164 +++++++++++++++++ settings.gradle | 10 - src/.gradle/4.5/taskHistory/taskHistory.bin | Bin 18754 -> 0 bytes src/.gradle/4.5/taskHistory/taskHistory.lock | Bin 17 -> 0 bytes .../buildOutputCleanup.lock | Bin 17 -> 0 bytes .../buildOutputCleanup/cache.properties | 2 - src/main/java/com/ilummc/tlib/TabooLib.java | 8 + .../JavaShells/scripts/-testshell.java | 0 .../main/resources}/Language/ITEM_NAME.yml | 0 .../main/resources}/Language2/Language2.yml | 0 .../main/resources}/Language2/zh_CN.yml | 0 .../main/resources}/TLM/CommandChanger.yml | 0 .../main/resources}/TLM/Kits.yml | 0 .../main/resources}/TLM/TimeCycle.yml | 0 {resources => src/main/resources}/config.yml | 0 {resources => src/main/resources}/items.yml | 0 {resources => src/main/resources}/module.yml | 0 {resources => src/main/resources}/plugin.yml | 2 +- 54 files changed, 350 insertions(+), 638 deletions(-) delete mode 100644 .gradle/4.5/fileChanges/last-build.bin delete mode 100644 .gradle/4.5/fileContent/annotation-processors.bin delete mode 100644 .gradle/4.5/fileContent/fileContent.lock delete mode 100644 .gradle/4.5/fileHashes/fileHashes.bin delete mode 100644 .gradle/4.5/fileHashes/fileHashes.lock delete mode 100644 .gradle/4.5/fileHashes/resourceHashesCache.bin delete mode 100644 .gradle/4.5/taskHistory/taskHistory.bin delete mode 100644 .gradle/4.5/taskHistory/taskHistory.lock delete mode 100644 .gradle/buildOutputCleanup/buildOutputCleanup.lock delete mode 100644 .gradle/buildOutputCleanup/cache.properties delete mode 100644 .gradle/vcsWorkingDirs/gc.properties delete mode 100644 .idea/gradle.xml create mode 100644 .idea/libraries/Maven__com_google_code_gson_gson_2_2_4.xml create mode 100644 .idea/libraries/Maven__com_google_guava_guava_17_0.xml create mode 100644 .idea/libraries/Maven__com_googlecode_json_simple_json_simple_1_1_1.xml create mode 100644 .idea/libraries/Maven__commons_lang_commons_lang_2_6.xml create mode 100644 .idea/libraries/Maven__javax_persistence_persistence_api_1_0.xml create mode 100644 .idea/libraries/Maven__junit_junit_4_10.xml create mode 100644 .idea/libraries/Maven__net_milkbowl_vault_VaultAPI_1_6.xml create mode 100644 .idea/libraries/Maven__org_avaje_ebean_2_8_1.xml create mode 100644 .idea/libraries/Maven__org_bukkit_bukkit_1_9_R0_1_SNAPSHOT.xml create mode 100644 .idea/libraries/Maven__org_hamcrest_hamcrest_core_1_1.xml create mode 100644 .idea/libraries/Maven__org_ow2_asm_asm_5_2.xml create mode 100644 .idea/libraries/Maven__org_yaml_snakeyaml_1_15.xml delete mode 100644 .idea/modules/TabooLib_main.iml delete mode 100644 .idea/modules/TabooLib_test.iml delete mode 100644 .settings/org.eclipse.buildship.core.prefs delete mode 100644 .settings/org.eclipse.core.resources.prefs delete mode 100644 build.gradle delete mode 100644 gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle/wrapper/gradle-wrapper.properties delete mode 100644 gradlew delete mode 100644 gradlew.bat create mode 100644 pom.xml delete mode 100644 settings.gradle delete mode 100644 src/.gradle/4.5/taskHistory/taskHistory.bin delete mode 100644 src/.gradle/4.5/taskHistory/taskHistory.lock delete mode 100644 src/.gradle/buildOutputCleanup/buildOutputCleanup.lock delete mode 100644 src/.gradle/buildOutputCleanup/cache.properties create mode 100644 src/main/java/com/ilummc/tlib/TabooLib.java rename {resources => src/main/resources}/JavaShells/scripts/-testshell.java (100%) rename {resources => src/main/resources}/Language/ITEM_NAME.yml (100%) rename {resources => src/main/resources}/Language2/Language2.yml (100%) rename {resources => src/main/resources}/Language2/zh_CN.yml (100%) rename {resources => src/main/resources}/TLM/CommandChanger.yml (100%) rename {resources => src/main/resources}/TLM/Kits.yml (100%) rename {resources => src/main/resources}/TLM/TimeCycle.yml (100%) rename {resources => src/main/resources}/config.yml (100%) rename {resources => src/main/resources}/items.yml (100%) rename {resources => src/main/resources}/module.yml (100%) rename {resources => src/main/resources}/plugin.yml (88%) diff --git a/.gitignore b/.gitignore index d51ef34..d587938 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,8 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* +.gradle/4.3.1/ +.idea/TabooLib.iml +.idea/misc.xml +.idea/modules.xml +.idea/workspace.xml diff --git a/.gradle/4.5/fileChanges/last-build.bin b/.gradle/4.5/fileChanges/last-build.bin deleted file mode 100644 index f76dd238ade08917e6712764a16a22005a50573d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1 IcmZPo000310RR91 diff --git a/.gradle/4.5/fileContent/annotation-processors.bin b/.gradle/4.5/fileContent/annotation-processors.bin deleted file mode 100644 index e2fb0147feda7f7b2e0b18b8fb93e0b74b42d345..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18875 zcmeI&&r1|x7{Kw@^)R%FMkcLDDytP_lqM>q9?T%4peRHU6vPrFMNLF8Dr8mkqS8U7 z4pCtg60%^rh$4u1mHdU^QBhPB1%DipY?pZ+{R=u6-+`HV`Ob5g_j8@OYmDpMksRja zh&WlYLI42-5I_I{1Q0*~0R#|0009ILKmY**5I_Kd|3x6zzY(Xs8P|13U=dblOk#+C z5z*2WJk{&54(-P|ZTkJ-)8y^)=(2(d>2=x%dvDdQti4H+{zJQOFQer`Yn&y0N&EPK zZ+SnjDMtD)?Tgm6xst@2op!$;seL1UxUBEN?qivMs(t6OZ{FEczbfD@B*uqh-EX`<3*@^M@b3c``qyJ*8p#?X#f@b{z&`1q5O=w$pepcOZ&t1xUGF>X@~S0?JvgqVxPQf z9kqMTp7tvD%lG|J@h+L~)?WS7c;3x4CCL2qbN-=z6;y3=kj-06k6w+5i9m diff --git a/.gradle/4.5/fileHashes/fileHashes.bin b/.gradle/4.5/fileHashes/fileHashes.bin deleted file mode 100644 index 10cc8e4dadb66f7a8142a705ae20da481aa121ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71365 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 JClBegCoZCg}sB_x*N zRC1{et<9`bQmIozh7u}9y4fUI&ig*o*`EG^-SeGu-kIlo-p~1-_x;Q}^UJ(Lqfj(e z#>fZd>toi}C9I$T6o3Ly017|>C;$bZ02F`%Pyh-*0Vn_kpa2wr0#E=7K!N{D0r&9} zkta?@Q(tysF(ZOPF;*O3=p9@t5G|>0P$zb?4AAcfaWzA{gygkTNUk8|f95kH1S2{G zXA~lyn17M0W_|xG!JUMNXLCg#t0Ij~5S%HH^2X@?#mSZL$oUnB=g==Sk5rlk6Wq~A z%8MV>c59qu5}a`paRDzs!Zhg62JAm?mHe9VXMyum1wyiQo5h^y!ar|ZyjwvltFh--#g)tnBTN?s3+BE+>q zPS;x7dEO-b>4?wU8#Vi(jK?6sS;L4g%(p4mULik3aK{nEEhWF)FjOh(Be@&mtM~mK z&Yv^vM{uT&lxI!S<=s2HpWqBT#A&1UOPIEarKI10I3vS>VqZ?NBe>H6#Mi4EwalWY zlJi-Q5Z}N~pzeFOIfU?8X^8vgF`ssM+-f1XV-?~*Wr};s2f1~m?;_=$`xLBX6vYI0 zPC?x7B*$_;L+pcRC;$bZ02F`%Pyh-*0Vn_kpa2wr0#E=7KmjNK z1)u;FfC5ke3P1rU00p1`6o3Ly017|>C;$bZ02F`%Pyh-*0Vn_k{)+`n#t&L+d{dp+ zRD^-^gRWk^?|psejybe6e#JPP`)^}NEKcv&G4Z_HqS{}6s!1O=au;VsYrAU4{y3HD z+S+GQiyKcz6+Bl2o=j41Nz=GR4IaRaDi`*$^~#h>Y}Qh@xLpP3aYMDXZn5FBO-h&j z)5A6CHWT-je{-bsLvpU13bcE8)4b*JTdl_cQ?hc;Q< zs}a?bmAi;jyeZfkH(Yi#v(kfVeVZb#beRXx zvjf%rzMdv87}o`Uy*F^<4DZdwnKlKIRm-}6V7(2t!j0^*FUk(rM%fv)K0|eKdnq(!-5a1(6Hq4L_USrIhTw;9O7%ZoCcM z{7E6S_)W&TUk%+wyS{T3HVy`T8a#gFXBqR%3dS}ob9_d??ygMs`%@df7|>fI+_@s$ z;P7`Zc^?13ls7Zw;0A*OWw_B+beHM2CU&Go_V%1ABhDt=i0<#zso*Mp)X})}+%cDZ z05?SY^|RD7WzKS4sgY$#vkPz|Cv~n-hzfgcJXHnfnilXp{*6 diff --git a/.gradle/4.5/taskHistory/taskHistory.bin b/.gradle/4.5/taskHistory/taskHistory.bin deleted file mode 100644 index 6f47e7b776bb5b225570757cf94ed20994802dd2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 484987 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

qkZzS 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

Xc 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 diff --git a/.gradle/4.5/taskHistory/taskHistory.lock b/.gradle/4.5/taskHistory/taskHistory.lock deleted file mode 100644 index 98e4b13dee12b09098387e117eb3d0c8659067da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 UcmZSH!ME-}(M*|K1_-bN05I?b3IG5A diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock deleted file mode 100644 index 4a90f298a466f8a4b44e7853e98fd3e2a0351730..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 UcmZQh^7K7ycJ5&_0|fX005RJHa{vGU diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties deleted file mode 100644 index a47101d..0000000 --- a/.gradle/buildOutputCleanup/cache.properties +++ /dev/null @@ -1,2 +0,0 @@ -#Sat Mar 10 18:07:09 CST 2018 -gradle.version=4.5 diff --git a/.gradle/vcsWorkingDirs/gc.properties b/.gradle/vcsWorkingDirs/gc.properties deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/compiler.xml b/.idea/compiler.xml index f0879a2..ae14021 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,7 +1,17 @@ + + + + + + + + + + diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 98b6aa4..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_code_gson_gson_2_2_4.xml b/.idea/libraries/Maven__com_google_code_gson_gson_2_2_4.xml new file mode 100644 index 0000000..4533c1b --- /dev/null +++ b/.idea/libraries/Maven__com_google_code_gson_gson_2_2_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_guava_guava_17_0.xml b/.idea/libraries/Maven__com_google_guava_guava_17_0.xml new file mode 100644 index 0000000..2a9069c --- /dev/null +++ b/.idea/libraries/Maven__com_google_guava_guava_17_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_googlecode_json_simple_json_simple_1_1_1.xml b/.idea/libraries/Maven__com_googlecode_json_simple_json_simple_1_1_1.xml new file mode 100644 index 0000000..f3f3738 --- /dev/null +++ b/.idea/libraries/Maven__com_googlecode_json_simple_json_simple_1_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__commons_lang_commons_lang_2_6.xml b/.idea/libraries/Maven__commons_lang_commons_lang_2_6.xml new file mode 100644 index 0000000..2ec8376 --- /dev/null +++ b/.idea/libraries/Maven__commons_lang_commons_lang_2_6.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__javax_persistence_persistence_api_1_0.xml b/.idea/libraries/Maven__javax_persistence_persistence_api_1_0.xml new file mode 100644 index 0000000..e60370e --- /dev/null +++ b/.idea/libraries/Maven__javax_persistence_persistence_api_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__junit_junit_4_10.xml b/.idea/libraries/Maven__junit_junit_4_10.xml new file mode 100644 index 0000000..ed8bf5f --- /dev/null +++ b/.idea/libraries/Maven__junit_junit_4_10.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__net_milkbowl_vault_VaultAPI_1_6.xml b/.idea/libraries/Maven__net_milkbowl_vault_VaultAPI_1_6.xml new file mode 100644 index 0000000..fa96a55 --- /dev/null +++ b/.idea/libraries/Maven__net_milkbowl_vault_VaultAPI_1_6.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_avaje_ebean_2_8_1.xml b/.idea/libraries/Maven__org_avaje_ebean_2_8_1.xml new file mode 100644 index 0000000..91f161a --- /dev/null +++ b/.idea/libraries/Maven__org_avaje_ebean_2_8_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_bukkit_bukkit_1_9_R0_1_SNAPSHOT.xml b/.idea/libraries/Maven__org_bukkit_bukkit_1_9_R0_1_SNAPSHOT.xml new file mode 100644 index 0000000..2fb4911 --- /dev/null +++ b/.idea/libraries/Maven__org_bukkit_bukkit_1_9_R0_1_SNAPSHOT.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_1.xml b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_1.xml new file mode 100644 index 0000000..acdf443 --- /dev/null +++ b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_ow2_asm_asm_5_2.xml b/.idea/libraries/Maven__org_ow2_asm_asm_5_2.xml new file mode 100644 index 0000000..02e02fd --- /dev/null +++ b/.idea/libraries/Maven__org_ow2_asm_asm_5_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_yaml_snakeyaml_1_15.xml b/.idea/libraries/Maven__org_yaml_snakeyaml_1_15.xml new file mode 100644 index 0000000..02d9152 --- /dev/null +++ b/.idea/libraries/Maven__org_yaml_snakeyaml_1_15.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/TabooLib_main.iml b/.idea/modules/TabooLib_main.iml deleted file mode 100644 index 335b82b..0000000 --- a/.idea/modules/TabooLib_main.iml +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - SPIGOT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/TabooLib_test.iml b/.idea/modules/TabooLib_test.iml deleted file mode 100644 index 35e5ad7..0000000 --- a/.idea/modules/TabooLib_test.iml +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - SPIGOT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs deleted file mode 100644 index dc85b8c..0000000 --- a/.settings/org.eclipse.buildship.core.prefs +++ /dev/null @@ -1,2 +0,0 @@ -#Sat Mar 10 18:07:18 CST 2018 -connection.project.dir= diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 6686ae1..0000000 --- a/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,3 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/java/me/skymc/taboolib/javashell/JavaShell.java=UTF-8 -encoding/=UTF-8 diff --git a/README.md b/README.md index bc0063a..468b1f1 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,9 @@ **3.56** 版本开始 `com.sun.tools.jar` 不再和插件一起发布。 如果需要启用 *JavaShell* 功能请将 [com.sun.tools.jar](http://skymc.oss-cn-shanghai.aliyuncs.com/plugins/com.sun.tools.jar) 放入 *"TabooLib/JavaShell/lib"* 文件夹中。 + +## 构建 + +``` +mvn clean install package +``` \ No newline at end of file diff --git a/build.gradle b/build.gradle deleted file mode 100644 index ab77c22..0000000 --- a/build.gradle +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file was generated by the Gradle 'init' task. - * - * This generated file contains a sample Java Library project to get you started. - * For more details take a look at the Java Libraries chapter in the Gradle - * user guide available at https://docs.gradle.org/4.5/userguide/java_library_plugin.html - */ - -plugins { - // Apply the java-library plugin to add support for Java Library - id 'java-library' -} - -tasks.withType(JavaCompile) { - options.encoding = "UTF-8" -} - -sourceCompatibility = targetCompatibility = "1.8" // Need this here so eclipse task generates correctly. -compileJava { - sourceCompatibility = targetCompatibility = "1.8" -} - -processResources { - from('resources') { - include '**' - } -} - -dependencies { - // Library - compile fileTree(dir:'libs', include:['*.jar']) -} - -// In this section you declare where to find the dependencies of your project -repositories { - // Use jcenter for resolving your dependencies. - // You can declare any Maven/Ivy/file repository here. - jcenter() -} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index a5fe1cb94b9ee5ce57e6113458225bcba12d83e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54329 zcmagFV|ZrKvM!pAZQHhO+qP}9lTNj?q^^Y^VFp)SH8qbSJ)2BQ2giZ5K2 zeL{Z~)c?v~^Z#E_K}1nTQbJ9gQ9<%vVRAxVj)8FwL5_iTdUB>&m3fhE=kRWl;g`&m z!W5kh{WsV%fO*%je&j+Lv4xxK~zsEYQls$Q-p&dwID|A)!7uWtJF-=Tm1{V@#x*+kUI$=%KUuf2ka zjiZ{oiL1MXE2EjciJM!jrjFNwCh`~hL>iemrqwqnX?T*MX;U>>8yRcZb{Oy+VKZos zLiFKYPw=LcaaQt8tj=eoo3-@bG_342HQ%?jpgAE?KCLEHC+DmjxAfJ%Og^$dpC8Xw zAcp-)tfJm}BPNq_+6m4gBgBm3+CvmL>4|$2N$^Bz7W(}fz1?U-u;nE`+9`KCLuqg} zwNstNM!J4Uw|78&Y9~9>MLf56to!@qGkJw5Thx%zkzj%Ek9Nn1QA@8NBXbwyWC>9H z#EPwjMNYPigE>*Ofz)HfTF&%PFj$U6mCe-AFw$U%-L?~-+nSXHHKkdgC5KJRTF}`G zE_HNdrE}S0zf4j{r_f-V2imSqW?}3w-4=f@o@-q+cZgaAbZ((hn))@|eWWhcT2pLpTpL!;_5*vM=sRL8 zqU##{U#lJKuyqW^X$ETU5ETeEVzhU|1m1750#f}38_5N9)B_2|v@1hUu=Kt7-@dhA zq_`OMgW01n`%1dB*}C)qxC8q;?zPeF_r;>}%JYmlER_1CUbKa07+=TV45~symC*g8 zW-8(gag#cAOuM0B1xG8eTp5HGVLE}+gYTmK=`XVVV*U!>H`~j4+ROIQ+NkN$LY>h4 zqpwdeE_@AX@PL};e5vTn`Ro(EjHVf$;^oiA%@IBQq>R7_D>m2D4OwwEepkg}R_k*M zM-o;+P27087eb+%*+6vWFCo9UEGw>t&WI17Pe7QVuoAoGHdJ(TEQNlJOqnjZ8adCb zI`}op16D@v7UOEo%8E-~m?c8FL1utPYlg@m$q@q7%mQ4?OK1h%ODjTjFvqd!C z-PI?8qX8{a@6d&Lb_X+hKxCImb*3GFemm?W_du5_&EqRq!+H?5#xiX#w$eLti-?E$;Dhu`{R(o>LzM4CjO>ICf z&DMfES#FW7npnbcuqREgjPQM#gs6h>`av_oEWwOJZ2i2|D|0~pYd#WazE2Bbsa}X@ zu;(9fi~%!VcjK6)?_wMAW-YXJAR{QHxrD5g(ou9mR6LPSA4BRG1QSZT6A?kelP_g- zH(JQjLc!`H4N=oLw=f3{+WmPA*s8QEeEUf6Vg}@!xwnsnR0bl~^2GSa5vb!Yl&4!> zWb|KQUsC$lT=3A|7vM9+d;mq=@L%uWKwXiO9}a~gP4s_4Yohc!fKEgV7WbVo>2ITbE*i`a|V!^p@~^<={#?Gz57 zyPWeM2@p>D*FW#W5Q`1`#5NW62XduP1XNO(bhg&cX`-LYZa|m-**bu|>}S;3)eP8_ zpNTnTfm8 ze+7wDH3KJ95p)5tlwk`S7mbD`SqHnYD*6`;gpp8VdHDz%RR_~I_Ar>5)vE-Pgu7^Y z|9Px+>pi3!DV%E%4N;ii0U3VBd2ZJNUY1YC^-e+{DYq+l@cGtmu(H#Oh%ibUBOd?C z{y5jW3v=0eV0r@qMLgv1JjZC|cZ9l9Q)k1lLgm))UR@#FrJd>w^`+iy$c9F@ic-|q zVHe@S2UAnc5VY_U4253QJxm&Ip!XKP8WNcnx9^cQ;KH6PlW8%pSihSH2(@{2m_o+m zr((MvBja2ctg0d0&U5XTD;5?d?h%JcRJp{_1BQW1xu&BrA3(a4Fh9hon-ly$pyeHq zG&;6q?m%NJ36K1Sq_=fdP(4f{Hop;_G_(i?sPzvB zDM}>*(uOsY0I1j^{$yn3#U(;B*g4cy$-1DTOkh3P!LQ;lJlP%jY8}Nya=h8$XD~%Y zbV&HJ%eCD9nui-0cw!+n`V~p6VCRqh5fRX z8`GbdZ@73r7~myQLBW%db;+BI?c-a>Y)m-FW~M=1^|<21_Sh9RT3iGbO{o-hpN%d6 z7%++#WekoBOP^d0$$|5npPe>u3PLvX_gjH2x(?{&z{jJ2tAOWTznPxv-pAv<*V7r$ z6&glt>7CAClWz6FEi3bToz-soY^{ScrjwVPV51=>n->c(NJngMj6TyHty`bfkF1hc zkJS%A@cL~QV0-aK4>Id!9dh7>0IV;1J9(myDO+gv76L3NLMUm9XyPauvNu$S<)-|F zZS}(kK_WnB)Cl`U?jsdYfAV4nrgzIF@+%1U8$poW&h^c6>kCx3;||fS1_7JvQT~CV zQ8Js+!p)3oW>Df(-}uqC`Tcd%E7GdJ0p}kYj5j8NKMp(KUs9u7?jQ94C)}0rba($~ zqyBx$(1ae^HEDG`Zc@-rXk1cqc7v0wibOR4qpgRDt#>-*8N3P;uKV0CgJE2SP>#8h z=+;i_CGlv+B^+$5a}SicVaSeaNn29K`C&=}`=#Nj&WJP9Xhz4mVa<+yP6hkrq1vo= z1rX4qg8dc4pmEvq%NAkpMK>mf2g?tg_1k2%v}<3`$6~Wlq@ItJ*PhHPoEh1Yi>v57 z4k0JMO)*=S`tKvR5gb-(VTEo>5Y>DZJZzgR+j6{Y`kd|jCVrg!>2hVjz({kZR z`dLlKhoqT!aI8=S+fVp(5*Dn6RrbpyO~0+?fy;bm$0jmTN|t5i6rxqr4=O}dY+ROd zo9Et|x}!u*xi~>-y>!M^+f&jc;IAsGiM_^}+4|pHRn{LThFFpD{bZ|TA*wcGm}XV^ zr*C6~@^5X-*R%FrHIgo-hJTBcyQ|3QEj+cSqp#>&t`ZzB?cXM6S(lRQw$I2?m5=wd z78ki`R?%;o%VUhXH?Z#(uwAn9$m`npJ=cA+lHGk@T7qq_M6Zoy1Lm9E0UUysN)I_x zW__OAqvku^>`J&CB=ie@yNWsaFmem}#L3T(x?a`oZ+$;3O-icj2(5z72Hnj=9Z0w% z<2#q-R=>hig*(t0^v)eGq2DHC%GymE-_j1WwBVGoU=GORGjtaqr0BNigOCqyt;O(S zKG+DoBsZU~okF<7ahjS}bzwXxbAxFfQAk&O@>LsZMsZ`?N?|CDWM(vOm%B3CBPC3o z%2t@%H$fwur}SSnckUm0-k)mOtht`?nwsDz=2#v=RBPGg39i#%odKq{K^;bTD!6A9 zskz$}t)sU^=a#jLZP@I=bPo?f-L}wpMs{Tc!m7-bi!Ldqj3EA~V;4(dltJmTXqH0r z%HAWKGutEc9vOo3P6Q;JdC^YTnby->VZ6&X8f{obffZ??1(cm&L2h7q)*w**+sE6dG*;(H|_Q!WxU{g)CeoT z(KY&bv!Usc|m+Fqfmk;h&RNF|LWuNZ!+DdX*L=s-=_iH=@i` z?Z+Okq^cFO4}_n|G*!)Wl_i%qiMBaH8(WuXtgI7EO=M>=i_+;MDjf3aY~6S9w0K zUuDO7O5Ta6+k40~xh~)D{=L&?Y0?c$s9cw*Ufe18)zzk%#ZY>Tr^|e%8KPb0ht`b( zuP@8#Ox@nQIqz9}AbW0RzE`Cf>39bOWz5N3qzS}ocxI=o$W|(nD~@EhW13Rj5nAp; zu2obEJa=kGC*#3=MkdkWy_%RKcN=?g$7!AZ8vBYKr$ePY(8aIQ&yRPlQ=mudv#q$q z4%WzAx=B{i)UdLFx4os?rZp6poShD7Vc&mSD@RdBJ=_m^&OlkEE1DFU@csgKcBifJ zz4N7+XEJhYzzO=86 z#%eBQZ$Nsf2+X0XPHUNmg#(sNt^NW1Y0|M(${e<0kW6f2q5M!2YE|hSEQ*X-%qo(V zHaFwyGZ0on=I{=fhe<=zo{=Og-_(to3?cvL4m6PymtNsdDINsBh8m>a%!5o3s(en) z=1I z6O+YNertC|OFNqd6P=$gMyvmfa`w~p9*gKDESFqNBy(~Zw3TFDYh}$iudn)9HxPBi zdokK@o~nu?%imcURr5Y~?6oo_JBe}t|pU5qjai|#JDyG=i^V~7+a{dEnO<(y>ahND#_X_fcEBNiZ)uc&%1HVtx8Ts z*H_Btvx^IhkfOB#{szN*n6;y05A>3eARDXslaE>tnLa>+`V&cgho?ED+&vv5KJszf zG4@G;7i;4_bVvZ>!mli3j7~tPgybF5|J6=Lt`u$D%X0l}#iY9nOXH@(%FFJLtzb%p zzHfABnSs;v-9(&nzbZytLiqqDIWzn>JQDk#JULcE5CyPq_m#4QV!}3421haQ+LcfO*>r;rg6K|r#5Sh|y@h1ao%Cl)t*u`4 zMTP!deC?aL7uTxm5^nUv#q2vS-5QbBKP|drbDXS%erB>fYM84Kpk^au99-BQBZR z7CDynflrIAi&ahza+kUryju5LR_}-Z27g)jqOc(!Lx9y)e z{cYc&_r947s9pteaa4}dc|!$$N9+M38sUr7h(%@Ehq`4HJtTpA>B8CLNO__@%(F5d z`SmX5jbux6i#qc}xOhumzbAELh*Mfr2SW99=WNOZRZgoCU4A2|4i|ZVFQt6qEhH#B zK_9G;&h*LO6tB`5dXRSBF0hq0tk{2q__aCKXYkP#9n^)@cq}`&Lo)1KM{W+>5mSed zKp~=}$p7>~nK@va`vN{mYzWN1(tE=u2BZhga5(VtPKk(*TvE&zmn5vSbjo zZLVobTl%;t@6;4SsZ>5+U-XEGUZGG;+~|V(pE&qqrp_f~{_1h@5ZrNETqe{bt9ioZ z#Qn~gWCH!t#Ha^n&fT2?{`}D@s4?9kXj;E;lWV9Zw8_4yM0Qg-6YSsKgvQ*fF{#Pq z{=(nyV>#*`RloBVCs;Lp*R1PBIQOY=EK4CQa*BD0MsYcg=opP?8;xYQDSAJBeJpw5 zPBc_Ft9?;<0?pBhCmOtWU*pN*;CkjJ_}qVic`}V@$TwFi15!mF1*m2wVX+>5p%(+R zQ~JUW*zWkalde{90@2v+oVlkxOZFihE&ZJ){c?hX3L2@R7jk*xjYtHi=}qb+4B(XJ z$gYcNudR~4Kz_WRq8eS((>ALWCO)&R-MXE+YxDn9V#X{_H@j616<|P(8h(7z?q*r+ zmpqR#7+g$cT@e&(%_|ipI&A%9+47%30TLY(yuf&*knx1wNx|%*H^;YB%ftt%5>QM= z^i;*6_KTSRzQm%qz*>cK&EISvF^ovbS4|R%)zKhTH_2K>jP3mBGn5{95&G9^a#4|K zv+!>fIsR8z{^x4)FIr*cYT@Q4Z{y}};rLHL+atCgHbfX*;+k&37DIgENn&=k(*lKD zG;uL-KAdLn*JQ?@r6Q!0V$xXP=J2i~;_+i3|F;_En;oAMG|I-RX#FwnmU&G}w`7R{ z788CrR-g1DW4h_`&$Z`ctN~{A)Hv_-Bl!%+pfif8wN32rMD zJDs$eVWBYQx1&2sCdB0!vU5~uf)=vy*{}t{2VBpcz<+~h0wb7F3?V^44*&83Z2#F` z32!rd4>uc63rQP$3lTH3zb-47IGR}f)8kZ4JvX#toIpXH`L%NnPDE~$QI1)0)|HS4 zVcITo$$oWWwCN@E-5h>N?Hua!N9CYb6f8vTFd>h3q5Jg-lCI6y%vu{Z_Uf z$MU{{^o~;nD_@m2|E{J)q;|BK7rx%`m``+OqZAqAVj-Dy+pD4-S3xK?($>wn5bi90CFAQ+ACd;&m6DQB8_o zjAq^=eUYc1o{#+p+ zn;K<)Pn*4u742P!;H^E3^Qu%2dM{2slouc$AN_3V^M7H_KY3H)#n7qd5_p~Za7zAj|s9{l)RdbV9e||_67`#Tu*c<8!I=zb@ z(MSvQ9;Wrkq6d)!9afh+G`!f$Ip!F<4ADdc*OY-y7BZMsau%y?EN6*hW4mOF%Q~bw z2==Z3^~?q<1GTeS>xGN-?CHZ7a#M4kDL zQxQr~1ZMzCSKFK5+32C%+C1kE#(2L=15AR!er7GKbp?Xd1qkkGipx5Q~FI-6zt< z*PTpeVI)Ngnnyaz5noIIgNZtb4bQdKG{Bs~&tf)?nM$a;7>r36djllw%hQxeCXeW^ z(i6@TEIuxD<2ulwLTt|&gZP%Ei+l!(%p5Yij6U(H#HMkqM8U$@OKB|5@vUiuY^d6X zW}fP3;Kps6051OEO(|JzmVU6SX(8q>*yf*x5QoxDK={PH^F?!VCzES_Qs>()_y|jg6LJlJWp;L zKM*g5DK7>W_*uv}{0WUB0>MHZ#oJZmO!b3MjEc}VhsLD~;E-qNNd?x7Q6~v zR=0$u>Zc2Xr}>x_5$-s#l!oz6I>W?lw;m9Ae{Tf9eMX;TI-Wf_mZ6sVrMnY#F}cDd z%CV*}fDsXUF7Vbw>PuDaGhu631+3|{xp<@Kl|%WxU+vuLlcrklMC!Aq+7n~I3cmQ! z`e3cA!XUEGdEPSu``&lZEKD1IKO(-VGvcnSc153m(i!8ohi`)N2n>U_BemYJ`uY>8B*Epj!oXRLV}XK}>D*^DHQ7?NY*&LJ9VSo`Ogi9J zGa;clWI8vIQqkngv2>xKd91K>?0`Sw;E&TMg&6dcd20|FcTsnUT7Yn{oI5V4@Ow~m zz#k~8TM!A9L7T!|colrC0P2WKZW7PNj_X4MfESbt<-soq*0LzShZ}fyUx!(xIIDwx zRHt^_GAWe0-Vm~bDZ(}XG%E+`XhKpPlMBo*5q_z$BGxYef8O!ToS8aT8pmjbPq)nV z%x*PF5ZuSHRJqJ!`5<4xC*xb2vC?7u1iljB_*iUGl6+yPyjn?F?GOF2_KW&gOkJ?w z3e^qc-te;zez`H$rsUCE0<@7PKGW?7sT1SPYWId|FJ8H`uEdNu4YJjre`8F*D}6Wh z|FQ`xf7yiphHIAkU&OYCn}w^ilY@o4larl?^M7&8YI;hzBIsX|i3UrLsx{QDKwCX< zy;a>yjfJ6!sz`NcVi+a!Fqk^VE^{6G53L?@Tif|j!3QZ0fk9QeUq8CWI;OmO-Hs+F zuZ4sHLA3{}LR2Qlyo+{d@?;`tpp6YB^BMoJt?&MHFY!JQwoa0nTSD+#Ku^4b{5SZVFwU9<~APYbaLO zu~Z)nS#dxI-5lmS-Bnw!(u15by(80LlC@|ynj{TzW)XcspC*}z0~8VRZq>#Z49G`I zgl|C#H&=}n-ajxfo{=pxPV(L*7g}gHET9b*s=cGV7VFa<;Htgjk>KyW@S!|z`lR1( zGSYkEl&@-bZ*d2WQ~hw3NpP=YNHF^XC{TMG$Gn+{b6pZn+5=<()>C!N^jncl0w6BJ zdHdnmSEGK5BlMeZD!v4t5m7ct7{k~$1Ie3GLFoHjAH*b?++s<|=yTF+^I&jT#zuMx z)MLhU+;LFk8bse|_{j+d*a=&cm2}M?*arjBPnfPgLwv)86D$6L zLJ0wPul7IenMvVAK$z^q5<^!)7aI|<&GGEbOr=E;UmGOIa}yO~EIr5xWU_(ol$&fa zR5E(2vB?S3EvJglTXdU#@qfDbCYs#82Yo^aZN6`{Ex#M)easBTe_J8utXu(fY1j|R z9o(sQbj$bKU{IjyhosYahY{63>}$9_+hWxB3j}VQkJ@2$D@vpeRSldU?&7I;qd2MF zSYmJ>zA(@N_iK}m*AMPIJG#Y&1KR)6`LJ83qg~`Do3v^B0>fU&wUx(qefuTgzFED{sJ65!iw{F2}1fQ3= ziFIP{kezQxmlx-!yo+sC4PEtG#K=5VM9YIN0z9~c4XTX?*4e@m;hFM!zVo>A`#566 z>f&3g94lJ{r)QJ5m7Xe3SLau_lOpL;A($wsjHR`;xTXgIiZ#o&vt~ zGR6KdU$FFbLfZCC3AEu$b`tj!9XgOGLSV=QPIYW zjI!hSP#?8pn0@ezuenOzoka8!8~jXTbiJ6+ZuItsWW03uzASFyn*zV2kIgPFR$Yzm zE<$cZlF>R8?Nr2_i?KiripBc+TGgJvG@vRTY2o?(_Di}D30!k&CT`>+7ry2!!iC*X z<@=U0_C#16=PN7bB39w+zPwDOHX}h20Ap);dx}kjXX0-QkRk=cr};GYsjSvyLZa-t zzHONWddi*)RDUH@RTAsGB_#&O+QJaaL+H<<9LLSE+nB@eGF1fALwjVOl8X_sdOYme z0lk!X=S(@25=TZHR7LlPp}fY~yNeThMIjD}pd9+q=j<_inh0$>mIzWVY+Z9p<{D^#0Xk+b_@eNSiR8;KzSZ#7lUsk~NGMcB8C2c=m2l5paHPq`q{S(kdA7Z1a zyfk2Y;w?^t`?@yC5Pz9&pzo}Hc#}mLgDmhKV|PJ3lKOY(Km@Fi2AV~CuET*YfUi}u zfInZnqDX(<#vaS<^fszuR=l)AbqG{}9{rnyx?PbZz3Pyu!eSJK`uwkJU!ORQXy4x83r!PNgOyD33}}L=>xX_93l6njNTuqL8J{l%*3FVn3MG4&Fv*`lBXZ z?=;kn6HTT^#SrPX-N)4EZiIZI!0ByXTWy;;J-Tht{jq1mjh`DSy7yGjHxIaY%*sTx zuy9#9CqE#qi>1misx=KRWm=qx4rk|}vd+LMY3M`ow8)}m$3Ggv&)Ri*ON+}<^P%T5 z_7JPVPfdM=Pv-oH<tecoE}(0O7|YZc*d8`Uv_M*3Rzv7$yZnJE6N_W=AQ3_BgU_TjA_T?a)U1csCmJ&YqMp-lJe`y6>N zt++Bi;ZMOD%%1c&-Q;bKsYg!SmS^#J@8UFY|G3!rtyaTFb!5@e(@l?1t(87ln8rG? z--$1)YC~vWnXiW3GXm`FNSyzu!m$qT=Eldf$sMl#PEfGmzQs^oUd=GIQfj(X=}dw+ zT*oa0*oS%@cLgvB&PKIQ=Ok?>x#c#dC#sQifgMwtAG^l3D9nIg(Zqi;D%807TtUUCL3_;kjyte#cAg?S%e4S2W>9^A(uy8Ss0Tc++ZTjJw1 z&Em2g!3lo@LlDyri(P^I8BPpn$RE7n*q9Q-c^>rfOMM6Pd5671I=ZBjAvpj8oIi$! zl0exNl(>NIiQpX~FRS9UgK|0l#s@#)p4?^?XAz}Gjb1?4Qe4?j&cL$C8u}n)?A@YC zfmbSM`Hl5pQFwv$CQBF=_$Sq zxsV?BHI5bGZTk?B6B&KLdIN-40S426X3j_|ceLla*M3}3gx3(_7MVY1++4mzhH#7# zD>2gTHy*%i$~}mqc#gK83288SKp@y3wz1L_e8fF$Rb}ex+`(h)j}%~Ld^3DUZkgez zOUNy^%>>HHE|-y$V@B}-M|_{h!vXpk01xaD%{l{oQ|~+^>rR*rv9iQen5t?{BHg|% zR`;S|KtUb!X<22RTBA4AAUM6#M?=w5VY-hEV)b`!y1^mPNEoy2K)a>OyA?Q~Q*&(O zRzQI~y_W=IPi?-OJX*&&8dvY0zWM2%yXdFI!D-n@6FsG)pEYdJbuA`g4yy;qrgR?G z8Mj7gv1oiWq)+_$GqqQ$(ZM@#|0j7})=#$S&hZwdoijFI4aCFLVI3tMH5fLreZ;KD zqA`)0l~D2tuIBYOy+LGw&hJ5OyE+@cnZ0L5+;yo2pIMdt@4$r^5Y!x7nHs{@>|W(MzJjATyWGNwZ^4j+EPU0RpAl-oTM@u{lx*i0^yyWPfHt6QwPvYpk9xFMWfBFt!+Gu6TlAmr zeQ#PX71vzN*_-xh&__N`IXv6`>CgV#eA_%e@7wjgkj8jlKzO~Ic6g$cT`^W{R{606 zCDP~+NVZ6DMO$jhL~#+!g*$T!XW63#(ngDn#Qwy71yj^gazS{e;3jGRM0HedGD@pt z?(ln3pCUA(ekqAvvnKy0G@?-|-dh=eS%4Civ&c}s%wF@0K5Bltaq^2Os1n6Z3%?-Q zAlC4goQ&vK6TpgtzkHVt*1!tBYt-`|5HLV1V7*#45Vb+GACuU+QB&hZ=N_flPy0TY zR^HIrdskB#<$aU;HY(K{a3(OQa$0<9qH(oa)lg@Uf>M5g2W0U5 zk!JSlhrw8quBx9A>RJ6}=;W&wt@2E$7J=9SVHsdC?K(L(KACb#z)@C$xXD8^!7|uv zZh$6fkq)aoD}^79VqdJ!Nz-8$IrU(_-&^cHBI;4 z^$B+1aPe|LG)C55LjP;jab{dTf$0~xbXS9!!QdcmDYLbL^jvxu2y*qnx2%jbL%rB z{aP85qBJe#(&O~Prk%IJARcdEypZ)vah%ZZ%;Zk{eW(U)Bx7VlzgOi8)x z`rh4l`@l_Ada7z&yUK>ZF;i6YLGwI*Sg#Fk#Qr0Jg&VLax(nNN$u-XJ5=MsP3|(lEdIOJ7|(x3iY;ea)5#BW*mDV%^=8qOeYO&gIdJVuLLN3cFaN=xZtFB=b zH{l)PZl_j^u+qx@89}gAQW7ofb+k)QwX=aegihossZq*+@PlCpb$rpp>Cbk9UJO<~ zDjlXQ_Ig#W0zdD3&*ei(FwlN#3b%FSR%&M^ywF@Fr>d~do@-kIS$e%wkIVfJ|Ohh=zc zF&Rnic^|>@R%v?@jO}a9;nY3Qrg_!xC=ZWUcYiA5R+|2nsM*$+c$TOs6pm!}Z}dfM zGeBhMGWw3$6KZXav^>YNA=r6Es>p<6HRYcZY)z{>yasbC81A*G-le8~QoV;rtKnkx z;+os8BvEe?0A6W*a#dOudsv3aWs?d% z0oNngyVMjavLjtjiG`!007#?62ClTqqU$@kIY`=x^$2e>iqIy1>o|@Tw@)P)B8_1$r#6>DB_5 zmaOaoE~^9TolgDgooKFuEFB#klSF%9-~d2~_|kQ0Y{Ek=HH5yq9s zDq#1S551c`kSiWPZbweN^A4kWiP#Qg6er1}HcKv{fxb1*BULboD0fwfaNM_<55>qM zETZ8TJDO4V)=aPp_eQjX%||Ud<>wkIzvDlpNjqW>I}W!-j7M^TNe5JIFh#-}zAV!$ICOju8Kx)N z0vLtzDdy*rQN!7r>Xz7rLw8J-(GzQlYYVH$WK#F`i_i^qVlzTNAh>gBWKV@XC$T-` z3|kj#iCquDhiO7NKum07i|<-NuVsX}Q}mIP$jBJDMfUiaWR3c|F_kWBMw0_Sr|6h4 zk`_r5=0&rCR^*tOy$A8K;@|NqwncjZ>Y-75vlpxq%Cl3EgH`}^^~=u zoll6xxY@a>0f%Ddpi;=cY}fyG!K2N-dEyXXmUP5u){4VnyS^T4?pjN@Ot4zjL(Puw z_U#wMH2Z#8Pts{olG5Dy0tZj;N@;fHheu>YKYQU=4Bk|wcD9MbA`3O4bj$hNRHwzb zSLcG0SLV%zywdbuwl(^E_!@&)TdXge4O{MRWk2RKOt@!8E{$BU-AH(@4{gxs=YAz9LIob|Hzto0}9cWoz6Tp2x0&xi#$ zHh$dwO&UCR1Ob2w00-2eG7d4=cN(Y>0R#$q8?||q@iTi+7-w-xR%uMr&StFIthC<# zvK(aPduwuNB}oJUV8+Zl)%cnfsHI%4`;x6XW^UF^e4s3Z@S<&EV8?56Wya;HNs0E> z`$0dgRdiUz9RO9Au3RmYq>K#G=X%*_dUbSJHP`lSfBaN8t-~@F>)BL1RT*9I851A3 z<-+Gb#_QRX>~av#Ni<#zLswtu-c6{jGHR>wflhKLzC4P@b%8&~u)fosoNjk4r#GvC zlU#UU9&0Hv;d%g72Wq?Ym<&&vtA3AB##L}=ZjiTR4hh7J)e>ei} zt*u+>h%MwN`%3}b4wYpV=QwbY!jwfIj#{me)TDOG`?tI!%l=AwL2G@9I~}?_dA5g6 zCKgK(;6Q0&P&K21Tx~k=o6jwV{dI_G+Ba*Zts|Tl6q1zeC?iYJTb{hel*x>^wb|2RkHkU$!+S4OU4ZOKPZjV>9OVsqNnv5jK8TRAE$A&^yRwK zj-MJ3Pl?)KA~fq#*K~W0l4$0=8GRx^9+?w z!QT8*-)w|S^B0)ZeY5gZPI2G(QtQf?DjuK(s^$rMA!C%P22vynZY4SuOE=wX2f8$R z)A}mzJi4WJnZ`!bHG1=$lwaxm!GOnRbR15F$nRC-M*H<*VfF|pQw(;tbSfp({>9^5 zw_M1-SJ9eGF~m(0dvp*P8uaA0Yw+EkP-SWqu zqal$hK8SmM7#Mrs0@OD+%_J%H*bMyZiWAZdsIBj#lkZ!l2c&IpLu(5^T0Ge5PHzR} zn;TXs$+IQ_&;O~u=Jz+XE0wbOy`=6>m9JVG} zJ~Kp1e5m?K3x@@>!D)piw^eMIHjD4RebtR`|IlckplP1;r21wTi8v((KqNqn%2CB< zifaQc&T}*M&0i|LW^LgdjIaX|o~I$`owHolRqeH_CFrqCUCleN130&vH}dK|^kC>) z-r2P~mApHotL4dRX$25lIcRh_*kJaxi^%ZN5-GAAMOxfB!6flLPY-p&QzL9TE%ho( zRwftE3sy5<*^)qYzKkL|rE>n@hyr;xPqncY6QJ8125!MWr`UCWuC~A#G1AqF1@V$kv>@NBvN&2ygy*{QvxolkRRb%Ui zsmKROR%{*g*WjUUod@@cS^4eF^}yQ1>;WlGwOli z+Y$(8I`0(^d|w>{eaf!_BBM;NpCoeem2>J}82*!em=}}ymoXk>QEfJ>G(3LNA2-46 z5PGvjr)Xh9>aSe>vEzM*>xp{tJyZox1ZRl}QjcvX2TEgNc^(_-hir@Es>NySoa1g^ zFow_twnHdx(j?Q_3q51t3XI7YlJ4_q&(0#)&a+RUy{IcBq?)eaWo*=H2UUVIqtp&lW9JTJiP&u zw8+4vo~_IJXZIJb_U^&=GI1nSD%e;P!c{kZALNCm5c%%oF+I3DrA63_@4)(v4(t~JiddILp7jmoy+>cD~ivwoctFfEL zP*#2Rx?_&bCpX26MBgp^4G>@h`Hxc(lnqyj!*t>9sOBcXN(hTwEDpn^X{x!!gPX?1 z*uM$}cYRwHXuf+gYTB}gDTcw{TXSOUU$S?8BeP&sc!Lc{{pEv}x#ELX>6*ipI1#>8 zKes$bHjiJ1OygZge_ak^Hz#k;=od1wZ=o71ba7oClBMq>Uk6hVq|ePPt)@FM5bW$I z;d2Or@wBjbTyZj|;+iHp%Bo!Vy(X3YM-}lasMItEV_QrP-Kk_J4C>)L&I3Xxj=E?| zsAF(IfVQ4w+dRRnJ>)}o^3_012YYgFWE)5TT=l2657*L8_u1KC>Y-R{7w^S&A^X^U}h20jpS zQsdeaA#WIE*<8KG*oXc~$izYilTc#z{5xhpXmdT-YUnGh9v4c#lrHG6X82F2-t35} zB`jo$HjKe~E*W$=g|j&P>70_cI`GnOQ;Jp*JK#CT zuEGCn{8A@bC)~0%wsEv?O^hSZF*iqjO~_h|>xv>PO+?525Nw2472(yqS>(#R)D7O( zg)Zrj9n9$}=~b00=Wjf?E418qP-@8%MQ%PBiCTX=$B)e5cHFDu$LnOeJ~NC;xmOk# z>z&TbsK>Qzk)!88lNI8fOE2$Uxso^j*1fz>6Ot49y@=po)j4hbTIcVR`ePHpuJSfp zxaD^Dn3X}Na3@<_Pc>a;-|^Pon(>|ytG_+U^8j_JxP=_d>L$Hj?|0lz>_qQ#a|$+( z(x=Lipuc8p4^}1EQhI|TubffZvB~lu$zz9ao%T?%ZLyV5S9}cLeT?c} z>yCN9<04NRi~1oR)CiBakoNhY9BPnv)kw%*iv8vdr&&VgLGIs(-FbJ?d_gfbL2={- zBk4lkdPk~7+jIxd4{M(-W1AC_WcN&Oza@jZoj zaE*9Y;g83#m(OhA!w~LNfUJNUuRz*H-=$s*z+q+;snKPRm9EptejugC-@7-a-}Tz0 z@KHra#Y@OXK+KsaSN9WiGf?&jlZ!V7L||%KHP;SLksMFfjkeIMf<1e~t?!G3{n)H8 zQAlFY#QwfKuj;l@<$YDATAk;%PtD%B(0<|8>rXU< zJ66rkAVW_~Dj!7JGdGGi4NFuE?7ZafdMxIh65Sz7yQoA7fBZCE@WwysB=+`kT^LFX zz8#FlSA5)6FG9(qL3~A24mpzL@@2D#>0J7mMS1T*9UJ zvOq!!a(%IYY69+h45CE?(&v9H4FCr>gK0>mK~F}5RdOuH2{4|}k@5XpsX7+LZo^Qa4sH5`eUj>iffoBVm+ zz4Mtf`h?NW$*q1yr|}E&eNl)J``SZvTf6Qr*&S%tVv_OBpbjnA0&Vz#(;QmGiq-k! zgS0br4I&+^2mgA15*~Cd00cXLYOLA#Ep}_)eED>m+K@JTPr_|lSN}(OzFXQSBc6fM z@f-%2;1@BzhZa*LFV z-LrLmkmB%<<&jEURBEW>soaZ*rSIJNwaV%-RSaCZi4X)qYy^PxZ=oL?6N-5OGOMD2 z;q_JK?zkwQ@b3~ln&sDtT5SpW9a0q+5Gm|fpVY2|zqlNYBR}E5+ahgdj!CvK$Tlk0 z9g$5N;aar=CqMsudQV>yb4l@hN(9Jcc=1(|OHsqH6|g=K-WBd8GxZ`AkT?OO z-z_Ued-??Z*R4~L7jwJ%-`s~FK|qNAJ;EmIVDVpk{Lr7T4l{}vL)|GuUuswe9c5F| zv*5%u01hlv08?00Vpwyk*Q&&fY8k6MjOfpZfKa@F-^6d=Zv|0@&4_544RP5(s|4VPVP-f>%u(J@23BHqo2=zJ#v9g=F!cP((h zpt0|(s++ej?|$;2PE%+kc6JMmJjDW)3BXvBK!h!E`8Y&*7hS{c_Z?4SFP&Y<3evqf z9-ke+bSj$%Pk{CJlJbWwlBg^mEC^@%Ou?o>*|O)rl&`KIbHrjcpqsc$Zqt0^^F-gU2O=BusO+(Op}!jNzLMc zT;0YT%$@ClS%V+6lMTfhuzzxomoat=1H?1$5Ei7&M|gxo`~{UiV5w64Np6xV zVK^nL$)#^tjhCpTQMspXI({TW^U5h&Wi1Jl8g?P1YCV4=%ZYyjSo#5$SX&`r&1PyC zzc;uzCd)VTIih|8eNqFNeBMe#j_FS6rq81b>5?aXg+E#&$m++Gz9<+2)h=K(xtn}F ziV{rmu+Y>A)qvF}ms}4X^Isy!M&1%$E!rTO~5(p+8{U6#hWu>(Ll1}eD64Xa>~73A*538wry?v$vW z>^O#FRdbj(k0Nr&)U`Tl(4PI*%IV~;ZcI2z&rmq=(k^}zGOYZF3b2~Klpzd2eZJl> zB=MOLwI1{$RxQ7Y4e30&yOx?BvAvDkTBvWPpl4V8B7o>4SJn*+h1Ms&fHso%XLN5j z-zEwT%dTefp~)J_C8;Q6i$t!dnlh-!%haR1X_NuYUuP-)`IGWjwzAvp!9@h`kPZhf zwLwFk{m3arCdx8rD~K2`42mIN4}m%OQ|f)4kf%pL?Af5Ul<3M2fv>;nlhEPR8b)u} zIV*2-wyyD%%) zl$G@KrC#cUwoL?YdQyf9WH)@gWB{jd5w4evI& zOFF)p_D8>;3-N1z6mES!OPe>B^<;9xsh)){Cw$Vs-ez5nXS95NOr3s$IU;>VZSzKn zBvub8_J~I%(DozZW@{)Vp37-zevxMRZ8$8iRfwHmYvyjOxIOAF2FUngKj289!(uxY zaClWm!%x&teKmr^ABrvZ(ikx{{I-lEzw5&4t3P0eX%M~>$wG0ZjA4Mb&op+0$#SO_ z--R`>X!aqFu^F|a!{Up-iF(K+alKB{MNMs>e(i@Tpy+7Z-dK%IEjQFO(G+2mOb@BO zP>WHlS#fSQm0et)bG8^ZDScGnh-qRKIFz zfUdnk=m){ej0i(VBd@RLtRq3Ep=>&2zZ2%&vvf?Iex01hx1X!8U+?>ER;yJlR-2q4 z;Y@hzhEC=d+Le%=esE>OQ!Q|E%6yG3V_2*uh&_nguPcZ{q?DNq8h_2ahaP6=pP-+x zK!(ve(yfoYC+n(_+chiJ6N(ZaN+XSZ{|H{TR1J_s8x4jpis-Z-rlRvRK#U%SMJ(`C z?T2 zF(NNfO_&W%2roEC2j#v*(nRgl1X)V-USp-H|CwFNs?n@&vpRcj@W@xCJwR6@T!jt377?XjZ06=`d*MFyTdyvW!`mQm~t3luzYzvh^F zM|V}rO>IlBjZc}9Z zd$&!tthvr>5)m;5;96LWiAV0?t)7suqdh0cZis`^Pyg@?t>Ms~7{nCU;z`Xl+raSr zXpp=W1oHB*98s!Tpw=R5C)O{{Inl>9l7M*kq%#w9a$6N~v?BY2GKOVRkXYCgg*d

<5G2M1WZP5 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 \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - -exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index f955316..0000000 --- a/gradlew.bat +++ /dev/null @@ -1,84 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..0c643ec --- /dev/null +++ b/pom.xml @@ -0,0 +1,164 @@ + + + 4.0.0 + + me.skymc + TabooLib + 3.832 + + + clean install package + + + src/main/resources + true + + + src/main/java + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.2 + + 1.8 + 1.8 + UTF-8 + + + + org.apache.maven.plugins + maven-shade-plugin + 3.0.0 + + + package + + shade + + + + + org.ow2.asm + + + false + + + + + + + + + vault + http://nexus.hc.to/content/repositories/pub_releases + + + + + org.ow2.asm + asm + 5.2 + + + bukkit + bukkit1_12 + 1 + system + ${basedir}/libs/1_12_R1.jar + + + bukkit + bukkit1_8 + 1 + system + ${basedir}/libs/1_8_R3.jar + + + bukkit + bukkit1_9 + 1 + system + ${basedir}/libs/1_9_R3.jar + + + bukkit + bukkit1_10 + 1 + system + ${basedir}/libs/1_10_R1.jar + + + bukkit + bukkit1_11 + system + 1 + ${basedir}/libs/1_11_R1.jar + + + com.sun.tools + jshell + 1 + system + ${basedir}/libs/com.sun.tools.jar + + + lombok + lombok + 1 + system + ${basedir}/libs/lombok.jar + + + placeholder + placeholder + 1 + system + ${basedir}/libs/PlaceholderAPI.jar + + + plib + plib + 1 + system + ${basedir}/libs/ProtocolLib.jar + + + sk + sk + 1 + system + ${basedir}/libs/Skript.jar + + + taboocode + taboocode + 1 + system + ${basedir}/libs/TabooCode5.jar + + + net.milkbowl.vault + VaultAPI + 1.6 + + + wg + wg + 1 + system + ${basedir}/libs/WorldGuard.jar + + + yum + yum + 1 + system + ${basedir}/libs/Yum.jar + + + + \ No newline at end of file diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 1793624..0000000 --- a/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -/* - * This file was generated by the Gradle 'init' task. - * - * The settings file is used to specify which projects to include in your build. - * - * Detailed information about configuring a multi-project build in Gradle can be found - * in the user guide at https://docs.gradle.org/4.5/userguide/multi_project_builds.html - */ - -rootProject.name = 'TabooLib' diff --git a/src/.gradle/4.5/taskHistory/taskHistory.bin b/src/.gradle/4.5/taskHistory/taskHistory.bin deleted file mode 100644 index 45489493647331e53ea5e610b176919db6d447d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18754 zcmeI(ze>a~9Ki9^b5IfNBHSVlPJ$Lu?Cx=bv#5)M*0z?O{by58>L4z+3F4xHn=c^v z1};8<%RPXDAb4X3MRWF!djdh^8~7zZk`VIytRZzFs`^*2i9wqjq+|#nfB*srAb8s9EX2aNO0>q~{Pos*v0W~&t@Pgy z`lFhkE!XG~KmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0;4cU)sY?_pI^EE2_iR(<&S5B{{V<4~U@>W)m<=<}^WJ4E>i>YI zKTn;vFT}&}>)GhdTTwd|+LIQip5djI6S#(z_(o>Q18F$E Date: Sun, 1 Apr 2018 15:18:57 +0800 Subject: [PATCH 02/44] =?UTF-8?q?=E7=94=BB=E9=A5=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/uiDesigner.xml | 124 ++++++++++++++++++ .../java/com/ilummc/tlib/ExampleMain.java | 35 +++++ .../com/ilummc/tlib/annotations/Config.java | 19 +++ .../ilummc/tlib/annotations/ConfigNode.java | 6 + .../ilummc/tlib/annotations/Dependencies.java | 7 + .../tlib/annotations/PluginInstance.java | 6 + .../ilummc/tlib/annotations/db/Database.java | 11 ++ .../tlib/annotations/db/DatabasePassword.java | 4 + .../tlib/annotations/db/DatabaseType.java | 4 + .../tlib/annotations/db/DatabaseUrl.java | 4 + .../tlib/annotations/db/DatabaseUser.java | 4 + .../ilummc/tlib/annotations/db/SQLTable.java | 7 + .../com/ilummc/tlib/bean/BooleanProperty.java | 17 +++ .../java/com/ilummc/tlib/bean/Property.java | 4 + 14 files changed, 252 insertions(+) create mode 100644 .idea/uiDesigner.xml create mode 100644 src/main/java/com/ilummc/tlib/ExampleMain.java create mode 100644 src/main/java/com/ilummc/tlib/annotations/Config.java create mode 100644 src/main/java/com/ilummc/tlib/annotations/ConfigNode.java create mode 100644 src/main/java/com/ilummc/tlib/annotations/Dependencies.java create mode 100644 src/main/java/com/ilummc/tlib/annotations/PluginInstance.java create mode 100644 src/main/java/com/ilummc/tlib/annotations/db/Database.java create mode 100644 src/main/java/com/ilummc/tlib/annotations/db/DatabasePassword.java create mode 100644 src/main/java/com/ilummc/tlib/annotations/db/DatabaseType.java create mode 100644 src/main/java/com/ilummc/tlib/annotations/db/DatabaseUrl.java create mode 100644 src/main/java/com/ilummc/tlib/annotations/db/DatabaseUser.java create mode 100644 src/main/java/com/ilummc/tlib/annotations/db/SQLTable.java create mode 100644 src/main/java/com/ilummc/tlib/bean/BooleanProperty.java create mode 100644 src/main/java/com/ilummc/tlib/bean/Property.java diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..e96534f --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/ilummc/tlib/ExampleMain.java b/src/main/java/com/ilummc/tlib/ExampleMain.java new file mode 100644 index 0000000..a22a8ad --- /dev/null +++ b/src/main/java/com/ilummc/tlib/ExampleMain.java @@ -0,0 +1,35 @@ +package com.ilummc.tlib; + +import com.ilummc.tlib.annotations.Config; +import com.ilummc.tlib.annotations.ConfigNode; +import com.ilummc.tlib.bean.BooleanProperty; +import org.bukkit.Bukkit; +import org.bukkit.plugin.java.JavaPlugin; + +@Config(name = "cfg.yml", charset = "GBK") +public class ExampleMain extends JavaPlugin { + + @ConfigNode("enableUpdate") + private BooleanProperty update = new BooleanProperty(true); + + @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() { + + } + } +} diff --git a/src/main/java/com/ilummc/tlib/annotations/Config.java b/src/main/java/com/ilummc/tlib/annotations/Config.java new file mode 100644 index 0000000..b702063 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/annotations/Config.java @@ -0,0 +1,19 @@ +package com.ilummc.tlib.annotations; + +public @interface Config { + + String name() default "config.yml"; + + boolean fromJar() default true; + + boolean saveOnExit() default false; + + boolean readOnly() default true; + + boolean fixUnicode() default true; + + String charset() default "UTF-8"; + + boolean listenChanges() default false; + +} diff --git a/src/main/java/com/ilummc/tlib/annotations/ConfigNode.java b/src/main/java/com/ilummc/tlib/annotations/ConfigNode.java new file mode 100644 index 0000000..810a26f --- /dev/null +++ b/src/main/java/com/ilummc/tlib/annotations/ConfigNode.java @@ -0,0 +1,6 @@ +package com.ilummc.tlib.annotations; + +public @interface ConfigNode { + + String value(); +} diff --git a/src/main/java/com/ilummc/tlib/annotations/Dependencies.java b/src/main/java/com/ilummc/tlib/annotations/Dependencies.java new file mode 100644 index 0000000..b17f877 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/annotations/Dependencies.java @@ -0,0 +1,7 @@ +package com.ilummc.tlib.annotations; + +public @interface Dependencies { + + String[] value(); + +} diff --git a/src/main/java/com/ilummc/tlib/annotations/PluginInstance.java b/src/main/java/com/ilummc/tlib/annotations/PluginInstance.java new file mode 100644 index 0000000..02c713e --- /dev/null +++ b/src/main/java/com/ilummc/tlib/annotations/PluginInstance.java @@ -0,0 +1,6 @@ +package com.ilummc.tlib.annotations; + +public @interface PluginInstance { + + String value(); +} diff --git a/src/main/java/com/ilummc/tlib/annotations/db/Database.java b/src/main/java/com/ilummc/tlib/annotations/db/Database.java new file mode 100644 index 0000000..cdf2b49 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/annotations/db/Database.java @@ -0,0 +1,11 @@ +package com.ilummc.tlib.annotations.db; + +public @interface Database { + + boolean sharedPool() default true; + + int poolSize() default 8; + + Class configClass(); + +} diff --git a/src/main/java/com/ilummc/tlib/annotations/db/DatabasePassword.java b/src/main/java/com/ilummc/tlib/annotations/db/DatabasePassword.java new file mode 100644 index 0000000..6f42c90 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/annotations/db/DatabasePassword.java @@ -0,0 +1,4 @@ +package com.ilummc.tlib.annotations.db; + +public @interface DatabasePassword { +} diff --git a/src/main/java/com/ilummc/tlib/annotations/db/DatabaseType.java b/src/main/java/com/ilummc/tlib/annotations/db/DatabaseType.java new file mode 100644 index 0000000..48070ca --- /dev/null +++ b/src/main/java/com/ilummc/tlib/annotations/db/DatabaseType.java @@ -0,0 +1,4 @@ +package com.ilummc.tlib.annotations.db; + +public @interface DatabaseType { +} diff --git a/src/main/java/com/ilummc/tlib/annotations/db/DatabaseUrl.java b/src/main/java/com/ilummc/tlib/annotations/db/DatabaseUrl.java new file mode 100644 index 0000000..056dd25 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/annotations/db/DatabaseUrl.java @@ -0,0 +1,4 @@ +package com.ilummc.tlib.annotations.db; + +public @interface DatabaseUrl { +} diff --git a/src/main/java/com/ilummc/tlib/annotations/db/DatabaseUser.java b/src/main/java/com/ilummc/tlib/annotations/db/DatabaseUser.java new file mode 100644 index 0000000..b8ab435 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/annotations/db/DatabaseUser.java @@ -0,0 +1,4 @@ +package com.ilummc.tlib.annotations.db; + +public @interface DatabaseUser { +} diff --git a/src/main/java/com/ilummc/tlib/annotations/db/SQLTable.java b/src/main/java/com/ilummc/tlib/annotations/db/SQLTable.java new file mode 100644 index 0000000..eb868f2 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/annotations/db/SQLTable.java @@ -0,0 +1,7 @@ +package com.ilummc.tlib.annotations.db; + +public @interface SQLTable { + + String value(); + +} diff --git a/src/main/java/com/ilummc/tlib/bean/BooleanProperty.java b/src/main/java/com/ilummc/tlib/bean/BooleanProperty.java new file mode 100644 index 0000000..2837d76 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/bean/BooleanProperty.java @@ -0,0 +1,17 @@ +package com.ilummc.tlib.bean; + +import java.util.function.BiConsumer; + +public class BooleanProperty { + + private boolean property; + + public BooleanProperty(boolean property) { + this.property = property; + } + + public void addListener(BiConsumer consumer) { + + } + +} diff --git a/src/main/java/com/ilummc/tlib/bean/Property.java b/src/main/java/com/ilummc/tlib/bean/Property.java new file mode 100644 index 0000000..12b16c7 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/bean/Property.java @@ -0,0 +1,4 @@ +package com.ilummc.tlib.bean; + +public class Property { +} From 77280f2639d3d5884f250b0c81fc7a84b85e1283 Mon Sep 17 00:00:00 2001 From: IzzelAliz Date: Tue, 3 Apr 2018 12:53:35 +0800 Subject: [PATCH 03/44] Change to MIT License --- LICENSE | 695 ++------------------------------------------------------ 1 file changed, 21 insertions(+), 674 deletions(-) diff --git a/LICENSE b/LICENSE index 9f2247b..a62108d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,674 +1,21 @@ -GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - {one line to give the program's name and a brief idea of what it does.} - Copyright (C) 2018 {name of author} - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - TabooLib Copyright (C) 2018 坏黑 - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. \ No newline at end of file +MIT License + +Copyright (c) 2018 Bkm016 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From c7517f72400e6be2d7955d53db7289ac3278a43b Mon Sep 17 00:00:00 2001 From: IzzelAliz Date: Tue, 3 Apr 2018 12:55:27 +0800 Subject: [PATCH 04/44] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 468b1f1..5c5be7c 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,10 @@ 如果需要启用 *JavaShell* 功能请将 [com.sun.tools.jar](http://skymc.oss-cn-shanghai.aliyuncs.com/plugins/com.sun.tools.jar) 放入 *"TabooLib/JavaShell/lib"* 文件夹中。 +**3.832** 以后的版本的开源协议更改为 MIT License,3.832 及以前的版本维持 GPLv3 协议。 + ## 构建 ``` mvn clean install package -``` \ No newline at end of file +``` From add76a30cb636406cf0de39f4683dbb4f41ed1f4 Mon Sep 17 00:00:00 2001 From: Izzel_Aliz Date: Wed, 4 Apr 2018 20:00:39 +0800 Subject: [PATCH 05/44] =?UTF-8?q?=E5=8B=89=E5=BC=BA=E8=83=BD=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E4=BE=9D=E8=B5=96=E5=8A=A0=E8=BD=BD=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E5=81=9A=E5=A5=BD=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...en__com_ilummc_eagletdl_EagletCore_1_0.xml | 13 ++ .../libraries/Maven__org_ow2_asm_asm_5_2.xml | 13 -- .../Maven__org_ow2_asm_asm_6_1_1.xml | 13 ++ ...aven__org_projectlombok_lombok_1_16_20.xml | 13 ++ pom.xml | 31 ++-- .../java/com/ilummc/tlib/ExampleMain.java | 4 +- src/main/java/com/ilummc/tlib/TLib.java | 28 +++ src/main/java/com/ilummc/tlib/TabooLib.java | 8 - .../com/ilummc/tlib/annotations/Config.java | 7 + .../ilummc/tlib/annotations/ConfigNode.java | 7 + .../ilummc/tlib/annotations/Dependencies.java | 9 +- .../ilummc/tlib/annotations/Dependency.java | 16 ++ .../com/ilummc/tlib/annotations/Logger.java | 18 ++ .../tlib/annotations/PluginInstance.java | 7 + .../ilummc/tlib/annotations/db/SQLTable.java | 7 + .../com/ilummc/tlib/bean/BooleanProperty.java | 17 -- .../java/com/ilummc/tlib/bean/Property.java | 39 +++- .../ilummc/tlib/dependency/TDependency.java | 77 ++++++++ .../tlib/dependency/TDependencyLoader.java | 32 ++++ .../tlib/inject/DependencyInjector.java | 99 +++++++++++ .../ilummc/tlib/inject/TLibPluginManager.java | 168 ++++++++++++++++++ .../java/com/ilummc/tlib/util/Strings.java | 27 +++ .../java/com/ilummc/tlib/util/TLogger.java | 63 +++++++ src/main/java/me/skymc/taboolib/Main.java | 6 +- 24 files changed, 665 insertions(+), 57 deletions(-) create mode 100644 .idea/libraries/Maven__com_ilummc_eagletdl_EagletCore_1_0.xml delete mode 100644 .idea/libraries/Maven__org_ow2_asm_asm_5_2.xml create mode 100644 .idea/libraries/Maven__org_ow2_asm_asm_6_1_1.xml create mode 100644 .idea/libraries/Maven__org_projectlombok_lombok_1_16_20.xml create mode 100644 src/main/java/com/ilummc/tlib/TLib.java delete mode 100644 src/main/java/com/ilummc/tlib/TabooLib.java create mode 100644 src/main/java/com/ilummc/tlib/annotations/Dependency.java create mode 100644 src/main/java/com/ilummc/tlib/annotations/Logger.java delete mode 100644 src/main/java/com/ilummc/tlib/bean/BooleanProperty.java create mode 100644 src/main/java/com/ilummc/tlib/dependency/TDependency.java create mode 100644 src/main/java/com/ilummc/tlib/dependency/TDependencyLoader.java create mode 100644 src/main/java/com/ilummc/tlib/inject/DependencyInjector.java create mode 100644 src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java create mode 100644 src/main/java/com/ilummc/tlib/util/Strings.java create mode 100644 src/main/java/com/ilummc/tlib/util/TLogger.java diff --git a/.idea/libraries/Maven__com_ilummc_eagletdl_EagletCore_1_0.xml b/.idea/libraries/Maven__com_ilummc_eagletdl_EagletCore_1_0.xml new file mode 100644 index 0000000..edabcdb --- /dev/null +++ b/.idea/libraries/Maven__com_ilummc_eagletdl_EagletCore_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_ow2_asm_asm_5_2.xml b/.idea/libraries/Maven__org_ow2_asm_asm_5_2.xml deleted file mode 100644 index 02e02fd..0000000 --- a/.idea/libraries/Maven__org_ow2_asm_asm_5_2.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__org_ow2_asm_asm_6_1_1.xml b/.idea/libraries/Maven__org_ow2_asm_asm_6_1_1.xml new file mode 100644 index 0000000..db66af9 --- /dev/null +++ b/.idea/libraries/Maven__org_ow2_asm_asm_6_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_projectlombok_lombok_1_16_20.xml b/.idea/libraries/Maven__org_projectlombok_lombok_1_16_20.xml new file mode 100644 index 0000000..bcbf2ac --- /dev/null +++ b/.idea/libraries/Maven__org_projectlombok_lombok_1_16_20.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 0c643ec..02279a1 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ - org.ow2.asm + com.ilummc.eagletdl false @@ -58,10 +58,20 @@ + + com.ilummc.eagletdl + EagletCore + 1.0 + org.ow2.asm asm - 5.2 + 6.1.1 + + + org.projectlombok + lombok + 1.16.20 bukkit @@ -70,6 +80,11 @@ system ${basedir}/libs/1_12_R1.jar + + net.milkbowl.vault + VaultAPI + 1.6 + bukkit bukkit1_8 @@ -105,13 +120,6 @@ system ${basedir}/libs/com.sun.tools.jar - - lombok - lombok - 1 - system - ${basedir}/libs/lombok.jar - placeholder placeholder @@ -140,11 +148,6 @@ system ${basedir}/libs/TabooCode5.jar - - net.milkbowl.vault - VaultAPI - 1.6 - wg wg diff --git a/src/main/java/com/ilummc/tlib/ExampleMain.java b/src/main/java/com/ilummc/tlib/ExampleMain.java index a22a8ad..46af092 100644 --- a/src/main/java/com/ilummc/tlib/ExampleMain.java +++ b/src/main/java/com/ilummc/tlib/ExampleMain.java @@ -2,7 +2,7 @@ package com.ilummc.tlib; import com.ilummc.tlib.annotations.Config; import com.ilummc.tlib.annotations.ConfigNode; -import com.ilummc.tlib.bean.BooleanProperty; +import com.ilummc.tlib.bean.Property; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; @@ -10,7 +10,7 @@ import org.bukkit.plugin.java.JavaPlugin; public class ExampleMain extends JavaPlugin { @ConfigNode("enableUpdate") - private BooleanProperty update = new BooleanProperty(true); + private Property update = Property.of(false); @Override public void onEnable() { diff --git a/src/main/java/com/ilummc/tlib/TLib.java b/src/main/java/com/ilummc/tlib/TLib.java new file mode 100644 index 0000000..cd20cc0 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/TLib.java @@ -0,0 +1,28 @@ +package com.ilummc.tlib; + +import com.ilummc.tlib.inject.TLibPluginManager; +import me.skymc.taboolib.Main; +import me.skymc.taboolib.message.MsgUtils; +import org.bukkit.Bukkit; + +import java.io.File; +import java.lang.reflect.Field; + +public class TLib { + + @SuppressWarnings({"unchecked"}) + public static void init() { + // 注入 PluginLoader 用于加载依赖 + try { + Field field = Bukkit.getServer().getClass().getDeclaredField("pluginManager"); + field.setAccessible(true); + field.set(Bukkit.getServer(), new TLibPluginManager()); + MsgUtils.send("注入成功"); + } catch (NoSuchFieldException | IllegalAccessException e) { + e.printStackTrace(); + MsgUtils.warn("注入失败"); + } + new File(Main.getInst().getDataFolder(), "/libs").mkdirs(); + } + +} diff --git a/src/main/java/com/ilummc/tlib/TabooLib.java b/src/main/java/com/ilummc/tlib/TabooLib.java deleted file mode 100644 index 57b888d..0000000 --- a/src/main/java/com/ilummc/tlib/TabooLib.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.ilummc.tlib; - -public class TabooLib { - - public void init() { - - } -} diff --git a/src/main/java/com/ilummc/tlib/annotations/Config.java b/src/main/java/com/ilummc/tlib/annotations/Config.java index b702063..1e4548a 100644 --- a/src/main/java/com/ilummc/tlib/annotations/Config.java +++ b/src/main/java/com/ilummc/tlib/annotations/Config.java @@ -1,5 +1,12 @@ 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 Config { String name() default "config.yml"; diff --git a/src/main/java/com/ilummc/tlib/annotations/ConfigNode.java b/src/main/java/com/ilummc/tlib/annotations/ConfigNode.java index 810a26f..7e2478d 100644 --- a/src/main/java/com/ilummc/tlib/annotations/ConfigNode.java +++ b/src/main/java/com/ilummc/tlib/annotations/ConfigNode.java @@ -1,5 +1,12 @@ 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 ConfigNode { String value(); diff --git a/src/main/java/com/ilummc/tlib/annotations/Dependencies.java b/src/main/java/com/ilummc/tlib/annotations/Dependencies.java index b17f877..a87a8d7 100644 --- a/src/main/java/com/ilummc/tlib/annotations/Dependencies.java +++ b/src/main/java/com/ilummc/tlib/annotations/Dependencies.java @@ -1,7 +1,14 @@ 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 Dependencies { - String[] value(); + Dependency[] value(); } diff --git a/src/main/java/com/ilummc/tlib/annotations/Dependency.java b/src/main/java/com/ilummc/tlib/annotations/Dependency.java new file mode 100644 index 0000000..bde26ea --- /dev/null +++ b/src/main/java/com/ilummc/tlib/annotations/Dependency.java @@ -0,0 +1,16 @@ +package com.ilummc.tlib.annotations; + +import java.lang.annotation.*; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Repeatable(Dependencies.class) +public @interface Dependency { + + enum Type {PLUGIN, LIBRARY} + + Type type(); + + String[] args(); + +} diff --git a/src/main/java/com/ilummc/tlib/annotations/Logger.java b/src/main/java/com/ilummc/tlib/annotations/Logger.java new file mode 100644 index 0000000..2e504b3 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/annotations/Logger.java @@ -0,0 +1,18 @@ +package com.ilummc.tlib.annotations; + +import com.ilummc.tlib.util.TLogger; + +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}"; + + int level() default TLogger.INFO; + +} diff --git a/src/main/java/com/ilummc/tlib/annotations/PluginInstance.java b/src/main/java/com/ilummc/tlib/annotations/PluginInstance.java index 02c713e..9e10b55 100644 --- a/src/main/java/com/ilummc/tlib/annotations/PluginInstance.java +++ b/src/main/java/com/ilummc/tlib/annotations/PluginInstance.java @@ -1,5 +1,12 @@ 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 PluginInstance { String value(); diff --git a/src/main/java/com/ilummc/tlib/annotations/db/SQLTable.java b/src/main/java/com/ilummc/tlib/annotations/db/SQLTable.java index eb868f2..543d3f2 100644 --- a/src/main/java/com/ilummc/tlib/annotations/db/SQLTable.java +++ b/src/main/java/com/ilummc/tlib/annotations/db/SQLTable.java @@ -1,5 +1,12 @@ 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(); diff --git a/src/main/java/com/ilummc/tlib/bean/BooleanProperty.java b/src/main/java/com/ilummc/tlib/bean/BooleanProperty.java deleted file mode 100644 index 2837d76..0000000 --- a/src/main/java/com/ilummc/tlib/bean/BooleanProperty.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.ilummc.tlib.bean; - -import java.util.function.BiConsumer; - -public class BooleanProperty { - - private boolean property; - - public BooleanProperty(boolean property) { - this.property = property; - } - - public void addListener(BiConsumer consumer) { - - } - -} diff --git a/src/main/java/com/ilummc/tlib/bean/Property.java b/src/main/java/com/ilummc/tlib/bean/Property.java index 12b16c7..29cfff7 100644 --- a/src/main/java/com/ilummc/tlib/bean/Property.java +++ b/src/main/java/com/ilummc/tlib/bean/Property.java @@ -1,4 +1,41 @@ package com.ilummc.tlib.bean; -public class Property { +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiConsumer; + +public class Property { + + private Property(T value) { + this.value = value; + } + + private List> consumers; + + private T value; + + public void set(T value) { + if (value != this.value) { + if (consumers != null) + for (BiConsumer consumer : consumers) { + consumer.accept(this.value, value); + } + this.value = value; + } + } + + public T get() { + return value; + } + + public void addListener(BiConsumer consumer) { + if (consumers == null) + consumers = new ArrayList<>(); + consumers.add(consumer); + } + + public static Property of(T value) { + return new Property<>(value); + } + } diff --git a/src/main/java/com/ilummc/tlib/dependency/TDependency.java b/src/main/java/com/ilummc/tlib/dependency/TDependency.java new file mode 100644 index 0000000..421676d --- /dev/null +++ b/src/main/java/com/ilummc/tlib/dependency/TDependency.java @@ -0,0 +1,77 @@ +package com.ilummc.tlib.dependency; + +import com.ilummc.eagletdl.EagletTask; +import me.skymc.taboolib.Main; +import me.skymc.taboolib.message.MsgUtils; + +import java.io.File; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.ReentrantLock; + +public class TDependency { + + public static final String MAVEN_REPO = "http://repo.maven.apache.org/maven2"; + + /** + * 请求一个插件作为依赖,这个插件将会在所有已经添加的 Jenkins 仓库、Maven 仓库寻找 + *

+ * 阻塞线程进行下载/加载 + * + * @param args 插件名称,下载地址(可选) + * @return 是否成功加载了依赖 + */ + public static boolean requestPlugin(String... args) { + return false; + } + + /** + * 请求一个库作为依赖,这个库将会在 Maven Central、oss.sonatype 以及自定义的 Maven 仓库寻找 + *

+ * 阻塞线程进行下载/加载 + * + * @param args 依赖名,格式为 groupId:artifactId:version + * @return 是否成功加载库,如果加载成功,插件将可以任意调用使用的类 + */ + public static boolean requestLib(String... args) { + if (args[0].matches(".*:.*:.*")) { + String[] arr = args[0].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(MAVEN_REPO, arr[0], arr[1], arr[2], file)) { + 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) { + ReentrantLock lock = new ReentrantLock(); + AtomicBoolean failed = new AtomicBoolean(false); + new EagletTask() + .url(url + "/" + groupId.replace('.', '/') + "/" + artifactId + "/" + version + "/" + artifactId + "-" + version + ".jar") + .file(target) + .setThreads(8) + .setOnStart(event -> lock.lock()) + .setOnProgress(event -> MsgUtils.send(" 下载速度 " + event.getSpeedFormatted())) + .setOnConnected(event -> MsgUtils.send(" 正在下载 " + String.join(":", new String[]{groupId, artifactId, version}) + + " 大小 " + event.getContentLength())) + .setOnError(event -> failed.set(true)) + .setOnComplete(event -> { + lock.unlock(); + MsgUtils.send(" 下载 " + String.join(":", new String[]{groupId, artifactId, version}) + " 完成"); + }) + .start(); + try { + while (lock.tryLock()) lock.unlock(); + } catch (Exception ignored) { + } finally { + lock.lock(); + lock.unlock(); + } + return !failed.get(); + } + +} diff --git a/src/main/java/com/ilummc/tlib/dependency/TDependencyLoader.java b/src/main/java/com/ilummc/tlib/dependency/TDependencyLoader.java new file mode 100644 index 0000000..3c52502 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/dependency/TDependencyLoader.java @@ -0,0 +1,32 @@ +package com.ilummc.tlib.dependency; + +import org.bukkit.plugin.Plugin; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; + +public class TDependencyLoader { + + public static synchronized void addToPath(Plugin plugin, URL url) { + try { + Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); + method.setAccessible(true); + method.invoke(plugin.getClass().getClassLoader(), url); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } + + public static synchronized void addToPath(Plugin plugin, File file) { + try { + addToPath(plugin, file.toURI().toURL()); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java new file mode 100644 index 0000000..6e1ab86 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java @@ -0,0 +1,99 @@ +package com.ilummc.tlib.inject; + +import com.ilummc.tlib.annotations.Dependencies; +import com.ilummc.tlib.annotations.Dependency; +import com.ilummc.tlib.annotations.Logger; +import com.ilummc.tlib.annotations.PluginInstance; +import com.ilummc.tlib.dependency.TDependency; +import com.ilummc.tlib.util.TLogger; +import me.skymc.taboolib.message.MsgUtils; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; + +import java.lang.reflect.Field; + +public class DependencyInjector { + + public static void inject(Plugin plugin, Object o) { + injectLogger(plugin, o); + injectPluginInstance(plugin, o); + injectDependencies(plugin, o); + } + + static void injectOnEnable(Plugin plugin) { + inject(plugin, plugin); + } + + static void onDisable(Plugin plugin) { + + } + + private static void injectLogger(Plugin plugin, Object o) { + try { + for (Field field : o.getClass().getDeclaredFields()) { + Logger logger; + if ((logger = field.getAnnotation(Logger.class)) != null) { + field.getType().asSubclass(TLogger.class); + TLogger tLogger = new TLogger(logger.value(), plugin, logger.level()); + if (!field.isAccessible()) + field.setAccessible(true); + field.set(o, tLogger); + } + } + } catch (Exception ignored) { + } + } + + private static void injectPluginInstance(Plugin plugin, Object o) { + try { + for (Field field : o.getClass().getDeclaredFields()) { + 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())) { + MsgUtils.warn(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 = 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}; + } + if (dependencies.length != 0) { + MsgUtils.send("正在加载 " + plugin.getName() + " 插件所需的依赖"); + for (Dependency dependency : dependencies) { + if (dependency.type() == Dependency.Type.PLUGIN) + if (TDependency.requestPlugin(dependency.args())) + MsgUtils.send(plugin.getName() + " 请求的插件 " + dependency.args()[0] + " 加载成功。"); + else + MsgUtils.warn(plugin.getName() + " 请求的插件 " + dependency.args()[0] + " 加载失败。"); + if (dependency.type() == Dependency.Type.LIBRARY) + if (TDependency.requestLib(dependency.args())) + MsgUtils.send(plugin.getName() + " 请求的库文件 " + String.join(":", dependency.args()) + " 加载成功。"); + else + MsgUtils.send(plugin.getName() + " 请求的库文件 " + String.join(":", dependency.args()) + " 加载失败。"); + } + MsgUtils.send("依赖加载完成"); + } + } + +} diff --git a/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java b/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java new file mode 100644 index 0000000..f8a22f6 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java @@ -0,0 +1,168 @@ +package com.ilummc.tlib.inject; + +import org.bukkit.Bukkit; +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.util.Set; + +public class TLibPluginManager implements PluginManager { + + private final PluginManager instance; + + public TLibPluginManager() { + instance = Bukkit.getPluginManager(); + } + + @Override + public void registerInterface(Class 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() { + instance.disablePlugins(); + } + + @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 aClass, Listener listener, EventPriority eventPriority, EventExecutor eventExecutor, Plugin plugin) { + instance.registerEvent(aClass, listener, eventPriority, eventExecutor, plugin); + } + + @Override + public void registerEvent(Class 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) { + DependencyInjector.injectOnEnable(plugin); + instance.enablePlugin(plugin); + } + + @Override + public void disablePlugin(Plugin plugin) { + DependencyInjector.onDisable(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 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 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 getDefaultPermSubscriptions(boolean b) { + return instance.getDefaultPermSubscriptions(b); + } + + @Override + public Set getPermissions() { + return instance.getPermissions(); + } + + @Override + public boolean useTimings() { + return instance.useTimings(); + } +} diff --git a/src/main/java/com/ilummc/tlib/util/Strings.java b/src/main/java/com/ilummc/tlib/util/Strings.java new file mode 100644 index 0000000..050c43a --- /dev/null +++ b/src/main/java/com/ilummc/tlib/util/Strings.java @@ -0,0 +1,27 @@ +package com.ilummc.tlib.util; + +public class Strings { + + /** + * 优化过的 String#replace,比默认快了大概 5 倍 + * + * @param template 模板替换文件 + * @param args 替换的参数 + * @return 替换好的字符串 + */ + public static String replaceWithOrder(String template, String... args) { + 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(); + } + +} diff --git a/src/main/java/com/ilummc/tlib/util/TLogger.java b/src/main/java/com/ilummc/tlib/util/TLogger.java new file mode 100644 index 0000000..88dd23d --- /dev/null +++ b/src/main/java/com/ilummc/tlib/util/TLogger.java @@ -0,0 +1,63 @@ +package com.ilummc.tlib.util; + +import lombok.Getter; +import lombok.Setter; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +public class TLogger { + + public static final int VERBOSE = 0, FINEST = 1, FINE = 2, INFO = 3, WARN = 4, ERROR = 5, FATAL = 6; + + @Getter + private final String pattern; + + @Getter + private Plugin plugin; + + @Getter + @Setter + private int level; + + public TLogger(String pattern, Plugin plugin, int level) { + this.pattern = pattern; + this.plugin = plugin; + this.level = level; + } + + public void verbose(String msg) { + if (level >= VERBOSE) + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), msg)); + } + + public void finest(String msg) { + if (level >= FINEST) + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), msg)); + } + + public void fine(String msg) { + if (level >= FINE) + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), msg)); + } + + public void info(String msg) { + if (level >= INFO) + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), msg)); + } + + public void warn(String msg) { + if (level >= WARN) + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), msg)); + } + + public void error(String msg) { + if (level >= ERROR) + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), msg)); + } + + public void fatal(String msg) { + if (level >= FATAL) + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), msg)); + } + +} diff --git a/src/main/java/me/skymc/taboolib/Main.java b/src/main/java/me/skymc/taboolib/Main.java index f0ec280..2546d2c 100644 --- a/src/main/java/me/skymc/taboolib/Main.java +++ b/src/main/java/me/skymc/taboolib/Main.java @@ -1,5 +1,7 @@ package me.skymc.taboolib; +import com.ilummc.tlib.TLib; +import com.ilummc.tlib.annotations.Dependency; import lombok.Getter; import lombok.Setter; import me.skymc.taboolib.anvil.AnvilContainerAPI; @@ -103,7 +105,9 @@ public class Main extends JavaPlugin implements Listener { @Override public void onLoad() { inst = this; disable = false; - + + TLib.init(); + // 启动监控 new Metrics(this); From 96269db54df5e6c19323a50983572d56106fefa9 Mon Sep 17 00:00:00 2001 From: Izzel_Aliz Date: Thu, 5 Apr 2018 02:53:25 +0800 Subject: [PATCH 06/44] =?UTF-8?q?=E5=AE=8C=E5=96=84=E4=BA=86=E4=B8=80?= =?UTF-8?q?=E4=B8=8B=E4=B8=8B=E8=BD=BD=E5=BA=93=E4=BB=A5=E5=8F=8A=20TLib?= =?UTF-8?q?=20=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...n__com_ilummc_eagletdl_EagletCore_1_1.xml} | 8 +-- .../Maven__com_zaxxer_HikariCP_3_0_0.xml | 13 +++++ .../Maven__org_slf4j_slf4j_api_1_7_25.xml | 13 +++++ pom.xml | 7 ++- src/main/java/com/ilummc/tlib/TLib.java | 31 ++++++++++-- .../com/ilummc/tlib/annotations/Config.java | 2 +- .../ilummc/tlib/annotations/Dependency.java | 10 +++- .../com/ilummc/tlib/annotations/Logger.java | 2 +- .../ilummc/tlib/dependency/TDependency.java | 49 ++++++++++--------- .../tlib/inject/DependencyInjector.java | 27 ++++++---- .../ilummc/tlib/inject/TConfigInjector.java | 6 +++ .../java/com/ilummc/tlib/util/TLogger.java | 14 +++--- 12 files changed, 130 insertions(+), 52 deletions(-) rename .idea/libraries/{Maven__com_ilummc_eagletdl_EagletCore_1_0.xml => Maven__com_ilummc_eagletdl_EagletCore_1_1.xml} (61%) create mode 100644 .idea/libraries/Maven__com_zaxxer_HikariCP_3_0_0.xml create mode 100644 .idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml create mode 100644 src/main/java/com/ilummc/tlib/inject/TConfigInjector.java diff --git a/.idea/libraries/Maven__com_ilummc_eagletdl_EagletCore_1_0.xml b/.idea/libraries/Maven__com_ilummc_eagletdl_EagletCore_1_1.xml similarity index 61% rename from .idea/libraries/Maven__com_ilummc_eagletdl_EagletCore_1_0.xml rename to .idea/libraries/Maven__com_ilummc_eagletdl_EagletCore_1_1.xml index edabcdb..ab97cb6 100644 --- a/.idea/libraries/Maven__com_ilummc_eagletdl_EagletCore_1_0.xml +++ b/.idea/libraries/Maven__com_ilummc_eagletdl_EagletCore_1_1.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_zaxxer_HikariCP_3_0_0.xml b/.idea/libraries/Maven__com_zaxxer_HikariCP_3_0_0.xml new file mode 100644 index 0000000..f69ad99 --- /dev/null +++ b/.idea/libraries/Maven__com_zaxxer_HikariCP_3_0_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml b/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml new file mode 100644 index 0000000..20e8163 --- /dev/null +++ b/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 02279a1..a92e266 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,12 @@ com.ilummc.eagletdl EagletCore - 1.0 + 1.1 + + + com.zaxxer + HikariCP + 3.0.0 org.ow2.asm diff --git a/src/main/java/com/ilummc/tlib/TLib.java b/src/main/java/com/ilummc/tlib/TLib.java index cd20cc0..e193b09 100644 --- a/src/main/java/com/ilummc/tlib/TLib.java +++ b/src/main/java/com/ilummc/tlib/TLib.java @@ -1,28 +1,51 @@ package com.ilummc.tlib; +import com.ilummc.tlib.annotations.Dependency; +import com.ilummc.tlib.annotations.Logger; +import com.ilummc.tlib.inject.DependencyInjector; import com.ilummc.tlib.inject.TLibPluginManager; +import com.ilummc.tlib.util.TLogger; import me.skymc.taboolib.Main; -import me.skymc.taboolib.message.MsgUtils; import org.bukkit.Bukkit; import java.io.File; import java.lang.reflect.Field; +@Dependency(type = Dependency.Type.LIBRARY, maven = "org.ow2.asm:asm:6.1.1") +@Dependency(type = Dependency.Type.LIBRARY, maven = "com.zaxxer:HikariCP:3.0.0") public class TLib { + private static TLib tLib; + + @Logger("§3[§6TLib§3|{1}§3] §f{2}") + private TLogger tLogger; + + private TLib() { + } + + public TLogger getLogger() { + return tLogger; + } + + public static TLib getTLib() { + return tLib; + } + @SuppressWarnings({"unchecked"}) public static void init() { + new File(Main.getInst().getDataFolder(), "/libs").mkdirs(); + tLib = new TLib(); + DependencyInjector.inject(Main.getInst(), tLib); // 注入 PluginLoader 用于加载依赖 try { Field field = Bukkit.getServer().getClass().getDeclaredField("pluginManager"); field.setAccessible(true); field.set(Bukkit.getServer(), new TLibPluginManager()); - MsgUtils.send("注入成功"); + tLib.getLogger().info("注入成功"); } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); - MsgUtils.warn("注入失败"); + tLib.getLogger().fatal("注入失败"); } - new File(Main.getInst().getDataFolder(), "/libs").mkdirs(); } } diff --git a/src/main/java/com/ilummc/tlib/annotations/Config.java b/src/main/java/com/ilummc/tlib/annotations/Config.java index 1e4548a..ca16a4f 100644 --- a/src/main/java/com/ilummc/tlib/annotations/Config.java +++ b/src/main/java/com/ilummc/tlib/annotations/Config.java @@ -11,7 +11,7 @@ public @interface Config { String name() default "config.yml"; - boolean fromJar() default true; + boolean fromJar() default false; boolean saveOnExit() default false; diff --git a/src/main/java/com/ilummc/tlib/annotations/Dependency.java b/src/main/java/com/ilummc/tlib/annotations/Dependency.java index bde26ea..9c706c9 100644 --- a/src/main/java/com/ilummc/tlib/annotations/Dependency.java +++ b/src/main/java/com/ilummc/tlib/annotations/Dependency.java @@ -1,5 +1,7 @@ package com.ilummc.tlib.annotations; +import com.ilummc.tlib.dependency.TDependency; + import java.lang.annotation.*; @Target(ElementType.TYPE) @@ -11,6 +13,12 @@ public @interface Dependency { Type type(); - String[] args(); + String plugin() default ""; + + String maven() default ""; + + String mavenRepo() default TDependency.MAVEN_REPO; + + String url() default ""; } diff --git a/src/main/java/com/ilummc/tlib/annotations/Logger.java b/src/main/java/com/ilummc/tlib/annotations/Logger.java index 2e504b3..bec8bc5 100644 --- a/src/main/java/com/ilummc/tlib/annotations/Logger.java +++ b/src/main/java/com/ilummc/tlib/annotations/Logger.java @@ -11,7 +11,7 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) public @interface Logger { - String value() default "[{0}] {1}"; + String value() default "[{0}|{1}] {1}"; int level() default TLogger.INFO; diff --git a/src/main/java/com/ilummc/tlib/dependency/TDependency.java b/src/main/java/com/ilummc/tlib/dependency/TDependency.java index 421676d..5488a45 100644 --- a/src/main/java/com/ilummc/tlib/dependency/TDependency.java +++ b/src/main/java/com/ilummc/tlib/dependency/TDependency.java @@ -1,8 +1,9 @@ package com.ilummc.tlib.dependency; import com.ilummc.eagletdl.EagletTask; +import com.ilummc.eagletdl.ProgressEvent; +import com.ilummc.tlib.TLib; import me.skymc.taboolib.Main; -import me.skymc.taboolib.message.MsgUtils; import java.io.File; import java.util.concurrent.atomic.AtomicBoolean; @@ -29,17 +30,17 @@ public class TDependency { *

* 阻塞线程进行下载/加载 * - * @param args 依赖名,格式为 groupId:artifactId:version + * @param type 依赖名,格式为 groupId:artifactId:version * @return 是否成功加载库,如果加载成功,插件将可以任意调用使用的类 */ - public static boolean requestLib(String... args) { - if (args[0].matches(".*:.*:.*")) { - String[] arr = args[0].split(":"); + 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(MAVEN_REPO, arr[0], arr[1], arr[2], file)) { + } else if (downloadMaven(repo, arr[0], arr[1], arr[2], file, url)) { TDependencyLoader.addToPath(Main.getInst(), file); return true; } else return false; @@ -47,30 +48,32 @@ public class TDependency { return false; } - private static boolean downloadMaven(String url, String groupId, String artifactId, String version, File target) { + private static boolean downloadMaven(String url, String groupId, String artifactId, String version, File target, String dl) { ReentrantLock lock = new ReentrantLock(); AtomicBoolean failed = new AtomicBoolean(false); - new EagletTask() - .url(url + "/" + groupId.replace('.', '/') + "/" + artifactId + "/" + version + "/" + artifactId + "-" + version + ".jar") + EagletTask task = new EagletTask() + .url(dl == null ? url + "/" + groupId.replace('.', '/') + "/" + + artifactId + "/" + version + "/" + artifactId + "-" + version + ".jar" : dl) .file(target) .setThreads(8) .setOnStart(event -> lock.lock()) - .setOnProgress(event -> MsgUtils.send(" 下载速度 " + event.getSpeedFormatted())) - .setOnConnected(event -> MsgUtils.send(" 正在下载 " + String.join(":", new String[]{groupId, artifactId, version}) + - " 大小 " + event.getContentLength())) - .setOnError(event -> failed.set(true)) + .setOnConnected(event -> TLib.getTLib().getLogger().info(" 正在下载 " + String.join(":", + new String[]{groupId, artifactId, version}) + + " 大小 " + ProgressEvent.format(event.getContentLength()))) + .setOnProgress(event -> TLib.getTLib().getLogger().info(" 下载速度 " + event.getSpeedFormatted() + + " 进度 " + event.getPercentageFormatted())) .setOnComplete(event -> { + if (event.isSuccess()) { + TLib.getTLib().getLogger().info(" 下载 " + String.join(":", new String[]{groupId, artifactId, version}) + " 完成"); + } else { + failed.set(true); + } lock.unlock(); - MsgUtils.send(" 下载 " + String.join(":", new String[]{groupId, artifactId, version}) + " 完成"); - }) - .start(); - try { - while (lock.tryLock()) lock.unlock(); - } catch (Exception ignored) { - } finally { - lock.lock(); - lock.unlock(); - } + }); + task.start(); + while (lock.tryLock()) lock.unlock(); + lock.lock(); + lock.unlock(); return !failed.get(); } diff --git a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java index 6e1ab86..faca285 100644 --- a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java @@ -1,12 +1,12 @@ package com.ilummc.tlib.inject; +import com.ilummc.tlib.TLib; import com.ilummc.tlib.annotations.Dependencies; import com.ilummc.tlib.annotations.Dependency; import com.ilummc.tlib.annotations.Logger; import com.ilummc.tlib.annotations.PluginInstance; import com.ilummc.tlib.dependency.TDependency; import com.ilummc.tlib.util.TLogger; -import me.skymc.taboolib.message.MsgUtils; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; @@ -19,6 +19,7 @@ public class DependencyInjector { injectLogger(plugin, o); injectPluginInstance(plugin, o); injectDependencies(plugin, o); + injectConfig(plugin, o); } static void injectOnEnable(Plugin plugin) { @@ -29,6 +30,10 @@ public class DependencyInjector { } + private static void injectConfig(Plugin plugin, Object o) { + + } + private static void injectLogger(Plugin plugin, Object o) { try { for (Field field : o.getClass().getDeclaredFields()) { @@ -56,7 +61,7 @@ public class DependencyInjector { Plugin pl; if ((pl = Bukkit.getPluginManager().getPlugin(instance.value())) == null) { if (!TDependency.requestPlugin(instance.value())) { - MsgUtils.warn(plugin.getName() + " 所需的依赖插件 " + instance.value() + " 自动加载失败"); + TLib.getTLib().getLogger().warn(plugin.getName() + " 所需的依赖插件 " + instance.value() + " 自动加载失败"); return; } else { pl = Bukkit.getPluginManager().getPlugin(instance.value()); @@ -79,20 +84,22 @@ public class DependencyInjector { if (d2 != null) dependencies = new Dependency[]{d2}; } if (dependencies.length != 0) { - MsgUtils.send("正在加载 " + plugin.getName() + " 插件所需的依赖"); + TLib.getTLib().getLogger().info("正在加载 " + plugin.getName() + " 插件所需的依赖"); for (Dependency dependency : dependencies) { if (dependency.type() == Dependency.Type.PLUGIN) - if (TDependency.requestPlugin(dependency.args())) - MsgUtils.send(plugin.getName() + " 请求的插件 " + dependency.args()[0] + " 加载成功。"); + if (TDependency.requestPlugin(dependency.plugin())) + TLib.getTLib().getLogger().info(" " + plugin.getName() + " 请求的插件 " + dependency.plugin() + " 加载成功。"); else - MsgUtils.warn(plugin.getName() + " 请求的插件 " + dependency.args()[0] + " 加载失败。"); + TLib.getTLib().getLogger().warn(" " + plugin.getName() + " 请求的插件 " + dependency.plugin() + " 加载失败。"); if (dependency.type() == Dependency.Type.LIBRARY) - if (TDependency.requestLib(dependency.args())) - MsgUtils.send(plugin.getName() + " 请求的库文件 " + String.join(":", dependency.args()) + " 加载成功。"); + if (TDependency.requestLib(dependency.maven(), dependency.mavenRepo(), dependency.url())) + TLib.getTLib().getLogger().info(" " + plugin.getName() + " 请求的库文件 " + String.join(":", + dependency.maven()) + " 加载成功。"); else - MsgUtils.send(plugin.getName() + " 请求的库文件 " + String.join(":", dependency.args()) + " 加载失败。"); + TLib.getTLib().getLogger().warn(" " + plugin.getName() + " 请求的库文件 " + String.join(":", + dependency.maven()) + " 加载失败。"); } - MsgUtils.send("依赖加载完成"); + TLib.getTLib().getLogger().info("依赖加载完成"); } } diff --git a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java new file mode 100644 index 0000000..76921a9 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java @@ -0,0 +1,6 @@ +package com.ilummc.tlib.inject; + +public class TConfigInjector { + + +} diff --git a/src/main/java/com/ilummc/tlib/util/TLogger.java b/src/main/java/com/ilummc/tlib/util/TLogger.java index 88dd23d..5d5aa42 100644 --- a/src/main/java/com/ilummc/tlib/util/TLogger.java +++ b/src/main/java/com/ilummc/tlib/util/TLogger.java @@ -27,37 +27,37 @@ public class TLogger { public void verbose(String msg) { if (level >= VERBOSE) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), msg)); + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§f全部", msg)); } public void finest(String msg) { if (level >= FINEST) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), msg)); + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§e良好", msg)); } public void fine(String msg) { if (level >= FINE) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), msg)); + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§a正常", msg)); } public void info(String msg) { if (level >= INFO) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), msg)); + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§b信息", msg)); } public void warn(String msg) { if (level >= WARN) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), msg)); + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§6警告", msg)); } public void error(String msg) { if (level >= ERROR) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), msg)); + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§c错误", msg)); } public void fatal(String msg) { if (level >= FATAL) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), msg)); + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§4致命错误", msg)); } } From 4bb5df7cbb0998d69a5094034e0cc2490590c571 Mon Sep 17 00:00:00 2001 From: Izzel_Aliz Date: Thu, 5 Apr 2018 13:56:24 +0800 Subject: [PATCH 07/44] =?UTF-8?q?=E6=9A=82=E6=97=B6=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E7=94=A8=E7=9A=84=20@Config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/dictionaries/csh20.xml | 8 + .../java/com/ilummc/tlib/ExampleMain.java | 2 - src/main/java/com/ilummc/tlib/TLib.java | 17 ++ .../com/ilummc/tlib/annotations/Config.java | 7 +- .../ilummc/tlib/annotations/ConfigNode.java | 13 -- .../ilummc/tlib/bean/PropertyTypeAdaptor.java | 16 ++ .../ilummc/tlib/dependency/TDependency.java | 2 +- .../tlib/inject/DependencyInjector.java | 26 ++- .../ilummc/tlib/inject/TConfigInjector.java | 155 ++++++++++++++++++ 9 files changed, 218 insertions(+), 28 deletions(-) create mode 100644 .idea/dictionaries/csh20.xml delete mode 100644 src/main/java/com/ilummc/tlib/annotations/ConfigNode.java create mode 100644 src/main/java/com/ilummc/tlib/bean/PropertyTypeAdaptor.java diff --git a/.idea/dictionaries/csh20.xml b/.idea/dictionaries/csh20.xml new file mode 100644 index 0000000..7fec0b9 --- /dev/null +++ b/.idea/dictionaries/csh20.xml @@ -0,0 +1,8 @@ + + + + unserialize + unserializer + + + \ No newline at end of file diff --git a/src/main/java/com/ilummc/tlib/ExampleMain.java b/src/main/java/com/ilummc/tlib/ExampleMain.java index 46af092..ed4022f 100644 --- a/src/main/java/com/ilummc/tlib/ExampleMain.java +++ b/src/main/java/com/ilummc/tlib/ExampleMain.java @@ -1,7 +1,6 @@ package com.ilummc.tlib; import com.ilummc.tlib.annotations.Config; -import com.ilummc.tlib.annotations.ConfigNode; import com.ilummc.tlib.bean.Property; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; @@ -9,7 +8,6 @@ import org.bukkit.plugin.java.JavaPlugin; @Config(name = "cfg.yml", charset = "GBK") public class ExampleMain extends JavaPlugin { - @ConfigNode("enableUpdate") private Property update = Property.of(false); @Override diff --git a/src/main/java/com/ilummc/tlib/TLib.java b/src/main/java/com/ilummc/tlib/TLib.java index e193b09..f9919a2 100644 --- a/src/main/java/com/ilummc/tlib/TLib.java +++ b/src/main/java/com/ilummc/tlib/TLib.java @@ -1,5 +1,6 @@ package com.ilummc.tlib; +import com.ilummc.tlib.annotations.Config; import com.ilummc.tlib.annotations.Dependency; import com.ilummc.tlib.annotations.Logger; import com.ilummc.tlib.inject.DependencyInjector; @@ -20,9 +21,15 @@ public class TLib { @Logger("§3[§6TLib§3|{1}§3] §f{2}") private TLogger tLogger; + private TLibConfig config; + private TLib() { } + public TLibConfig getConfig() { + return config; + } + public TLogger getLogger() { return tLogger; } @@ -48,4 +55,14 @@ public class TLib { } } + @Config(name = "tlib.yml") + public class TLibConfig { + + private int downloadPoolSize = 4; + + public int getDownloadPoolSize() { + return downloadPoolSize; + } + } + } diff --git a/src/main/java/com/ilummc/tlib/annotations/Config.java b/src/main/java/com/ilummc/tlib/annotations/Config.java index ca16a4f..03b792a 100644 --- a/src/main/java/com/ilummc/tlib/annotations/Config.java +++ b/src/main/java/com/ilummc/tlib/annotations/Config.java @@ -4,6 +4,7 @@ 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) @@ -15,12 +16,10 @@ public @interface Config { boolean saveOnExit() default false; - boolean readOnly() default true; - - boolean fixUnicode() default true; - String charset() default "UTF-8"; boolean listenChanges() default false; + int excludeModifiers() default Modifier.STATIC | Modifier.TRANSIENT; + } diff --git a/src/main/java/com/ilummc/tlib/annotations/ConfigNode.java b/src/main/java/com/ilummc/tlib/annotations/ConfigNode.java deleted file mode 100644 index 7e2478d..0000000 --- a/src/main/java/com/ilummc/tlib/annotations/ConfigNode.java +++ /dev/null @@ -1,13 +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 ConfigNode { - - String value(); -} diff --git a/src/main/java/com/ilummc/tlib/bean/PropertyTypeAdaptor.java b/src/main/java/com/ilummc/tlib/bean/PropertyTypeAdaptor.java new file mode 100644 index 0000000..f802433 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/bean/PropertyTypeAdaptor.java @@ -0,0 +1,16 @@ +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 { + + @Override + public Property deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) throws JsonParseException { + return null; + } +} diff --git a/src/main/java/com/ilummc/tlib/dependency/TDependency.java b/src/main/java/com/ilummc/tlib/dependency/TDependency.java index 5488a45..b4bbcf2 100644 --- a/src/main/java/com/ilummc/tlib/dependency/TDependency.java +++ b/src/main/java/com/ilummc/tlib/dependency/TDependency.java @@ -55,7 +55,7 @@ public class TDependency { .url(dl == null ? url + "/" + groupId.replace('.', '/') + "/" + artifactId + "/" + version + "/" + artifactId + "-" + version + ".jar" : dl) .file(target) - .setThreads(8) + .setThreads(TLib.getTLib().getConfig().getDownloadPoolSize()) .setOnStart(event -> lock.lock()) .setOnConnected(event -> TLib.getTLib().getLogger().info(" 正在下载 " + String.join(":", new String[]{groupId, artifactId, version}) + diff --git a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java index faca285..e09a874 100644 --- a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java @@ -1,10 +1,7 @@ package com.ilummc.tlib.inject; import com.ilummc.tlib.TLib; -import com.ilummc.tlib.annotations.Dependencies; -import com.ilummc.tlib.annotations.Dependency; -import com.ilummc.tlib.annotations.Logger; -import com.ilummc.tlib.annotations.PluginInstance; +import com.ilummc.tlib.annotations.*; import com.ilummc.tlib.dependency.TDependency; import com.ilummc.tlib.util.TLogger; import org.bukkit.Bukkit; @@ -31,12 +28,25 @@ public class DependencyInjector { } private static void injectConfig(Plugin plugin, Object o) { - + for (Field field : o.getClass().getDeclaredFields()) { + try { + Config config; + if ((config = field.getType().getAnnotation(Config.class)) != null) { + field.setAccessible(true); + Object obj = TConfigInjector.loadConfig(plugin, field.getType()); + if (obj != null) { + TLib.getTLib().getLogger().info("插件 " + plugin.getName() + " 的 " + config.name() + " 配置文件成功加载"); + field.set(o, obj); + } + } + } catch (IllegalAccessException ignored) { + } + } } private static void injectLogger(Plugin plugin, Object o) { - try { - for (Field field : o.getClass().getDeclaredFields()) { + for (Field field : o.getClass().getDeclaredFields()) { + try { Logger logger; if ((logger = field.getAnnotation(Logger.class)) != null) { field.getType().asSubclass(TLogger.class); @@ -45,8 +55,8 @@ public class DependencyInjector { field.setAccessible(true); field.set(o, tLogger); } + } catch (Exception ignored) { } - } catch (Exception ignored) { } } diff --git a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java index 76921a9..447484a 100644 --- a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java @@ -1,6 +1,161 @@ package com.ilummc.tlib.inject; +import com.google.common.collect.Lists; +import com.google.common.io.Files; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.SerializedName; +import com.ilummc.tlib.TLib; +import com.ilummc.tlib.annotations.Config; +import com.ilummc.tlib.bean.Property; +import org.apache.commons.lang3.Validate; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.plugin.Plugin; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.nio.charset.Charset; +import java.util.*; +import java.util.stream.Collectors; + public class TConfigInjector { + public static Object loadConfig(Plugin plugin, Class clazz) { + try { + Config config = clazz.getAnnotation(Config.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); + return unserialize(plugin, clazz); + } catch (NullPointerException e) { + TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败:没有 @Config 注解"); + } catch (Exception e) { + TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败"); + } + return null; + } + + public static Object unserialize(Plugin plugin, Class clazz) { + try { + Config config = clazz.getAnnotation(Config.class); + Validate.notNull(config); + return new GsonBuilder().disableHtmlEscaping().excludeFieldsWithModifiers(config.excludeModifiers()) + .create().fromJson(new Gson().toJson(new Yaml() + .dump(Files.toString(new File(plugin.getDataFolder(), config.name()), Charset.forName(config.charset())))), clazz); + } catch (NullPointerException e) { + TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败:没有 @Config 注解"); + return null; + } catch (Exception e) { + try { + return clazz.newInstance(); + } catch (InstantiationException | IllegalAccessException e1) { + TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败"); + return null; + } + } + } + + public static Map serialize(Plugin plugin, Class clazz) { + try { + Constructor constructor = clazz.getConstructor(); + constructor.setAccessible(true); + Config config = clazz.getAnnotation(Config.class); + Validate.notNull(config); + return new Serializer(new LinkedHashMap<>(), constructor.newInstance(), config.excludeModifiers()).get(); + } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { + TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 序列化失败:没有无参构造方法"); + } catch (NullPointerException e) { + TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 序列化失败:没有 @Config 注解"); + } catch (Exception e) { + TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 序列化失败"); + } + return null; + } + + public static void saveConfig(Plugin plugin, Class clazz) throws IOException, NullPointerException { + Object obj = serialize(plugin, clazz); + Validate.notNull(obj); + Config config = clazz.getAnnotation(Config.class); + Validate.notNull(config); + File target = new File(plugin.getDataFolder(), config.name()); + if (!target.exists()) target.createNewFile(); + DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + Yaml yaml = new Yaml(options); + String str = yaml.dump(obj); + byte[] arr = str.getBytes(config.charset()); + Files.write(arr, target); + } + + private static final List primitiveType = Lists.newArrayList(Integer.class, + Double.class, Float.class, Boolean.class, Short.class, Byte.class, Character.class, Long.class, String.class); + + private static class Serializer { + + private HashMap map; + private Object o; + private int modifiers; + + private Serializer(HashMap map, Object o, int modifiers) { + this.map = map; + this.o = o; + this.modifiers = modifiers; + } + + private HashMap get() { + for (Field field : o.getClass().getDeclaredFields()) { + if ((field.getModifiers() & modifiers) == 0 && !field.isSynthetic()) + try { + SerializedName node = field.getAnnotation(SerializedName.class); + if (!field.isAccessible()) field.setAccessible(true); + Object obj = field.get(o); + map.put(node == null ? field.getName() : node.value(), serialize(obj)); + } catch (Exception ignored) { + } + } + return map; + } + + @SuppressWarnings({"unchecked"}) + private Object serialize(Object o) { + try { + if (o.getClass().isPrimitive() || primitiveType.contains(o.getClass())) { + return o; + } else if (o.getClass().isArray()) { + List list = new ArrayList(); + int len = (int) o.getClass().getField("length").get(o); + for (int i = 0; i < len; i++) { + list.add(serialize(Array.get(o, i))); + } + return list; + } else if (o instanceof Collection) { + return ((Collection) o).stream().map(this::serialize).collect(Collectors.toList()); + } else if (o instanceof Map) { + Map map = new LinkedHashMap<>(); + ((Map) o).forEach((o1, o2) -> map.put((String) o1, serialize(o2))); + return map; + } else if (o instanceof ConfigurationSerializable) { + Map map = new LinkedHashMap(); + map.put("==", o.getClass().getName()); + map.putAll(((ConfigurationSerializable) o).serialize()); + return map; + } else if (o instanceof Property) { + return serialize(((Property) o).get()); + } else { + return new Serializer(new HashMap<>(), o, modifiers).get(); + } + } catch (Exception ignored) { + return null; + } + } + + } } From d8f8ffc5a3248ba9e7f26ee29cbe3c3ee83c248d Mon Sep 17 00:00:00 2001 From: Izzel_Aliz Date: Fri, 6 Apr 2018 15:09:36 +0800 Subject: [PATCH 08/44] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=8F=8A=E6=96=87=E4=BB=B6=E7=9B=91=E5=90=AC=E5=8F=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/ilummc/tlib/TLib.java | 16 ++++- .../tlib/inject/DependencyInjector.java | 40 +++++++++++++ .../ilummc/tlib/inject/TConfigInjector.java | 30 ++++------ .../ilummc/tlib/inject/TConfigWatcher.java | 59 +++++++++++++++++++ .../ilummc/tlib/inject/TLibPluginManager.java | 8 ++- .../java/com/ilummc/tlib/util/TLogger.java | 14 ++--- src/main/java/me/skymc/taboolib/Main.java | 2 + 7 files changed, 142 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java diff --git a/src/main/java/com/ilummc/tlib/TLib.java b/src/main/java/com/ilummc/tlib/TLib.java index f9919a2..435af77 100644 --- a/src/main/java/com/ilummc/tlib/TLib.java +++ b/src/main/java/com/ilummc/tlib/TLib.java @@ -4,6 +4,7 @@ import com.ilummc.tlib.annotations.Config; import com.ilummc.tlib.annotations.Dependency; import com.ilummc.tlib.annotations.Logger; import com.ilummc.tlib.inject.DependencyInjector; +import com.ilummc.tlib.inject.TConfigWatcher; import com.ilummc.tlib.inject.TLibPluginManager; import com.ilummc.tlib.util.TLogger; import me.skymc.taboolib.Main; @@ -23,6 +24,8 @@ public class TLib { private TLibConfig config; + private TConfigWatcher configWatcher = new TConfigWatcher(); + private TLib() { } @@ -34,6 +37,10 @@ public class TLib { return tLogger; } + public TConfigWatcher getConfigWatcher() { + return configWatcher; + } + public static TLib getTLib() { return tLib; } @@ -55,8 +62,13 @@ public class TLib { } } - @Config(name = "tlib.yml") - public class TLibConfig { + public static void unload() { + tLib.getConfigWatcher().unregisterAll(); + DependencyInjector.eject(Main.getInst(), tLib); + } + + @Config(name = "tlib.yml", listenChanges = true) + public static class TLibConfig { private int downloadPoolSize = 4; diff --git a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java index e09a874..e3e71e3 100644 --- a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java @@ -8,6 +8,8 @@ import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; +import java.io.File; +import java.io.IOException; import java.lang.reflect.Field; public class DependencyInjector { @@ -24,7 +26,26 @@ public class DependencyInjector { } static void onDisable(Plugin plugin) { + ejectConfig(plugin, plugin); + } + public static void eject(Plugin plugin, Object o) { + ejectConfig(plugin, o); + } + + private static void ejectConfig(Plugin plugin, Object o) { + for (Field field : o.getClass().getDeclaredFields()) { + Config config; + if ((config = field.getType().getAnnotation(Config.class)) != null) { + try { + field.setAccessible(true); + TConfigInjector.saveConfig(plugin, o); + TLib.getTLib().getLogger().info("插件 " + plugin + " 的配置 " + config.name() + " 已保存"); + } catch (IOException e) { + TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置 " + config.name() + " 保存失败"); + } + } + } } private static void injectConfig(Plugin plugin, Object o) { @@ -37,6 +58,25 @@ public class DependencyInjector { if (obj != null) { TLib.getTLib().getLogger().info("插件 " + plugin.getName() + " 的 " + config.name() + " 配置文件成功加载"); field.set(o, obj); + if (config.listenChanges()) { + TLib.getTLib().getLogger().info("开始监听插件 " + plugin.getName() + " 的 " + config.name() + " 配置文件"); + TLib.getTLib().getConfigWatcher().addOnListen( + new File(plugin.getDataFolder(), config.name()), + obj, + object -> { + try { + Object newObj = TConfigInjector.loadConfig(plugin, object.getClass()); + for (Field f : newObj.getClass().getDeclaredFields()) { + f.setAccessible(true); + f.set(obj, f.get(newObj)); + } + TLib.getTLib().getLogger().info("插件 " + plugin.getName() + " 的 " + config.name() + " 配置文件成功重载"); + } catch (Exception ignored) { + TLib.getTLib().getLogger().warn("插件 " + plugin.getName() + " 的 " + config.name() + " 配置文件重载时发生错误"); + } + } + ); + } } } } catch (IllegalAccessException ignored) { diff --git a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java index 447484a..f599646 100644 --- a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java @@ -10,6 +10,7 @@ import com.ilummc.tlib.annotations.Config; import com.ilummc.tlib.bean.Property; import org.apache.commons.lang3.Validate; import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.ConfigurationSerialization; import org.bukkit.plugin.Plugin; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; @@ -17,9 +18,7 @@ import org.yaml.snakeyaml.Yaml; import java.io.File; import java.io.IOException; import java.lang.reflect.Array; -import java.lang.reflect.Constructor; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.nio.charset.Charset; import java.util.*; import java.util.stream.Collectors; @@ -50,7 +49,7 @@ public class TConfigInjector { .create().fromJson(new Gson().toJson(new Yaml() .dump(Files.toString(new File(plugin.getDataFolder(), config.name()), Charset.forName(config.charset())))), clazz); } catch (NullPointerException e) { - TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败:没有 @Config 注解"); + TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败:没有 @Config 注解或文件不存在"); return null; } catch (Exception e) { try { @@ -62,28 +61,24 @@ public class TConfigInjector { } } - public static Map serialize(Plugin plugin, Class clazz) { + public static Map serialize(Plugin plugin, Object object) { try { - Constructor constructor = clazz.getConstructor(); - constructor.setAccessible(true); - Config config = clazz.getAnnotation(Config.class); + Config config = object.getClass().getAnnotation(Config.class); Validate.notNull(config); - return new Serializer(new LinkedHashMap<>(), constructor.newInstance(), config.excludeModifiers()).get(); - } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { - TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 序列化失败:没有无参构造方法"); + return new Serializer(new LinkedHashMap<>(), object, config.excludeModifiers()).get(); } catch (NullPointerException e) { - TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 序列化失败:没有 @Config 注解"); + TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + object.getClass().getSimpleName() + " 序列化失败:没有 @Config 注解"); } catch (Exception e) { - TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 序列化失败"); + TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + object.getClass().getSimpleName() + " 序列化失败"); } return null; } - public static void saveConfig(Plugin plugin, Class clazz) throws IOException, NullPointerException { - Object obj = serialize(plugin, clazz); - Validate.notNull(obj); - Config config = clazz.getAnnotation(Config.class); + public static void saveConfig(Plugin plugin, Object object) throws IOException, NullPointerException { + Config config = object.getClass().getAnnotation(Config.class); Validate.notNull(config); + Object obj = serialize(plugin, object); + Validate.notNull(obj); File target = new File(plugin.getDataFolder(), config.name()); if (!target.exists()) target.createNewFile(); DumperOptions options = new DumperOptions(); @@ -143,7 +138,8 @@ public class TConfigInjector { return map; } else if (o instanceof ConfigurationSerializable) { Map map = new LinkedHashMap(); - map.put("==", o.getClass().getName()); + map.put(ConfigurationSerialization.SERIALIZED_TYPE_KEY, + ConfigurationSerialization.getAlias((Class) o.getClass())); map.putAll(((ConfigurationSerializable) o).serialize()); return map; } else if (o instanceof Property) { diff --git a/src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java b/src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java new file mode 100644 index 0000000..8327b96 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java @@ -0,0 +1,59 @@ +package com.ilummc.tlib.inject; + +import com.ilummc.tlib.TLib; +import org.apache.commons.lang3.tuple.Triple; + +import java.io.File; +import java.io.IOException; +import java.nio.file.*; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +public class TConfigWatcher { + + private ScheduledExecutorService service = Executors.newScheduledThreadPool(1); + + private Map>> map = new HashMap<>(); + + public TConfigWatcher() { + service.scheduleAtFixedRate(() -> { + map.forEach((service, triple) -> { + WatchKey key; + while ((key = service.poll()) != null) { + for (WatchEvent watchEvent : key.pollEvents()) { + if (triple.getLeft().getName().equals(Objects.toString(watchEvent.context()))) + triple.getRight().accept(triple.getMiddle()); + } + key.reset(); + } + }); + }, 1000, 100, TimeUnit.MILLISECONDS); + } + + public void addOnListen(File file, Object obj, Consumer consumer) { + try { + WatchService service = FileSystems.getDefault().newWatchService(); + file.getParentFile().toPath().register(service, StandardWatchEventKinds.ENTRY_MODIFY); + map.put(service, Triple.of(file, obj, consumer)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void unregisterAll() { + service.shutdown(); + map.forEach((service, pair) -> { + try { + service.close(); + } catch (IOException e) { + e.printStackTrace(); + } + }); + } + +} diff --git a/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java b/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java index f8a22f6..42f640d 100644 --- a/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java +++ b/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java @@ -1,5 +1,6 @@ package com.ilummc.tlib.inject; +import me.skymc.taboolib.Main; import org.bukkit.Bukkit; import org.bukkit.event.Event; import org.bukkit.event.EventPriority; @@ -15,6 +16,8 @@ public class TLibPluginManager implements PluginManager { private final PluginManager instance; + private final Main main = (Main) Main.getInst(); + public TLibPluginManager() { instance = Bukkit.getPluginManager(); } @@ -56,7 +59,10 @@ public class TLibPluginManager implements PluginManager { @Override public void disablePlugins() { - instance.disablePlugins(); + for (Plugin plugin : getPlugins()) { + if (plugin != main) disablePlugin(plugin); + } + disablePlugin(main); } @Override diff --git a/src/main/java/com/ilummc/tlib/util/TLogger.java b/src/main/java/com/ilummc/tlib/util/TLogger.java index 5d5aa42..e2f7bcb 100644 --- a/src/main/java/com/ilummc/tlib/util/TLogger.java +++ b/src/main/java/com/ilummc/tlib/util/TLogger.java @@ -26,37 +26,37 @@ public class TLogger { } public void verbose(String msg) { - if (level >= VERBOSE) + if (level <= VERBOSE) Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§f全部", msg)); } public void finest(String msg) { - if (level >= FINEST) + if (level <= FINEST) Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§e良好", msg)); } public void fine(String msg) { - if (level >= FINE) + if (level <= FINE) Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§a正常", msg)); } public void info(String msg) { - if (level >= INFO) + if (level <= INFO) Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§b信息", msg)); } public void warn(String msg) { - if (level >= WARN) + if (level <= WARN) Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§6警告", msg)); } public void error(String msg) { - if (level >= ERROR) + if (level <= ERROR) Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§c错误", msg)); } public void fatal(String msg) { - if (level >= FATAL) + if (level <= FATAL) Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§4致命错误", msg)); } diff --git a/src/main/java/me/skymc/taboolib/Main.java b/src/main/java/me/skymc/taboolib/Main.java index 2546d2c..f1733da 100644 --- a/src/main/java/me/skymc/taboolib/Main.java +++ b/src/main/java/me/skymc/taboolib/Main.java @@ -274,6 +274,8 @@ public class Main extends JavaPlugin implements Listener { if (connection != null && connection.isConnection()) { connection.closeConnection(); } + + TLib.unload(); // 关闭服务器 Bukkit.shutdown(); From b22ade7cff03bee84b65a4d4116da77daa04c764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9D=8F=E9=BB=91?= Date: Sat, 7 Apr 2018 21:53:09 +0800 Subject: [PATCH 09/44] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/ilummc/tlib/TLib.java | 3 +- .../ilummc/tlib/dependency/TDependency.java | 22 +++++--- .../tlib/inject/DependencyInjector.java | 51 ++++++++++--------- .../ilummc/tlib/inject/TConfigInjector.java | 10 ++-- .../java/com/ilummc/tlib/util/TLogger.java | 6 +-- src/main/java/me/skymc/taboolib/Main.java | 20 +++----- .../skymc/taboolib/inventory/ItemUtils.java | 11 ++-- .../string/language2/Language2Format.java | 21 ++++---- src/main/resources/config.yml | 4 ++ 9 files changed, 82 insertions(+), 66 deletions(-) diff --git a/src/main/java/com/ilummc/tlib/TLib.java b/src/main/java/com/ilummc/tlib/TLib.java index 435af77..8a5ac8a 100644 --- a/src/main/java/com/ilummc/tlib/TLib.java +++ b/src/main/java/com/ilummc/tlib/TLib.java @@ -19,7 +19,7 @@ public class TLib { private static TLib tLib; - @Logger("§3[§6TLib§3|{1}§3] §f{2}") + @Logger("§8[§3§lTabooLib§8][§r{1}§8] §f{2}") private TLogger tLogger; private TLibConfig config; @@ -45,7 +45,6 @@ public class TLib { return tLib; } - @SuppressWarnings({"unchecked"}) public static void init() { new File(Main.getInst().getDataFolder(), "/libs").mkdirs(); tLib = new TLib(); diff --git a/src/main/java/com/ilummc/tlib/dependency/TDependency.java b/src/main/java/com/ilummc/tlib/dependency/TDependency.java index b4bbcf2..e15e975 100644 --- a/src/main/java/com/ilummc/tlib/dependency/TDependency.java +++ b/src/main/java/com/ilummc/tlib/dependency/TDependency.java @@ -40,20 +40,30 @@ public class TDependency { 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; + } else { + boolean downloadFinish = false; + try { + downloadFinish = downloadMaven(repo, arr[0], arr[1], arr[2], file, url); + } catch (Exception ignored) { + } + if (downloadFinish) { + TDependencyLoader.addToPath(Main.getInst(), file); + } + return downloadFinish; + } } return false; } private static boolean downloadMaven(String url, String groupId, String artifactId, String version, File target, String dl) { + if (Main.getInst().getConfig().getBoolean("OFFLINE-MODE")) { + TLib.getTLib().getLogger().warn("已启用离线模式, 将不会下载第三方依赖库"); + return false; + } ReentrantLock lock = new ReentrantLock(); AtomicBoolean failed = new AtomicBoolean(false); EagletTask task = new EagletTask() - .url(dl == null ? url + "/" + groupId.replace('.', '/') + "/" + - artifactId + "/" + version + "/" + artifactId + "-" + version + ".jar" : dl) + .url(dl == null ? url + "/" + groupId.replace('.', '/') + "/" + artifactId + "/" + version + "/" + artifactId + "-" + version + ".jar" : dl) .file(target) .setThreads(TLib.getTLib().getConfig().getDownloadPoolSize()) .setOnStart(event -> lock.lock()) diff --git a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java index e3e71e3..dc98f4c 100644 --- a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java @@ -15,10 +15,10 @@ import java.lang.reflect.Field; public class DependencyInjector { public static void inject(Plugin plugin, Object o) { - injectLogger(plugin, o); - injectPluginInstance(plugin, o); - injectDependencies(plugin, o); - injectConfig(plugin, o); + injectLogger(plugin, o); + injectPluginInstance(plugin, o); + injectDependencies(plugin, o); + injectConfig(plugin, o); } static void injectOnEnable(Plugin plugin) { @@ -41,7 +41,7 @@ public class DependencyInjector { field.setAccessible(true); TConfigInjector.saveConfig(plugin, o); TLib.getTLib().getLogger().info("插件 " + plugin + " 的配置 " + config.name() + " 已保存"); - } catch (IOException e) { + } catch (Exception e) { TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置 " + config.name() + " 保存失败"); } } @@ -85,9 +85,9 @@ public class DependencyInjector { } private static void injectLogger(Plugin plugin, Object o) { - for (Field field : o.getClass().getDeclaredFields()) { - try { - Logger logger; + for (Field field : o.getClass().getDeclaredFields()) { + try { + Logger logger; if ((logger = field.getAnnotation(Logger.class)) != null) { field.getType().asSubclass(TLogger.class); TLogger tLogger = new TLogger(logger.value(), plugin, logger.level()); @@ -97,7 +97,7 @@ public class DependencyInjector { } } catch (Exception ignored) { } - } + } } private static void injectPluginInstance(Plugin plugin, Object o) { @@ -126,28 +126,33 @@ public class DependencyInjector { } private static void injectDependencies(Plugin plugin, Object o) { - Dependency[] dependencies = new Dependency[0]; - { + Dependency[] dependencies = new Dependency[0]; { Dependencies d = o.getClass().getAnnotation(Dependencies.class); - if (d != null) dependencies = d.value(); + if (d != null) { + dependencies = d.value(); + } Dependency d2 = o.getClass().getAnnotation(Dependency.class); - if (d2 != null) dependencies = new Dependency[]{d2}; + if (d2 != null) { + dependencies = new Dependency[]{d2}; + } } if (dependencies.length != 0) { TLib.getTLib().getLogger().info("正在加载 " + plugin.getName() + " 插件所需的依赖"); for (Dependency dependency : dependencies) { - if (dependency.type() == Dependency.Type.PLUGIN) - if (TDependency.requestPlugin(dependency.plugin())) + if (dependency.type() == Dependency.Type.PLUGIN) { + if (TDependency.requestPlugin(dependency.plugin())) { TLib.getTLib().getLogger().info(" " + plugin.getName() + " 请求的插件 " + dependency.plugin() + " 加载成功。"); - else + } else { TLib.getTLib().getLogger().warn(" " + plugin.getName() + " 请求的插件 " + dependency.plugin() + " 加载失败。"); - if (dependency.type() == Dependency.Type.LIBRARY) - if (TDependency.requestLib(dependency.maven(), dependency.mavenRepo(), dependency.url())) - TLib.getTLib().getLogger().info(" " + plugin.getName() + " 请求的库文件 " + String.join(":", - dependency.maven()) + " 加载成功。"); - else - TLib.getTLib().getLogger().warn(" " + plugin.getName() + " 请求的库文件 " + String.join(":", - dependency.maven()) + " 加载失败。"); + } + } + if (dependency.type() == Dependency.Type.LIBRARY) { + if (TDependency.requestLib(dependency.maven(), dependency.mavenRepo(), dependency.url())) { + TLib.getTLib().getLogger().info(" " + plugin.getName() + " 请求的库文件 " + String.join(":", dependency.maven()) + " 加载成功。"); + } else { + TLib.getTLib().getLogger().warn(" " + plugin.getName() + " 请求的库文件 " + String.join(":", dependency.maven()) + " 加载失败。"); + } + } } TLib.getTLib().getLogger().info("依赖加载完成"); } diff --git a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java index f599646..4d1c0e0 100644 --- a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java @@ -89,7 +89,7 @@ public class TConfigInjector { Files.write(arr, target); } - private static final List primitiveType = Lists.newArrayList(Integer.class, + private static final List> primitiveType = Lists.newArrayList(Integer.class, Double.class, Float.class, Boolean.class, Short.class, Byte.class, Character.class, Long.class, String.class); private static class Serializer { @@ -118,13 +118,13 @@ public class TConfigInjector { return map; } - @SuppressWarnings({"unchecked"}) + @SuppressWarnings({"unchecked", "rawtypes"}) private Object serialize(Object o) { try { if (o.getClass().isPrimitive() || primitiveType.contains(o.getClass())) { return o; } else if (o.getClass().isArray()) { - List list = new ArrayList(); + List list = new ArrayList<>(); int len = (int) o.getClass().getField("length").get(o); for (int i = 0; i < len; i++) { list.add(serialize(Array.get(o, i))); @@ -133,11 +133,11 @@ public class TConfigInjector { } else if (o instanceof Collection) { return ((Collection) o).stream().map(this::serialize).collect(Collectors.toList()); } else if (o instanceof Map) { - Map map = new LinkedHashMap<>(); + Map map = new LinkedHashMap<>(); ((Map) o).forEach((o1, o2) -> map.put((String) o1, serialize(o2))); return map; } else if (o instanceof ConfigurationSerializable) { - Map map = new LinkedHashMap(); + Map map = new LinkedHashMap<>(); map.put(ConfigurationSerialization.SERIALIZED_TYPE_KEY, ConfigurationSerialization.getAlias((Class) o.getClass())); map.putAll(((ConfigurationSerializable) o).serialize()); diff --git a/src/main/java/com/ilummc/tlib/util/TLogger.java b/src/main/java/com/ilummc/tlib/util/TLogger.java index e2f7bcb..325e430 100644 --- a/src/main/java/com/ilummc/tlib/util/TLogger.java +++ b/src/main/java/com/ilummc/tlib/util/TLogger.java @@ -47,17 +47,17 @@ public class TLogger { public void warn(String msg) { if (level <= WARN) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§6警告", msg)); + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§6警告", "§6" + msg)); } public void error(String msg) { if (level <= ERROR) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§c错误", msg)); + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§c错误", "§c" + msg)); } public void fatal(String msg) { if (level <= FATAL) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§4致命错误", msg)); + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§4致命错误", "§4" + msg)); } } diff --git a/src/main/java/me/skymc/taboolib/Main.java b/src/main/java/me/skymc/taboolib/Main.java index f1733da..7cf75c6 100644 --- a/src/main/java/me/skymc/taboolib/Main.java +++ b/src/main/java/me/skymc/taboolib/Main.java @@ -64,8 +64,6 @@ public class Main extends JavaPlugin implements Listener { @Getter private static File serverDataFolder; @Getter - private static File docsFolder; - @Getter private static StorageType storageType; @Getter private static boolean disable = false; @@ -105,14 +103,12 @@ public class Main extends JavaPlugin implements Listener { @Override public void onLoad() { inst = this; disable = false; - - TLib.init(); - - // 启动监控 - new Metrics(this); - // 载入配置 saveDefaultConfig(); + + // 加载依赖 + TLib.init(); + // 载入目录 setupDataFolder(); // 注册配置 @@ -218,6 +214,8 @@ public class Main extends JavaPlugin implements Listener { // 更新检测 new UpdateTask(); + // 启动监控 + new Metrics(this); // 启动 started = true; @@ -286,16 +284,10 @@ public class Main extends JavaPlugin implements Listener { if (!playerDataFolder.exists()) { playerDataFolder.mkdirs(); } - serverDataFolder = new File(getConfig().getString("DATAURL.SERVER-DATA")); if (!serverDataFolder.exists()) { serverDataFolder.mkdirs(); } - - docsFolder = new File(getDataFolder(), "Document"); - if (!docsFolder.exists()) { - docsFolder.mkdirs(); - } } private void registerListener() { diff --git a/src/main/java/me/skymc/taboolib/inventory/ItemUtils.java b/src/main/java/me/skymc/taboolib/inventory/ItemUtils.java index 299884f..5f4420b 100644 --- a/src/main/java/me/skymc/taboolib/inventory/ItemUtils.java +++ b/src/main/java/me/skymc/taboolib/inventory/ItemUtils.java @@ -76,9 +76,13 @@ public class ItemUtils { } public static void LoadLib() { - itemdir = YamlConfiguration.loadConfiguration(new File(Main.getInst().getConfig().getString("DATAURL.ITEMDIR"))); - reloadItemName(); - reloadItemCache(); + try { + reloadItemName(); + reloadItemCache(); + itemdir = YamlConfiguration.loadConfiguration(new File(Main.getInst().getConfig().getString("DATAURL.ITEMDIR"))); + } catch (Exception e) { + MsgUtils.warn("物品库载入失败: &4" + e.getMessage()); + } } public static void loadItemsFile(File file, boolean finalFile) { @@ -135,7 +139,6 @@ public class ItemUtils { return item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName() : itemlib.get(item.getType() + ":" + data) == null ? item.getType().toString() : itemlib.get(item.getType() + ":" + data); } - @SuppressWarnings("deprecation") public static ItemStack getItemFromDir(String name) { if (itemdir != null) { return itemdir.getItemStack("item." + name); diff --git a/src/main/java/me/skymc/taboolib/string/language2/Language2Format.java b/src/main/java/me/skymc/taboolib/string/language2/Language2Format.java index b5bd00d..ccb1dff 100644 --- a/src/main/java/me/skymc/taboolib/string/language2/Language2Format.java +++ b/src/main/java/me/skymc/taboolib/string/language2/Language2Format.java @@ -2,6 +2,8 @@ package me.skymc.taboolib.string.language2; import lombok.Getter; import me.skymc.taboolib.string.language2.value.*; + +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import java.util.ArrayList; @@ -100,40 +102,41 @@ public class Language2Format implements Language2Line { private void parseValue(Player player, List list, Language2Type type) { if (list.size() == 0) { return; - } + } // 变量转换 - list = language2Value.setPlaceholder(list, player); + List listPlaceholder = language2Value.setPlaceholder(list, player); // 大标题 switch (type) { case TITLE: - language2Lines.add(new Language2Title(this, list)); + language2Lines.add(new Language2Title(this, listPlaceholder)); break; // 小标题 case ACTION: - language2Lines.add(new Language2Action(this, list)); + language2Lines.add(new Language2Action(this, listPlaceholder)); break; // JSON case JSON: - language2Lines.add(new Language2Json(this, list, player)); + language2Lines.add(new Language2Json(this, listPlaceholder, player)); break; // JSON2 case JSON2: - language2Lines.add(new Language2Json2(this, list, player)); + language2Lines.add(new Language2Json2(this, listPlaceholder, player)); break; // 音效 case SOUND: - language2Lines.add(new Language2Sound(this, list)); + language2Lines.add(new Language2Sound(this, listPlaceholder)); break; // 书本 case BOOK: - language2Lines.add(new Language2Book(this, list, player)); + language2Lines.add(new Language2Book(this, listPlaceholder, player)); break; default: - language2Lines.add(new Language2Text(this, list)); + language2Lines.add(new Language2Text(this, listPlaceholder)); break; } // 清理数据 list.clear(); + listPlaceholder.clear(); } @Override diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index e819d77..eff92f7 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -17,6 +17,10 @@ DATAURL: # 启用后将收到来自其他插件的调试信息 DEBUG: false +# 是否启用离线模式 +# 离线模式下将不会下载依赖 +OFFLINE-MODE: false + # 是否启用更新检测 UPDATE-CHECK: true From 7758ac22411641763dd2dd62d73be99a4494298b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9D=8F=E9=BB=91?= Date: Sat, 7 Apr 2018 23:16:25 +0800 Subject: [PATCH 10/44] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E5=87=A0?= =?UTF-8?q?=E4=B8=AA=E5=8A=A0=E8=BD=BD=E6=8F=92=E4=BB=B6=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/ilummc/tlib/TLib.java | 3 +- .../ilummc/tlib/dependency/TDependency.java | 3 +- .../tlib/inject/DependencyInjector.java | 47 +++++++++++++------ 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/ilummc/tlib/TLib.java b/src/main/java/com/ilummc/tlib/TLib.java index 8a5ac8a..f16f01c 100644 --- a/src/main/java/com/ilummc/tlib/TLib.java +++ b/src/main/java/com/ilummc/tlib/TLib.java @@ -22,7 +22,7 @@ public class TLib { @Logger("§8[§3§lTabooLib§8][§r{1}§8] §f{2}") private TLogger tLogger; - private TLibConfig config; + private TLibConfig config = new TLibConfig(); private TConfigWatcher configWatcher = new TConfigWatcher(); @@ -75,5 +75,4 @@ public class TLib { return downloadPoolSize; } } - } diff --git a/src/main/java/com/ilummc/tlib/dependency/TDependency.java b/src/main/java/com/ilummc/tlib/dependency/TDependency.java index e15e975..3987e25 100644 --- a/src/main/java/com/ilummc/tlib/dependency/TDependency.java +++ b/src/main/java/com/ilummc/tlib/dependency/TDependency.java @@ -45,6 +45,7 @@ public class TDependency { try { downloadFinish = downloadMaven(repo, arr[0], arr[1], arr[2], file, url); } catch (Exception ignored) { + ignored.printStackTrace(); } if (downloadFinish) { TDependencyLoader.addToPath(Main.getInst(), file); @@ -63,7 +64,7 @@ public class TDependency { ReentrantLock lock = new ReentrantLock(); AtomicBoolean failed = new AtomicBoolean(false); EagletTask task = new EagletTask() - .url(dl == null ? url + "/" + groupId.replace('.', '/') + "/" + artifactId + "/" + version + "/" + artifactId + "-" + version + ".jar" : dl) + .url(dl.length() == 0 ? url + "/" + groupId.replace('.', '/') + "/" + artifactId + "/" + version + "/" + artifactId + "-" + version + ".jar" : dl) .file(target) .setThreads(TLib.getTLib().getConfig().getDownloadPoolSize()) .setOnStart(event -> lock.lock()) diff --git a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java index dc98f4c..bcf97e8 100644 --- a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java @@ -9,16 +9,27 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import java.io.File; -import java.io.IOException; import java.lang.reflect.Field; public class DependencyInjector { public static void inject(Plugin plugin, Object o) { - injectLogger(plugin, o); - injectPluginInstance(plugin, o); - injectDependencies(plugin, o); - injectConfig(plugin, o); + try { + injectConfig(plugin, o); + } catch (NoClassDefFoundError ignored) { + } + try { + injectLogger(plugin, o); + } catch (NoClassDefFoundError ignored) { + } + try { + injectPluginInstance(plugin, o); + } catch (NoClassDefFoundError ignored) { + } + try { + injectDependencies(plugin, o); + } catch (NoClassDefFoundError ignored) { + } } static void injectOnEnable(Plugin plugin) { @@ -26,11 +37,17 @@ public class DependencyInjector { } static void onDisable(Plugin plugin) { - ejectConfig(plugin, plugin); + try { + ejectConfig(plugin, plugin); + } catch (NoClassDefFoundError ignored) { + } } public static void eject(Plugin plugin, Object o) { - ejectConfig(plugin, o); + try { + ejectConfig(plugin, o); + } catch (NoClassDefFoundError ignored) { + } } private static void ejectConfig(Plugin plugin, Object o) { @@ -79,7 +96,7 @@ public class DependencyInjector { } } } - } catch (IllegalAccessException ignored) { + } catch (Exception ignored) { } } } @@ -95,15 +112,15 @@ public class DependencyInjector { field.setAccessible(true); field.set(o, tLogger); } - } catch (Exception ignored) { - } + } catch (Exception ignored2) { + } } } private static void injectPluginInstance(Plugin plugin, Object o) { - try { - for (Field field : o.getClass().getDeclaredFields()) { - PluginInstance instance; + for (Field field : o.getClass().getDeclaredFields()) { + try { + PluginInstance instance; if ((instance = field.getAnnotation(PluginInstance.class)) != null) { if (!field.isAccessible()) field.setAccessible(true); @@ -120,8 +137,8 @@ public class DependencyInjector { if (pl != null) field.set(o, pl); } - } - } catch (Exception ignored) { + } catch (Exception ignored) { + } } } From 33905330f3c717dc53b5ec4cda36c8e9427cce07 Mon Sep 17 00:00:00 2001 From: Izzel_Aliz Date: Sun, 8 Apr 2018 22:42:31 +0800 Subject: [PATCH 11/44] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=8A=A0=E8=BD=BD=E5=92=8C=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/ilummc/tlib/TLib.java | 2 +- .../ilummc/tlib/dependency/TDependency.java | 30 ++++---- .../tlib/inject/DependencyInjector.java | 77 +++++++++---------- .../ilummc/tlib/inject/TConfigInjector.java | 2 +- 4 files changed, 55 insertions(+), 56 deletions(-) diff --git a/src/main/java/com/ilummc/tlib/TLib.java b/src/main/java/com/ilummc/tlib/TLib.java index f16f01c..c7d2216 100644 --- a/src/main/java/com/ilummc/tlib/TLib.java +++ b/src/main/java/com/ilummc/tlib/TLib.java @@ -22,7 +22,7 @@ public class TLib { @Logger("§8[§3§lTabooLib§8][§r{1}§8] §f{2}") private TLogger tLogger; - private TLibConfig config = new TLibConfig(); + private TLibConfig config; private TConfigWatcher configWatcher = new TConfigWatcher(); diff --git a/src/main/java/com/ilummc/tlib/dependency/TDependency.java b/src/main/java/com/ilummc/tlib/dependency/TDependency.java index 3987e25..8ce20c5 100644 --- a/src/main/java/com/ilummc/tlib/dependency/TDependency.java +++ b/src/main/java/com/ilummc/tlib/dependency/TDependency.java @@ -41,33 +41,31 @@ public class TDependency { TDependencyLoader.addToPath(Main.getInst(), file); return true; } else { - boolean downloadFinish = false; - try { - downloadFinish = downloadMaven(repo, arr[0], arr[1], arr[2], file, url); - } catch (Exception ignored) { - ignored.printStackTrace(); - } - if (downloadFinish) { - TDependencyLoader.addToPath(Main.getInst(), file); - } - return downloadFinish; + 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.getInst().getConfig().getBoolean("OFFLINE-MODE")) { - TLib.getTLib().getLogger().warn("已启用离线模式, 将不会下载第三方依赖库"); - return false; - } + if (Main.getInst().getConfig().getBoolean("OFFLINE-MODE")) { + TLib.getTLib().getLogger().warn("已启用离线模式, 将不会下载第三方依赖库"); + return false; + } ReentrantLock lock = new ReentrantLock(); AtomicBoolean failed = new AtomicBoolean(false); + String link = dl.length() == 0 ? url + "/" + groupId.replace('.', '/') + "/" + artifactId + "/" + version + "/" + artifactId + "-" + version + ".jar" : dl; EagletTask task = new EagletTask() - .url(dl.length() == 0 ? url + "/" + groupId.replace('.', '/') + "/" + artifactId + "/" + version + "/" + artifactId + "-" + version + ".jar" : dl) + .url(link) .file(target) .setThreads(TLib.getTLib().getConfig().getDownloadPoolSize()) .setOnStart(event -> lock.lock()) + .setOnError(event -> { + }) .setOnConnected(event -> TLib.getTLib().getLogger().info(" 正在下载 " + String.join(":", new String[]{groupId, artifactId, version}) + " 大小 " + ProgressEvent.format(event.getContentLength()))) @@ -78,6 +76,8 @@ public class TDependency { TLib.getTLib().getLogger().info(" 下载 " + String.join(":", new String[]{groupId, artifactId, version}) + " 完成"); } else { failed.set(true); + TLib.getTLib().getLogger().error(" 下载 " + String.join(":", new String[]{groupId, artifactId, version}) + " 失败"); + TLib.getTLib().getLogger().error(" 请手动下载 " + link + " 并重命名为 " + target.getName() + " 后放在 /TabooLib/libs 文件夹内"); } lock.unlock(); }); diff --git a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java index bcf97e8..adb3499 100644 --- a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java @@ -14,22 +14,22 @@ import java.lang.reflect.Field; public class DependencyInjector { public static void inject(Plugin plugin, Object o) { - try { - injectConfig(plugin, o); - } catch (NoClassDefFoundError ignored) { - } - try { - injectLogger(plugin, o); - } catch (NoClassDefFoundError ignored) { - } - try { - injectPluginInstance(plugin, o); - } catch (NoClassDefFoundError ignored) { - } - try { - injectDependencies(plugin, o); - } catch (NoClassDefFoundError ignored) { - } + try { + injectLogger(plugin, o); + } catch (NoClassDefFoundError ignored) { + } + try { + injectConfig(plugin, o); + } catch (NoClassDefFoundError ignored) { + } + try { + injectPluginInstance(plugin, o); + } catch (NoClassDefFoundError ignored) { + } + try { + injectDependencies(plugin, o); + } catch (NoClassDefFoundError ignored) { + } } static void injectOnEnable(Plugin plugin) { @@ -37,17 +37,14 @@ public class DependencyInjector { } static void onDisable(Plugin plugin) { - try { - ejectConfig(plugin, plugin); - } catch (NoClassDefFoundError ignored) { - } + eject(plugin, plugin); } public static void eject(Plugin plugin, Object o) { - try { - ejectConfig(plugin, o); - } catch (NoClassDefFoundError ignored) { - } + try { + ejectConfig(plugin, o); + } catch (NoClassDefFoundError ignored) { + } } private static void ejectConfig(Plugin plugin, Object o) { @@ -56,10 +53,11 @@ public class DependencyInjector { if ((config = field.getType().getAnnotation(Config.class)) != null) { try { field.setAccessible(true); - TConfigInjector.saveConfig(plugin, o); + TConfigInjector.saveConfig(plugin, field.get(o)); TLib.getTLib().getLogger().info("插件 " + plugin + " 的配置 " + config.name() + " 已保存"); } catch (Exception e) { TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置 " + config.name() + " 保存失败"); + e.printStackTrace(); } } } @@ -102,9 +100,9 @@ public class DependencyInjector { } private static void injectLogger(Plugin plugin, Object o) { - for (Field field : o.getClass().getDeclaredFields()) { - try { - Logger logger; + for (Field field : o.getClass().getDeclaredFields()) { + try { + Logger logger; if ((logger = field.getAnnotation(Logger.class)) != null) { field.getType().asSubclass(TLogger.class); TLogger tLogger = new TLogger(logger.value(), plugin, logger.level()); @@ -112,15 +110,15 @@ public class DependencyInjector { field.setAccessible(true); field.set(o, tLogger); } - } catch (Exception ignored2) { - } - } + } catch (Exception ignored2) { + } + } } private static void injectPluginInstance(Plugin plugin, Object o) { - for (Field field : o.getClass().getDeclaredFields()) { - try { - PluginInstance instance; + for (Field field : o.getClass().getDeclaredFields()) { + try { + PluginInstance instance; if ((instance = field.getAnnotation(PluginInstance.class)) != null) { if (!field.isAccessible()) field.setAccessible(true); @@ -137,20 +135,21 @@ public class DependencyInjector { if (pl != null) field.set(o, pl); } - } catch (Exception ignored) { - } + } catch (Exception ignored) { + } } } private static void injectDependencies(Plugin plugin, Object o) { - Dependency[] dependencies = new Dependency[0]; { + Dependency[] dependencies = new Dependency[0]; + { Dependencies d = o.getClass().getAnnotation(Dependencies.class); if (d != null) { - dependencies = d.value(); + dependencies = d.value(); } Dependency d2 = o.getClass().getAnnotation(Dependency.class); if (d2 != null) { - dependencies = new Dependency[]{d2}; + dependencies = new Dependency[]{d2}; } } if (dependencies.length != 0) { diff --git a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java index 4d1c0e0..6d2e4bf 100644 --- a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java @@ -31,7 +31,7 @@ public class TConfigInjector { 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); + else saveConfig(plugin, clazz.newInstance()); return unserialize(plugin, clazz); } catch (NullPointerException e) { TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败:没有 @Config 注解"); From 4e7fc4216787fe7b6043a87ed164c9f7c9641b9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9D=8F=E9=BB=91?= Date: Tue, 10 Apr 2018 22:34:37 +0800 Subject: [PATCH 12/44] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../taboolib/timeutil/TimeFormatter.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/main/java/me/skymc/taboolib/timeutil/TimeFormatter.java diff --git a/src/main/java/me/skymc/taboolib/timeutil/TimeFormatter.java b/src/main/java/me/skymc/taboolib/timeutil/TimeFormatter.java new file mode 100644 index 0000000..b3fdb4a --- /dev/null +++ b/src/main/java/me/skymc/taboolib/timeutil/TimeFormatter.java @@ -0,0 +1,31 @@ +package me.skymc.taboolib.timeutil; + +import java.util.concurrent.TimeUnit; + +import lombok.Data; + +/** + * @author sky + * @since 2018-04-10 22:11:04 + */ +@Data +public class TimeFormatter { + + private long days; + private long hours; + private long minutes; + private long seconds; + private long milliseconds; + + public TimeFormatter(long millisecond) { + days = TimeUnit.MILLISECONDS.toDays(millisecond); + hours = TimeUnit.MILLISECONDS.toHours(millisecond) - days * 24L; + minutes = TimeUnit.MILLISECONDS.toMinutes(millisecond) - TimeUnit.MILLISECONDS.toHours(millisecond) * 60L; + seconds = TimeUnit.MILLISECONDS.toSeconds(millisecond) - TimeUnit.MILLISECONDS.toMinutes(millisecond) * 60L; + milliseconds = TimeUnit.MILLISECONDS.toMillis(millisecond) - TimeUnit.MILLISECONDS.toSeconds(millisecond) * 1000L; + } + + public long toMilliseconds() { + return milliseconds + (seconds * 1000L) + (minutes * 1000L * 60L) + (hours * 1000L * 60L * 60L) + (days * 1000L * 60L * 60L * 24L); + } +} From b941cac63fa38ee02db9b0e4d80888b23b1e95e7 Mon Sep 17 00:00:00 2001 From: Izzel_Aliz Date: Fri, 13 Apr 2018 13:38:54 +0800 Subject: [PATCH 13/44] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E4=B8=BA=20onLoad=20=E5=89=8D=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit //TODO 在插件启动之前加载依赖 --- .idea/encodings.xml | 6 + src/main/java/com/ilummc/tlib/TLib.java | 17 +- .../tlib/inject/DependencyInjector.java | 2 +- .../ilummc/tlib/inject/TLibPluginManager.java | 5 +- src/main/java/me/skymc/taboolib/Main.java | 486 +++++++++--------- 5 files changed, 266 insertions(+), 250 deletions(-) create mode 100644 .idea/encodings.xml diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..97626ba --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/com/ilummc/tlib/TLib.java b/src/main/java/com/ilummc/tlib/TLib.java index c7d2216..0273481 100644 --- a/src/main/java/com/ilummc/tlib/TLib.java +++ b/src/main/java/com/ilummc/tlib/TLib.java @@ -45,22 +45,27 @@ public class TLib { return tLib; } - public static void init() { - new File(Main.getInst().getDataFolder(), "/libs").mkdirs(); - tLib = new TLib(); - DependencyInjector.inject(Main.getInst(), tLib); + public static void injectPluginManager() { // 注入 PluginLoader 用于加载依赖 try { Field field = Bukkit.getServer().getClass().getDeclaredField("pluginManager"); field.setAccessible(true); field.set(Bukkit.getServer(), new TLibPluginManager()); - tLib.getLogger().info("注入成功"); } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); - tLib.getLogger().fatal("注入失败"); } } + public static void init() { + new File(Main.getInst().getDataFolder(), "/libs").mkdirs(); + tLib = new TLib(); + DependencyInjector.inject(Main.getInst(), tLib); + if (Bukkit.getPluginManager() instanceof TLibPluginManager) + tLib.getLogger().info("注入成功"); + else + tLib.getLogger().fatal("注入失败"); + } + public static void unload() { tLib.getConfigWatcher().unregisterAll(); DependencyInjector.eject(Main.getInst(), tLib); diff --git a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java index adb3499..8c32a5d 100644 --- a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java @@ -43,7 +43,7 @@ public class DependencyInjector { public static void eject(Plugin plugin, Object o) { try { ejectConfig(plugin, o); - } catch (NoClassDefFoundError ignored) { + } catch (Throwable ignored) { } } diff --git a/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java b/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java index 42f640d..3d92b66 100644 --- a/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java +++ b/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java @@ -49,7 +49,9 @@ public class TLibPluginManager implements PluginManager { @Override public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException { - return instance.loadPlugin(file); + Plugin plugin = instance.loadPlugin(file); + DependencyInjector.injectOnEnable(plugin); + return plugin; } @Override @@ -92,7 +94,6 @@ public class TLibPluginManager implements PluginManager { @Override public void enablePlugin(Plugin plugin) { - DependencyInjector.injectOnEnable(plugin); instance.enablePlugin(plugin); } diff --git a/src/main/java/me/skymc/taboolib/Main.java b/src/main/java/me/skymc/taboolib/Main.java index 7cf75c6..7c5d3f7 100644 --- a/src/main/java/me/skymc/taboolib/Main.java +++ b/src/main/java/me/skymc/taboolib/Main.java @@ -1,7 +1,6 @@ package me.skymc.taboolib; import com.ilummc.tlib.TLib; -import com.ilummc.tlib.annotations.Dependency; import lombok.Getter; import lombok.Setter; import me.skymc.taboolib.anvil.AnvilContainerAPI; @@ -51,14 +50,29 @@ import java.util.Random; @SuppressWarnings("deprecation") public class Main extends JavaPlugin implements Listener { - - @Getter - private static Plugin inst; - @Getter - private static String prefix = "§8[§3§lTabooLib§8] §7"; - @Getter - @Setter - private static Economy Economy; + + public Main() { + super(); + + inst = this; + disable = false; + + TLib.injectPluginManager(); + + // 载入配置 + saveDefaultConfig(); + + // 加载依赖 + TLib.init(); + } + + @Getter + private static Plugin inst; + @Getter + private static String prefix = "§8[§3§lTabooLib§8] §7"; + @Getter + @Setter + private static Economy Economy; @Getter private static File playerDataFolder; @Getter @@ -77,245 +91,235 @@ public class Main extends JavaPlugin implements Listener { private static Language2 exampleLangauge2; @Getter private static boolean started; - + public static Random getRandom() { - return NumberUtils.getRand(); - } - - public static String getTablePrefix() { - return inst.getConfig().getString("MYSQL.PREFIX"); - } - - @Override - public void saveDefaultConfig() { - reloadConfig(); - } - - @Override - public void reloadConfig() { - File file = new File(getDataFolder(), "config.yml"); - if (!file.exists()) { - saveResource("config.yml", true); - } - config = ConfigUtils.load(this, file); - } - - @Override - public void onLoad() { - inst = this; disable = false; - // 载入配置 - saveDefaultConfig(); - - // 加载依赖 - TLib.init(); - - // 载入目录 - setupDataFolder(); - // 注册配置 - DataUtils.addPluginData("TabooLibrary", null); - - // 启用数据库 - if (getConfig().getBoolean("MYSQL.ENABLE")) { - // 连接数据库 - connection = new MySQLConnection(getConfig().getString("MYSQL.HOST"), getConfig().getString("MYSQL.USER"), getConfig().getString("MYSQL.POST"), getConfig().getString("MYSQL.PASSWORD"), getConfig().getString("MYSQL.DATABASE"), 30, this); - // 连接成功 - if (connection.isConnection()) { - // 创建表 - connection.createTable(getTablePrefix() + "_playerdata", "username", "configuration"); - connection.createTable(getTablePrefix() + "_plugindata", "name", "variable", "upgrade"); - connection.createTable(getTablePrefix() + "_serveruuid", "uuid", "hash"); - - // 如果没有数据 - if (!connection.isExists(getTablePrefix() + "_serveruuid", "uuid", TabooLib.getServerUID())) { - connection.intoValue(getTablePrefix() + "_serveruuid", TabooLib.getServerUID(), StringUtils.hashKeyForDisk(getDataFolder().getPath())); - } - else { - String hash = connection.getValue(getTablePrefix() + "_serveruuid", "uuid", TabooLib.getServerUID(), "hash").toString(); - // 如果这个值和我的值不同 - if (!hash.equals(StringUtils.hashKeyForDisk(getDataFolder().getPath()))) { - MsgUtils.warn("检测到本服序列号与其他服务器相同, 已重新生成!"); - // 重新生成序列号 - TabooLib.resetServerUID(); - // 关服 - Bukkit.shutdown(); - } - } - } - else { - // 提示 - MsgUtils.warn("数据库连接失败, 请检查配置是否正确!"); - // 关服 - Bukkit.shutdown(); - } - // 储存方式 - storageType = StorageType.SQL; - } - else { - // 储存方式 - storageType = StorageType.LOCAL; - } + return NumberUtils.getRand(); } - + + public static String getTablePrefix() { + return inst.getConfig().getString("MYSQL.PREFIX"); + } + @Override - public void onEnable() { - // 注册指令 - getCommand("taboolib").setExecutor(new MainCommands()); - getCommand("language2").setExecutor(new Language2Command()); - getCommand("taboolibrarymodule").setExecutor(new TLMCommands()); - - // 注册监听 - registerListener(); - // 载入经济 - EcoUtils.setupEconomy(); - // 载入权限 - PermissionUtils.loadRegisteredServiceProvider(); - // 物品名称 - ItemUtils.LoadLib(); - // 低层工具 - DabItemUtils.getInstance(); - // 载入周期管理器 - TimeCycleManager.load(); - // 启动脚本 - JavaShell.javaShellSetup(); - // 载入语言文件 - exampleLangauge2 = new Language2("Language2", this); - // 注册脚本 - SkriptHandler.getInst(); - - // 启动数据库储存方法 - if (getStorageType() == StorageType.SQL) { - GlobalDataManager.SQLMethod.startSQLMethod(); - } - - // 载入完成 - MsgUtils.send("§7插件载入完成!"); - MsgUtils.send("§7插件版本: §f" + getDescription().getVersion()); - MsgUtils.send("§7插件作者: §f" + getDescription().getAuthors()); - MsgUtils.send("§7游戏版本: §f" + TabooLib.getVerint()); - - // 文件保存 + public void saveDefaultConfig() { + reloadConfig(); + } + + @Override + public void reloadConfig() { + File file = new File(getDataFolder(), "config.yml"); + if (!file.exists()) { + saveResource("config.yml", true); + } + config = ConfigUtils.load(this, file); + } + + @Override + public void onLoad() { + // 载入目录 + setupDataFolder(); + // 注册配置 + DataUtils.addPluginData("TabooLibrary", null); + + // 启用数据库 + if (getConfig().getBoolean("MYSQL.ENABLE")) { + // 连接数据库 + connection = new MySQLConnection(getConfig().getString("MYSQL.HOST"), getConfig().getString("MYSQL.USER"), getConfig().getString("MYSQL.POST"), getConfig().getString("MYSQL.PASSWORD"), getConfig().getString("MYSQL.DATABASE"), 30, this); + // 连接成功 + if (connection.isConnection()) { + // 创建表 + connection.createTable(getTablePrefix() + "_playerdata", "username", "configuration"); + connection.createTable(getTablePrefix() + "_plugindata", "name", "variable", "upgrade"); + connection.createTable(getTablePrefix() + "_serveruuid", "uuid", "hash"); + + // 如果没有数据 + if (!connection.isExists(getTablePrefix() + "_serveruuid", "uuid", TabooLib.getServerUID())) { + connection.intoValue(getTablePrefix() + "_serveruuid", TabooLib.getServerUID(), StringUtils.hashKeyForDisk(getDataFolder().getPath())); + } else { + String hash = connection.getValue(getTablePrefix() + "_serveruuid", "uuid", TabooLib.getServerUID(), "hash").toString(); + // 如果这个值和我的值不同 + if (!hash.equals(StringUtils.hashKeyForDisk(getDataFolder().getPath()))) { + MsgUtils.warn("检测到本服序列号与其他服务器相同, 已重新生成!"); + // 重新生成序列号 + TabooLib.resetServerUID(); + // 关服 + Bukkit.shutdown(); + } + } + } else { + // 提示 + MsgUtils.warn("数据库连接失败, 请检查配置是否正确!"); + // 关服 + Bukkit.shutdown(); + } + // 储存方式 + storageType = StorageType.SQL; + } else { + // 储存方式 + storageType = StorageType.LOCAL; + } + } + + @Override + public void onEnable() { + // 注册指令 + getCommand("taboolib").setExecutor(new MainCommands()); + getCommand("language2").setExecutor(new Language2Command()); + getCommand("taboolibrarymodule").setExecutor(new TLMCommands()); + + // 注册监听 + registerListener(); + // 载入经济 + EcoUtils.setupEconomy(); + // 载入权限 + PermissionUtils.loadRegisteredServiceProvider(); + // 物品名称 + ItemUtils.LoadLib(); + // 低层工具 + DabItemUtils.getInstance(); + // 载入周期管理器 + TimeCycleManager.load(); + // 启动脚本 + JavaShell.javaShellSetup(); + // 载入语言文件 + exampleLangauge2 = new Language2("Language2", this); + // 注册脚本 + SkriptHandler.getInst(); + + // 启动数据库储存方法 + if (getStorageType() == StorageType.SQL) { + GlobalDataManager.SQLMethod.startSQLMethod(); + } + + // 载入完成 + MsgUtils.send("§7插件载入完成!"); + MsgUtils.send("§7插件版本: §f" + getDescription().getVersion()); + MsgUtils.send("§7插件作者: §f" + getDescription().getAuthors()); + MsgUtils.send("§7游戏版本: §f" + TabooLib.getVerint()); + + // 文件保存 Bukkit.getScheduler().runTaskTimerAsynchronously(this, DataUtils::saveAllCaches, 20, 20 * 120); - Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> PlayerDataManager.saveAllCaches(true, false), 20, 20 * 60); - - // 插件联动 - new BukkitRunnable() { - - @Override - public void run() { - if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { - new SupportPlaceholder(getInst(), "taboolib").hook(); - } - // 载入 SpecialItem 接口 - SpecialItem.getInst().loadItems(); - // 载入 TLM 接口 - TLM.getInst(); - } - }.runTask(this); - - // 更新检测 - new UpdateTask(); - // 启动监控 - new Metrics(this); - - // 启动 - started = true; - } - - @Override - public void onDisable() { - disable = true; - - // 如果插件尚未启动完成 - if (!started) { - MsgUtils.send("&c插件尚未启动完成, 已跳过卸载代码"); - MsgUtils.send("&c插件作者: &4坏黑"); - return; - } - - // 保存数据 - Bukkit.getOnlinePlayers().forEach(x -> DataUtils.saveOnline(x.getName())); - // 结束线程 - Bukkit.getScheduler().cancelTasks(this); - // 保存插件数据 - DataUtils.saveAllCaches(); - // 保存玩家数据 - PlayerDataManager.saveAllPlayers(false, true); - // 结束脚本 - JavaShell.javaShellCancel(); - // 注销 SpecialItem 接口 - SpecialItem.getInst().unloadItems(); - // 注销 TLM 接口 - TabooLibraryModule.getInst().unloadModules(); - - // 结束数据库储存方法 - if (getStorageType() == StorageType.SQL) { - GlobalDataManager.SQLMethod.cancelSQLMethod(); - } - - // 清理数据 - if (getStorageType() == StorageType.LOCAL && getConfig().getBoolean("DELETE-DATA")) { - getPlayerDataFolder().delete(); - } - // 清理数据 - if (getStorageType() == StorageType.SQL && getConfig().getBoolean("DELETE-VARIABLE")) { - GlobalDataManager.clearInvalidVariables(); - } - - // 提示信息 - MsgUtils.send("&c插件已卸载, 感谢您使用&4禁忌书库"); - MsgUtils.send("&c插件作者: &4坏黑"); - - // 清理头衔 - TagUtils.delete(); - - // 结束连接 - if (connection != null && connection.isConnection()) { - connection.closeConnection(); - } + Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> PlayerDataManager.saveAllCaches(true, false), 20, 20 * 60); - TLib.unload(); - - // 关闭服务器 - Bukkit.shutdown(); - } - - private void setupDataFolder() { - playerDataFolder = new File(getConfig().getString("DATAURL.PLAYER-DATA")); - if (!playerDataFolder.exists()) { - playerDataFolder.mkdirs(); - } - serverDataFolder = new File(getConfig().getString("DATAURL.SERVER-DATA")); - if (!serverDataFolder.exists()) { - serverDataFolder.mkdirs(); - } - } - - private void registerListener() { - getServer().getPluginManager().registerEvents(this, this); - getServer().getPluginManager().registerEvents(new ListenerPlayerCommand(), this); - getServer().getPluginManager().registerEvents(new ListenerPlayerJump(), this); - getServer().getPluginManager().registerEvents(new ListenerPlayerQuit(), this); - getServer().getPluginManager().registerEvents(new ChatCatcher(), this); - getServer().getPluginManager().registerEvents(new DataUtils(), this); - getServer().getPluginManager().registerEvents(new AnvilContainerAPI(), this); - getServer().getPluginManager().registerEvents(new ListenerPluginDisable(), this); - getServer().getPluginManager().registerEvents(new PlayerDataManager(), this); - getServer().getPluginManager().registerEvents(new ItemLibraryPatch(), this); - getServer().getPluginManager().registerEvents(new SoundsLibraryPatch(), this); + // 插件联动 + new BukkitRunnable() { - - if (TabooLib.getVerint() > 10700) { - getServer().getPluginManager().registerEvents(new EntityUtils(), this); - getServer().getPluginManager().registerEvents(new SignUtils(), this); - } - - // 如果 YUM 插件存在 - if (Bukkit.getPluginManager().getPlugin("YUM") != null) { - getServer().getPluginManager().registerEvents(new ListenerNetWork(), this); - } - } + @Override + public void run() { + if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { + new SupportPlaceholder(getInst(), "taboolib").hook(); + } + // 载入 SpecialItem 接口 + SpecialItem.getInst().loadItems(); + // 载入 TLM 接口 + TLM.getInst(); + } + }.runTask(this); + + // 更新检测 + new UpdateTask(); + // 启动监控 + new Metrics(this); + + // 启动 + started = true; + } + + @Override + public void onDisable() { + disable = true; + + // 如果插件尚未启动完成 + if (!started) { + MsgUtils.send("&c插件尚未启动完成, 已跳过卸载代码"); + MsgUtils.send("&c插件作者: &4坏黑"); + return; + } + + // 保存数据 + Bukkit.getOnlinePlayers().forEach(x -> DataUtils.saveOnline(x.getName())); + // 结束线程 + Bukkit.getScheduler().cancelTasks(this); + // 保存插件数据 + DataUtils.saveAllCaches(); + // 保存玩家数据 + PlayerDataManager.saveAllPlayers(false, true); + // 结束脚本 + JavaShell.javaShellCancel(); + // 注销 SpecialItem 接口 + SpecialItem.getInst().unloadItems(); + // 注销 TLM 接口 + TabooLibraryModule.getInst().unloadModules(); + + // 结束数据库储存方法 + if (getStorageType() == StorageType.SQL) { + GlobalDataManager.SQLMethod.cancelSQLMethod(); + } + + // 清理数据 + if (getStorageType() == StorageType.LOCAL && getConfig().getBoolean("DELETE-DATA")) { + getPlayerDataFolder().delete(); + } + // 清理数据 + if (getStorageType() == StorageType.SQL && getConfig().getBoolean("DELETE-VARIABLE")) { + GlobalDataManager.clearInvalidVariables(); + } + + // 提示信息 + MsgUtils.send("&c插件已卸载, 感谢您使用&4禁忌书库"); + MsgUtils.send("&c插件作者: &4坏黑"); + + // 清理头衔 + TagUtils.delete(); + + // 结束连接 + if (connection != null && connection.isConnection()) { + connection.closeConnection(); + } + + TLib.unload(); + + // 关闭服务器 + Bukkit.shutdown(); + } + + private void setupDataFolder() { + playerDataFolder = new File(getConfig().getString("DATAURL.PLAYER-DATA")); + if (!playerDataFolder.exists()) { + playerDataFolder.mkdirs(); + } + serverDataFolder = new File(getConfig().getString("DATAURL.SERVER-DATA")); + if (!serverDataFolder.exists()) { + serverDataFolder.mkdirs(); + } + } + + private void registerListener() { + getServer().getPluginManager().registerEvents(this, this); + getServer().getPluginManager().registerEvents(new ListenerPlayerCommand(), this); + getServer().getPluginManager().registerEvents(new ListenerPlayerJump(), this); + getServer().getPluginManager().registerEvents(new ListenerPlayerQuit(), this); + getServer().getPluginManager().registerEvents(new ChatCatcher(), this); + getServer().getPluginManager().registerEvents(new DataUtils(), this); + getServer().getPluginManager().registerEvents(new AnvilContainerAPI(), this); + getServer().getPluginManager().registerEvents(new ListenerPluginDisable(), this); + getServer().getPluginManager().registerEvents(new PlayerDataManager(), this); + getServer().getPluginManager().registerEvents(new ItemLibraryPatch(), this); + getServer().getPluginManager().registerEvents(new SoundsLibraryPatch(), this); + + + if (TabooLib.getVerint() > 10700) { + getServer().getPluginManager().registerEvents(new EntityUtils(), this); + getServer().getPluginManager().registerEvents(new SignUtils(), this); + } + + // 如果 YUM 插件存在 + if (Bukkit.getPluginManager().getPlugin("YUM") != null) { + getServer().getPluginManager().registerEvents(new ListenerNetWork(), this); + } + } public enum StorageType { LOCAL, SQL - } + } } From 2edca32b89e8b870f092e1a93db7cc639135b2f7 Mon Sep 17 00:00:00 2001 From: Izzel_Aliz Date: Sat, 21 Apr 2018 13:58:56 +0800 Subject: [PATCH 14/44] =?UTF-8?q?onEnable=20=E4=B9=8B=E5=89=8D=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E6=8F=92=E4=BB=B6=20=E4=BF=AE=E5=A4=8D=20NoClassDefFo?= =?UTF-8?q?undError=20=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/ilummc/tlib/TLib.java | 3 +- .../com/ilummc/tlib/annotations/Config.java | 4 +- .../tlib/inject/DependencyInjector.java | 29 +++------ .../ilummc/tlib/inject/TLibPluginManager.java | 5 +- src/main/java/com/ilummc/tlib/util/IO.java | 18 ++++++ src/main/java/com/ilummc/tlib/util/Ref.java | 59 +++++++++++++++++++ .../com/ilummc/tlib/util/asm/AsmAnalyser.java | 31 ++++++++++ src/main/java/me/skymc/taboolib/Main.java | 26 ++++---- 8 files changed, 135 insertions(+), 40 deletions(-) create mode 100644 src/main/java/com/ilummc/tlib/util/IO.java create mode 100644 src/main/java/com/ilummc/tlib/util/Ref.java create mode 100644 src/main/java/com/ilummc/tlib/util/asm/AsmAnalyser.java diff --git a/src/main/java/com/ilummc/tlib/TLib.java b/src/main/java/com/ilummc/tlib/TLib.java index 0273481..62261f6 100644 --- a/src/main/java/com/ilummc/tlib/TLib.java +++ b/src/main/java/com/ilummc/tlib/TLib.java @@ -14,7 +14,8 @@ import java.io.File; import java.lang.reflect.Field; @Dependency(type = Dependency.Type.LIBRARY, maven = "org.ow2.asm:asm:6.1.1") -@Dependency(type = Dependency.Type.LIBRARY, maven = "com.zaxxer:HikariCP:3.0.0") +@Dependency(type = Dependency.Type.LIBRARY, maven = "com.zaxxer:HikariCP:3.1.0") +@Dependency(type = Dependency.Type.LIBRARY, maven = "org.slf4j:slf4j-api:1.7.25") public class TLib { private static TLib tLib; diff --git a/src/main/java/com/ilummc/tlib/annotations/Config.java b/src/main/java/com/ilummc/tlib/annotations/Config.java index 03b792a..b4ebd42 100644 --- a/src/main/java/com/ilummc/tlib/annotations/Config.java +++ b/src/main/java/com/ilummc/tlib/annotations/Config.java @@ -1,5 +1,7 @@ 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; @@ -20,6 +22,6 @@ public @interface Config { boolean listenChanges() default false; - int excludeModifiers() default Modifier.STATIC | Modifier.TRANSIENT; + int excludeModifiers() default Modifier.STATIC | Modifier.TRANSIENT | Ref.ACC_SYNTHETIC | Ref.ACC_BRIDGE; } diff --git a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java index 8c32a5d..04b4030 100644 --- a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java @@ -3,6 +3,7 @@ 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.util.Ref; import com.ilummc.tlib.util.TLogger; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; @@ -14,22 +15,10 @@ import java.lang.reflect.Field; public class DependencyInjector { public static void inject(Plugin plugin, Object o) { - try { - injectLogger(plugin, o); - } catch (NoClassDefFoundError ignored) { - } - try { - injectConfig(plugin, o); - } catch (NoClassDefFoundError ignored) { - } - try { - injectPluginInstance(plugin, o); - } catch (NoClassDefFoundError ignored) { - } - try { - injectDependencies(plugin, o); - } catch (NoClassDefFoundError ignored) { - } + injectLogger(plugin, o); + injectConfig(plugin, o); + injectPluginInstance(plugin, o); + injectDependencies(plugin, o); } static void injectOnEnable(Plugin plugin) { @@ -48,7 +37,7 @@ public class DependencyInjector { } private static void ejectConfig(Plugin plugin, Object o) { - for (Field field : o.getClass().getDeclaredFields()) { + for (Field field : Ref.getDeclaredFields(o.getClass())) { Config config; if ((config = field.getType().getAnnotation(Config.class)) != null) { try { @@ -64,7 +53,7 @@ public class DependencyInjector { } private static void injectConfig(Plugin plugin, Object o) { - for (Field field : o.getClass().getDeclaredFields()) { + for (Field field : Ref.getDeclaredFields(o.getClass())) { try { Config config; if ((config = field.getType().getAnnotation(Config.class)) != null) { @@ -100,7 +89,7 @@ public class DependencyInjector { } private static void injectLogger(Plugin plugin, Object o) { - for (Field field : o.getClass().getDeclaredFields()) { + for (Field field : Ref.getDeclaredFields(o.getClass())) { try { Logger logger; if ((logger = field.getAnnotation(Logger.class)) != null) { @@ -116,7 +105,7 @@ public class DependencyInjector { } private static void injectPluginInstance(Plugin plugin, Object o) { - for (Field field : o.getClass().getDeclaredFields()) { + for (Field field : Ref.getDeclaredFields(o.getClass())) { try { PluginInstance instance; if ((instance = field.getAnnotation(PluginInstance.class)) != null) { diff --git a/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java b/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java index 3d92b66..42f640d 100644 --- a/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java +++ b/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java @@ -49,9 +49,7 @@ public class TLibPluginManager implements PluginManager { @Override public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException { - Plugin plugin = instance.loadPlugin(file); - DependencyInjector.injectOnEnable(plugin); - return plugin; + return instance.loadPlugin(file); } @Override @@ -94,6 +92,7 @@ public class TLibPluginManager implements PluginManager { @Override public void enablePlugin(Plugin plugin) { + DependencyInjector.injectOnEnable(plugin); instance.enablePlugin(plugin); } diff --git a/src/main/java/com/ilummc/tlib/util/IO.java b/src/main/java/com/ilummc/tlib/util/IO.java new file mode 100644 index 0000000..92d4d16 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/util/IO.java @@ -0,0 +1,18 @@ +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(); + } +} diff --git a/src/main/java/com/ilummc/tlib/util/Ref.java b/src/main/java/com/ilummc/tlib/util/Ref.java new file mode 100644 index 0000000..218fa55 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/util/Ref.java @@ -0,0 +1,59 @@ +package com.ilummc.tlib.util; + +import com.ilummc.tlib.util.asm.AsmAnalyser; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; + +import javax.annotation.concurrent.ThreadSafe; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +@ThreadSafe +public class Ref { + + private static final Map> cachedFields = new ConcurrentHashMap<>(); + + public static final int ACC_BRIDGE = 0x0040; + public static final int ACC_SYNTHETIC = 0x1000; + + public static List getDeclaredFields(Class clazz) { + return getDeclaredFields(clazz, 0, false); + } + + public static List getDeclaredFields(String clazz, int excludeModifiers, boolean cache) { + try { + return getDeclaredFields(Class.forName(clazz), excludeModifiers, cache); + } catch (ClassNotFoundException e) { + return Collections.emptyList(); + } + } + + public static List getDeclaredFields(Class clazz, int excludeModifiers, boolean cache) { + try { + Class.forName("org.objectweb.asm.ClassVisitor"); + List fields; + if ((fields = cachedFields.get(clazz.getName())) != null) return fields; + ClassReader classReader = new ClassReader(clazz.getResourceAsStream("/" + clazz.getName().replace('.', '/') + ".class")); + AsmAnalyser analyser = new AsmAnalyser(new ClassWriter(ClassWriter.COMPUTE_MAXS), excludeModifiers); + classReader.accept(analyser, ClassReader.SKIP_DEBUG); + fields = analyser.getFields().stream().map(name -> { + try { + return clazz.getDeclaredField(name); + } catch (Throwable ignored) { + } + return null; + }).filter(Objects::nonNull).collect(Collectors.toList()); + if (cache) cachedFields.putIfAbsent(clazz.getName(), fields); + return fields; + } catch (Exception e) { + return Collections.emptyList(); + } + } + +} diff --git a/src/main/java/com/ilummc/tlib/util/asm/AsmAnalyser.java b/src/main/java/com/ilummc/tlib/util/asm/AsmAnalyser.java new file mode 100644 index 0000000..70d6937 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/util/asm/AsmAnalyser.java @@ -0,0 +1,31 @@ +package com.ilummc.tlib.util.asm; + +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.Opcodes; + +import java.util.ArrayList; +import java.util.List; + +public class AsmAnalyser extends ClassVisitor implements Opcodes { + + private final List fields = new ArrayList<>(); + + private final int excludeModifier; + + public AsmAnalyser(ClassVisitor classVisitor, int excludeModifiers) { + super(Opcodes.ASM6, classVisitor); + this.excludeModifier = excludeModifiers; + } + + @Override + public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { + if ((access & excludeModifier) == 0) + fields.add(name); + return super.visitField(access, name, descriptor, signature, value); + } + + public List getFields() { + return fields; + } +} diff --git a/src/main/java/me/skymc/taboolib/Main.java b/src/main/java/me/skymc/taboolib/Main.java index 7c5d3f7..cd6b530 100644 --- a/src/main/java/me/skymc/taboolib/Main.java +++ b/src/main/java/me/skymc/taboolib/Main.java @@ -51,21 +51,6 @@ import java.util.Random; @SuppressWarnings("deprecation") public class Main extends JavaPlugin implements Listener { - public Main() { - super(); - - inst = this; - disable = false; - - TLib.injectPluginManager(); - - // 载入配置 - saveDefaultConfig(); - - // 加载依赖 - TLib.init(); - } - @Getter private static Plugin inst; @Getter @@ -116,6 +101,17 @@ public class Main extends JavaPlugin implements Listener { @Override public void onLoad() { + inst = this; + disable = false; + + TLib.injectPluginManager(); + + // 载入配置 + saveDefaultConfig(); + + // 加载依赖 + TLib.init(); + // 载入目录 setupDataFolder(); // 注册配置 From 385b2aa974cd81cd3839beda79bc98394413e72f Mon Sep 17 00:00:00 2001 From: Izzel_Aliz Date: Sat, 21 Apr 2018 14:21:47 +0800 Subject: [PATCH 15/44] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=90=84=E7=A7=8D?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/ilummc/tlib/util/Ref.java | 13 ++++++++----- src/main/resources/plugin.yml | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/ilummc/tlib/util/Ref.java b/src/main/java/com/ilummc/tlib/util/Ref.java index 218fa55..b9d4f1a 100644 --- a/src/main/java/com/ilummc/tlib/util/Ref.java +++ b/src/main/java/com/ilummc/tlib/util/Ref.java @@ -1,16 +1,13 @@ package com.ilummc.tlib.util; +import com.ilummc.tlib.TLib; import com.ilummc.tlib.util.asm.AsmAnalyser; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import javax.annotation.concurrent.ThreadSafe; -import java.io.IOException; import java.lang.reflect.Field; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -36,6 +33,11 @@ public class Ref { public static List getDeclaredFields(Class clazz, int excludeModifiers, boolean cache) { try { + + // 特殊判断 + if (clazz == TLib.class) + return Arrays.asList(clazz.getDeclaredFields()); + Class.forName("org.objectweb.asm.ClassVisitor"); List fields; if ((fields = cachedFields.get(clazz.getName())) != null) return fields; @@ -44,6 +46,7 @@ public class Ref { classReader.accept(analyser, ClassReader.SKIP_DEBUG); fields = analyser.getFields().stream().map(name -> { try { + System.out.println(name); return clazz.getDeclaredField(name); } catch (Throwable ignored) { } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index f9437be..712a7ae 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -19,5 +19,5 @@ commands: aliases: [tlm] depend: [Vault] -softdepend: [PlaceholderAPI, Skript, TabooCode] +softdepend: [PlaceholderAPI, Skript, TabooCode, MassiveLag] loadbefore: [Skript] \ No newline at end of file From c573617a019103f135f84b6cf5d6cbee18c0acb0 Mon Sep 17 00:00:00 2001 From: Izzel_Aliz Date: Sun, 22 Apr 2018 13:30:50 +0800 Subject: [PATCH 16/44] =?UTF-8?q?=E8=88=B9=E6=96=B0=20I18n=20=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=20=E4=BF=AE=E4=BA=86=E4=B8=80=E4=B8=AA=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6=E5=B0=8Fbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/dictionaries/csh20.xml | 3 + ..._com_ilummc_eagletdl_EagletCore_1_1_2.xml} | 8 +- ...l => Maven__com_zaxxer_HikariCP_3_1_0.xml} | 8 +- pom.xml | 12 +-- src/main/java/com/ilummc/tlib/TLib.java | 25 ++++- .../com/ilummc/tlib/annotations/Config.java | 2 + .../tlib/compat/PlaceholderApiHook.java | 40 ++++++++ .../ilummc/tlib/dependency/TDependency.java | 12 +-- .../tlib/inject/DependencyInjector.java | 6 +- .../ilummc/tlib/inject/TConfigInjector.java | 45 +++++++-- .../ilummc/tlib/resources/LocaleInstance.java | 65 +++++++++++++ .../ilummc/tlib/resources/LocaleLoader.java | 76 +++++++++++++++ .../com/ilummc/tlib/resources/Sendable.java | 21 ++++ .../tlib/resources/SimpleChatMessage.java | 95 +++++++++++++++++++ .../com/ilummc/tlib/resources/TLocale.java | 54 +++++++++++ src/main/java/com/ilummc/tlib/util/Ref.java | 44 ++++++++- .../java/com/ilummc/tlib/util/Strings.java | 1 + src/main/resources/lang/zh_CN.yml | 0 18 files changed, 479 insertions(+), 38 deletions(-) rename .idea/libraries/{Maven__com_ilummc_eagletdl_EagletCore_1_1.xml => Maven__com_ilummc_eagletdl_EagletCore_1_1_2.xml} (59%) rename .idea/libraries/{Maven__com_zaxxer_HikariCP_3_0_0.xml => Maven__com_zaxxer_HikariCP_3_1_0.xml} (65%) create mode 100644 src/main/java/com/ilummc/tlib/compat/PlaceholderApiHook.java create mode 100644 src/main/java/com/ilummc/tlib/resources/LocaleInstance.java create mode 100644 src/main/java/com/ilummc/tlib/resources/LocaleLoader.java create mode 100644 src/main/java/com/ilummc/tlib/resources/Sendable.java create mode 100644 src/main/java/com/ilummc/tlib/resources/SimpleChatMessage.java create mode 100644 src/main/java/com/ilummc/tlib/resources/TLocale.java create mode 100644 src/main/resources/lang/zh_CN.yml diff --git a/.idea/dictionaries/csh20.xml b/.idea/dictionaries/csh20.xml index 7fec0b9..e6ef750 100644 --- a/.idea/dictionaries/csh20.xml +++ b/.idea/dictionaries/csh20.xml @@ -1,6 +1,9 @@ + mvdw + papi + sendable unserialize unserializer diff --git a/.idea/libraries/Maven__com_ilummc_eagletdl_EagletCore_1_1.xml b/.idea/libraries/Maven__com_ilummc_eagletdl_EagletCore_1_1_2.xml similarity index 59% rename from .idea/libraries/Maven__com_ilummc_eagletdl_EagletCore_1_1.xml rename to .idea/libraries/Maven__com_ilummc_eagletdl_EagletCore_1_1_2.xml index ab97cb6..bc3a043 100644 --- a/.idea/libraries/Maven__com_ilummc_eagletdl_EagletCore_1_1.xml +++ b/.idea/libraries/Maven__com_ilummc_eagletdl_EagletCore_1_1_2.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_zaxxer_HikariCP_3_0_0.xml b/.idea/libraries/Maven__com_zaxxer_HikariCP_3_1_0.xml similarity index 65% rename from .idea/libraries/Maven__com_zaxxer_HikariCP_3_0_0.xml rename to .idea/libraries/Maven__com_zaxxer_HikariCP_3_1_0.xml index f69ad99..3f79c94 100644 --- a/.idea/libraries/Maven__com_zaxxer_HikariCP_3_0_0.xml +++ b/.idea/libraries/Maven__com_zaxxer_HikariCP_3_1_0.xml @@ -1,13 +1,13 @@ - + - + - + - + \ No newline at end of file diff --git a/pom.xml b/pom.xml index a92e266..0f99a1e 100644 --- a/pom.xml +++ b/pom.xml @@ -58,15 +58,15 @@ - - com.ilummc.eagletdl - EagletCore - 1.1 - com.zaxxer HikariCP - 3.0.0 + 3.1.0 + + + com.ilummc.eagletdl + EagletCore + 1.1.2 org.ow2.asm diff --git a/src/main/java/com/ilummc/tlib/TLib.java b/src/main/java/com/ilummc/tlib/TLib.java index 62261f6..a235b22 100644 --- a/src/main/java/com/ilummc/tlib/TLib.java +++ b/src/main/java/com/ilummc/tlib/TLib.java @@ -3,9 +3,12 @@ package com.ilummc.tlib; import com.ilummc.tlib.annotations.Config; import com.ilummc.tlib.annotations.Dependency; import com.ilummc.tlib.annotations.Logger; +import com.ilummc.tlib.compat.PlaceholderApiHook; import com.ilummc.tlib.inject.DependencyInjector; import com.ilummc.tlib.inject.TConfigWatcher; import com.ilummc.tlib.inject.TLibPluginManager; +import com.ilummc.tlib.resources.LocaleLoader; +import com.ilummc.tlib.resources.TLocale; import com.ilummc.tlib.util.TLogger; import me.skymc.taboolib.Main; import org.bukkit.Bukkit; @@ -21,7 +24,7 @@ public class TLib { private static TLib tLib; @Logger("§8[§3§lTabooLib§8][§r{1}§8] §f{2}") - private TLogger tLogger; + private TLogger tLogger = new TLogger("§8[§3§lTabooLib§8][§r{1}§8] §f{2}", Main.getInst(), TLogger.FINE); private TLibConfig config; @@ -60,11 +63,17 @@ public class TLib { public static void init() { new File(Main.getInst().getDataFolder(), "/libs").mkdirs(); tLib = new TLib(); + LocaleLoader.init(); + PlaceholderApiHook.init(); DependencyInjector.inject(Main.getInst(), tLib); if (Bukkit.getPluginManager() instanceof TLibPluginManager) tLib.getLogger().info("注入成功"); else tLib.getLogger().fatal("注入失败"); + TLocale.sendToConsole("test1"); + TLocale.sendToConsole("test2"); + TLocale.sendToConsole("test3"); + TLocale.sendToConsole("test4.node1", "Hello", "world"); } public static void unload() { @@ -72,7 +81,7 @@ public class TLib { DependencyInjector.eject(Main.getInst(), tLib); } - @Config(name = "tlib.yml", listenChanges = true) + @Config(name = "tlib.yml", listenChanges = true, readOnly = false) public static class TLibConfig { private int downloadPoolSize = 4; @@ -80,5 +89,17 @@ public class TLib { public int getDownloadPoolSize() { return downloadPoolSize; } + + private String[] locale = {"zh_CN", "en_US"}; + + public String[] getLocale() { + return locale; + } + + private boolean enablePapiByDefault = false; + + public boolean isEnablePapiByDefault() { + return enablePapiByDefault; + } } } diff --git a/src/main/java/com/ilummc/tlib/annotations/Config.java b/src/main/java/com/ilummc/tlib/annotations/Config.java index b4ebd42..62af121 100644 --- a/src/main/java/com/ilummc/tlib/annotations/Config.java +++ b/src/main/java/com/ilummc/tlib/annotations/Config.java @@ -18,6 +18,8 @@ public @interface Config { boolean saveOnExit() default false; + boolean readOnly() default true; + String charset() default "UTF-8"; boolean listenChanges() default false; diff --git a/src/main/java/com/ilummc/tlib/compat/PlaceholderApiHook.java b/src/main/java/com/ilummc/tlib/compat/PlaceholderApiHook.java new file mode 100644 index 0000000..728ee4c --- /dev/null +++ b/src/main/java/com/ilummc/tlib/compat/PlaceholderApiHook.java @@ -0,0 +1,40 @@ +package com.ilummc.tlib.compat; + +import me.clip.placeholderapi.PlaceholderAPI; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public abstract class PlaceholderApiHook { + + private static PlaceholderApiHook impl; + + public static void init() { + if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) + impl = new PlaceholderImpl(); + else impl = new AbstractImpl(); + } + + public static String replace(CommandSender sender, String text) { + return sender instanceof Player ? impl.replace(((Player) sender), text) : text; + } + + abstract String replace(Player player, String text); + + private static class PlaceholderImpl extends PlaceholderApiHook { + + @Override + String replace(Player player, String text) { + return PlaceholderAPI.setPlaceholders(player, text); + } + } + + private static class AbstractImpl extends PlaceholderApiHook { + + @Override + String replace(Player player, String text) { + return text; + } + } + +} diff --git a/src/main/java/com/ilummc/tlib/dependency/TDependency.java b/src/main/java/com/ilummc/tlib/dependency/TDependency.java index 8ce20c5..ab8b631 100644 --- a/src/main/java/com/ilummc/tlib/dependency/TDependency.java +++ b/src/main/java/com/ilummc/tlib/dependency/TDependency.java @@ -7,7 +7,6 @@ import me.skymc.taboolib.Main; import java.io.File; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.locks.ReentrantLock; public class TDependency { @@ -56,14 +55,12 @@ public class TDependency { TLib.getTLib().getLogger().warn("已启用离线模式, 将不会下载第三方依赖库"); return false; } - ReentrantLock lock = new ReentrantLock(); AtomicBoolean failed = new AtomicBoolean(false); String link = dl.length() == 0 ? url + "/" + groupId.replace('.', '/') + "/" + artifactId + "/" + version + "/" + artifactId + "-" + version + ".jar" : dl; - EagletTask task = new EagletTask() + new EagletTask() .url(link) .file(target) .setThreads(TLib.getTLib().getConfig().getDownloadPoolSize()) - .setOnStart(event -> lock.lock()) .setOnError(event -> { }) .setOnConnected(event -> TLib.getTLib().getLogger().info(" 正在下载 " + String.join(":", @@ -79,12 +76,7 @@ public class TDependency { TLib.getTLib().getLogger().error(" 下载 " + String.join(":", new String[]{groupId, artifactId, version}) + " 失败"); TLib.getTLib().getLogger().error(" 请手动下载 " + link + " 并重命名为 " + target.getName() + " 后放在 /TabooLib/libs 文件夹内"); } - lock.unlock(); - }); - task.start(); - while (lock.tryLock()) lock.unlock(); - lock.lock(); - lock.unlock(); + }).start().waitUntil(); return !failed.get(); } diff --git a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java index 04b4030..b528cf3 100644 --- a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java @@ -3,6 +3,7 @@ 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.LocaleLoader; import com.ilummc.tlib.util.Ref; import com.ilummc.tlib.util.TLogger; import org.bukkit.Bukkit; @@ -15,10 +16,11 @@ import java.lang.reflect.Field; public class DependencyInjector { public static void inject(Plugin plugin, Object o) { + injectDependencies(plugin, o); injectLogger(plugin, o); injectConfig(plugin, o); injectPluginInstance(plugin, o); - injectDependencies(plugin, o); + LocaleLoader.load(plugin, true); } static void injectOnEnable(Plugin plugin) { @@ -39,7 +41,7 @@ public class DependencyInjector { private static void ejectConfig(Plugin plugin, Object o) { for (Field field : Ref.getDeclaredFields(o.getClass())) { Config config; - if ((config = field.getType().getAnnotation(Config.class)) != null) { + if ((config = field.getType().getAnnotation(Config.class)) != null && config.saveOnExit()) { try { field.setAccessible(true); TConfigInjector.saveConfig(plugin, field.get(o)); diff --git a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java index 6d2e4bf..7a14c74 100644 --- a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java @@ -1,5 +1,6 @@ package com.ilummc.tlib.inject; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.io.Files; import com.google.gson.Gson; @@ -9,6 +10,7 @@ import com.ilummc.tlib.TLib; import com.ilummc.tlib.annotations.Config; import com.ilummc.tlib.bean.Property; import org.apache.commons.lang3.Validate; +import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.ConfigurationSerialization; import org.bukkit.plugin.Plugin; @@ -17,7 +19,6 @@ import org.yaml.snakeyaml.Yaml; import java.io.File; import java.io.IOException; -import java.lang.reflect.Array; import java.lang.reflect.Field; import java.nio.charset.Charset; import java.util.*; @@ -25,6 +26,36 @@ import java.util.stream.Collectors; 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 { Config config = clazz.getAnnotation(Config.class); @@ -32,7 +63,9 @@ public class TConfigInjector { File file = new File(plugin.getDataFolder(), config.name()); if (!file.exists()) if (config.fromJar()) plugin.saveResource(config.name(), true); else saveConfig(plugin, clazz.newInstance()); - return unserialize(plugin, clazz); + Object obj = unserialize(plugin, clazz); + if (!config.readOnly()) saveConfig(plugin, obj); + return obj; } catch (NullPointerException e) { TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置类 " + clazz.getSimpleName() + " 加载失败:没有 @Config 注解"); } catch (Exception e) { @@ -83,6 +116,7 @@ public class TConfigInjector { if (!target.exists()) target.createNewFile(); DumperOptions options = new DumperOptions(); options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + options.setAllowUnicode(false); Yaml yaml = new Yaml(options); String str = yaml.dump(obj); byte[] arr = str.getBytes(config.charset()); @@ -124,12 +158,7 @@ public class TConfigInjector { if (o.getClass().isPrimitive() || primitiveType.contains(o.getClass())) { return o; } else if (o.getClass().isArray()) { - List list = new ArrayList<>(); - int len = (int) o.getClass().getField("length").get(o); - for (int i = 0; i < len; i++) { - list.add(serialize(Array.get(o, i))); - } - return list; + return ImmutableList.copyOf(((Object[]) o)); } else if (o instanceof Collection) { return ((Collection) o).stream().map(this::serialize).collect(Collectors.toList()); } else if (o instanceof Map) { diff --git a/src/main/java/com/ilummc/tlib/resources/LocaleInstance.java b/src/main/java/com/ilummc/tlib/resources/LocaleInstance.java new file mode 100644 index 0000000..aec3862 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/resources/LocaleInstance.java @@ -0,0 +1,65 @@ +package com.ilummc.tlib.resources; + +import com.google.common.collect.ImmutableList; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; + +import javax.annotation.concurrent.ThreadSafe; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; +import java.util.stream.Collectors; + +@ThreadSafe +class LocaleInstance { + + private static final Function TO_SENDABLE = o -> { + if (o instanceof Sendable) return ((Sendable) o); + else if (o instanceof String) return SimpleChatMessage.of(((String) o)); + else return SimpleChatMessage.of(String.valueOf(o)); + }; + + LocaleInstance() { + } + + private final Map> map = new ConcurrentHashMap<>(); + + void sendTo(String path, CommandSender sender) { + map.getOrDefault(path, ImmutableList.of(Sendable.EMPTY)).forEach(sendable -> sendable.sendTo(sender)); + } + + void sendTo(String path, CommandSender sender, String... args) { + map.getOrDefault(path, ImmutableList.of(Sendable.EMPTY)).forEach(sendable -> sendable.sendTo(sender, args)); + System.out.println(map.toString()); + } + + void load(YamlConfiguration configuration) { + configuration.getKeys(false).forEach(s -> { + Object object = configuration.get(s); + if (object instanceof ConfigurationSection) + loadRecursively(s, (ConfigurationSection) object); + else if (object instanceof Sendable) + map.put(s, Collections.singletonList((Sendable) object)); + else if (object instanceof List && !((List) object).isEmpty()) + map.put(s, ((List) object).stream().map(TO_SENDABLE).collect(Collectors.toList())); + else map.put(s, Collections.singletonList(SimpleChatMessage.of(String.valueOf(object)))); + }); + } + + private void loadRecursively(String path, ConfigurationSection section) { + section.getKeys(false).forEach(s -> { + Object object = section.get(path + "." + s); + if (object instanceof ConfigurationSection) + loadRecursively(path + "." + s, (ConfigurationSection) object); + else if (object instanceof Sendable) + map.put(path + "." + s, Collections.singletonList((Sendable) object)); + else if (object instanceof List && !((List) object).isEmpty()) + map.put(path + "." + s, ((List) object).stream().map(TO_SENDABLE).collect(Collectors.toList())); + else map.put(path + "." + s, Collections.singletonList(SimpleChatMessage.of(String.valueOf(object)))); + }); + } + +} diff --git a/src/main/java/com/ilummc/tlib/resources/LocaleLoader.java b/src/main/java/com/ilummc/tlib/resources/LocaleLoader.java new file mode 100644 index 0000000..9767d43 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/resources/LocaleLoader.java @@ -0,0 +1,76 @@ +package com.ilummc.tlib.resources; + +import com.ilummc.tlib.TLib; +import com.ilummc.tlib.inject.TConfigInjector; +import me.skymc.taboolib.Main; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.configuration.serialization.ConfigurationSerialization; +import org.bukkit.plugin.Plugin; + +import java.io.File; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public class LocaleLoader { + + private static final Map map = new HashMap<>(); + + static void sendTo(Plugin plugin, String path, CommandSender sender, String... args) { + Optional.ofNullable(map.get(plugin.getName())).ifPresent(localeInstance -> localeInstance.sendTo(path, sender, args)); + } + + static void sendTo(Plugin plugin, String path, CommandSender sender) { + Optional.ofNullable(map.get(plugin.getName())).ifPresent(localeInstance -> localeInstance.sendTo(path, sender)); + } + + public static void init() { + ConfigurationSerialization.registerClass(SimpleChatMessage.class); + ConfigurationSerialization.registerClass(SimpleChatMessage.class, "Message"); + ConfigurationSerialization.registerClass(SimpleChatMessage.class, "MESSAGE"); + ConfigurationSerialization.registerClass(SimpleChatMessage.class, "TEXT"); + ConfigurationSerialization.registerClass(SimpleChatMessage.class, "Text"); + } + + public static void load(Plugin plugin, boolean ignoreLoaded) { + try { + if ((!ignoreLoaded || !map.containsKey(plugin.getName())) && plugin == Main.getInst() || + plugin.getDescription().getDepend().contains("TabooLib") || plugin.getDescription().getSoftDepend().contains("TabooLib")) { + InputStream inputStream = null; + File file = null; + String lang = null; + for (String s : TLib.getTLib().getConfig().getLocale()) { + lang = s; + file = new File(plugin.getDataFolder(), "/lang/" + s + ".yml"); + if (file.exists()) { + inputStream = Files.newInputStream(file.toPath(), StandardOpenOption.READ); + break; + } else if ((inputStream = plugin.getClass().getResourceAsStream("/lang/" + s + ".yml")) != null) + break; + } + if (inputStream == null) return; + TLib.getTLib().getLogger().info("尝试加载 " + lang + ".yml 作为语言文件"); + YamlConfiguration configuration = YamlConfiguration.loadConfiguration(new InputStreamReader(inputStream, Charset.forName("utf-8"))); + LocaleInstance localeInstance = new LocaleInstance(); + localeInstance.load(configuration); + map.put(plugin.getName(), localeInstance); + TConfigInjector.fixUnicode(configuration); + if (!file.exists()) { + file.getParentFile().mkdirs(); + file.createNewFile(); + } + configuration.save(file); + TLib.getTLib().getLogger().info("成功加载 " + lang + " 语言文件"); + } + } catch (Exception e) { + TLib.getTLib().getLogger().error("载入语言文件发生异常:" + e.toString()); + } + } + +} diff --git a/src/main/java/com/ilummc/tlib/resources/Sendable.java b/src/main/java/com/ilummc/tlib/resources/Sendable.java new file mode 100644 index 0000000..e033cb4 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/resources/Sendable.java @@ -0,0 +1,21 @@ +package com.ilummc.tlib.resources; + +import org.bukkit.command.CommandSender; + +public interface Sendable { + + Sendable EMPTY = new Sendable() { + @Override + public void sendTo(CommandSender sender) { + } + + @Override + public void sendTo(CommandSender sender, String... args) { + } + }; + + void sendTo(CommandSender sender); + + void sendTo(CommandSender sender, String... args); + +} diff --git a/src/main/java/com/ilummc/tlib/resources/SimpleChatMessage.java b/src/main/java/com/ilummc/tlib/resources/SimpleChatMessage.java new file mode 100644 index 0000000..7e8781d --- /dev/null +++ b/src/main/java/com/ilummc/tlib/resources/SimpleChatMessage.java @@ -0,0 +1,95 @@ +package com.ilummc.tlib.resources; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import com.ilummc.tlib.TLib; +import com.ilummc.tlib.compat.PlaceholderApiHook; +import com.ilummc.tlib.util.Strings; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.SerializableAs; + +import javax.annotation.concurrent.Immutable; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +@Immutable +@SerializableAs("TEXT") +@SuppressWarnings("unchecked") +public class SimpleChatMessage implements Sendable, ConfigurationSerializable { + + private final Object text; + + private final boolean usePlaceholder; + + private SimpleChatMessage(Object text, boolean usePlaceholder) { + this.usePlaceholder = usePlaceholder; + if (text instanceof String) + this.text = text; + else if (text instanceof List) + this.text = ImmutableList.copyOf(((List) text)); + else + throw new IllegalArgumentException("Param 'text' can only be an instance of String or String[] or List"); + } + + @Override + public void sendTo(CommandSender sender) { + if (text instanceof String) + sender.sendMessage(replaceMsg(sender, (String) text)); + else if (text instanceof List) + ((List) text).forEach(s -> sender.sendMessage(replaceMsg(sender, String.valueOf(s)))); + } + + @Override + public void sendTo(CommandSender sender, String... args) { + if (text instanceof String) + sender.sendMessage(replaceMsg(sender, Strings.replaceWithOrder((String) text, args))); + else if (text instanceof List) + ((List) text).forEach(s -> sender.sendMessage(replaceMsg(sender, Strings.replaceWithOrder(String.valueOf(s), args)))); + } + + private String replaceMsg(CommandSender sender, String s) { + return usePlaceholder ? PlaceholderApiHook.replace(sender, s) : s; + } + + @Override + public String toString() { + if (text instanceof String[]) return Arrays.toString((String[]) text); + else return text.toString(); + } + + @Override + public Map serialize() { + if (usePlaceholder) return Maps.newHashMap(ImmutableMap.of("text", text, "papi", true)); + return Maps.newHashMap(ImmutableMap.of("text", text)); + } + + public static SimpleChatMessage valueOf(Map map) { + if (map.containsKey("text")) { + Object object = map.get("text"); + Object objPapi = map.getOrDefault("papi", TLib.getTLib().getConfig().isEnablePapiByDefault()); + boolean papi = objPapi instanceof Boolean ? (boolean) objPapi : objPapi instanceof String && objPapi.equals("true"); + if (object instanceof List) + return new SimpleChatMessage(((List) object).stream() + .map(s -> ChatColor.translateAlternateColorCodes('&', s)) + .collect(Collectors.toList()), papi); + else if (object instanceof String[]) + return new SimpleChatMessage(Arrays.stream(((String[]) object)) + .map(s -> ChatColor.translateAlternateColorCodes('&', s)) + .collect(Collectors.toList()), papi); + else + return new SimpleChatMessage(ChatColor.translateAlternateColorCodes('&', Objects.toString(object)), papi); + } + return new SimpleChatMessage("§cError chat message loaded.", TLib.getTLib().getConfig().isEnablePapiByDefault()); + } + + public static SimpleChatMessage of(String s) { + return new SimpleChatMessage(ChatColor.translateAlternateColorCodes('&', s), TLib.getTLib().getConfig().isEnablePapiByDefault()); + } + +} diff --git a/src/main/java/com/ilummc/tlib/resources/TLocale.java b/src/main/java/com/ilummc/tlib/resources/TLocale.java new file mode 100644 index 0000000..99fc5ca --- /dev/null +++ b/src/main/java/com/ilummc/tlib/resources/TLocale.java @@ -0,0 +1,54 @@ +package com.ilummc.tlib.resources; + +import com.ilummc.tlib.util.Ref; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.java.JavaPlugin; + +import java.lang.reflect.Field; + +public final class TLocale { + + private TLocale() { + throw new AssertionError(); + } + + private static void sendTo(String path, CommandSender sender, String[] args, Class callerClass) { + try { + Field pluginField = callerClass.getClassLoader().getClass().getDeclaredField("plugin"); + pluginField.setAccessible(true); + JavaPlugin plugin = (JavaPlugin) pluginField.get(callerClass.getClassLoader()); + if (args.length == 0) + LocaleLoader.sendTo(plugin, path, sender); + else + LocaleLoader.sendTo(plugin, path, sender, args); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void sendTo(String path, CommandSender sender, String... args) { + Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, sender, args, clazz)); + } + + public static void sendTo(String path, CommandSender sender) { + Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, sender, new String[0], clazz)); + } + + public static void sendTo(CommandSender sender, String path, String... args) { + Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, sender, args, clazz)); + } + + public static void sendTo(CommandSender sender, String path) { + Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, sender, new String[0], clazz)); + } + + public static void sendToConsole(String path, String... args) { + Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, Bukkit.getConsoleSender(), args, clazz)); + } + + public static void sendToConsole(String path) { + Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, Bukkit.getConsoleSender(), new String[0], clazz)); + } + +} diff --git a/src/main/java/com/ilummc/tlib/util/Ref.java b/src/main/java/com/ilummc/tlib/util/Ref.java index b9d4f1a..3aa0990 100644 --- a/src/main/java/com/ilummc/tlib/util/Ref.java +++ b/src/main/java/com/ilummc/tlib/util/Ref.java @@ -4,6 +4,7 @@ import com.ilummc.tlib.TLib; import com.ilummc.tlib.util.asm.AsmAnalyser; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; +import sun.reflect.Reflection; import javax.annotation.concurrent.ThreadSafe; import java.lang.reflect.Field; @@ -46,11 +47,10 @@ public class Ref { classReader.accept(analyser, ClassReader.SKIP_DEBUG); fields = analyser.getFields().stream().map(name -> { try { - System.out.println(name); return clazz.getDeclaredField(name); } catch (Throwable ignored) { + return null; } - return null; }).filter(Objects::nonNull).collect(Collectors.toList()); if (cache) cachedFields.putIfAbsent(clazz.getName(), fields); return fields; @@ -59,4 +59,44 @@ public class Ref { } } + public static Optional> getCallerClass(int depth) { + return Optional.ofNullable(CallerClass.impl.getCallerClass(depth + 1)); + } + + private static abstract class CallerClass { + + private static CallerClass impl; + + static { + try { + Class.forName("sun.reflect.Reflection"); + impl = new ReflectionImpl(); + } catch (ClassNotFoundException e) { + impl = new StackTraceImpl(); + } + } + + abstract Class getCallerClass(int i); + + private static class ReflectionImpl extends CallerClass { + @Override + Class getCallerClass(int i) { + return Reflection.getCallerClass(i); + } + } + + private static class StackTraceImpl extends CallerClass { + + @Override + Class getCallerClass(int i) { + StackTraceElement[] elements = Thread.currentThread().getStackTrace(); + try { + return Class.forName(elements[i].getClassName()); + } catch (ClassNotFoundException e) { + return null; + } + } + } + } + } diff --git a/src/main/java/com/ilummc/tlib/util/Strings.java b/src/main/java/com/ilummc/tlib/util/Strings.java index 050c43a..3e5bba3 100644 --- a/src/main/java/com/ilummc/tlib/util/Strings.java +++ b/src/main/java/com/ilummc/tlib/util/Strings.java @@ -10,6 +10,7 @@ public class Strings { * @return 替换好的字符串 */ public static String replaceWithOrder(String template, String... args) { + if (args.length == 0) return template; char[] arr = template.toCharArray(); StringBuilder stringBuilder = new StringBuilder(template.length()); for (int i = 0; i < arr.length; i++) { diff --git a/src/main/resources/lang/zh_CN.yml b/src/main/resources/lang/zh_CN.yml new file mode 100644 index 0000000..e69de29 From b49a779859fc50806fbd058df8fedccafa2683bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9D=8F=E9=BB=91?= Date: Sun, 22 Apr 2018 22:12:42 +0800 Subject: [PATCH 17/44] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/ilummc/tlib/ExampleMain.java | 5 +- src/main/java/com/ilummc/tlib/TLib.java | 117 +++++------ .../com/ilummc/tlib/annotations/Config.java | 4 +- .../ilummc/tlib/annotations/Dependency.java | 8 +- .../com/ilummc/tlib/annotations/Logger.java | 4 +- .../ilummc/tlib/bean/PropertyTypeAdaptor.java | 4 +- .../ilummc/tlib/compat/PlaceholderHook.java | 41 ++++ .../com/ilummc/tlib/config/TLibConfig.java | 23 +++ .../ilummc/tlib/dependency/TDependency.java | 27 +-- .../tlib/dependency/TDependencyLoader.java | 4 +- .../com/ilummc/tlib/filter/TLoggerFilter.java | 32 ++++ .../ilummc/tlib/inject/TConfigInjector.java | 36 ++-- .../ilummc/tlib/inject/TConfigWatcher.java | 11 +- .../tlib/inject/TDependencyInjector.java | 173 +++++++++++++++++ .../ilummc/tlib/inject/TPluginManager.java | 181 ++++++++++++++++++ .../com/ilummc/tlib/resources/TLocale.java | 71 ++++--- .../tlib/resources/TLocaleInstance.java | 98 ++++++++++ .../ilummc/tlib/resources/TLocaleLoader.java | 104 ++++++++++ .../tlib/resources/TLocaleSendable.java | 25 +++ .../tlib/resources/type/TLocaleText.java | 107 +++++++++++ .../tlib/resources/type/TLocaleTitle.java | 83 ++++++++ src/main/java/com/ilummc/tlib/util/Ref.java | 30 ++- .../java/com/ilummc/tlib/util/TLogger.java | 20 +- .../com/ilummc/tlib/util/asm/AsmAnalyser.java | 6 +- src/main/java/me/skymc/taboolib/Main.java | 28 ++- src/main/java/me/skymc/taboolib/TabooLib.java | 78 ++------ .../taboolib/anvil/AnvilContainerAPI.java | 9 +- .../versions/AnvilContainer_V1_11_R1.java | 8 +- .../versions/AnvilContainer_V1_8_R3.java | 8 +- .../anvil/versions/AnvilContainer_V1_9_4.java | 8 +- .../bookformatter/BookAchievement.java | 37 +++- .../taboolib/bookformatter/BookFormatter.java | 6 +- .../bookformatter/BookReflection.java | 19 +- .../me/skymc/taboolib/bstats/Metrics.java | 33 ++-- .../skymc/taboolib/commands/MainCommands.java | 23 ++- .../locale/TabooLibLocaleCommand.java | 75 ++++++++ .../commands/sub/AttributesCommand.java | 5 +- .../taboolib/commands/sub/HelpCommand.java | 15 +- .../taboolib/commands/sub/InfoCommand.java | 7 +- .../taboolib/commands/sub/SaveCommand.java | 2 +- .../taboolib/commands/sub/SlotCommand.java | 5 +- .../commands/sub/TagDeleteCommand.java | 7 +- .../commands/sub/cycle/CycleCommand.java | 3 +- .../commands/sub/cycle/CycleInfoCommand.java | 7 +- .../commands/sub/cycle/CycleListCommand.java | 5 +- .../sub/cycle/CycleUpdateCommand.java | 7 +- .../itemlist/listener/ItemLibraryPatch.java | 13 +- .../commands/sub/shell/ShellCommand.java | 3 +- .../sounds/listener/SoundsLibraryPatch.java | 9 +- .../taboolib/cooldown/CooldownUtils.java | 5 +- .../cooldown/seconds/CooldownUtils2.java | 4 +- .../me/skymc/taboolib/csvutils/CsvReader.java | 10 +- .../me/skymc/taboolib/csvutils/CsvWriter.java | 7 +- .../me/skymc/taboolib/damage/DamageUtils.java | 5 +- .../taboolib/database/GlobalDataManager.java | 15 +- .../taboolib/database/PlayerDataManager.java | 21 +- .../skymc/taboolib/display/ActionUtils.java | 5 +- .../me/skymc/taboolib/display/TitleUtils.java | 4 +- .../me/skymc/taboolib/entity/EntityTag.java | 9 +- .../taboolib/events/CustomBookOpenEvent.java | 5 +- .../skymc/taboolib/events/DefaultEvent2.java | 7 +- .../skymc/taboolib/fileutils/ConfigUtils.java | 23 ++- .../skymc/taboolib/fileutils/EncodeUtils.java | 9 +- .../skymc/taboolib/fileutils/FileUtils.java | 36 ++-- .../me/skymc/taboolib/fileutils/LogUtils.java | 9 +- .../skymc/taboolib/inventory/DropUtils.java | 3 +- .../taboolib/inventory/InventoryUtil.java | 6 +- .../skymc/taboolib/inventory/ItemUtils.java | 33 ++-- .../inventory/speciaitem/SpecialItem.java | 13 +- .../itemnbtapi/NBTReflectionUtil.java | 19 +- .../taboolib/javascript/JavaScriptUtils.java | 9 +- .../skymc/taboolib/javashell/JavaShell.java | 21 +- .../taboolib/javashell/utils/JarUtils.java | 15 +- .../me/skymc/taboolib/json/JSONObject.java | 8 +- .../me/skymc/taboolib/json/JSONTokener.java | 7 +- .../taboolib/jsonformatter/JSONFormatter.java | 19 +- .../jsonformatter/hover/ShowItemEvent.java | 17 +- .../listener/ListenerPlayerCommand.java | 11 +- .../taboolib/listener/ListenerPlayerJump.java | 5 +- .../taboolib/listener/ListenerPlayerQuit.java | 3 +- .../listener/ListenerPluginDisable.java | 15 +- .../skymc/taboolib/message/ChatCatcher.java | 7 +- .../taboolib/methods/ReflectionUtils.java | 4 +- .../skymc/taboolib/mysql/MysqlConnection.java | 6 +- .../me/skymc/taboolib/mysql/MysqlUtils.java | 9 +- .../mysql/protect/MySQLConnection.java | 17 +- .../java/me/skymc/taboolib/nms/NMSUtil18.java | 26 +-- .../java/me/skymc/taboolib/nms/NMSUtil19.java | 26 ++- .../java/me/skymc/taboolib/nms/NMSUtils.java | 4 +- .../skymc/taboolib/nms/item/DabItemUtils.java | 19 +- .../taboolib/nms/item/IDabItemUtils.java | 9 +- .../taboolib/nms/item/impl/_164ItemUtils.java | 26 ++- .../nms/item/impl/_1710ItemUtils.java | 26 ++- .../taboolib/nms/item/impl/_194ItemUtils.java | 25 ++- .../me/skymc/taboolib/other/WeightUtils.java | 4 +- .../me/skymc/taboolib/packet/PacketUtils.java | 5 +- .../me/skymc/taboolib/particle/EffLib.java | 19 +- .../taboolib/permission/PermissionUtils.java | 5 +- .../skymc/taboolib/playerdata/DataUtils.java | 19 +- .../me/skymc/taboolib/plugin/PluginUtils.java | 33 ++-- .../skymc/taboolib/regen/WorldGuardUtils.java | 7 +- .../taboolib/scoreboard/ScoreboardUtil.java | 10 +- .../skymc/taboolib/skript/SkriptHandler.java | 5 +- .../expression/ExpressionTabooCodeItem.java | 5 +- .../me/skymc/taboolib/string/Language.java | 18 +- .../skymc/taboolib/string/LanguageUtils.java | 7 +- .../string/language2/Language2Format.java | 17 +- .../string/language2/Language2Value.java | 13 +- .../language2/value/Language2Action.java | 13 +- .../string/language2/value/Language2Book.java | 25 +-- .../string/language2/value/Language2Json.java | 15 +- .../language2/value/Language2Json2.java | 25 +-- .../string/language2/value/Language2Text.java | 11 +- .../language2/value/Language2Title.java | 11 +- .../taboolib/support/SupportPlaceholder.java | 5 +- .../taboolib/support/SupportWorldGuard.java | 9 +- .../me/skymc/taboolib/team/TagManager.java | 9 +- .../taboolib/timecycle/TimeCycleManager.java | 15 +- .../me/skymc/taboolib/update/UpdateTask.java | 18 +- src/main/java/me/skymc/tlm/TLM.java | 3 +- .../skymc/tlm/annotation/DisableConfig.java | 6 +- .../skymc/tlm/command/sub/TLMKitCommand.java | 13 +- .../skymc/tlm/module/TabooLibraryModule.java | 11 +- .../me/skymc/tlm/module/sub/ModuleKits.java | 13 +- .../skymc/tlm/module/sub/ModuleTimeCycle.java | 11 +- src/main/resources/config.yml | 5 +- 126 files changed, 1896 insertions(+), 705 deletions(-) create mode 100644 src/main/java/com/ilummc/tlib/compat/PlaceholderHook.java create mode 100644 src/main/java/com/ilummc/tlib/config/TLibConfig.java create mode 100644 src/main/java/com/ilummc/tlib/filter/TLoggerFilter.java create mode 100644 src/main/java/com/ilummc/tlib/inject/TDependencyInjector.java create mode 100644 src/main/java/com/ilummc/tlib/inject/TPluginManager.java create mode 100644 src/main/java/com/ilummc/tlib/resources/TLocaleInstance.java create mode 100644 src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java create mode 100644 src/main/java/com/ilummc/tlib/resources/TLocaleSendable.java create mode 100644 src/main/java/com/ilummc/tlib/resources/type/TLocaleText.java create mode 100644 src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java create mode 100644 src/main/java/me/skymc/taboolib/commands/locale/TabooLibLocaleCommand.java diff --git a/src/main/java/com/ilummc/tlib/ExampleMain.java b/src/main/java/com/ilummc/tlib/ExampleMain.java index ed4022f..3ac4877 100644 --- a/src/main/java/com/ilummc/tlib/ExampleMain.java +++ b/src/main/java/com/ilummc/tlib/ExampleMain.java @@ -1,9 +1,10 @@ package com.ilummc.tlib; +import org.bukkit.Bukkit; +import org.bukkit.plugin.java.JavaPlugin; + import com.ilummc.tlib.annotations.Config; import com.ilummc.tlib.bean.Property; -import org.bukkit.Bukkit; -import org.bukkit.plugin.java.JavaPlugin; @Config(name = "cfg.yml", charset = "GBK") public class ExampleMain extends JavaPlugin { diff --git a/src/main/java/com/ilummc/tlib/TLib.java b/src/main/java/com/ilummc/tlib/TLib.java index a235b22..4b5514b 100644 --- a/src/main/java/com/ilummc/tlib/TLib.java +++ b/src/main/java/com/ilummc/tlib/TLib.java @@ -1,105 +1,76 @@ package com.ilummc.tlib; -import com.ilummc.tlib.annotations.Config; -import com.ilummc.tlib.annotations.Dependency; -import com.ilummc.tlib.annotations.Logger; -import com.ilummc.tlib.compat.PlaceholderApiHook; -import com.ilummc.tlib.inject.DependencyInjector; -import com.ilummc.tlib.inject.TConfigWatcher; -import com.ilummc.tlib.inject.TLibPluginManager; -import com.ilummc.tlib.resources.LocaleLoader; -import com.ilummc.tlib.resources.TLocale; -import com.ilummc.tlib.util.TLogger; -import me.skymc.taboolib.Main; -import org.bukkit.Bukkit; - import java.io.File; import java.lang.reflect.Field; +import org.bukkit.Bukkit; + +import com.ilummc.tlib.annotations.Dependency; +import com.ilummc.tlib.compat.PlaceholderHook; +import com.ilummc.tlib.config.TLibConfig; +import com.ilummc.tlib.filter.TLoggerFilter; +import com.ilummc.tlib.inject.TConfigWatcher; +import com.ilummc.tlib.inject.TDependencyInjector; +import com.ilummc.tlib.inject.TPluginManager; +import com.ilummc.tlib.resources.TLocaleLoader; +import com.ilummc.tlib.util.TLogger; + +import lombok.Getter; +import me.skymc.taboolib.Main; + @Dependency(type = Dependency.Type.LIBRARY, maven = "org.ow2.asm:asm:6.1.1") @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") public class TLib { + @Getter private static TLib tLib; - @Logger("§8[§3§lTabooLib§8][§r{1}§8] §f{2}") - private TLogger tLogger = new TLogger("§8[§3§lTabooLib§8][§r{1}§8] §f{2}", Main.getInst(), TLogger.FINE); + @Getter + private TLogger logger = new TLogger("§8[§3§lTabooLib§8][§r{1}§8] §f{2}", Main.getInst(), TLogger.FINE); + @Getter private TLibConfig config; + @Getter private TConfigWatcher configWatcher = new TConfigWatcher(); + + @Getter + private File libsFolder; private TLib() { - } - - public TLibConfig getConfig() { - return config; - } - - public TLogger getLogger() { - return tLogger; - } - - public TConfigWatcher getConfigWatcher() { - return configWatcher; - } - - public static TLib getTLib() { - return tLib; - } - - public static void injectPluginManager() { - // 注入 PluginLoader 用于加载依赖 - try { - Field field = Bukkit.getServer().getClass().getDeclaredField("pluginManager"); - field.setAccessible(true); - field.set(Bukkit.getServer(), new TLibPluginManager()); - } catch (NoSuchFieldException | IllegalAccessException e) { - e.printStackTrace(); - } + libsFolder = new File(Main.getInst().getDataFolder(), "/libs"); + if (!libsFolder.exists()) { + libsFolder.mkdirs(); + } } public static void init() { - new File(Main.getInst().getDataFolder(), "/libs").mkdirs(); tLib = new TLib(); - LocaleLoader.init(); - PlaceholderApiHook.init(); - DependencyInjector.inject(Main.getInst(), tLib); - if (Bukkit.getPluginManager() instanceof TLibPluginManager) + + TLoggerFilter.init(); + TLocaleLoader.init(); + PlaceholderHook.init(); + TDependencyInjector.inject(Main.getInst(), tLib); + + if (Bukkit.getPluginManager() instanceof TPluginManager) { tLib.getLogger().info("注入成功"); - else + } else { tLib.getLogger().fatal("注入失败"); - TLocale.sendToConsole("test1"); - TLocale.sendToConsole("test2"); - TLocale.sendToConsole("test3"); - TLocale.sendToConsole("test4.node1", "Hello", "world"); + } } public static void unload() { tLib.getConfigWatcher().unregisterAll(); - DependencyInjector.eject(Main.getInst(), tLib); + TDependencyInjector.eject(Main.getInst(), tLib); } - - @Config(name = "tlib.yml", listenChanges = true, readOnly = false) - public static class TLibConfig { - - private int downloadPoolSize = 4; - - public int getDownloadPoolSize() { - return downloadPoolSize; - } - - private String[] locale = {"zh_CN", "en_US"}; - - public String[] getLocale() { - return locale; - } - - private boolean enablePapiByDefault = false; - - public boolean isEnablePapiByDefault() { - return enablePapiByDefault; + + public static void injectPluginManager() { + try { + Field field = Bukkit.getServer().getClass().getDeclaredField("pluginManager"); + field.setAccessible(true); + field.set(Bukkit.getServer(), new TPluginManager()); + } catch (NoSuchFieldException | IllegalAccessException ignored) { } } } diff --git a/src/main/java/com/ilummc/tlib/annotations/Config.java b/src/main/java/com/ilummc/tlib/annotations/Config.java index 62af121..87b6aa3 100644 --- a/src/main/java/com/ilummc/tlib/annotations/Config.java +++ b/src/main/java/com/ilummc/tlib/annotations/Config.java @@ -1,13 +1,13 @@ 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; +import com.ilummc.tlib.util.Ref; + @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Config { diff --git a/src/main/java/com/ilummc/tlib/annotations/Dependency.java b/src/main/java/com/ilummc/tlib/annotations/Dependency.java index 9c706c9..0f00aca 100644 --- a/src/main/java/com/ilummc/tlib/annotations/Dependency.java +++ b/src/main/java/com/ilummc/tlib/annotations/Dependency.java @@ -1,8 +1,12 @@ package com.ilummc.tlib.annotations; -import com.ilummc.tlib.dependency.TDependency; +import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; -import java.lang.annotation.*; +import com.ilummc.tlib.dependency.TDependency; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) diff --git a/src/main/java/com/ilummc/tlib/annotations/Logger.java b/src/main/java/com/ilummc/tlib/annotations/Logger.java index bec8bc5..af54460 100644 --- a/src/main/java/com/ilummc/tlib/annotations/Logger.java +++ b/src/main/java/com/ilummc/tlib/annotations/Logger.java @@ -1,12 +1,12 @@ package com.ilummc.tlib.annotations; -import com.ilummc.tlib.util.TLogger; - import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import com.ilummc.tlib.util.TLogger; + @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Logger { diff --git a/src/main/java/com/ilummc/tlib/bean/PropertyTypeAdaptor.java b/src/main/java/com/ilummc/tlib/bean/PropertyTypeAdaptor.java index f802433..0a52b19 100644 --- a/src/main/java/com/ilummc/tlib/bean/PropertyTypeAdaptor.java +++ b/src/main/java/com/ilummc/tlib/bean/PropertyTypeAdaptor.java @@ -1,12 +1,12 @@ package com.ilummc.tlib.bean; +import java.lang.reflect.Type; + 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 { @Override diff --git a/src/main/java/com/ilummc/tlib/compat/PlaceholderHook.java b/src/main/java/com/ilummc/tlib/compat/PlaceholderHook.java new file mode 100644 index 0000000..520044e --- /dev/null +++ b/src/main/java/com/ilummc/tlib/compat/PlaceholderHook.java @@ -0,0 +1,41 @@ +package com.ilummc.tlib.compat; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import me.clip.placeholderapi.PlaceholderAPI; + +public abstract class PlaceholderHook { + + private static PlaceholderHook impl; + + public static void init() { + if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) + impl = new PlaceholderImpl(); + else impl = new AbstractImpl(); + } + + public static String replace(CommandSender sender, String text) { + return sender instanceof Player ? impl.replace(((Player) sender), text) : text; + } + + abstract String replace(Player player, String text); + + private static class PlaceholderImpl extends PlaceholderHook { + + @Override + String replace(Player player, String text) { + return PlaceholderAPI.setPlaceholders(player, text); + } + } + + private static class AbstractImpl extends PlaceholderHook { + + @Override + String replace(Player player, String text) { + return text; + } + } + +} diff --git a/src/main/java/com/ilummc/tlib/config/TLibConfig.java b/src/main/java/com/ilummc/tlib/config/TLibConfig.java new file mode 100644 index 0000000..744d9f0 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/config/TLibConfig.java @@ -0,0 +1,23 @@ +package com.ilummc.tlib.config; + +import com.ilummc.tlib.annotations.Config; + +/** + * @author sky + * @since 2018-04-22 14:31:11 + */ +@Config(name = "tlib.yml", listenChanges = true, readOnly = false) +public class TLibConfig { + + private String[] locale = {"zh_CN", "en_US"}; + + public String[] getLocale() { + return locale; + } + + private boolean enablePlaceholderHookByDefault = false; + + public boolean isEnablePlaceholderHookByDefault() { + return enablePlaceholderHookByDefault; + } +} diff --git a/src/main/java/com/ilummc/tlib/dependency/TDependency.java b/src/main/java/com/ilummc/tlib/dependency/TDependency.java index ab8b631..61e86a1 100644 --- a/src/main/java/com/ilummc/tlib/dependency/TDependency.java +++ b/src/main/java/com/ilummc/tlib/dependency/TDependency.java @@ -1,12 +1,13 @@ package com.ilummc.tlib.dependency; +import java.io.File; +import java.util.concurrent.atomic.AtomicBoolean; + import com.ilummc.eagletdl.EagletTask; import com.ilummc.eagletdl.ProgressEvent; import com.ilummc.tlib.TLib; -import me.skymc.taboolib.Main; -import java.io.File; -import java.util.concurrent.atomic.AtomicBoolean; +import me.skymc.taboolib.Main; public class TDependency { @@ -43,8 +44,9 @@ public class TDependency { if (downloadMaven(repo, arr[0], arr[1], arr[2], file, url)) { TDependencyLoader.addToPath(Main.getInst(), file); return true; - } else + } else { return false; + } } } return false; @@ -60,14 +62,10 @@ public class TDependency { new EagletTask() .url(link) .file(target) - .setThreads(TLib.getTLib().getConfig().getDownloadPoolSize()) - .setOnError(event -> { - }) - .setOnConnected(event -> TLib.getTLib().getLogger().info(" 正在下载 " + String.join(":", - new String[]{groupId, artifactId, version}) + - " 大小 " + ProgressEvent.format(event.getContentLength()))) - .setOnProgress(event -> TLib.getTLib().getLogger().info(" 下载速度 " + event.getSpeedFormatted() - + " 进度 " + event.getPercentageFormatted())) + .setThreads(getDownloadPoolSize()) + .setOnError(event -> {}) + .setOnConnected(event -> TLib.getTLib().getLogger().info(" 正在下载 " + String.join(":", new String[]{groupId, artifactId, version}) + " 大小 " + ProgressEvent.format(event.getContentLength()))) + .setOnProgress(event -> TLib.getTLib().getLogger().info(" 下载速度 " + event.getSpeedFormatted() + " 进度 " + event.getPercentageFormatted())) .setOnComplete(event -> { if (event.isSuccess()) { TLib.getTLib().getLogger().info(" 下载 " + String.join(":", new String[]{groupId, artifactId, version}) + " 完成"); @@ -79,5 +77,8 @@ public class TDependency { }).start().waitUntil(); return !failed.get(); } - + + private static int getDownloadPoolSize() { + return Main.getInst().getConfig().contains("DOWNLOAD-POOL-SIZE") ? Main.getInst().getConfig().getInt("DOWNLOAD-POOL-SIZE") : 4; + } } diff --git a/src/main/java/com/ilummc/tlib/dependency/TDependencyLoader.java b/src/main/java/com/ilummc/tlib/dependency/TDependencyLoader.java index 3c52502..3db37f7 100644 --- a/src/main/java/com/ilummc/tlib/dependency/TDependencyLoader.java +++ b/src/main/java/com/ilummc/tlib/dependency/TDependencyLoader.java @@ -1,7 +1,5 @@ package com.ilummc.tlib.dependency; -import org.bukkit.plugin.Plugin; - import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -9,6 +7,8 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import org.bukkit.plugin.Plugin; + public class TDependencyLoader { public static synchronized void addToPath(Plugin plugin, URL url) { diff --git a/src/main/java/com/ilummc/tlib/filter/TLoggerFilter.java b/src/main/java/com/ilummc/tlib/filter/TLoggerFilter.java new file mode 100644 index 0000000..a3db470 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/filter/TLoggerFilter.java @@ -0,0 +1,32 @@ +package com.ilummc.tlib.filter; + +import java.util.Arrays; +import java.util.logging.Filter; +import java.util.logging.LogRecord; + +import org.bukkit.Bukkit; + +/** + * @author Bkm016 + * @since 2018-04-22 + */ +public class TLoggerFilter implements Filter { + + public static void init() { + Bukkit.getLogger().setFilter(new TLoggerFilter()); + } + + @Override + public boolean isLoggable(LogRecord e) { + if (e.getMessage().contains("Cannot load configuration from stream")) { + StackTraceElement[] elements = Thread.currentThread().getStackTrace(); + for (StackTraceElement element : elements) { + if (element.getClassName().contains("ConfigUtils")) { + System.out.println(Arrays.asList(e.getParameters())); + } + } + return false; + } + return true; + } +} diff --git a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java index 7a14c74..e2cbd02 100644 --- a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java @@ -1,5 +1,25 @@ package com.ilummc.tlib.inject; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.nio.charset.Charset; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.Validate; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.ConfigurationSerialization; +import org.bukkit.plugin.Plugin; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; + import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.io.Files; @@ -9,24 +29,10 @@ import com.google.gson.annotations.SerializedName; import com.ilummc.tlib.TLib; import com.ilummc.tlib.annotations.Config; import com.ilummc.tlib.bean.Property; -import org.apache.commons.lang3.Validate; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.configuration.serialization.ConfigurationSerializable; -import org.bukkit.configuration.serialization.ConfigurationSerialization; -import org.bukkit.plugin.Plugin; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Field; -import java.nio.charset.Charset; -import java.util.*; -import java.util.stream.Collectors; public class TConfigInjector { - public static void fixUnicode(YamlConfiguration configuration) { + public static void fixUnicode(FileConfiguration configuration) { try { Field field = YamlConfiguration.class.getDeclaredField("yamlOptions"); field.setAccessible(true); diff --git a/src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java b/src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java index 8327b96..bfb013c 100644 --- a/src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java +++ b/src/main/java/com/ilummc/tlib/inject/TConfigWatcher.java @@ -1,11 +1,12 @@ package com.ilummc.tlib.inject; -import com.ilummc.tlib.TLib; -import org.apache.commons.lang3.tuple.Triple; - import java.io.File; import java.io.IOException; -import java.nio.file.*; +import java.nio.file.FileSystems; +import java.nio.file.StandardWatchEventKinds; +import java.nio.file.WatchEvent; +import java.nio.file.WatchKey; +import java.nio.file.WatchService; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -14,6 +15,8 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; +import org.apache.commons.lang3.tuple.Triple; + public class TConfigWatcher { private ScheduledExecutorService service = Executors.newScheduledThreadPool(1); diff --git a/src/main/java/com/ilummc/tlib/inject/TDependencyInjector.java b/src/main/java/com/ilummc/tlib/inject/TDependencyInjector.java new file mode 100644 index 0000000..da78271 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/inject/TDependencyInjector.java @@ -0,0 +1,173 @@ +package com.ilummc.tlib.inject; + +import java.io.File; +import java.lang.reflect.Field; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; + +import com.ilummc.tlib.TLib; +import com.ilummc.tlib.annotations.Config; +import com.ilummc.tlib.annotations.Dependencies; +import com.ilummc.tlib.annotations.Dependency; +import com.ilummc.tlib.annotations.Logger; +import com.ilummc.tlib.annotations.PluginInstance; +import com.ilummc.tlib.dependency.TDependency; +import com.ilummc.tlib.resources.TLocaleLoader; +import com.ilummc.tlib.util.Ref; +import com.ilummc.tlib.util.TLogger; + +public class TDependencyInjector { + + public static void inject(Plugin plugin, Object o) { + injectDependencies(plugin, o); + injectLogger(plugin, o); + injectConfig(plugin, o); + injectPluginInstance(plugin, o); + TLocaleLoader.load(plugin, true); + } + + static void injectOnEnable(Plugin plugin) { + inject(plugin, plugin); + } + + static void onDisable(Plugin plugin) { + eject(plugin, plugin); + } + + public static void eject(Plugin plugin, Object o) { + try { + ejectConfig(plugin, o); + } catch (Throwable ignored) { + } + } + + private static void ejectConfig(Plugin plugin, Object o) { + for (Field field : Ref.getDeclaredFields(o.getClass())) { + Config config; + if ((config = field.getType().getAnnotation(Config.class)) != null && config.saveOnExit()) { + try { + field.setAccessible(true); + TConfigInjector.saveConfig(plugin, field.get(o)); + TLib.getTLib().getLogger().info("插件 " + plugin + " 的配置 " + config.name() + " 已保存"); + } catch (Exception e) { + TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置 " + config.name() + " 保存失败"); + e.printStackTrace(); + } + } + } + } + + private static void injectConfig(Plugin plugin, Object o) { + for (Field field : Ref.getDeclaredFields(o.getClass())) { + try { + Config config; + if ((config = field.getType().getAnnotation(Config.class)) != null) { + field.setAccessible(true); + Object obj = TConfigInjector.loadConfig(plugin, field.getType()); + if (obj != null) { + TLib.getTLib().getLogger().info("插件 " + plugin.getName() + " 的 " + config.name() + " 配置文件成功加载"); + field.set(o, obj); + if (config.listenChanges()) { + TLib.getTLib().getLogger().info("开始监听插件 " + plugin.getName() + " 的 " + config.name() + " 配置文件"); + TLib.getTLib().getConfigWatcher().addOnListen( + new File(plugin.getDataFolder(), config.name()), + obj, + object -> { + try { + Object newObj = TConfigInjector.loadConfig(plugin, object.getClass()); + for (Field f : newObj.getClass().getDeclaredFields()) { + f.setAccessible(true); + f.set(obj, f.get(newObj)); + } + TLib.getTLib().getLogger().info("插件 " + plugin.getName() + " 的 " + config.name() + " 配置文件成功重载"); + } catch (Exception ignored) { + TLib.getTLib().getLogger().warn("插件 " + plugin.getName() + " 的 " + 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(TLogger.class); + TLogger tLogger = new TLogger(logger.value(), plugin, logger.level()); + if (!field.isAccessible()) + field.setAccessible(true); + field.set(o, 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())) { + TLib.getTLib().getLogger().warn(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 = 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}; + } + } + if (dependencies.length != 0) { + TLib.getTLib().getLogger().info("正在加载 " + plugin.getName() + " 插件所需的依赖"); + for (Dependency dependency : dependencies) { + if (dependency.type() == Dependency.Type.PLUGIN) { + if (TDependency.requestPlugin(dependency.plugin())) { + TLib.getTLib().getLogger().info(" " + plugin.getName() + " 请求的插件 " + dependency.plugin() + " 加载成功。"); + } else { + TLib.getTLib().getLogger().warn(" " + plugin.getName() + " 请求的插件 " + dependency.plugin() + " 加载失败。"); + } + } + if (dependency.type() == Dependency.Type.LIBRARY) { + if (TDependency.requestLib(dependency.maven(), dependency.mavenRepo(), dependency.url())) { + TLib.getTLib().getLogger().info(" " + plugin.getName() + " 请求的库文件 " + String.join(":", dependency.maven()) + " 加载成功。"); + } else { + TLib.getTLib().getLogger().warn(" " + plugin.getName() + " 请求的库文件 " + String.join(":", dependency.maven()) + " 加载失败。"); + } + } + } + TLib.getTLib().getLogger().info("依赖加载完成"); + } + } + +} diff --git a/src/main/java/com/ilummc/tlib/inject/TPluginManager.java b/src/main/java/com/ilummc/tlib/inject/TPluginManager.java new file mode 100644 index 0000000..54b2318 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/inject/TPluginManager.java @@ -0,0 +1,181 @@ +package com.ilummc.tlib.inject; + +import java.io.File; +import java.util.Set; + +import org.bukkit.Bukkit; +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.EventExecutor; +import org.bukkit.plugin.InvalidDescriptionException; +import org.bukkit.plugin.InvalidPluginException; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginLoader; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.UnknownDependencyException; + +import me.skymc.taboolib.Main; + +public class TPluginManager implements PluginManager { + + private final PluginManager instance; + + private final Main main = (Main) Main.getInst(); + + public TPluginManager() { + instance = Bukkit.getPluginManager(); + } + + @Override + public void registerInterface(Class 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) disablePlugin(plugin); + } + 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 aClass, Listener listener, EventPriority eventPriority, EventExecutor eventExecutor, Plugin plugin) { + instance.registerEvent(aClass, listener, eventPriority, eventExecutor, plugin); + } + + @Override + public void registerEvent(Class 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.onDisable(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 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 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 getDefaultPermSubscriptions(boolean b) { + return instance.getDefaultPermSubscriptions(b); + } + + @Override + public Set getPermissions() { + return instance.getPermissions(); + } + + @Override + public boolean useTimings() { + return instance.useTimings(); + } +} diff --git a/src/main/java/com/ilummc/tlib/resources/TLocale.java b/src/main/java/com/ilummc/tlib/resources/TLocale.java index 99fc5ca..8842d60 100644 --- a/src/main/java/com/ilummc/tlib/resources/TLocale.java +++ b/src/main/java/com/ilummc/tlib/resources/TLocale.java @@ -1,54 +1,69 @@ package com.ilummc.tlib.resources; -import com.ilummc.tlib.util.Ref; +import java.lang.reflect.Field; + import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; -import java.lang.reflect.Field; +import com.google.common.base.Strings; +import com.ilummc.tlib.TLib; +import com.ilummc.tlib.util.Ref; + +import me.skymc.taboolib.Main; +import me.skymc.taboolib.TabooLib; public final class TLocale { private TLocale() { throw new AssertionError(); } + + private static JavaPlugin getCallerPlugin(Class callerClass) { + try { + Field pluginField = callerClass.getClassLoader().getClass().getDeclaredField("plugin"); + pluginField.setAccessible(true); + return (JavaPlugin) pluginField.get(callerClass.getClassLoader()); + } catch (Exception ignored) { + TLib.getTLib().getLogger().error("无效的语言文件发送形式: &4" + callerClass.getName()); + } + return (JavaPlugin) Main.getInst(); + } private static void sendTo(String path, CommandSender sender, String[] args, Class callerClass) { - try { - Field pluginField = callerClass.getClassLoader().getClass().getDeclaredField("plugin"); - pluginField.setAccessible(true); - JavaPlugin plugin = (JavaPlugin) pluginField.get(callerClass.getClassLoader()); - if (args.length == 0) - LocaleLoader.sendTo(plugin, path, sender); - else - LocaleLoader.sendTo(plugin, path, sender, args); - } catch (Exception e) { - e.printStackTrace(); - } + TLocaleLoader.sendTo(getCallerPlugin(callerClass), path, sender, args); } - - public static void sendTo(String path, CommandSender sender, String... args) { - Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, sender, args, clazz)); + + private static String asString(String path, String[] args, Class callerClass) { + return TLocaleLoader.asString(getCallerPlugin(callerClass), path); } - - public static void sendTo(String path, CommandSender sender) { - Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, sender, new String[0], clazz)); + + public static void sendToConsole(String path, String... args) { + Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, Bukkit.getConsoleSender(), args, clazz)); } public static void sendTo(CommandSender sender, String path, String... args) { Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, sender, args, clazz)); } - - public static void sendTo(CommandSender sender, String path) { - Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, sender, new String[0], clazz)); + + public static void sendTo(String path, CommandSender sender, String... args) { + Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, sender, args, clazz)); } - public static void sendToConsole(String path, String... args) { - Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, Bukkit.getConsoleSender(), args, clazz)); + public static String asString(String path, String... args) { + try { + return asString(path, args, Ref.getCallerClass(3).get()); + } catch (Exception e) { + TLib.getTLib().getLogger().error("语言文件获取失败: " + path); + TLib.getTLib().getLogger().error("原因: " + e.getMessage()); + return "§4<" + path + "§4>"; + } } - - public static void sendToConsole(String path) { - Ref.getCallerClass(3).ifPresent(clazz -> sendTo(path, Bukkit.getConsoleSender(), new String[0], clazz)); + + public static void reload() { + Ref.getCallerClass(3).ifPresent(clazz -> TLocaleLoader.load(getCallerPlugin(clazz), false)); } - } diff --git a/src/main/java/com/ilummc/tlib/resources/TLocaleInstance.java b/src/main/java/com/ilummc/tlib/resources/TLocaleInstance.java new file mode 100644 index 0000000..591aa4a --- /dev/null +++ b/src/main/java/com/ilummc/tlib/resources/TLocaleInstance.java @@ -0,0 +1,98 @@ +package com.ilummc.tlib.resources; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; +import java.util.stream.Collectors; + +import javax.annotation.concurrent.ThreadSafe; + +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +import com.google.common.collect.ImmutableList; +import com.ilummc.tlib.TLib; +import com.ilummc.tlib.resources.type.TLocaleText; + +@ThreadSafe +@SuppressWarnings("rawtypes") +class TLocaleInstance { + + TLocaleInstance() { + } + + void sendTo(String path, CommandSender sender) { + try { + map.getOrDefault(path, ImmutableList.of(TLocaleSendable.getEmpty(path))).forEach(sendable -> sendable.sendTo(sender)); + } catch (Exception e) { + TLib.getTLib().getLogger().error("语言文件发送失败: " + path); + TLib.getTLib().getLogger().error("原因: " + e.getMessage()); + } + } + + void sendTo(String path, CommandSender sender, String... args) { + try { + map.getOrDefault(path, ImmutableList.of(TLocaleSendable.getEmpty(path))).forEach(sendable -> sendable.sendTo(sender, args)); + } catch (Exception e) { + TLib.getTLib().getLogger().error("语言文件发送失败: " + path); + TLib.getTLib().getLogger().error("原因: " + e.getMessage()); + } + } + + String asString(String path) { + return map.getOrDefault(path, ImmutableList.of(TLocaleSendable.getEmpty(path))).get(0).asString(); + } + + void load(FileConfiguration configuration) { + configuration.getKeys(false).forEach(s -> { + Object object = configuration.get(s); + if (object instanceof ConfigurationSection) { + loadRecursively(s, (ConfigurationSection) object); + } + else if (object instanceof TLocaleSendable) { + map.put(s, Collections.singletonList((TLocaleSendable) object)); + } + else if (object instanceof List && !((List) object).isEmpty()) { + map.put(s, ((List) object).stream().map(TO_SENDABLE).collect(Collectors.toList())); + } + else { + map.put(s, Collections.singletonList(TLocaleText.of(String.valueOf(object)))); + } + }); + } + + private static final Function TO_SENDABLE = o -> { + if (o instanceof TLocaleSendable) { + return ((TLocaleSendable) o); + } else if (o instanceof String) { + return TLocaleText.of(((String) o)); + } else { + return TLocaleText.of(String.valueOf(o)); + } + }; + + private final Map> map = new ConcurrentHashMap<>(); + + private void loadRecursively(String path, ConfigurationSection section) { + section.getKeys(false).forEach(s -> { + Object object = section.get(path + "." + s); + if (object instanceof ConfigurationSection) { + loadRecursively(path + "." + s, (ConfigurationSection) object); + } + else if (object instanceof TLocaleSendable) { + map.put(path + "." + s, Collections.singletonList((TLocaleSendable) object)); + } + else if (object instanceof List && !((List) object).isEmpty()) { + map.put(path + "." + s, ((List) object).stream().map(TO_SENDABLE).collect(Collectors.toList())); + } + else { + map.put(path + "." + s, Collections.singletonList(TLocaleText.of(String.valueOf(object)))); + } + }); + } + +} diff --git a/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java b/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java new file mode 100644 index 0000000..2397547 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java @@ -0,0 +1,104 @@ +package com.ilummc.tlib.resources; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.channels.FileChannel; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.configuration.serialization.ConfigurationSerialization; +import org.bukkit.plugin.Plugin; + +import com.ilummc.tlib.TLib; +import com.ilummc.tlib.inject.TConfigInjector; +import com.ilummc.tlib.resources.type.TLocaleText; + +import me.skymc.taboolib.Main; +import me.skymc.taboolib.fileutils.ConfigUtils; +import me.skymc.taboolib.fileutils.FileUtils; + +public class TLocaleLoader { + + private static final Map map = new HashMap<>(); + + static void sendTo(Plugin plugin, String path, CommandSender sender, String... args) { + Optional.ofNullable(map.get(plugin.getName())).ifPresent(localeInstance -> localeInstance.sendTo(path, sender, args)); + } + + static String asString(Plugin plugin, String path) { + return Optional.ofNullable(map.get(plugin.getName())).get().asString(path); + } + + public static void init() { + ConfigurationSerialization.registerClass(TLocaleText.class, "TEXT"); + } + + public static void load(Plugin plugin, boolean ignoreLoaded) { + try { + if ((!ignoreLoaded || !map.containsKey(plugin.getName())) && plugin == Main.getInst() || plugin.getDescription().getDepend().contains("TabooLib") || plugin.getDescription().getSoftDepend().contains("TabooLib")) { + InputStream inputStream = null; + File file = null; + String lang = null; + for (String s : TLib.getTLib().getConfig().getLocale()) { + lang = s; + file = new File(plugin.getDataFolder(), "/lang/" + s + ".yml"); + if (file.exists()) { + inputStream = Files.newInputStream(file.toPath(), StandardOpenOption.READ); + break; + } else if ((inputStream = plugin.getClass().getResourceAsStream("/lang/" + s + ".yml")) != null) { + break; + } + } + if (inputStream == null) { + TLib.getTLib().getLogger().error("语言文件加载失败"); + return; + } + if (!file.exists()) { + file.getParentFile().mkdirs(); + file.createNewFile(); + saveResource(inputStream, file); + } + TLib.getTLib().getLogger().info("尝试加载 " + lang + ".yml 作为语言文件"); + FileConfiguration configuration = ConfigUtils.load(plugin, file); + TLocaleInstance localeInstance = new TLocaleInstance(); + localeInstance.load(configuration); + map.put(plugin.getName(), localeInstance); + TConfigInjector.fixUnicode(configuration); + TLib.getTLib().getLogger().info("成功加载 " + lang + " 语言文件"); + } + } catch (Exception e) { + TLib.getTLib().getLogger().error("载入语言文件发生异常:" + e.toString()); + } + } + + private static void saveResource(InputStream inputStream, File file) { + FileOutputStream fileOutputStream = null; + try { + byte[] data = FileUtils.read(inputStream); + fileOutputStream = new FileOutputStream(file); + fileOutputStream.write(data); + } catch (Exception e) { + TLib.getTLib().getLogger().error("资源文件写入失败: " + file); + TLib.getTLib().getLogger().error("原因: " + e.getMessage()); + } finally { + try { + if (fileOutputStream != null) { + fileOutputStream.close(); + } + } catch (Exception ignored) { + } + } + } +} diff --git a/src/main/java/com/ilummc/tlib/resources/TLocaleSendable.java b/src/main/java/com/ilummc/tlib/resources/TLocaleSendable.java new file mode 100644 index 0000000..e00b9d1 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/resources/TLocaleSendable.java @@ -0,0 +1,25 @@ +package com.ilummc.tlib.resources; + +import org.bukkit.command.CommandSender; + +public interface TLocaleSendable { + + public static TLocaleSendable getEmpty(String path) { + return new TLocaleSendable() { + + @Override + public void sendTo(CommandSender sender, String... args) { + sender.sendMessage("§4<" + path + "§4>"); + } + + @Override + public String asString(String... args) { + return "§4<" + path + "§4>"; + } + }; + } + + void sendTo(CommandSender sender, String... args); + + String asString(String... args); +} diff --git a/src/main/java/com/ilummc/tlib/resources/type/TLocaleText.java b/src/main/java/com/ilummc/tlib/resources/type/TLocaleText.java new file mode 100644 index 0000000..875dbee --- /dev/null +++ b/src/main/java/com/ilummc/tlib/resources/type/TLocaleText.java @@ -0,0 +1,107 @@ +package com.ilummc.tlib.resources.type; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import javax.annotation.concurrent.Immutable; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.SerializableAs; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import com.ilummc.tlib.TLib; +import com.ilummc.tlib.compat.PlaceholderHook; +import com.ilummc.tlib.resources.TLocaleSendable; +import com.ilummc.tlib.util.Strings; + +@Immutable +@SerializableAs("TEXT") +@SuppressWarnings({"unchecked", "rawtypes"}) +public class TLocaleText implements TLocaleSendable, ConfigurationSerializable { + + private final Object text; + + private final boolean usePlaceholder; + + private TLocaleText(Object text, boolean usePlaceholder) { + this.usePlaceholder = usePlaceholder; + if (text instanceof String) { + this.text = text; + } + else if (text instanceof List) { + this.text = ImmutableList.copyOf(((List) text)); + } + else { + throw new IllegalArgumentException("Param 'text' can only be an instance of String or String[] or List"); + } + } + + private String replaceMsg(CommandSender sender, String s) { + return usePlaceholder ? PlaceholderHook.replace(sender, s) : s; + } + + @Override + public void sendTo(CommandSender sender, String... args) { + if (text instanceof String) { + sender.sendMessage(replaceMsg(sender, Strings.replaceWithOrder((String) text, args))); + } + else if (text instanceof List) { + ((List) text).forEach(s -> sender.sendMessage(replaceMsg(sender, Strings.replaceWithOrder(String.valueOf(s), args)))); + } + } + + @Override + public String asString(String... args) { + return Strings.replaceWithOrder((String) text, args); + } + + @Override + public String toString() { + if (text instanceof String[]) { + return Arrays.toString((String[]) text); + } else { + return text.toString(); + } + } + + @Override + public Map serialize() { + if (usePlaceholder) { + return Maps.newHashMap(ImmutableMap.of("text", text, "papi", true)); + } + return Maps.newHashMap(ImmutableMap.of("text", text)); + } + + public static TLocaleText valueOf(Map map) { + if (map.containsKey("text")) { + Object object = map.get("text"); + Object objPapi = map.getOrDefault("papi", TLib.getTLib().getConfig().isEnablePlaceholderHookByDefault()); + boolean papi = objPapi instanceof Boolean ? (boolean) objPapi : objPapi instanceof String && objPapi.equals("true"); + if (object instanceof List) { + return new TLocaleText(((List) object).stream() + .map(s -> ChatColor.translateAlternateColorCodes('&', s)) + .collect(Collectors.toList()), papi); + } + else if (object instanceof String[]) { + return new TLocaleText(Arrays.stream(((String[]) object)) + .map(s -> ChatColor.translateAlternateColorCodes('&', s)) + .collect(Collectors.toList()), papi); + } + else { + return new TLocaleText(ChatColor.translateAlternateColorCodes('&', Objects.toString(object)), papi); + } + } + return new TLocaleText("§cError chat message loaded.", TLib.getTLib().getConfig().isEnablePlaceholderHookByDefault()); + } + + public static TLocaleText of(String s) { + return new TLocaleText(ChatColor.translateAlternateColorCodes('&', s), TLib.getTLib().getConfig().isEnablePlaceholderHookByDefault()); + } +} diff --git a/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java b/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java new file mode 100644 index 0000000..ee8c808 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java @@ -0,0 +1,83 @@ +package com.ilummc.tlib.resources.type; + +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.concurrent.Immutable; + +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.SerializableAs; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import com.ilummc.tlib.TLib; +import com.ilummc.tlib.resources.TLocaleSendable; + +import lombok.Data; +import lombok.Getter; +import net.minecraft.server.v1_11_R1.EntityEvoker.e; + +/** + * @author Bkm016 + * @since 2018-04-22 + */ + +@Immutable +@SerializableAs("TITLE") +@Data +public class TLocaleTitle implements TLocaleSendable, ConfigurationSerializable { + + private String title; + private String subtitle; + private int fadein; + private int fadeout; + private int stay; + + private boolean usePlaceholder; + + private TLocaleTitle(boolean usePlaceholder) { + this.usePlaceholder = usePlaceholder; + } + + @Override + public void sendTo(CommandSender sender, String... args) { + // TODO Auto-generated method stub + } + + @Override + public String asString(String... args) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Map serialize() { + HashMap map = Maps.newHashMap(); + map.put("papi", usePlaceholder); + map.put("title", title); + map.put("subtitle", subtitle); + map.put("fadein", fadein); + map.put("fadeout", fadeout); + map.put("stay", stay); + return map; + } + + public static TLocaleTitle valueOf(Map map) { + TLocaleTitle title; + try { + title = new TLocaleTitle((boolean) map.getOrDefault("papi", TLib.getTLib().getConfig().isEnablePlaceholderHookByDefault())); + title.setTitle((String) map.getOrDefault("title", "")); + title.setSubtitle((String) map.getOrDefault("subtitle", "")); + title.setFadein((int) map.getOrDefault("fadein", 10)); + title.setFadeout((int) map.getOrDefault("fadeout", 10)); + title.setStay((int) map.getOrDefault("stay", 10)); + } catch (Exception e) { + title = new TLocaleTitle(false); + title.setTitle("§4Load failed!"); + title.setSubtitle("§c" + e.getMessage()); + } + return title; + } + +} diff --git a/src/main/java/com/ilummc/tlib/util/Ref.java b/src/main/java/com/ilummc/tlib/util/Ref.java index 3aa0990..8e83627 100644 --- a/src/main/java/com/ilummc/tlib/util/Ref.java +++ b/src/main/java/com/ilummc/tlib/util/Ref.java @@ -1,16 +1,24 @@ package com.ilummc.tlib.util; +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +import javax.annotation.concurrent.ThreadSafe; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; + import com.ilummc.tlib.TLib; import com.ilummc.tlib.util.asm.AsmAnalyser; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassWriter; -import sun.reflect.Reflection; -import javax.annotation.concurrent.ThreadSafe; -import java.lang.reflect.Field; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; +import sun.reflect.Reflection; @ThreadSafe public class Ref { @@ -62,7 +70,7 @@ public class Ref { public static Optional> getCallerClass(int depth) { return Optional.ofNullable(CallerClass.impl.getCallerClass(depth + 1)); } - + private static abstract class CallerClass { private static CallerClass impl; @@ -79,7 +87,9 @@ public class Ref { abstract Class getCallerClass(int i); private static class ReflectionImpl extends CallerClass { - @Override + + @SuppressWarnings({ "deprecation", "restriction" }) + @Override Class getCallerClass(int i) { return Reflection.getCallerClass(i); } diff --git a/src/main/java/com/ilummc/tlib/util/TLogger.java b/src/main/java/com/ilummc/tlib/util/TLogger.java index 325e430..bbbe2bf 100644 --- a/src/main/java/com/ilummc/tlib/util/TLogger.java +++ b/src/main/java/com/ilummc/tlib/util/TLogger.java @@ -1,9 +1,11 @@ package com.ilummc.tlib.util; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.plugin.Plugin; + import lombok.Getter; import lombok.Setter; -import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; public class TLogger { @@ -27,37 +29,37 @@ public class TLogger { public void verbose(String msg) { if (level <= VERBOSE) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§f全部", msg)); + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§f全部", ChatColor.translateAlternateColorCodes('&', msg))); } public void finest(String msg) { if (level <= FINEST) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§e良好", msg)); + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§e良好", ChatColor.translateAlternateColorCodes('&', msg))); } public void fine(String msg) { if (level <= FINE) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§a正常", msg)); + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§a正常", ChatColor.translateAlternateColorCodes('&', msg))); } public void info(String msg) { if (level <= INFO) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§b信息", msg)); + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§b信息", ChatColor.translateAlternateColorCodes('&', msg))); } public void warn(String msg) { if (level <= WARN) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§6警告", "§6" + msg)); + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§6警告", "§6" + ChatColor.translateAlternateColorCodes('&', msg))); } public void error(String msg) { if (level <= ERROR) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§c错误", "§c" + msg)); + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§c错误", "§c" + ChatColor.translateAlternateColorCodes('&', msg))); } public void fatal(String msg) { if (level <= FATAL) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§4致命错误", "§4" + msg)); + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§4致命错误", "§4" + ChatColor.translateAlternateColorCodes('&', msg))); } } diff --git a/src/main/java/com/ilummc/tlib/util/asm/AsmAnalyser.java b/src/main/java/com/ilummc/tlib/util/asm/AsmAnalyser.java index 70d6937..9a42734 100644 --- a/src/main/java/com/ilummc/tlib/util/asm/AsmAnalyser.java +++ b/src/main/java/com/ilummc/tlib/util/asm/AsmAnalyser.java @@ -1,12 +1,12 @@ package com.ilummc.tlib.util.asm; +import java.util.ArrayList; +import java.util.List; + import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.Opcodes; -import java.util.ArrayList; -import java.util.List; - public class AsmAnalyser extends ClassVisitor implements Opcodes { private final List fields = new ArrayList<>(); diff --git a/src/main/java/me/skymc/taboolib/Main.java b/src/main/java/me/skymc/taboolib/Main.java index cd6b530..9dd4698 100644 --- a/src/main/java/me/skymc/taboolib/Main.java +++ b/src/main/java/me/skymc/taboolib/Main.java @@ -1,6 +1,17 @@ package me.skymc.taboolib; +import java.io.File; +import java.util.Random; + +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.event.Listener; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitRunnable; + import com.ilummc.tlib.TLib; + import lombok.Getter; import lombok.Setter; import me.skymc.taboolib.anvil.AnvilContainerAPI; @@ -8,6 +19,7 @@ import me.skymc.taboolib.bstats.Metrics; import me.skymc.taboolib.client.LogClient; import me.skymc.taboolib.commands.MainCommands; import me.skymc.taboolib.commands.language.Language2Command; +import me.skymc.taboolib.commands.locale.TabooLibLocaleCommand; import me.skymc.taboolib.commands.sub.itemlist.listener.ItemLibraryPatch; import me.skymc.taboolib.commands.sub.sounds.listener.SoundsLibraryPatch; import me.skymc.taboolib.database.GlobalDataManager; @@ -18,7 +30,11 @@ import me.skymc.taboolib.fileutils.ConfigUtils; import me.skymc.taboolib.inventory.ItemUtils; import me.skymc.taboolib.inventory.speciaitem.SpecialItem; import me.skymc.taboolib.javashell.JavaShell; -import me.skymc.taboolib.listener.*; +import me.skymc.taboolib.listener.ListenerNetWork; +import me.skymc.taboolib.listener.ListenerPlayerCommand; +import me.skymc.taboolib.listener.ListenerPlayerJump; +import me.skymc.taboolib.listener.ListenerPlayerQuit; +import me.skymc.taboolib.listener.ListenerPluginDisable; import me.skymc.taboolib.message.ChatCatcher; import me.skymc.taboolib.message.MsgUtils; import me.skymc.taboolib.mysql.protect.MySQLConnection; @@ -38,15 +54,6 @@ import me.skymc.tlm.TLM; import me.skymc.tlm.command.TLMCommands; import me.skymc.tlm.module.TabooLibraryModule; import net.milkbowl.vault.economy.Economy; -import org.bukkit.Bukkit; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.event.Listener; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.scheduler.BukkitRunnable; - -import java.io.File; -import java.util.Random; @SuppressWarnings("deprecation") public class Main extends JavaPlugin implements Listener { @@ -162,6 +169,7 @@ public class Main extends JavaPlugin implements Listener { getCommand("taboolib").setExecutor(new MainCommands()); getCommand("language2").setExecutor(new Language2Command()); getCommand("taboolibrarymodule").setExecutor(new TLMCommands()); + getCommand("tabooliblocale").setExecutor(new TabooLibLocaleCommand()); // 注册监听 registerListener(); diff --git a/src/main/java/me/skymc/taboolib/TabooLib.java b/src/main/java/me/skymc/taboolib/TabooLib.java index d218a54..2f5cf19 100644 --- a/src/main/java/me/skymc/taboolib/TabooLib.java +++ b/src/main/java/me/skymc/taboolib/TabooLib.java @@ -1,42 +1,35 @@ package me.skymc.taboolib; -import me.skymc.taboolib.playerdata.DataUtils; -import net.md_5.bungee.api.ChatColor; -import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; - import java.util.UUID; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +import me.skymc.taboolib.playerdata.DataUtils; +import net.md_5.bungee.api.ChatColor; + public class TabooLib { - /** - * 获取插件版本 - * - * @return - */ + public static void debug(Plugin plugin, String... args) { + if (Main.getInst().getConfig().getBoolean("DEBUG")) { + for (String var : args) { + Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "[TabooLib - DEBUG][" + plugin.getName() + "] " + ChatColor.RED + var); + } + } + } + public static double getPluginVersion() { try { return Double.valueOf(Main.getInst().getDescription().getVersion()); - } - catch (Exception e) { + } catch (Exception e) { return 0D; } } - /** - * 获取 NMS 版本 - * - * @return - */ public static String getVersion() { return Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; } - /** - * 获取服务器 UID - * - * @return - */ public static String getServerUID() { if (!DataUtils.getPluginData("TabooLibrary", null).contains("serverUID")) { DataUtils.getPluginData("TabooLibrary", null).set("serverUID", UUID.randomUUID().toString()); @@ -44,53 +37,24 @@ public class TabooLib { return DataUtils.getPluginData("TabooLibrary", null).getString("serverUID"); } - /** - * 重置服务器 UID - */ public static void resetServerUID() { DataUtils.getPluginData("TabooLibrary", null).set("serverUID", UUID.randomUUID().toString()); } - /** - * 向后台发送 DEBUG 信息 - * - * @param plugin - * @param ss - */ - public static void debug(Plugin plugin, String... ss) { - if (Main.getInst().getConfig().getBoolean("DEBUG")) { - for (String s : ss) { - // [00:42:41 INFO]: [TabooLib - DEBUG][TabooPlugin] Example bug message - Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "[TabooLib - DEBUG][" + plugin.getName() + "] " + ChatColor.RED + s); - } - } - } - - /** - * 获取 NMS 版本(数字) - * - * @return - */ public static int getVerint() { if (getVersion().startsWith("v1_7")) { return 10700; - } - else if (getVersion().startsWith("v1_8")) { + } else if (getVersion().startsWith("v1_8")) { return 10800; - } - else if (getVersion().startsWith("v1_9")) { + } else if (getVersion().startsWith("v1_9")) { return 10900; - } - else if (getVersion().startsWith("v1_10")) { + } else if (getVersion().startsWith("v1_10")) { return 11000; - } - else if (getVersion().startsWith("v1_11")) { + } else if (getVersion().startsWith("v1_11")) { return 11100; - } - else if (getVersion().startsWith("v1_12")) { + } else if (getVersion().startsWith("v1_12")) { return 11200; - } - else if (getVersion().startsWith("v1_13")) { + } else if (getVersion().startsWith("v1_13")) { return 11300; } return 0; diff --git a/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java b/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java index dc1fc87..b0fbdd0 100644 --- a/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java +++ b/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java @@ -1,6 +1,9 @@ package me.skymc.taboolib.anvil; -import me.skymc.taboolib.anvil.versions.AnvilContainer_V1_9_4; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Sound; @@ -15,9 +18,7 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; +import me.skymc.taboolib.anvil.versions.AnvilContainer_V1_9_4; public class AnvilContainerAPI implements Listener{ diff --git a/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_11_R1.java b/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_11_R1.java index b9c1b08..4c6c656 100644 --- a/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_11_R1.java +++ b/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_11_R1.java @@ -1,9 +1,15 @@ package me.skymc.taboolib.anvil.versions; -import net.minecraft.server.v1_11_R1.*; import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer; import org.bukkit.entity.Player; +import net.minecraft.server.v1_11_R1.BlockPosition; +import net.minecraft.server.v1_11_R1.ChatMessage; +import net.minecraft.server.v1_11_R1.ContainerAnvil; +import net.minecraft.server.v1_11_R1.EntityHuman; +import net.minecraft.server.v1_11_R1.EntityPlayer; +import net.minecraft.server.v1_11_R1.PacketPlayOutOpenWindow; + public class AnvilContainer_V1_11_R1 extends ContainerAnvil { public AnvilContainer_V1_11_R1(EntityHuman player) diff --git a/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_8_R3.java b/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_8_R3.java index 196ff3b..f5c0117 100644 --- a/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_8_R3.java +++ b/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_8_R3.java @@ -1,9 +1,15 @@ package me.skymc.taboolib.anvil.versions; -import net.minecraft.server.v1_8_R3.*; import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; import org.bukkit.entity.Player; +import net.minecraft.server.v1_8_R3.BlockPosition; +import net.minecraft.server.v1_8_R3.ChatMessage; +import net.minecraft.server.v1_8_R3.ContainerAnvil; +import net.minecraft.server.v1_8_R3.EntityHuman; +import net.minecraft.server.v1_8_R3.EntityPlayer; +import net.minecraft.server.v1_8_R3.PacketPlayOutOpenWindow; + public class AnvilContainer_V1_8_R3 extends ContainerAnvil { public AnvilContainer_V1_8_R3(EntityHuman player) diff --git a/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_9_4.java b/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_9_4.java index 6c0a1c0..33a80f5 100644 --- a/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_9_4.java +++ b/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_9_4.java @@ -1,9 +1,15 @@ package me.skymc.taboolib.anvil.versions; -import net.minecraft.server.v1_9_R2.*; import org.bukkit.craftbukkit.v1_9_R2.entity.CraftPlayer; import org.bukkit.entity.Player; +import net.minecraft.server.v1_9_R2.BlockPosition; +import net.minecraft.server.v1_9_R2.ChatMessage; +import net.minecraft.server.v1_9_R2.ContainerAnvil; +import net.minecraft.server.v1_9_R2.EntityHuman; +import net.minecraft.server.v1_9_R2.EntityPlayer; +import net.minecraft.server.v1_9_R2.PacketPlayOutOpenWindow; + public class AnvilContainer_V1_9_4 extends ContainerAnvil { public AnvilContainer_V1_9_4(EntityHuman player) diff --git a/src/main/java/me/skymc/taboolib/bookformatter/BookAchievement.java b/src/main/java/me/skymc/taboolib/bookformatter/BookAchievement.java index c2b143e..ea1c284 100644 --- a/src/main/java/me/skymc/taboolib/bookformatter/BookAchievement.java +++ b/src/main/java/me/skymc/taboolib/bookformatter/BookAchievement.java @@ -1,10 +1,43 @@ package me.skymc.taboolib.bookformatter; -import org.bukkit.Achievement; +import static org.bukkit.Achievement.ACQUIRE_IRON; +import static org.bukkit.Achievement.BAKE_CAKE; +import static org.bukkit.Achievement.BOOKCASE; +import static org.bukkit.Achievement.BREED_COW; +import static org.bukkit.Achievement.BREW_POTION; +import static org.bukkit.Achievement.BUILD_BETTER_PICKAXE; +import static org.bukkit.Achievement.BUILD_FURNACE; +import static org.bukkit.Achievement.BUILD_HOE; +import static org.bukkit.Achievement.BUILD_PICKAXE; +import static org.bukkit.Achievement.BUILD_SWORD; +import static org.bukkit.Achievement.BUILD_WORKBENCH; +import static org.bukkit.Achievement.COOK_FISH; +import static org.bukkit.Achievement.DIAMONDS_TO_YOU; +import static org.bukkit.Achievement.ENCHANTMENTS; +import static org.bukkit.Achievement.END_PORTAL; +import static org.bukkit.Achievement.EXPLORE_ALL_BIOMES; +import static org.bukkit.Achievement.FLY_PIG; +import static org.bukkit.Achievement.FULL_BEACON; +import static org.bukkit.Achievement.GET_BLAZE_ROD; +import static org.bukkit.Achievement.GET_DIAMONDS; +import static org.bukkit.Achievement.GHAST_RETURN; +import static org.bukkit.Achievement.KILL_COW; +import static org.bukkit.Achievement.KILL_ENEMY; +import static org.bukkit.Achievement.KILL_WITHER; +import static org.bukkit.Achievement.MAKE_BREAD; +import static org.bukkit.Achievement.MINE_WOOD; +import static org.bukkit.Achievement.NETHER_PORTAL; +import static org.bukkit.Achievement.ON_A_RAIL; +import static org.bukkit.Achievement.OPEN_INVENTORY; +import static org.bukkit.Achievement.OVERKILL; +import static org.bukkit.Achievement.OVERPOWERED; +import static org.bukkit.Achievement.SNIPE_SKELETON; +import static org.bukkit.Achievement.SPAWN_WITHER; +import static org.bukkit.Achievement.THE_END; import java.util.HashMap; -import static org.bukkit.Achievement.*; +import org.bukkit.Achievement; public final class BookAchievement { diff --git a/src/main/java/me/skymc/taboolib/bookformatter/BookFormatter.java b/src/main/java/me/skymc/taboolib/bookformatter/BookFormatter.java index ccf735b..2f9ff1b 100644 --- a/src/main/java/me/skymc/taboolib/bookformatter/BookFormatter.java +++ b/src/main/java/me/skymc/taboolib/bookformatter/BookFormatter.java @@ -1,13 +1,13 @@ package me.skymc.taboolib.bookformatter; -import me.skymc.taboolib.bookformatter.builder.BookBuilder; -import me.skymc.taboolib.events.CustomBookOpenEvent; - import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import me.skymc.taboolib.bookformatter.builder.BookBuilder; +import me.skymc.taboolib.events.CustomBookOpenEvent; + @SuppressWarnings("deprecation") public final class BookFormatter { diff --git a/src/main/java/me/skymc/taboolib/bookformatter/BookReflection.java b/src/main/java/me/skymc/taboolib/bookformatter/BookReflection.java index 2cbde2f..bb22245 100644 --- a/src/main/java/me/skymc/taboolib/bookformatter/BookReflection.java +++ b/src/main/java/me/skymc/taboolib/bookformatter/BookReflection.java @@ -1,14 +1,5 @@ package me.skymc.taboolib.bookformatter; -import lombok.Getter; -import net.md_5.bungee.api.chat.BaseComponent; -import net.md_5.bungee.api.chat.TextComponent; -import net.md_5.bungee.chat.ComponentSerializer; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.BookMeta; - import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -17,6 +8,16 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; + +import lombok.Getter; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.chat.ComponentSerializer; + /** * The NMS helper for all the Book-API */ diff --git a/src/main/java/me/skymc/taboolib/bstats/Metrics.java b/src/main/java/me/skymc/taboolib/bstats/Metrics.java index c5067ed..cb2f721 100644 --- a/src/main/java/me/skymc/taboolib/bstats/Metrics.java +++ b/src/main/java/me/skymc/taboolib/bstats/Metrics.java @@ -1,5 +1,25 @@ package me.skymc.taboolib.bstats; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.logging.Level; +import java.util.zip.GZIPOutputStream; + +import javax.net.ssl.HttpsURLConnection; + import org.bukkit.Bukkit; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; @@ -9,19 +29,6 @@ import org.bukkit.plugin.java.JavaPlugin; import org.json.simple.JSONArray; import org.json.simple.JSONObject; -import javax.net.ssl.HttpsURLConnection; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.URL; -import java.util.*; -import java.util.concurrent.Callable; -import java.util.logging.Level; -import java.util.zip.GZIPOutputStream; - /** * bStats collects some data for plugin authors. * diff --git a/src/main/java/me/skymc/taboolib/commands/MainCommands.java b/src/main/java/me/skymc/taboolib/commands/MainCommands.java index b6765c0..3e6704b 100644 --- a/src/main/java/me/skymc/taboolib/commands/MainCommands.java +++ b/src/main/java/me/skymc/taboolib/commands/MainCommands.java @@ -1,15 +1,30 @@ package me.skymc.taboolib.commands; -import me.skymc.taboolib.commands.sub.*; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +import me.skymc.taboolib.commands.sub.AttributesCommand; +import me.skymc.taboolib.commands.sub.EnchantCommand; +import me.skymc.taboolib.commands.sub.FlagCommand; +import me.skymc.taboolib.commands.sub.HelpCommand; +import me.skymc.taboolib.commands.sub.ImportCommand; +import me.skymc.taboolib.commands.sub.InfoCommand; +import me.skymc.taboolib.commands.sub.ItemCommand; +import me.skymc.taboolib.commands.sub.PotionCommand; +import me.skymc.taboolib.commands.sub.SaveCommand; +import me.skymc.taboolib.commands.sub.SlotCommand; +import me.skymc.taboolib.commands.sub.TagDeleteCommand; +import me.skymc.taboolib.commands.sub.TagPrefixCommand; +import me.skymc.taboolib.commands.sub.TagSuffixCommand; +import me.skymc.taboolib.commands.sub.VariableGetCommand; +import me.skymc.taboolib.commands.sub.VariableSetCommand; import me.skymc.taboolib.commands.sub.cycle.CycleCommand; import me.skymc.taboolib.commands.sub.itemlist.ItemListCommand; import me.skymc.taboolib.commands.sub.shell.ShellCommand; import me.skymc.taboolib.commands.sub.sounds.SoundsCommand; import me.skymc.taboolib.inventory.ItemUtils; import me.skymc.taboolib.message.MsgUtils; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; public class MainCommands implements CommandExecutor{ diff --git a/src/main/java/me/skymc/taboolib/commands/locale/TabooLibLocaleCommand.java b/src/main/java/me/skymc/taboolib/commands/locale/TabooLibLocaleCommand.java new file mode 100644 index 0000000..f1294b4 --- /dev/null +++ b/src/main/java/me/skymc/taboolib/commands/locale/TabooLibLocaleCommand.java @@ -0,0 +1,75 @@ +package me.skymc.taboolib.commands.locale; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.ilummc.tlib.resources.TLocale; + +/** + * @author sky + * @since 2018-04-22 14:36:28 + */ +public class TabooLibLocaleCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command arg1, String label, String[] args) { + if (args.length == 0) { + TLocale.sendTo(sender, "commands-taboolocale-helps", label); + } + else if (args[0].equalsIgnoreCase("send")) { + send(sender, args); + } + else if (args[0].equalsIgnoreCase("reload")) { + reload(sender); + } + else { + TLocale.sendTo(sender, "commands-taboolocale-invalid"); + } + return true; + } + + void send(CommandSender sender, String[] args) { + if (args.length < 3) { + TLocale.sendTo(sender, "commands-taboolocale-send-empty"); + return; + } + + List target = new ArrayList<>(); + if (args[1].equalsIgnoreCase("all")) { + target.addAll(Bukkit.getOnlinePlayers()); + } else { + Player player = Bukkit.getPlayerExact(args[1]); + if (player == null) { + TLocale.sendTo(sender, "commands-taboolocale-send-offline", args[1]); + return; + } + target.add(player); + } + + if (args.length > 3) { + String[] vars = new String[args.length - 3]; + for (int i = 3 ; i < args.length ; i++) { + vars[i - 3] = args[i]; + } + target.forEach(x -> TLocale.sendTo(x, args[2], vars)); + } else { + target.forEach(x -> TLocale.sendTo(x, args[2])); + } + + if (sender instanceof Player) { + TLocale.sendTo(sender, "commands-taboolocale-send-success"); + } + } + + void reload(CommandSender sender) { + TLocale.reload(); + TLocale.sendTo(sender, "commands-taboolocale-reload"); + } + +} diff --git a/src/main/java/me/skymc/taboolib/commands/sub/AttributesCommand.java b/src/main/java/me/skymc/taboolib/commands/sub/AttributesCommand.java index 04fbb24..48ab718 100644 --- a/src/main/java/me/skymc/taboolib/commands/sub/AttributesCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/sub/AttributesCommand.java @@ -1,11 +1,12 @@ package me.skymc.taboolib.commands.sub; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + import me.skymc.taboolib.commands.SubCommand; import me.skymc.taboolib.jsonformatter.JSONFormatter; import me.skymc.taboolib.jsonformatter.click.SuggestCommandEvent; import me.skymc.taboolib.jsonformatter.hover.ShowTextEvent; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; public class AttributesCommand extends SubCommand { diff --git a/src/main/java/me/skymc/taboolib/commands/sub/HelpCommand.java b/src/main/java/me/skymc/taboolib/commands/sub/HelpCommand.java index e5ac754..7a9e611 100644 --- a/src/main/java/me/skymc/taboolib/commands/sub/HelpCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/sub/HelpCommand.java @@ -1,17 +1,18 @@ package me.skymc.taboolib.commands.sub; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map.Entry; + +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; + import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.commands.SubCommand; import me.skymc.taboolib.jsonformatter.JSONFormatter; import me.skymc.taboolib.jsonformatter.click.SuggestCommandEvent; import me.skymc.taboolib.jsonformatter.hover.ShowTextEvent; -import org.bukkit.command.CommandSender; -import org.bukkit.command.ConsoleCommandSender; -import org.bukkit.entity.Player; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map.Entry; public class HelpCommand extends SubCommand { diff --git a/src/main/java/me/skymc/taboolib/commands/sub/InfoCommand.java b/src/main/java/me/skymc/taboolib/commands/sub/InfoCommand.java index 5defc7b..01c13ac 100644 --- a/src/main/java/me/skymc/taboolib/commands/sub/InfoCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/sub/InfoCommand.java @@ -1,5 +1,9 @@ package me.skymc.taboolib.commands.sub; +import org.bukkit.Material; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + import me.skymc.taboolib.commands.SubCommand; import me.skymc.taboolib.inventory.ItemUtils; import me.skymc.taboolib.itemnbtapi.NBTItem; @@ -8,9 +12,6 @@ import me.skymc.taboolib.jsonformatter.click.SuggestCommandEvent; import me.skymc.taboolib.jsonformatter.hover.ShowItemEvent; import me.skymc.taboolib.jsonformatter.hover.ShowTextEvent; import me.skymc.taboolib.message.MsgUtils; -import org.bukkit.Material; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; public class InfoCommand extends SubCommand { diff --git a/src/main/java/me/skymc/taboolib/commands/sub/SaveCommand.java b/src/main/java/me/skymc/taboolib/commands/sub/SaveCommand.java index e398335..ef62f08 100644 --- a/src/main/java/me/skymc/taboolib/commands/sub/SaveCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/sub/SaveCommand.java @@ -11,8 +11,8 @@ import me.skymc.taboolib.commands.SubCommand; import me.skymc.taboolib.fileutils.ConfigUtils; import me.skymc.taboolib.inventory.ItemUtils; import me.skymc.taboolib.message.ChatCatcher; -import me.skymc.taboolib.message.MsgUtils; import me.skymc.taboolib.message.ChatCatcher.Catcher; +import me.skymc.taboolib.message.MsgUtils; import me.skymc.taboolib.playerdata.DataUtils; public class SaveCommand extends SubCommand { diff --git a/src/main/java/me/skymc/taboolib/commands/sub/SlotCommand.java b/src/main/java/me/skymc/taboolib/commands/sub/SlotCommand.java index 5c4daba..57d8627 100644 --- a/src/main/java/me/skymc/taboolib/commands/sub/SlotCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/sub/SlotCommand.java @@ -1,11 +1,12 @@ package me.skymc.taboolib.commands.sub; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + import me.skymc.taboolib.commands.SubCommand; import me.skymc.taboolib.jsonformatter.JSONFormatter; import me.skymc.taboolib.jsonformatter.click.SuggestCommandEvent; import me.skymc.taboolib.jsonformatter.hover.ShowTextEvent; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; public class SlotCommand extends SubCommand { diff --git a/src/main/java/me/skymc/taboolib/commands/sub/TagDeleteCommand.java b/src/main/java/me/skymc/taboolib/commands/sub/TagDeleteCommand.java index dc09dfc..674200a 100644 --- a/src/main/java/me/skymc/taboolib/commands/sub/TagDeleteCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/sub/TagDeleteCommand.java @@ -1,11 +1,12 @@ package me.skymc.taboolib.commands.sub; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + import me.skymc.taboolib.commands.SubCommand; import me.skymc.taboolib.message.MsgUtils; import me.skymc.taboolib.team.TagManager; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; /** * @author sky diff --git a/src/main/java/me/skymc/taboolib/commands/sub/cycle/CycleCommand.java b/src/main/java/me/skymc/taboolib/commands/sub/cycle/CycleCommand.java index d085c9e..7427bf9 100644 --- a/src/main/java/me/skymc/taboolib/commands/sub/cycle/CycleCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/sub/cycle/CycleCommand.java @@ -1,8 +1,9 @@ package me.skymc.taboolib.commands.sub.cycle; +import org.bukkit.command.CommandSender; + import me.skymc.taboolib.commands.SubCommand; import me.skymc.taboolib.message.MsgUtils; -import org.bukkit.command.CommandSender; public class CycleCommand extends SubCommand { diff --git a/src/main/java/me/skymc/taboolib/commands/sub/cycle/CycleInfoCommand.java b/src/main/java/me/skymc/taboolib/commands/sub/cycle/CycleInfoCommand.java index 2feb7d1..8579c08 100644 --- a/src/main/java/me/skymc/taboolib/commands/sub/cycle/CycleInfoCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/sub/cycle/CycleInfoCommand.java @@ -1,13 +1,14 @@ package me.skymc.taboolib.commands.sub.cycle; +import java.util.concurrent.TimeUnit; + +import org.bukkit.command.CommandSender; + import me.skymc.taboolib.commands.SubCommand; import me.skymc.taboolib.message.MsgUtils; import me.skymc.taboolib.other.DateUtils; import me.skymc.taboolib.timecycle.TimeCycle; import me.skymc.taboolib.timecycle.TimeCycleManager; -import org.bukkit.command.CommandSender; - -import java.util.concurrent.TimeUnit; public class CycleInfoCommand extends SubCommand { diff --git a/src/main/java/me/skymc/taboolib/commands/sub/cycle/CycleListCommand.java b/src/main/java/me/skymc/taboolib/commands/sub/cycle/CycleListCommand.java index 1bc2ae7..ba6da82 100644 --- a/src/main/java/me/skymc/taboolib/commands/sub/cycle/CycleListCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/sub/cycle/CycleListCommand.java @@ -1,13 +1,14 @@ package me.skymc.taboolib.commands.sub.cycle; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + import me.skymc.taboolib.commands.SubCommand; import me.skymc.taboolib.jsonformatter.JSONFormatter; import me.skymc.taboolib.jsonformatter.click.SuggestCommandEvent; import me.skymc.taboolib.jsonformatter.hover.ShowTextEvent; import me.skymc.taboolib.timecycle.TimeCycle; import me.skymc.taboolib.timecycle.TimeCycleManager; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; public class CycleListCommand extends SubCommand { diff --git a/src/main/java/me/skymc/taboolib/commands/sub/cycle/CycleUpdateCommand.java b/src/main/java/me/skymc/taboolib/commands/sub/cycle/CycleUpdateCommand.java index 86a6c09..b16ac82 100644 --- a/src/main/java/me/skymc/taboolib/commands/sub/cycle/CycleUpdateCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/sub/cycle/CycleUpdateCommand.java @@ -1,5 +1,9 @@ package me.skymc.taboolib.commands.sub.cycle; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.scheduler.BukkitRunnable; + import me.skymc.taboolib.Main; import me.skymc.taboolib.commands.SubCommand; import me.skymc.taboolib.database.GlobalDataManager; @@ -7,9 +11,6 @@ import me.skymc.taboolib.message.MsgUtils; import me.skymc.taboolib.timecycle.TimeCycle; import me.skymc.taboolib.timecycle.TimeCycleEvent; import me.skymc.taboolib.timecycle.TimeCycleManager; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.scheduler.BukkitRunnable; public class CycleUpdateCommand extends SubCommand { diff --git a/src/main/java/me/skymc/taboolib/commands/sub/itemlist/listener/ItemLibraryPatch.java b/src/main/java/me/skymc/taboolib/commands/sub/itemlist/listener/ItemLibraryPatch.java index da13e59..6ba40ae 100644 --- a/src/main/java/me/skymc/taboolib/commands/sub/itemlist/listener/ItemLibraryPatch.java +++ b/src/main/java/me/skymc/taboolib/commands/sub/itemlist/listener/ItemLibraryPatch.java @@ -1,7 +1,10 @@ package me.skymc.taboolib.commands.sub.itemlist.listener; -import me.skymc.taboolib.inventory.InventoryUtil; -import me.skymc.taboolib.inventory.ItemUtils; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; + import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -13,10 +16,8 @@ import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; +import me.skymc.taboolib.inventory.InventoryUtil; +import me.skymc.taboolib.inventory.ItemUtils; /** * @author sky diff --git a/src/main/java/me/skymc/taboolib/commands/sub/shell/ShellCommand.java b/src/main/java/me/skymc/taboolib/commands/sub/shell/ShellCommand.java index 3690404..9150f31 100644 --- a/src/main/java/me/skymc/taboolib/commands/sub/shell/ShellCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/sub/shell/ShellCommand.java @@ -1,8 +1,9 @@ package me.skymc.taboolib.commands.sub.shell; +import org.bukkit.command.CommandSender; + import me.skymc.taboolib.commands.SubCommand; import me.skymc.taboolib.message.MsgUtils; -import org.bukkit.command.CommandSender; public class ShellCommand extends SubCommand { diff --git a/src/main/java/me/skymc/taboolib/commands/sub/sounds/listener/SoundsLibraryPatch.java b/src/main/java/me/skymc/taboolib/commands/sub/sounds/listener/SoundsLibraryPatch.java index 55b043e..e37ac1e 100644 --- a/src/main/java/me/skymc/taboolib/commands/sub/sounds/listener/SoundsLibraryPatch.java +++ b/src/main/java/me/skymc/taboolib/commands/sub/sounds/listener/SoundsLibraryPatch.java @@ -1,7 +1,8 @@ package me.skymc.taboolib.commands.sub.sounds.listener; -import me.skymc.taboolib.inventory.InventoryUtil; -import me.skymc.taboolib.inventory.ItemUtils; +import java.util.Arrays; +import java.util.HashMap; + import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Sound; @@ -14,8 +15,8 @@ import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import java.util.Arrays; -import java.util.HashMap; +import me.skymc.taboolib.inventory.InventoryUtil; +import me.skymc.taboolib.inventory.ItemUtils; /** * @author sky diff --git a/src/main/java/me/skymc/taboolib/cooldown/CooldownUtils.java b/src/main/java/me/skymc/taboolib/cooldown/CooldownUtils.java index 102506a..10c5e90 100644 --- a/src/main/java/me/skymc/taboolib/cooldown/CooldownUtils.java +++ b/src/main/java/me/skymc/taboolib/cooldown/CooldownUtils.java @@ -1,13 +1,14 @@ package me.skymc.taboolib.cooldown; -import me.skymc.taboolib.message.MsgUtils; +import java.util.concurrent.ConcurrentHashMap; + import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.server.PluginDisableEvent; import org.bukkit.plugin.Plugin; -import java.util.concurrent.ConcurrentHashMap; +import me.skymc.taboolib.message.MsgUtils; @Deprecated public class CooldownUtils implements Listener { diff --git a/src/main/java/me/skymc/taboolib/cooldown/seconds/CooldownUtils2.java b/src/main/java/me/skymc/taboolib/cooldown/seconds/CooldownUtils2.java index a467759..565eeac 100644 --- a/src/main/java/me/skymc/taboolib/cooldown/seconds/CooldownUtils2.java +++ b/src/main/java/me/skymc/taboolib/cooldown/seconds/CooldownUtils2.java @@ -1,13 +1,13 @@ package me.skymc.taboolib.cooldown.seconds; +import java.util.concurrent.ConcurrentHashMap; + import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.server.PluginDisableEvent; import org.bukkit.plugin.Plugin; -import java.util.concurrent.ConcurrentHashMap; - public class CooldownUtils2 implements Listener { private static ConcurrentHashMap packlist = new ConcurrentHashMap<>(); diff --git a/src/main/java/me/skymc/taboolib/csvutils/CsvReader.java b/src/main/java/me/skymc/taboolib/csvutils/CsvReader.java index b40f5cd..fdc1eb9 100644 --- a/src/main/java/me/skymc/taboolib/csvutils/CsvReader.java +++ b/src/main/java/me/skymc/taboolib/csvutils/CsvReader.java @@ -1,6 +1,14 @@ package me.skymc.taboolib.csvutils; -import java.io.*; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; import java.nio.charset.Charset; import java.text.NumberFormat; import java.util.HashMap; diff --git a/src/main/java/me/skymc/taboolib/csvutils/CsvWriter.java b/src/main/java/me/skymc/taboolib/csvutils/CsvWriter.java index 7df96a9..8547c74 100644 --- a/src/main/java/me/skymc/taboolib/csvutils/CsvWriter.java +++ b/src/main/java/me/skymc/taboolib/csvutils/CsvWriter.java @@ -1,6 +1,11 @@ package me.skymc.taboolib.csvutils; -import java.io.*; +import java.io.BufferedWriter; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; import java.nio.charset.Charset; public class CsvWriter diff --git a/src/main/java/me/skymc/taboolib/damage/DamageUtils.java b/src/main/java/me/skymc/taboolib/damage/DamageUtils.java index 9a865dc..45c6837 100644 --- a/src/main/java/me/skymc/taboolib/damage/DamageUtils.java +++ b/src/main/java/me/skymc/taboolib/damage/DamageUtils.java @@ -1,11 +1,12 @@ package me.skymc.taboolib.damage; -import me.skymc.taboolib.TabooLib; +import java.lang.reflect.InvocationTargetException; + import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; -import java.lang.reflect.InvocationTargetException; +import me.skymc.taboolib.TabooLib; public class DamageUtils { diff --git a/src/main/java/me/skymc/taboolib/database/GlobalDataManager.java b/src/main/java/me/skymc/taboolib/database/GlobalDataManager.java index 74b6fdb..0f4183c 100644 --- a/src/main/java/me/skymc/taboolib/database/GlobalDataManager.java +++ b/src/main/java/me/skymc/taboolib/database/GlobalDataManager.java @@ -1,17 +1,18 @@ package me.skymc.taboolib.database; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.concurrent.ConcurrentHashMap; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.scheduler.BukkitRunnable; + import me.skymc.taboolib.Main; import me.skymc.taboolib.Main.StorageType; import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.message.MsgUtils; import me.skymc.taboolib.playerdata.DataUtils; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.scheduler.BukkitRunnable; - -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.concurrent.ConcurrentHashMap; public class GlobalDataManager { diff --git a/src/main/java/me/skymc/taboolib/database/PlayerDataManager.java b/src/main/java/me/skymc/taboolib/database/PlayerDataManager.java index 8355004..0a87f65 100644 --- a/src/main/java/me/skymc/taboolib/database/PlayerDataManager.java +++ b/src/main/java/me/skymc/taboolib/database/PlayerDataManager.java @@ -1,12 +1,9 @@ package me.skymc.taboolib.database; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.Main.StorageType; -import me.skymc.taboolib.events.PlayerLoadedEvent; -import me.skymc.taboolib.exception.PlayerOfflineException; -import me.skymc.taboolib.fileutils.ConfigUtils; -import me.skymc.taboolib.fileutils.FileUtils; -import me.skymc.taboolib.message.MsgUtils; +import java.io.File; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.configuration.file.FileConfiguration; @@ -18,9 +15,13 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.scheduler.BukkitRunnable; -import java.io.File; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; +import me.skymc.taboolib.Main; +import me.skymc.taboolib.Main.StorageType; +import me.skymc.taboolib.events.PlayerLoadedEvent; +import me.skymc.taboolib.exception.PlayerOfflineException; +import me.skymc.taboolib.fileutils.ConfigUtils; +import me.skymc.taboolib.fileutils.FileUtils; +import me.skymc.taboolib.message.MsgUtils; public class PlayerDataManager implements Listener { diff --git a/src/main/java/me/skymc/taboolib/display/ActionUtils.java b/src/main/java/me/skymc/taboolib/display/ActionUtils.java index 92a8d03..b9ef334 100644 --- a/src/main/java/me/skymc/taboolib/display/ActionUtils.java +++ b/src/main/java/me/skymc/taboolib/display/ActionUtils.java @@ -1,10 +1,11 @@ package me.skymc.taboolib.display; -import me.skymc.taboolib.TabooLib; +import java.lang.reflect.Constructor; + import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import java.lang.reflect.Constructor; +import me.skymc.taboolib.TabooLib; public class ActionUtils { diff --git a/src/main/java/me/skymc/taboolib/display/TitleUtils.java b/src/main/java/me/skymc/taboolib/display/TitleUtils.java index 296686c..5cafc30 100644 --- a/src/main/java/me/skymc/taboolib/display/TitleUtils.java +++ b/src/main/java/me/skymc/taboolib/display/TitleUtils.java @@ -1,9 +1,9 @@ package me.skymc.taboolib.display; -import org.bukkit.entity.Player; - import java.lang.reflect.Constructor; +import org.bukkit.entity.Player; + public class TitleUtils { private static void sendPacket(Player player, Object packet) diff --git a/src/main/java/me/skymc/taboolib/entity/EntityTag.java b/src/main/java/me/skymc/taboolib/entity/EntityTag.java index 7a2821e..ce32a0d 100644 --- a/src/main/java/me/skymc/taboolib/entity/EntityTag.java +++ b/src/main/java/me/skymc/taboolib/entity/EntityTag.java @@ -1,13 +1,14 @@ package me.skymc.taboolib.entity; -import me.skymc.taboolib.Main; -import org.bukkit.entity.Entity; -import org.bukkit.scheduler.BukkitRunnable; - import java.util.List; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import org.bukkit.entity.Entity; +import org.bukkit.scheduler.BukkitRunnable; + +import me.skymc.taboolib.Main; + /** * 伪 - MetaData * diff --git a/src/main/java/me/skymc/taboolib/events/CustomBookOpenEvent.java b/src/main/java/me/skymc/taboolib/events/CustomBookOpenEvent.java index 6a806a7..1195671 100644 --- a/src/main/java/me/skymc/taboolib/events/CustomBookOpenEvent.java +++ b/src/main/java/me/skymc/taboolib/events/CustomBookOpenEvent.java @@ -1,13 +1,14 @@ package me.skymc.taboolib.events; -import lombok.Getter; -import lombok.Setter; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.bukkit.inventory.ItemStack; +import lombok.Getter; +import lombok.Setter; + /** * The event called when a book is opened trough this Util */ diff --git a/src/main/java/me/skymc/taboolib/events/DefaultEvent2.java b/src/main/java/me/skymc/taboolib/events/DefaultEvent2.java index d2a86bb..324609b 100644 --- a/src/main/java/me/skymc/taboolib/events/DefaultEvent2.java +++ b/src/main/java/me/skymc/taboolib/events/DefaultEvent2.java @@ -1,8 +1,9 @@ package me.skymc.taboolib.events; -import org.bukkit.event.player.*; -import org.bukkit.entity.*; -import org.bukkit.event.*; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; public class DefaultEvent2 extends PlayerEvent { diff --git a/src/main/java/me/skymc/taboolib/fileutils/ConfigUtils.java b/src/main/java/me/skymc/taboolib/fileutils/ConfigUtils.java index 0c1490f..225cc30 100644 --- a/src/main/java/me/skymc/taboolib/fileutils/ConfigUtils.java +++ b/src/main/java/me/skymc/taboolib/fileutils/ConfigUtils.java @@ -1,13 +1,21 @@ package me.skymc.taboolib.fileutils; -import com.google.common.base.Charsets; -import me.skymc.taboolib.message.MsgUtils; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStreamReader; +import java.io.StringReader; + +import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.Plugin; import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; -import java.io.*; +import com.google.common.base.Charsets; +import com.ilummc.tlib.TLib; + +import me.skymc.taboolib.message.MsgUtils; public class ConfigUtils { @@ -43,12 +51,13 @@ public class ConfigUtils { */ public static FileConfiguration load(Plugin plugin, File file) { YamlConfiguration yaml = new YamlConfiguration(); + try { yaml = YamlConfiguration.loadConfiguration(new InputStreamReader(new FileInputStream(file), Charsets.UTF_8)); - } catch (FileNotFoundException e) { - MsgUtils.warn("配置文件载入失败!"); - MsgUtils.warn("插件: &4" + plugin.getName()); - MsgUtils.warn("文件: &4" + file.getName()); + } catch (Exception e) { + TLib.getTLib().getLogger().error("配置文件载入失败!"); + TLib.getTLib().getLogger().error("插件: &4" + plugin.getName()); + TLib.getTLib().getLogger().error("文件: &4" + file); } return yaml; } diff --git a/src/main/java/me/skymc/taboolib/fileutils/EncodeUtils.java b/src/main/java/me/skymc/taboolib/fileutils/EncodeUtils.java index e0c43b7..13e1672 100644 --- a/src/main/java/me/skymc/taboolib/fileutils/EncodeUtils.java +++ b/src/main/java/me/skymc/taboolib/fileutils/EncodeUtils.java @@ -1,6 +1,13 @@ package me.skymc.taboolib.fileutils; -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; import java.nio.charset.Charset; import java.nio.charset.UnsupportedCharsetException; diff --git a/src/main/java/me/skymc/taboolib/fileutils/FileUtils.java b/src/main/java/me/skymc/taboolib/fileutils/FileUtils.java index e8fa55c..3f28a21 100644 --- a/src/main/java/me/skymc/taboolib/fileutils/FileUtils.java +++ b/src/main/java/me/skymc/taboolib/fileutils/FileUtils.java @@ -1,13 +1,22 @@ package me.skymc.taboolib.fileutils; -import me.skymc.taboolib.message.MsgUtils; - -import java.io.*; +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.nio.channels.FileChannel; +import ch.njol.util.Closeable; +import me.skymc.taboolib.message.MsgUtils; + public class FileUtils { public static String ip() { @@ -282,13 +291,7 @@ public class FileUtils { } } - /** - * 读取字节 - * - * @param in - * @return - */ - private static byte[] read(InputStream in) { + public static byte[] read(InputStream in) { byte[] buffer = new byte[1024]; int len = 0; ByteArrayOutputStream bos = new ByteArrayOutputStream(); @@ -296,11 +299,18 @@ public class FileUtils { while((len = in.read(buffer)) != -1) { bos.write(buffer, 0, len); } - bos.close(); } - catch (Exception e) { - e.printStackTrace(); + catch (Exception ignored) { } return bos.toByteArray(); } + + public static void close(Closeable closeable) { + try { + if (closeable != null) { + closeable.close(); + } + } catch (Exception ignored) { + } + } } diff --git a/src/main/java/me/skymc/taboolib/fileutils/LogUtils.java b/src/main/java/me/skymc/taboolib/fileutils/LogUtils.java index 07d57e1..3915139 100644 --- a/src/main/java/me/skymc/taboolib/fileutils/LogUtils.java +++ b/src/main/java/me/skymc/taboolib/fileutils/LogUtils.java @@ -1,13 +1,14 @@ package me.skymc.taboolib.fileutils; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.other.DateUtils; -import org.bukkit.plugin.Plugin; - import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; +import org.bukkit.plugin.Plugin; + +import me.skymc.taboolib.Main; +import me.skymc.taboolib.other.DateUtils; + @Deprecated public class LogUtils { diff --git a/src/main/java/me/skymc/taboolib/inventory/DropUtils.java b/src/main/java/me/skymc/taboolib/inventory/DropUtils.java index 25aa4bb..3392a17 100644 --- a/src/main/java/me/skymc/taboolib/inventory/DropUtils.java +++ b/src/main/java/me/skymc/taboolib/inventory/DropUtils.java @@ -1,12 +1,13 @@ package me.skymc.taboolib.inventory; -import me.skymc.taboolib.other.NumberUtils; import org.bukkit.Location; import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; +import me.skymc.taboolib.other.NumberUtils; + public class DropUtils { public static Item drop(Player player, ItemStack itemStack, double bulletSpread, double radius) { diff --git a/src/main/java/me/skymc/taboolib/inventory/InventoryUtil.java b/src/main/java/me/skymc/taboolib/inventory/InventoryUtil.java index f435c7c..6bea382 100644 --- a/src/main/java/me/skymc/taboolib/inventory/InventoryUtil.java +++ b/src/main/java/me/skymc/taboolib/inventory/InventoryUtil.java @@ -1,12 +1,12 @@ package me.skymc.taboolib.inventory; +import java.util.Arrays; +import java.util.LinkedList; + import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; -import java.util.Arrays; -import java.util.LinkedList; - public class InventoryUtil { public final static LinkedList SLOT_OF_CENTENTS = new LinkedList<>(Arrays.asList( diff --git a/src/main/java/me/skymc/taboolib/inventory/ItemUtils.java b/src/main/java/me/skymc/taboolib/inventory/ItemUtils.java index 5f4420b..4f85c9d 100644 --- a/src/main/java/me/skymc/taboolib/inventory/ItemUtils.java +++ b/src/main/java/me/skymc/taboolib/inventory/ItemUtils.java @@ -1,17 +1,10 @@ package me.skymc.taboolib.inventory; -import lombok.Getter; -import me.clip.placeholderapi.PlaceholderAPI; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.TabooLib; -import me.skymc.taboolib.fileutils.ConfigUtils; -import me.skymc.taboolib.itemnbtapi.NBTItem; -import me.skymc.taboolib.itemnbtapi.NBTList; -import me.skymc.taboolib.itemnbtapi.NBTListCompound; -import me.skymc.taboolib.itemnbtapi.NBTType; -import me.skymc.taboolib.message.MsgUtils; -import me.skymc.taboolib.other.NumberUtils; -import me.skymc.taboolib.string.Language; +import java.io.File; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -28,10 +21,18 @@ import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import java.io.File; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; +import lombok.Getter; +import me.clip.placeholderapi.PlaceholderAPI; +import me.skymc.taboolib.Main; +import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.fileutils.ConfigUtils; +import me.skymc.taboolib.itemnbtapi.NBTItem; +import me.skymc.taboolib.itemnbtapi.NBTList; +import me.skymc.taboolib.itemnbtapi.NBTListCompound; +import me.skymc.taboolib.itemnbtapi.NBTType; +import me.skymc.taboolib.message.MsgUtils; +import me.skymc.taboolib.other.NumberUtils; +import me.skymc.taboolib.string.Language; public class ItemUtils { diff --git a/src/main/java/me/skymc/taboolib/inventory/speciaitem/SpecialItem.java b/src/main/java/me/skymc/taboolib/inventory/speciaitem/SpecialItem.java index 6623df2..044a470 100644 --- a/src/main/java/me/skymc/taboolib/inventory/speciaitem/SpecialItem.java +++ b/src/main/java/me/skymc/taboolib/inventory/speciaitem/SpecialItem.java @@ -1,9 +1,8 @@ package me.skymc.taboolib.inventory.speciaitem; -import lombok.Getter; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.inventory.ItemUtils; -import me.skymc.taboolib.message.MsgUtils; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -13,8 +12,10 @@ import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.server.PluginDisableEvent; import org.bukkit.plugin.Plugin; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; +import lombok.Getter; +import me.skymc.taboolib.Main; +import me.skymc.taboolib.inventory.ItemUtils; +import me.skymc.taboolib.message.MsgUtils; /** * @author sky diff --git a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTReflectionUtil.java b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTReflectionUtil.java index 4ae8545..e53893d 100644 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTReflectionUtil.java +++ b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTReflectionUtil.java @@ -1,14 +1,5 @@ package me.skymc.taboolib.itemnbtapi; -import me.skymc.taboolib.TabooLib; -import me.skymc.taboolib.itemnbtapi.utils.GsonWrapper; -import me.skymc.taboolib.itemnbtapi.utils.MethodNames; -import me.skymc.taboolib.message.MsgUtils; -import org.bukkit.Bukkit; -import org.bukkit.block.BlockState; -import org.bukkit.entity.Entity; -import org.bukkit.inventory.ItemStack; - import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; @@ -17,6 +8,16 @@ import java.lang.reflect.Method; import java.util.Set; import java.util.Stack; +import org.bukkit.Bukkit; +import org.bukkit.block.BlockState; +import org.bukkit.entity.Entity; +import org.bukkit.inventory.ItemStack; + +import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.itemnbtapi.utils.GsonWrapper; +import me.skymc.taboolib.itemnbtapi.utils.MethodNames; +import me.skymc.taboolib.message.MsgUtils; + // TODO: finish codestyle cleanup -sgdc3 public class NBTReflectionUtil { diff --git a/src/main/java/me/skymc/taboolib/javascript/JavaScriptUtils.java b/src/main/java/me/skymc/taboolib/javascript/JavaScriptUtils.java index ea982a4..ee79a93 100644 --- a/src/main/java/me/skymc/taboolib/javascript/JavaScriptUtils.java +++ b/src/main/java/me/skymc/taboolib/javascript/JavaScriptUtils.java @@ -1,14 +1,15 @@ package me.skymc.taboolib.javascript; -import me.skymc.taboolib.Main; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; + +import me.skymc.taboolib.Main; public class JavaScriptUtils { diff --git a/src/main/java/me/skymc/taboolib/javashell/JavaShell.java b/src/main/java/me/skymc/taboolib/javashell/JavaShell.java index 86fa9d1..fc6d40d 100644 --- a/src/main/java/me/skymc/taboolib/javashell/JavaShell.java +++ b/src/main/java/me/skymc/taboolib/javashell/JavaShell.java @@ -1,10 +1,11 @@ package me.skymc.taboolib.javashell; -import lombok.Getter; -import lombok.Setter; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.javashell.utils.JarUtils; -import me.skymc.taboolib.message.MsgUtils; +import java.io.File; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.HashMap; + import org.apache.commons.lang.ArrayUtils; import org.bukkit.Bukkit; import org.bukkit.event.HandlerList; @@ -12,11 +13,11 @@ import org.bukkit.event.Listener; import org.bukkit.plugin.RegisteredListener; import org.bukkit.scheduler.BukkitRunnable; -import java.io.File; -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.HashMap; +import lombok.Getter; +import lombok.Setter; +import me.skymc.taboolib.Main; +import me.skymc.taboolib.javashell.utils.JarUtils; +import me.skymc.taboolib.message.MsgUtils; public class JavaShell { diff --git a/src/main/java/me/skymc/taboolib/javashell/utils/JarUtils.java b/src/main/java/me/skymc/taboolib/javashell/utils/JarUtils.java index 18fd574..df6d0da 100644 --- a/src/main/java/me/skymc/taboolib/javashell/utils/JarUtils.java +++ b/src/main/java/me/skymc/taboolib/javashell/utils/JarUtils.java @@ -1,9 +1,12 @@ package me.skymc.taboolib.javashell.utils; -import me.skymc.taboolib.message.MsgUtils; -import org.bukkit.Bukkit; - -import java.io.*; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; @@ -12,6 +15,10 @@ import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; +import org.bukkit.Bukkit; + +import me.skymc.taboolib.message.MsgUtils; + public class JarUtils { public static boolean extractFromJar(final String fileName, final String dest) throws IOException { diff --git a/src/main/java/me/skymc/taboolib/json/JSONObject.java b/src/main/java/me/skymc/taboolib/json/JSONObject.java index e038225..7007bf7 100644 --- a/src/main/java/me/skymc/taboolib/json/JSONObject.java +++ b/src/main/java/me/skymc/taboolib/json/JSONObject.java @@ -6,7 +6,13 @@ import java.io.Writer; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.*; +import java.util.Collection; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; +import java.util.ResourceBundle; @SuppressWarnings({"rawtypes", "unchecked"}) public class JSONObject { diff --git a/src/main/java/me/skymc/taboolib/json/JSONTokener.java b/src/main/java/me/skymc/taboolib/json/JSONTokener.java index 08f184b..dd68f9e 100644 --- a/src/main/java/me/skymc/taboolib/json/JSONTokener.java +++ b/src/main/java/me/skymc/taboolib/json/JSONTokener.java @@ -1,7 +1,12 @@ package me.skymc.taboolib.json; -import java.io.*; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; public class JSONTokener { diff --git a/src/main/java/me/skymc/taboolib/jsonformatter/JSONFormatter.java b/src/main/java/me/skymc/taboolib/jsonformatter/JSONFormatter.java index f8ab044..df230f3 100644 --- a/src/main/java/me/skymc/taboolib/jsonformatter/JSONFormatter.java +++ b/src/main/java/me/skymc/taboolib/jsonformatter/JSONFormatter.java @@ -1,20 +1,21 @@ package me.skymc.taboolib.jsonformatter; -import me.skymc.taboolib.json.JSONArray; -import me.skymc.taboolib.json.JSONObject; -import me.skymc.taboolib.jsonformatter.click.ClickEvent; -import me.skymc.taboolib.jsonformatter.hover.HoverEvent; -import me.skymc.taboolib.nms.NMSUtils; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; - import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import me.skymc.taboolib.json.JSONArray; +import me.skymc.taboolib.json.JSONObject; +import me.skymc.taboolib.jsonformatter.click.ClickEvent; +import me.skymc.taboolib.jsonformatter.hover.HoverEvent; +import me.skymc.taboolib.nms.NMSUtils; + public class JSONFormatter { private JSONArray ja = new JSONArray(); diff --git a/src/main/java/me/skymc/taboolib/jsonformatter/hover/ShowItemEvent.java b/src/main/java/me/skymc/taboolib/jsonformatter/hover/ShowItemEvent.java index 863294c..8509f4a 100644 --- a/src/main/java/me/skymc/taboolib/jsonformatter/hover/ShowItemEvent.java +++ b/src/main/java/me/skymc/taboolib/jsonformatter/hover/ShowItemEvent.java @@ -1,18 +1,19 @@ package me.skymc.taboolib.jsonformatter.hover; -import me.skymc.taboolib.TabooLib; -import me.skymc.taboolib.inventory.ItemUtils; -import me.skymc.taboolib.json.JSONObject; -import me.skymc.taboolib.nms.item.DabItemUtils; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.inventory.ItemUtils; +import me.skymc.taboolib.json.JSONObject; +import me.skymc.taboolib.nms.item.DabItemUtils; + public class ShowItemEvent extends HoverEvent{ private JSONObject object = new JSONObject(); diff --git a/src/main/java/me/skymc/taboolib/listener/ListenerPlayerCommand.java b/src/main/java/me/skymc/taboolib/listener/ListenerPlayerCommand.java index 4f92e24..c1a339f 100644 --- a/src/main/java/me/skymc/taboolib/listener/ListenerPlayerCommand.java +++ b/src/main/java/me/skymc/taboolib/listener/ListenerPlayerCommand.java @@ -1,5 +1,11 @@ package me.skymc.taboolib.listener; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.server.ServerCommandEvent; + import me.skymc.taboolib.Main; import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.database.PlayerDataManager; @@ -7,11 +13,6 @@ import me.skymc.taboolib.itemnbtapi.NBTItem; import me.skymc.taboolib.message.MsgUtils; import me.skymc.taboolib.permission.PermissionUtils; import me.skymc.taboolib.playerdata.DataUtils; -import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import org.bukkit.event.server.ServerCommandEvent; public class ListenerPlayerCommand implements Listener { diff --git a/src/main/java/me/skymc/taboolib/listener/ListenerPlayerJump.java b/src/main/java/me/skymc/taboolib/listener/ListenerPlayerJump.java index d0d4fa1..c8306c8 100644 --- a/src/main/java/me/skymc/taboolib/listener/ListenerPlayerJump.java +++ b/src/main/java/me/skymc/taboolib/listener/ListenerPlayerJump.java @@ -1,6 +1,7 @@ package me.skymc.taboolib.listener; -import me.skymc.taboolib.events.PlayerJumpEvent; +import java.util.HashMap; + import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Location; @@ -12,7 +13,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; -import java.util.HashMap; +import me.skymc.taboolib.events.PlayerJumpEvent; public class ListenerPlayerJump implements Listener diff --git a/src/main/java/me/skymc/taboolib/listener/ListenerPlayerQuit.java b/src/main/java/me/skymc/taboolib/listener/ListenerPlayerQuit.java index 066e77c..94a580a 100644 --- a/src/main/java/me/skymc/taboolib/listener/ListenerPlayerQuit.java +++ b/src/main/java/me/skymc/taboolib/listener/ListenerPlayerQuit.java @@ -1,11 +1,12 @@ package me.skymc.taboolib.listener; -import me.skymc.taboolib.playerdata.DataUtils; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; +import me.skymc.taboolib.playerdata.DataUtils; + public class ListenerPlayerQuit implements Listener{ @EventHandler (priority = EventPriority.MONITOR) diff --git a/src/main/java/me/skymc/taboolib/listener/ListenerPluginDisable.java b/src/main/java/me/skymc/taboolib/listener/ListenerPluginDisable.java index 95f9a60..119744d 100644 --- a/src/main/java/me/skymc/taboolib/listener/ListenerPluginDisable.java +++ b/src/main/java/me/skymc/taboolib/listener/ListenerPluginDisable.java @@ -1,17 +1,18 @@ package me.skymc.taboolib.listener; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.server.PluginDisableEvent; +import org.bukkit.scheduler.BukkitRunnable; + import me.skymc.taboolib.Main; import me.skymc.taboolib.message.MsgUtils; import me.skymc.taboolib.mysql.MysqlUtils; import me.skymc.taboolib.mysql.protect.MySQLConnection; import me.skymc.taboolib.timecycle.TimeCycleManager; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.server.PluginDisableEvent; -import org.bukkit.scheduler.BukkitRunnable; - -import java.util.ArrayList; -import java.util.List; public class ListenerPluginDisable implements Listener { diff --git a/src/main/java/me/skymc/taboolib/message/ChatCatcher.java b/src/main/java/me/skymc/taboolib/message/ChatCatcher.java index 60be8b6..2ed8bad 100644 --- a/src/main/java/me/skymc/taboolib/message/ChatCatcher.java +++ b/src/main/java/me/skymc/taboolib/message/ChatCatcher.java @@ -1,14 +1,15 @@ package me.skymc.taboolib.message; -import lombok.Getter; +import java.util.HashMap; +import java.util.LinkedList; + import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerQuitEvent; -import java.util.HashMap; -import java.util.LinkedList; +import lombok.Getter; public class ChatCatcher implements Listener { diff --git a/src/main/java/me/skymc/taboolib/methods/ReflectionUtils.java b/src/main/java/me/skymc/taboolib/methods/ReflectionUtils.java index 6b2c54a..b25e364 100644 --- a/src/main/java/me/skymc/taboolib/methods/ReflectionUtils.java +++ b/src/main/java/me/skymc/taboolib/methods/ReflectionUtils.java @@ -1,7 +1,5 @@ package me.skymc.taboolib.methods; -import org.bukkit.Bukkit; - import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -9,6 +7,8 @@ import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; +import org.bukkit.Bukkit; + /** * ReflectionUtils *

diff --git a/src/main/java/me/skymc/taboolib/mysql/MysqlConnection.java b/src/main/java/me/skymc/taboolib/mysql/MysqlConnection.java index e22b8a3..8f28b04 100644 --- a/src/main/java/me/skymc/taboolib/mysql/MysqlConnection.java +++ b/src/main/java/me/skymc/taboolib/mysql/MysqlConnection.java @@ -1,6 +1,10 @@ package me.skymc.taboolib.mysql; -import java.sql.*; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/me/skymc/taboolib/mysql/MysqlUtils.java b/src/main/java/me/skymc/taboolib/mysql/MysqlUtils.java index ebfe373..a1534bb 100644 --- a/src/main/java/me/skymc/taboolib/mysql/MysqlUtils.java +++ b/src/main/java/me/skymc/taboolib/mysql/MysqlUtils.java @@ -1,12 +1,13 @@ package me.skymc.taboolib.mysql; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.plugin.Plugin; + import me.skymc.taboolib.Main; import me.skymc.taboolib.message.MsgUtils; import me.skymc.taboolib.mysql.protect.MySQLConnection; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.plugin.Plugin; - -import java.util.concurrent.CopyOnWriteArrayList; public class MysqlUtils { diff --git a/src/main/java/me/skymc/taboolib/mysql/protect/MySQLConnection.java b/src/main/java/me/skymc/taboolib/mysql/protect/MySQLConnection.java index 565f328..c76d65d 100644 --- a/src/main/java/me/skymc/taboolib/mysql/protect/MySQLConnection.java +++ b/src/main/java/me/skymc/taboolib/mysql/protect/MySQLConnection.java @@ -1,16 +1,21 @@ package me.skymc.taboolib.mysql.protect; -import lombok.Getter; -import lombok.Setter; -import me.skymc.taboolib.Main; -import org.bukkit.plugin.Plugin; - -import java.sql.*; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import org.bukkit.plugin.Plugin; + +import lombok.Getter; +import lombok.Setter; +import me.skymc.taboolib.Main; + public class MySQLConnection { @Getter diff --git a/src/main/java/me/skymc/taboolib/nms/NMSUtil18.java b/src/main/java/me/skymc/taboolib/nms/NMSUtil18.java index 274cf6f..70c1b2d 100644 --- a/src/main/java/me/skymc/taboolib/nms/NMSUtil18.java +++ b/src/main/java/me/skymc/taboolib/nms/NMSUtil18.java @@ -1,16 +1,5 @@ package me.skymc.taboolib.nms; -import org.bukkit.*; -import org.bukkit.block.BlockFace; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; -import org.bukkit.util.Vector; - import java.io.InputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -20,6 +9,21 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import org.bukkit.Bukkit; +import org.bukkit.DyeColor; +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.block.BlockFace; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + @SuppressWarnings({ "rawtypes", "unchecked" }) @Deprecated public class NMSUtil18 { diff --git a/src/main/java/me/skymc/taboolib/nms/NMSUtil19.java b/src/main/java/me/skymc/taboolib/nms/NMSUtil19.java index 4437f76..09b2a4c 100644 --- a/src/main/java/me/skymc/taboolib/nms/NMSUtil19.java +++ b/src/main/java/me/skymc/taboolib/nms/NMSUtil19.java @@ -1,7 +1,24 @@ package me.skymc.taboolib.nms; +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.logging.Level; + import org.apache.commons.lang.StringUtils; -import org.bukkit.*; +import org.bukkit.Bukkit; +import org.bukkit.DyeColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Server; +import org.bukkit.World; import org.bukkit.block.BlockFace; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.MemorySection; @@ -15,13 +32,6 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.util.Vector; -import java.io.InputStream; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.*; -import java.util.logging.Level; - @SuppressWarnings({ "rawtypes", "unchecked" }) @Deprecated public class NMSUtil19 { diff --git a/src/main/java/me/skymc/taboolib/nms/NMSUtils.java b/src/main/java/me/skymc/taboolib/nms/NMSUtils.java index c68b463..2541858 100644 --- a/src/main/java/me/skymc/taboolib/nms/NMSUtils.java +++ b/src/main/java/me/skymc/taboolib/nms/NMSUtils.java @@ -1,12 +1,12 @@ package me.skymc.taboolib.nms; -import org.bukkit.Bukkit; - import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import org.bukkit.Bukkit; + public class NMSUtils { public static String getVersion(){ diff --git a/src/main/java/me/skymc/taboolib/nms/item/DabItemUtils.java b/src/main/java/me/skymc/taboolib/nms/item/DabItemUtils.java index dad63d1..a89c12a 100644 --- a/src/main/java/me/skymc/taboolib/nms/item/DabItemUtils.java +++ b/src/main/java/me/skymc/taboolib/nms/item/DabItemUtils.java @@ -1,5 +1,15 @@ package me.skymc.taboolib.nms.item; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + import me.skymc.taboolib.Main; import me.skymc.taboolib.json.JSONArray; import me.skymc.taboolib.json.JSONObject; @@ -7,15 +17,6 @@ import me.skymc.taboolib.message.MsgUtils; import me.skymc.taboolib.nms.item.impl._164ItemUtils; import me.skymc.taboolib.nms.item.impl._1710ItemUtils; import me.skymc.taboolib.nms.item.impl._194ItemUtils; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.lang.reflect.Method; -import java.util.List; -import java.util.Map; public class DabItemUtils { diff --git a/src/main/java/me/skymc/taboolib/nms/item/IDabItemUtils.java b/src/main/java/me/skymc/taboolib/nms/item/IDabItemUtils.java index c24b652..d30aaa5 100644 --- a/src/main/java/me/skymc/taboolib/nms/item/IDabItemUtils.java +++ b/src/main/java/me/skymc/taboolib/nms/item/IDabItemUtils.java @@ -1,13 +1,14 @@ package me.skymc.taboolib.nms.item; -import me.skymc.taboolib.json.JSONArray; -import me.skymc.taboolib.json.JSONObject; -import org.bukkit.inventory.ItemStack; - import java.lang.reflect.Method; import java.util.List; import java.util.Map; +import org.bukkit.inventory.ItemStack; + +import me.skymc.taboolib.json.JSONArray; +import me.skymc.taboolib.json.JSONObject; + public interface IDabItemUtils{ //@formatter:off diff --git a/src/main/java/me/skymc/taboolib/nms/item/impl/_164ItemUtils.java b/src/main/java/me/skymc/taboolib/nms/item/impl/_164ItemUtils.java index 9f92980..98ef84d 100644 --- a/src/main/java/me/skymc/taboolib/nms/item/impl/_164ItemUtils.java +++ b/src/main/java/me/skymc/taboolib/nms/item/impl/_164ItemUtils.java @@ -1,19 +1,27 @@ package me.skymc.taboolib.nms.item.impl; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + import me.skymc.taboolib.json.JSONArray; import me.skymc.taboolib.json.JSONObject; import me.skymc.taboolib.nms.NMSUtils; import me.skymc.taboolib.nms.item.IDabItemUtils; import me.skymc.taboolib.nms.nbt.NBTConstants; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.*; -import java.util.Map.Entry; public class _164ItemUtils implements IDabItemUtils{ diff --git a/src/main/java/me/skymc/taboolib/nms/item/impl/_1710ItemUtils.java b/src/main/java/me/skymc/taboolib/nms/item/impl/_1710ItemUtils.java index 8914883..6392b8e 100644 --- a/src/main/java/me/skymc/taboolib/nms/item/impl/_1710ItemUtils.java +++ b/src/main/java/me/skymc/taboolib/nms/item/impl/_1710ItemUtils.java @@ -1,19 +1,27 @@ package me.skymc.taboolib.nms.item.impl; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + import me.skymc.taboolib.json.JSONArray; import me.skymc.taboolib.json.JSONObject; import me.skymc.taboolib.nms.NMSUtils; import me.skymc.taboolib.nms.item.IDabItemUtils; import me.skymc.taboolib.nms.nbt.NBTConstants; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.*; -import java.util.Map.Entry; public class _1710ItemUtils implements IDabItemUtils{ diff --git a/src/main/java/me/skymc/taboolib/nms/item/impl/_194ItemUtils.java b/src/main/java/me/skymc/taboolib/nms/item/impl/_194ItemUtils.java index aab3be4..3ee5c7a 100644 --- a/src/main/java/me/skymc/taboolib/nms/item/impl/_194ItemUtils.java +++ b/src/main/java/me/skymc/taboolib/nms/item/impl/_194ItemUtils.java @@ -1,19 +1,26 @@ package me.skymc.taboolib.nms.item.impl; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + import me.skymc.taboolib.json.JSONArray; import me.skymc.taboolib.json.JSONObject; import me.skymc.taboolib.nms.NMSUtils; import me.skymc.taboolib.nms.item.IDabItemUtils; import me.skymc.taboolib.nms.nbt.NBTConstants; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.*; -import java.util.Map.Entry; public class _194ItemUtils implements IDabItemUtils{ diff --git a/src/main/java/me/skymc/taboolib/other/WeightUtils.java b/src/main/java/me/skymc/taboolib/other/WeightUtils.java index 3083104..0a9bb7e 100644 --- a/src/main/java/me/skymc/taboolib/other/WeightUtils.java +++ b/src/main/java/me/skymc/taboolib/other/WeightUtils.java @@ -1,9 +1,9 @@ package me.skymc.taboolib.other; -import me.skymc.taboolib.object.WeightCategory; - import java.util.List; +import me.skymc.taboolib.object.WeightCategory; + public class WeightUtils { public static String getStringByWeight(List categorys) { diff --git a/src/main/java/me/skymc/taboolib/packet/PacketUtils.java b/src/main/java/me/skymc/taboolib/packet/PacketUtils.java index 2624085..ddfdebb 100644 --- a/src/main/java/me/skymc/taboolib/packet/PacketUtils.java +++ b/src/main/java/me/skymc/taboolib/packet/PacketUtils.java @@ -1,11 +1,12 @@ package me.skymc.taboolib.packet; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.wrappers.WrappedDataWatcher; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; public class PacketUtils { diff --git a/src/main/java/me/skymc/taboolib/particle/EffLib.java b/src/main/java/me/skymc/taboolib/particle/EffLib.java index 4da1f84..1cc9a29 100644 --- a/src/main/java/me/skymc/taboolib/particle/EffLib.java +++ b/src/main/java/me/skymc/taboolib/particle/EffLib.java @@ -1,14 +1,5 @@ package me.skymc.taboolib.particle; -import me.skymc.taboolib.methods.ReflectionUtils; -import me.skymc.taboolib.methods.ReflectionUtils.PackageType; -import org.bukkit.Bukkit; -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -18,6 +9,16 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import org.bukkit.Bukkit; +import org.bukkit.Color; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import me.skymc.taboolib.methods.ReflectionUtils; +import me.skymc.taboolib.methods.ReflectionUtils.PackageType; + /** * ParticleEffect Library *

diff --git a/src/main/java/me/skymc/taboolib/permission/PermissionUtils.java b/src/main/java/me/skymc/taboolib/permission/PermissionUtils.java index 10fd367..b6588e1 100644 --- a/src/main/java/me/skymc/taboolib/permission/PermissionUtils.java +++ b/src/main/java/me/skymc/taboolib/permission/PermissionUtils.java @@ -1,9 +1,10 @@ package me.skymc.taboolib.permission; +import org.bukkit.entity.Player; +import org.bukkit.plugin.RegisteredServiceProvider; + import me.skymc.taboolib.Main; import net.milkbowl.vault.permission.Permission; -import org.bukkit.entity.Player; -import org.bukkit.plugin.RegisteredServiceProvider; public class PermissionUtils { diff --git a/src/main/java/me/skymc/taboolib/playerdata/DataUtils.java b/src/main/java/me/skymc/taboolib/playerdata/DataUtils.java index 5b612f5..774e380 100644 --- a/src/main/java/me/skymc/taboolib/playerdata/DataUtils.java +++ b/src/main/java/me/skymc/taboolib/playerdata/DataUtils.java @@ -1,10 +1,10 @@ package me.skymc.taboolib.playerdata; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.database.PlayerDataManager; -import me.skymc.taboolib.exception.PlayerOfflineException; -import me.skymc.taboolib.fileutils.FileUtils; -import me.skymc.taboolib.message.MsgUtils; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; + import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.configuration.file.FileConfiguration; @@ -14,10 +14,11 @@ import org.bukkit.event.Listener; import org.bukkit.event.server.PluginDisableEvent; import org.bukkit.plugin.Plugin; -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.concurrent.ConcurrentHashMap; +import me.skymc.taboolib.Main; +import me.skymc.taboolib.database.PlayerDataManager; +import me.skymc.taboolib.exception.PlayerOfflineException; +import me.skymc.taboolib.fileutils.FileUtils; +import me.skymc.taboolib.message.MsgUtils; public class DataUtils implements Listener { diff --git a/src/main/java/me/skymc/taboolib/plugin/PluginUtils.java b/src/main/java/me/skymc/taboolib/plugin/PluginUtils.java index d5374c5..5794f6c 100644 --- a/src/main/java/me/skymc/taboolib/plugin/PluginUtils.java +++ b/src/main/java/me/skymc/taboolib/plugin/PluginUtils.java @@ -1,23 +1,34 @@ package me.skymc.taboolib.plugin; -import com.google.common.base.Joiner; -import me.skymc.taboolib.Main; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.SortedSet; +import java.util.logging.Level; +import java.util.logging.Logger; + import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.PluginCommand; import org.bukkit.command.SimpleCommandMap; import org.bukkit.event.Event; -import org.bukkit.plugin.*; +import org.bukkit.plugin.InvalidDescriptionException; +import org.bukkit.plugin.InvalidPluginException; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.RegisteredListener; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Field; -import java.net.URLClassLoader; -import java.util.*; -import java.util.Map.Entry; -import java.util.logging.Level; -import java.util.logging.Logger; +import com.google.common.base.Joiner; + +import me.skymc.taboolib.Main; public class PluginUtils { diff --git a/src/main/java/me/skymc/taboolib/regen/WorldGuardUtils.java b/src/main/java/me/skymc/taboolib/regen/WorldGuardUtils.java index d0ad421..0985731 100644 --- a/src/main/java/me/skymc/taboolib/regen/WorldGuardUtils.java +++ b/src/main/java/me/skymc/taboolib/regen/WorldGuardUtils.java @@ -1,10 +1,11 @@ package me.skymc.taboolib.regen; +import java.util.Map; + +import org.bukkit.Location; + import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.protection.regions.ProtectedRegion; -import org.bukkit.Location; - -import java.util.Map; @Deprecated public class WorldGuardUtils { diff --git a/src/main/java/me/skymc/taboolib/scoreboard/ScoreboardUtil.java b/src/main/java/me/skymc/taboolib/scoreboard/ScoreboardUtil.java index f7331e8..2d96946 100644 --- a/src/main/java/me/skymc/taboolib/scoreboard/ScoreboardUtil.java +++ b/src/main/java/me/skymc/taboolib/scoreboard/ScoreboardUtil.java @@ -1,15 +1,15 @@ package me.skymc.taboolib.scoreboard; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.scoreboard.DisplaySlot; -import org.bukkit.scoreboard.Scoreboard; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Scoreboard; + public class ScoreboardUtil { private ScoreboardUtil() { } diff --git a/src/main/java/me/skymc/taboolib/skript/SkriptHandler.java b/src/main/java/me/skymc/taboolib/skript/SkriptHandler.java index 9b88a78..9df2f0d 100644 --- a/src/main/java/me/skymc/taboolib/skript/SkriptHandler.java +++ b/src/main/java/me/skymc/taboolib/skript/SkriptHandler.java @@ -1,11 +1,12 @@ package me.skymc.taboolib.skript; +import org.bukkit.Bukkit; +import org.bukkit.inventory.ItemStack; + import ch.njol.skript.Skript; import ch.njol.skript.lang.ExpressionType; import me.skymc.taboolib.skript.expression.ExpressionItemCache; import me.skymc.taboolib.skript.expression.ExpressionTabooCodeItem; -import org.bukkit.Bukkit; -import org.bukkit.inventory.ItemStack; /** * @author sky diff --git a/src/main/java/me/skymc/taboolib/skript/expression/ExpressionTabooCodeItem.java b/src/main/java/me/skymc/taboolib/skript/expression/ExpressionTabooCodeItem.java index 566305a..df51680 100644 --- a/src/main/java/me/skymc/taboolib/skript/expression/ExpressionTabooCodeItem.java +++ b/src/main/java/me/skymc/taboolib/skript/expression/ExpressionTabooCodeItem.java @@ -1,12 +1,13 @@ package me.skymc.taboolib.skript.expression; +import org.bukkit.event.Event; +import org.bukkit.inventory.ItemStack; + import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.util.Kleenean; import me.skymc.taboocode.TabooCodeItem; -import org.bukkit.event.Event; -import org.bukkit.inventory.ItemStack; /** * @author sky diff --git a/src/main/java/me/skymc/taboolib/string/Language.java b/src/main/java/me/skymc/taboolib/string/Language.java index db5dea2..f81c70b 100644 --- a/src/main/java/me/skymc/taboolib/string/Language.java +++ b/src/main/java/me/skymc/taboolib/string/Language.java @@ -1,13 +1,5 @@ package me.skymc.taboolib.string; -import com.google.common.base.Charsets; -import me.skymc.taboolib.message.MsgUtils; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; - import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -15,6 +7,16 @@ import java.io.InputStreamReader; import java.util.Collections; import java.util.List; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import com.google.common.base.Charsets; + +import me.skymc.taboolib.message.MsgUtils; + public class Language { private FileConfiguration conf = null; diff --git a/src/main/java/me/skymc/taboolib/string/LanguageUtils.java b/src/main/java/me/skymc/taboolib/string/LanguageUtils.java index 2e4d935..199e61f 100644 --- a/src/main/java/me/skymc/taboolib/string/LanguageUtils.java +++ b/src/main/java/me/skymc/taboolib/string/LanguageUtils.java @@ -1,12 +1,13 @@ package me.skymc.taboolib.string; -import me.skymc.taboolib.message.MsgUtils; -import org.bukkit.plugin.Plugin; - import java.io.File; import java.util.Collections; import java.util.List; +import org.bukkit.plugin.Plugin; + +import me.skymc.taboolib.message.MsgUtils; + @Deprecated public class LanguageUtils { diff --git a/src/main/java/me/skymc/taboolib/string/language2/Language2Format.java b/src/main/java/me/skymc/taboolib/string/language2/Language2Format.java index ccb1dff..b2ecc8b 100644 --- a/src/main/java/me/skymc/taboolib/string/language2/Language2Format.java +++ b/src/main/java/me/skymc/taboolib/string/language2/Language2Format.java @@ -1,15 +1,20 @@ package me.skymc.taboolib.string.language2; -import lombok.Getter; -import me.skymc.taboolib.string.language2.value.*; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - import java.util.ArrayList; import java.util.LinkedList; import java.util.List; +import org.bukkit.entity.Player; + +import lombok.Getter; +import me.skymc.taboolib.string.language2.value.Language2Action; +import me.skymc.taboolib.string.language2.value.Language2Book; +import me.skymc.taboolib.string.language2.value.Language2Json; +import me.skymc.taboolib.string.language2.value.Language2Json2; +import me.skymc.taboolib.string.language2.value.Language2Sound; +import me.skymc.taboolib.string.language2.value.Language2Text; +import me.skymc.taboolib.string.language2.value.Language2Title; + /** * @author sky * @since 2018-03-08 22:45:56 diff --git a/src/main/java/me/skymc/taboolib/string/language2/Language2Value.java b/src/main/java/me/skymc/taboolib/string/language2/Language2Value.java index fddf89e..9f2abd5 100644 --- a/src/main/java/me/skymc/taboolib/string/language2/Language2Value.java +++ b/src/main/java/me/skymc/taboolib/string/language2/Language2Value.java @@ -1,14 +1,19 @@ package me.skymc.taboolib.string.language2; -import lombok.Getter; -import me.skymc.taboolib.string.language2.value.Language2Text; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map.Entry; + import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import java.util.*; -import java.util.Map.Entry; +import lombok.Getter; +import me.skymc.taboolib.string.language2.value.Language2Text; /** * @author sky diff --git a/src/main/java/me/skymc/taboolib/string/language2/value/Language2Action.java b/src/main/java/me/skymc/taboolib/string/language2/value/Language2Action.java index 9ac909e..10ede35 100644 --- a/src/main/java/me/skymc/taboolib/string/language2/value/Language2Action.java +++ b/src/main/java/me/skymc/taboolib/string/language2/value/Language2Action.java @@ -1,5 +1,12 @@ package me.skymc.taboolib.string.language2.value; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + import lombok.Getter; import me.skymc.taboolib.Main; import me.skymc.taboolib.TabooLib; @@ -8,12 +15,6 @@ import me.skymc.taboolib.other.NumberUtils; import me.skymc.taboolib.string.language2.Language2Format; import me.skymc.taboolib.string.language2.Language2Line; import me.skymc.taboolib.string.language2.Language2Value; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; - -import java.util.List; /** * @author sky diff --git a/src/main/java/me/skymc/taboolib/string/language2/value/Language2Book.java b/src/main/java/me/skymc/taboolib/string/language2/value/Language2Book.java index b59586f..7a0957e 100644 --- a/src/main/java/me/skymc/taboolib/string/language2/value/Language2Book.java +++ b/src/main/java/me/skymc/taboolib/string/language2/value/Language2Book.java @@ -1,5 +1,18 @@ package me.skymc.taboolib.string.language2.value; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + import lombok.Getter; import me.skymc.taboolib.bookformatter.BookFormatter; import me.skymc.taboolib.bookformatter.action.ClickAction; @@ -12,18 +25,6 @@ import me.skymc.taboolib.other.NumberUtils; import me.skymc.taboolib.string.language2.Language2Format; import me.skymc.taboolib.string.language2.Language2Line; import me.skymc.taboolib.string.language2.Language2Value; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map.Entry; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * @author sky diff --git a/src/main/java/me/skymc/taboolib/string/language2/value/Language2Json.java b/src/main/java/me/skymc/taboolib/string/language2/value/Language2Json.java index 9dd12a4..36d5ed2 100644 --- a/src/main/java/me/skymc/taboolib/string/language2/value/Language2Json.java +++ b/src/main/java/me/skymc/taboolib/string/language2/value/Language2Json.java @@ -1,5 +1,13 @@ package me.skymc.taboolib.string.language2.value; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + import lombok.Getter; import me.skymc.taboolib.inventory.ItemUtils; import me.skymc.taboolib.jsonformatter.JSONFormatter; @@ -13,13 +21,6 @@ import me.skymc.taboolib.jsonformatter.hover.ShowTextEvent; import me.skymc.taboolib.string.language2.Language2Format; import me.skymc.taboolib.string.language2.Language2Line; import me.skymc.taboolib.string.language2.Language2Value; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import java.util.List; /** * @author sky diff --git a/src/main/java/me/skymc/taboolib/string/language2/value/Language2Json2.java b/src/main/java/me/skymc/taboolib/string/language2/value/Language2Json2.java index 40b1503..843cb87 100644 --- a/src/main/java/me/skymc/taboolib/string/language2/value/Language2Json2.java +++ b/src/main/java/me/skymc/taboolib/string/language2/value/Language2Json2.java @@ -1,5 +1,18 @@ package me.skymc.taboolib.string.language2.value; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + import lombok.Getter; import me.skymc.taboolib.inventory.ItemUtils; import me.skymc.taboolib.jsonformatter.JSONFormatter; @@ -13,18 +26,6 @@ import me.skymc.taboolib.jsonformatter.hover.ShowTextEvent; import me.skymc.taboolib.string.language2.Language2Format; import me.skymc.taboolib.string.language2.Language2Line; import me.skymc.taboolib.string.language2.Language2Value; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map.Entry; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * @author sky diff --git a/src/main/java/me/skymc/taboolib/string/language2/value/Language2Text.java b/src/main/java/me/skymc/taboolib/string/language2/value/Language2Text.java index 2c66ed6..270cd05 100644 --- a/src/main/java/me/skymc/taboolib/string/language2/value/Language2Text.java +++ b/src/main/java/me/skymc/taboolib/string/language2/value/Language2Text.java @@ -1,14 +1,15 @@ package me.skymc.taboolib.string.language2.value; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + import lombok.Getter; import me.skymc.taboolib.string.language2.Language2Format; import me.skymc.taboolib.string.language2.Language2Line; import me.skymc.taboolib.string.language2.Language2Value; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -import java.util.ArrayList; -import java.util.List; /** * @author sky diff --git a/src/main/java/me/skymc/taboolib/string/language2/value/Language2Title.java b/src/main/java/me/skymc/taboolib/string/language2/value/Language2Title.java index 372d6e9..aa6894a 100644 --- a/src/main/java/me/skymc/taboolib/string/language2/value/Language2Title.java +++ b/src/main/java/me/skymc/taboolib/string/language2/value/Language2Title.java @@ -1,16 +1,17 @@ package me.skymc.taboolib.string.language2.value; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + import lombok.Getter; import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.display.TitleUtils; import me.skymc.taboolib.string.language2.Language2Format; import me.skymc.taboolib.string.language2.Language2Line; import me.skymc.taboolib.string.language2.Language2Value; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; - -import java.util.List; /** * @author sky diff --git a/src/main/java/me/skymc/taboolib/support/SupportPlaceholder.java b/src/main/java/me/skymc/taboolib/support/SupportPlaceholder.java index 0272787..34e13b9 100644 --- a/src/main/java/me/skymc/taboolib/support/SupportPlaceholder.java +++ b/src/main/java/me/skymc/taboolib/support/SupportPlaceholder.java @@ -1,12 +1,13 @@ package me.skymc.taboolib.support; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + import me.clip.placeholderapi.external.EZPlaceholderHook; import me.skymc.taboolib.database.GlobalDataManager; import me.skymc.tlm.TLM; import me.skymc.tlm.module.TabooLibraryModule; import me.skymc.tlm.module.sub.ModuleKits; -import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; public class SupportPlaceholder extends EZPlaceholderHook { diff --git a/src/main/java/me/skymc/taboolib/support/SupportWorldGuard.java b/src/main/java/me/skymc/taboolib/support/SupportWorldGuard.java index 503bec6..e326e33 100644 --- a/src/main/java/me/skymc/taboolib/support/SupportWorldGuard.java +++ b/src/main/java/me/skymc/taboolib/support/SupportWorldGuard.java @@ -1,15 +1,16 @@ package me.skymc.taboolib.support; -import com.sk89q.worldguard.bukkit.WorldGuardPlugin; -import com.sk89q.worldguard.protection.managers.RegionManager; -import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import java.util.Collection; + import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; -import java.util.Collection; +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import com.sk89q.worldguard.protection.managers.RegionManager; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; public class SupportWorldGuard { diff --git a/src/main/java/me/skymc/taboolib/team/TagManager.java b/src/main/java/me/skymc/taboolib/team/TagManager.java index 5d37efa..997a487 100644 --- a/src/main/java/me/skymc/taboolib/team/TagManager.java +++ b/src/main/java/me/skymc/taboolib/team/TagManager.java @@ -1,8 +1,7 @@ package me.skymc.taboolib.team; -import lombok.Getter; -import lombok.Setter; -import me.skymc.taboolib.Main; +import java.util.HashMap; + import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -12,7 +11,9 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Team; -import java.util.HashMap; +import lombok.Getter; +import lombok.Setter; +import me.skymc.taboolib.Main; /** * @author sky diff --git a/src/main/java/me/skymc/taboolib/timecycle/TimeCycleManager.java b/src/main/java/me/skymc/taboolib/timecycle/TimeCycleManager.java index a5a705b..a9f0270 100644 --- a/src/main/java/me/skymc/taboolib/timecycle/TimeCycleManager.java +++ b/src/main/java/me/skymc/taboolib/timecycle/TimeCycleManager.java @@ -1,16 +1,17 @@ package me.skymc.taboolib.timecycle; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.database.GlobalDataManager; -import me.skymc.taboolib.message.MsgUtils; -import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; -import org.bukkit.scheduler.BukkitRunnable; - import java.util.Collection; import java.util.HashMap; import java.util.concurrent.ConcurrentHashMap; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitRunnable; + +import me.skymc.taboolib.Main; +import me.skymc.taboolib.database.GlobalDataManager; +import me.skymc.taboolib.message.MsgUtils; + public class TimeCycleManager { /** diff --git a/src/main/java/me/skymc/taboolib/update/UpdateTask.java b/src/main/java/me/skymc/taboolib/update/UpdateTask.java index 3b9bc1c..0c1c5f1 100644 --- a/src/main/java/me/skymc/taboolib/update/UpdateTask.java +++ b/src/main/java/me/skymc/taboolib/update/UpdateTask.java @@ -1,13 +1,14 @@ package me.skymc.taboolib.update; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.bukkit.scheduler.BukkitRunnable; + import me.skymc.taboolib.Main; import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.fileutils.FileUtils; import me.skymc.taboolib.message.MsgUtils; -import org.bukkit.scheduler.BukkitRunnable; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * @author sky @@ -23,19 +24,18 @@ public class UpdateTask { @Override public void run() { - // 是否禁用 if (!Main.getInst().getConfig().getBoolean("UPDATE-CHECK")) { return; } - String value = FileUtils.getStringFromURL("https://github.com/Bkm016/TabooLib/releases", 1024); + if (value == null) { + return; + } Pattern pattern = Pattern.compile(""); Matcher matcher = pattern.matcher(value); if (matcher.find()) { - // 最新版本 double newVersion = Double.valueOf(matcher.group(1)); - // 如果是最新版 - if (TabooLib.getPluginVersion() == newVersion) { + if (TabooLib.getPluginVersion() >= newVersion) { MsgUtils.send("插件已是最新版, 无需更新!"); } else { diff --git a/src/main/java/me/skymc/tlm/TLM.java b/src/main/java/me/skymc/tlm/TLM.java index 7495c49..cff3dce 100644 --- a/src/main/java/me/skymc/tlm/TLM.java +++ b/src/main/java/me/skymc/tlm/TLM.java @@ -1,5 +1,7 @@ package me.skymc.tlm; +import org.bukkit.configuration.file.FileConfiguration; + import lombok.Getter; import me.skymc.taboolib.Main; import me.skymc.taboolib.fileutils.ConfigUtils; @@ -10,7 +12,6 @@ import me.skymc.tlm.module.sub.ModuleCommandChanger; import me.skymc.tlm.module.sub.ModuleInventorySave; import me.skymc.tlm.module.sub.ModuleKits; import me.skymc.tlm.module.sub.ModuleTimeCycle; -import org.bukkit.configuration.file.FileConfiguration; /** * @author sky diff --git a/src/main/java/me/skymc/tlm/annotation/DisableConfig.java b/src/main/java/me/skymc/tlm/annotation/DisableConfig.java index 091301e..83b8a2a 100644 --- a/src/main/java/me/skymc/tlm/annotation/DisableConfig.java +++ b/src/main/java/me/skymc/tlm/annotation/DisableConfig.java @@ -1,11 +1,11 @@ package me.skymc.tlm.annotation; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + @Retention(RUNTIME) @Target(TYPE) public @interface DisableConfig { diff --git a/src/main/java/me/skymc/tlm/command/sub/TLMKitCommand.java b/src/main/java/me/skymc/tlm/command/sub/TLMKitCommand.java index 65055e9..42949ee 100644 --- a/src/main/java/me/skymc/tlm/command/sub/TLMKitCommand.java +++ b/src/main/java/me/skymc/tlm/command/sub/TLMKitCommand.java @@ -1,16 +1,17 @@ package me.skymc.tlm.command.sub; -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.tlm.TLM; -import me.skymc.tlm.module.TabooLibraryModule; -import me.skymc.tlm.module.sub.ModuleKits; +import java.util.HashMap; +import java.util.List; + import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import java.util.HashMap; -import java.util.List; +import me.skymc.taboolib.commands.SubCommand; +import me.skymc.tlm.TLM; +import me.skymc.tlm.module.TabooLibraryModule; +import me.skymc.tlm.module.sub.ModuleKits; /** * @author sky diff --git a/src/main/java/me/skymc/tlm/module/TabooLibraryModule.java b/src/main/java/me/skymc/tlm/module/TabooLibraryModule.java index e1d9216..ae1dd5c 100644 --- a/src/main/java/me/skymc/tlm/module/TabooLibraryModule.java +++ b/src/main/java/me/skymc/tlm/module/TabooLibraryModule.java @@ -1,15 +1,16 @@ package me.skymc.tlm.module; -import me.skymc.taboolib.Main; -import me.skymc.tlm.annotation.DisableConfig; +import java.io.File; +import java.util.HashMap; +import java.util.Set; + import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.event.Listener; -import java.io.File; -import java.util.HashMap; -import java.util.Set; +import me.skymc.taboolib.Main; +import me.skymc.tlm.annotation.DisableConfig; /** * @author sky diff --git a/src/main/java/me/skymc/tlm/module/sub/ModuleKits.java b/src/main/java/me/skymc/tlm/module/sub/ModuleKits.java index 250e12a..cdaed64 100644 --- a/src/main/java/me/skymc/tlm/module/sub/ModuleKits.java +++ b/src/main/java/me/skymc/tlm/module/sub/ModuleKits.java @@ -1,17 +1,18 @@ package me.skymc.tlm.module.sub; +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + import me.skymc.taboolib.inventory.ItemUtils; import me.skymc.taboolib.message.MsgUtils; import me.skymc.taboolib.other.DateUtils; import me.skymc.taboolib.other.NumberUtils; import me.skymc.taboolib.playerdata.DataUtils; import me.skymc.tlm.module.ITabooLibraryModule; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import java.util.ArrayList; -import java.util.List; /** * @author sky diff --git a/src/main/java/me/skymc/tlm/module/sub/ModuleTimeCycle.java b/src/main/java/me/skymc/tlm/module/sub/ModuleTimeCycle.java index a367941..7e52f22 100644 --- a/src/main/java/me/skymc/tlm/module/sub/ModuleTimeCycle.java +++ b/src/main/java/me/skymc/tlm/module/sub/ModuleTimeCycle.java @@ -1,5 +1,11 @@ package me.skymc.tlm.module.sub; +import java.util.Calendar; + +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + import me.skymc.taboolib.Main; import me.skymc.taboolib.message.MsgUtils; import me.skymc.taboolib.other.DateUtils; @@ -9,11 +15,6 @@ import me.skymc.taboolib.timecycle.TimeCycleEvent; import me.skymc.taboolib.timecycle.TimeCycleInitializeEvent; import me.skymc.taboolib.timecycle.TimeCycleManager; import me.skymc.tlm.module.ITabooLibraryModule; -import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; - -import java.util.Calendar; /** * @author sky diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index eff92f7..b7c6087 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -21,6 +21,9 @@ DEBUG: false # 离线模式下将不会下载依赖 OFFLINE-MODE: false +# 下载依赖时启用的线程数 +DOWNLOAD-POOL-SIZE: 4 + # 是否启用更新检测 UPDATE-CHECK: true @@ -62,4 +65,4 @@ MYSQL: PluginData: # 检查更新间隔(单位:秒) # 检查变量是否被其他服务器更新 - CHECK-DELAY: 30 \ No newline at end of file + CHECK-DELAY: 5 \ No newline at end of file From dbb9eadde73c1cfee3556530d1a7e404d4b3847f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9D=8F=E9=BB=91?= Date: Sun, 22 Apr 2018 23:10:05 +0800 Subject: [PATCH 18/44] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ilummc/tlib/inject/TConfigInjector.java | 2 +- .../tlib/resources/TLocaleInstance.java | 2 +- .../ilummc/tlib/resources/TLocaleLoader.java | 2 +- .../tlib/resources/type/TLocaleTitle.java | 38 +++++++++---------- .../skymc/taboolib/fileutils/ConfigUtils.java | 5 ++- 5 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java index e2cbd02..f3a6312 100644 --- a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java @@ -32,7 +32,7 @@ import com.ilummc.tlib.bean.Property; public class TConfigInjector { - public static void fixUnicode(FileConfiguration configuration) { + public static void fixUnicode(YamlConfiguration configuration) { try { Field field = YamlConfiguration.class.getDeclaredField("yamlOptions"); field.setAccessible(true); diff --git a/src/main/java/com/ilummc/tlib/resources/TLocaleInstance.java b/src/main/java/com/ilummc/tlib/resources/TLocaleInstance.java index 591aa4a..4768d7b 100644 --- a/src/main/java/com/ilummc/tlib/resources/TLocaleInstance.java +++ b/src/main/java/com/ilummc/tlib/resources/TLocaleInstance.java @@ -47,7 +47,7 @@ class TLocaleInstance { return map.getOrDefault(path, ImmutableList.of(TLocaleSendable.getEmpty(path))).get(0).asString(); } - void load(FileConfiguration configuration) { + void load(YamlConfiguration configuration) { configuration.getKeys(false).forEach(s -> { Object object = configuration.get(s); if (object instanceof ConfigurationSection) { diff --git a/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java b/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java index 2397547..966334a 100644 --- a/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java +++ b/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java @@ -71,7 +71,7 @@ public class TLocaleLoader { saveResource(inputStream, file); } TLib.getTLib().getLogger().info("尝试加载 " + lang + ".yml 作为语言文件"); - FileConfiguration configuration = ConfigUtils.load(plugin, file); + YamlConfiguration configuration = ConfigUtils.loadYaml(plugin, file); TLocaleInstance localeInstance = new TLocaleInstance(); localeInstance.load(configuration); map.put(plugin.getName(), localeInstance); diff --git a/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java b/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java index ee8c808..4f19da4 100644 --- a/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java +++ b/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java @@ -23,31 +23,32 @@ import net.minecraft.server.v1_11_R1.EntityEvoker.e; * @since 2018-04-22 */ -@Immutable @SerializableAs("TITLE") -@Data public class TLocaleTitle implements TLocaleSendable, ConfigurationSerializable { - private String title; - private String subtitle; - private int fadein; - private int fadeout; - private int stay; + private final String title; + private final String subtitle; + private final int fadein; + private final int fadeout; + private final int stay; private boolean usePlaceholder; - private TLocaleTitle(boolean usePlaceholder) { + private TLocaleTitle(String title, String subString, int fadein, int fadeout, int stay, boolean usePlaceholder) { + this.title = title; + this.subtitle = subString; + this.fadein = fadein; + this.fadeout = fadeout; + this.stay = stay; this.usePlaceholder = usePlaceholder; } @Override public void sendTo(CommandSender sender, String... args) { - // TODO Auto-generated method stub } @Override public String asString(String... args) { - // TODO Auto-generated method stub return null; } @@ -66,16 +67,15 @@ public class TLocaleTitle implements TLocaleSendable, ConfigurationSerializable public static TLocaleTitle valueOf(Map map) { TLocaleTitle title; try { - title = new TLocaleTitle((boolean) map.getOrDefault("papi", TLib.getTLib().getConfig().isEnablePlaceholderHookByDefault())); - title.setTitle((String) map.getOrDefault("title", "")); - title.setSubtitle((String) map.getOrDefault("subtitle", "")); - title.setFadein((int) map.getOrDefault("fadein", 10)); - title.setFadeout((int) map.getOrDefault("fadeout", 10)); - title.setStay((int) map.getOrDefault("stay", 10)); + title = new TLocaleTitle( + (String) map.getOrDefault("title", ""), + (String) map.getOrDefault("subtitle", ""), + (int) map.getOrDefault("fadein", 10), + (int) map.getOrDefault("fadeout", 10), + (int) map.getOrDefault("stay", 20), + (boolean) map.getOrDefault("papi", TLib.getTLib().getConfig().isEnablePlaceholderHookByDefault())); } catch (Exception e) { - title = new TLocaleTitle(false); - title.setTitle("§4Load failed!"); - title.setSubtitle("§c" + e.getMessage()); + title = new TLocaleTitle("§4Load failed!", "§c" + e.getMessage(), 10, 20, 10, false); } return title; } diff --git a/src/main/java/me/skymc/taboolib/fileutils/ConfigUtils.java b/src/main/java/me/skymc/taboolib/fileutils/ConfigUtils.java index 225cc30..952c1c0 100644 --- a/src/main/java/me/skymc/taboolib/fileutils/ConfigUtils.java +++ b/src/main/java/me/skymc/taboolib/fileutils/ConfigUtils.java @@ -50,8 +50,11 @@ public class ConfigUtils { * @return */ public static FileConfiguration load(Plugin plugin, File file) { + return loadYaml(plugin, file); + } + + public static YamlConfiguration loadYaml(Plugin plugin, File file) { YamlConfiguration yaml = new YamlConfiguration(); - try { yaml = YamlConfiguration.loadConfiguration(new InputStreamReader(new FileInputStream(file), Charsets.UTF_8)); } catch (Exception e) { From 4f16196170d3a6f6cb470f77b0b4cb6df2d8ffa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9D=8F=E9=BB=91?= Date: Wed, 25 Apr 2018 22:58:58 +0800 Subject: [PATCH 19/44] =?UTF-8?q?=E5=85=BC=E5=AE=B9=20PlugMan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/ilummc/tlib/TLib.java | 2 +- .../com/ilummc/tlib/annotations/Logger.java | 2 +- .../tlib/inject/TDependencyInjector.java | 2 +- .../ilummc/tlib/inject/TPluginManager.java | 52 +++++++++++++- .../java/com/ilummc/tlib/logger/TLogger.java | 67 +++++++++++++++++++ .../tlib/resources/type/TLocaleTitle.java | 22 ++++-- 6 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/ilummc/tlib/logger/TLogger.java diff --git a/src/main/java/com/ilummc/tlib/TLib.java b/src/main/java/com/ilummc/tlib/TLib.java index 4b5514b..ac89b55 100644 --- a/src/main/java/com/ilummc/tlib/TLib.java +++ b/src/main/java/com/ilummc/tlib/TLib.java @@ -12,8 +12,8 @@ import com.ilummc.tlib.filter.TLoggerFilter; 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.TLocaleLoader; -import com.ilummc.tlib.util.TLogger; import lombok.Getter; import me.skymc.taboolib.Main; diff --git a/src/main/java/com/ilummc/tlib/annotations/Logger.java b/src/main/java/com/ilummc/tlib/annotations/Logger.java index af54460..2fc75a9 100644 --- a/src/main/java/com/ilummc/tlib/annotations/Logger.java +++ b/src/main/java/com/ilummc/tlib/annotations/Logger.java @@ -5,7 +5,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import com.ilummc.tlib.util.TLogger; +import com.ilummc.tlib.logger.TLogger; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) diff --git a/src/main/java/com/ilummc/tlib/inject/TDependencyInjector.java b/src/main/java/com/ilummc/tlib/inject/TDependencyInjector.java index da78271..d60e313 100644 --- a/src/main/java/com/ilummc/tlib/inject/TDependencyInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/TDependencyInjector.java @@ -14,9 +14,9 @@ import com.ilummc.tlib.annotations.Dependency; import com.ilummc.tlib.annotations.Logger; import com.ilummc.tlib.annotations.PluginInstance; import com.ilummc.tlib.dependency.TDependency; +import com.ilummc.tlib.logger.TLogger; import com.ilummc.tlib.resources.TLocaleLoader; import com.ilummc.tlib.util.Ref; -import com.ilummc.tlib.util.TLogger; public class TDependencyInjector { diff --git a/src/main/java/com/ilummc/tlib/inject/TPluginManager.java b/src/main/java/com/ilummc/tlib/inject/TPluginManager.java index 54b2318..59b80df 100644 --- a/src/main/java/com/ilummc/tlib/inject/TPluginManager.java +++ b/src/main/java/com/ilummc/tlib/inject/TPluginManager.java @@ -1,9 +1,18 @@ package com.ilummc.tlib.inject; import java.io.File; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.regex.Pattern; 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; @@ -17,16 +26,57 @@ import org.bukkit.plugin.PluginLoader; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.UnknownDependencyException; +import com.ilummc.tlib.TLib; + import me.skymc.taboolib.Main; +@SuppressWarnings("unused") public class TPluginManager implements PluginManager { private final PluginManager instance; - private final Main main = (Main) Main.getInst(); + private static File updateDirectory = null; + private Server server; + private Map fileAssociations = new HashMap<>(); + private List plugins = new ArrayList<>(); + private Map lookupNames = new HashMap<>(); + private SimpleCommandMap commandMap; + private Map permissions = new HashMap<>(); + private Map> defaultPerms = new LinkedHashMap<>(); + private Map> permSubs = new HashMap<>(); + private Map> defSubs = new HashMap<>(); + private boolean useTimings = false; 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"); + } + + private void cloneField(String bukkitName) { + try { + Field bukkitField = instance.getClass().getDeclaredField(bukkitName); + Field thisFiled = this.getClass().getDeclaredField(bukkitName); + if (bukkitField == null || thisFiled == null) { + TLib.getTLib().getLogger().warn("拷贝 " + bukkitName + " 对象失败"); + return; + } + bukkitField.setAccessible(true); + thisFiled.setAccessible(true); + thisFiled.set(this, bukkitField.get(instance)); + } catch (Exception ignored) { + TLib.getTLib().getLogger().error("拷贝 " + bukkitName + " 对象出错"); + } } @Override diff --git a/src/main/java/com/ilummc/tlib/logger/TLogger.java b/src/main/java/com/ilummc/tlib/logger/TLogger.java new file mode 100644 index 0000000..2f6b3e0 --- /dev/null +++ b/src/main/java/com/ilummc/tlib/logger/TLogger.java @@ -0,0 +1,67 @@ +package com.ilummc.tlib.logger; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.plugin.Plugin; + +import com.ilummc.tlib.util.Strings; + +import lombok.Getter; +import lombok.Setter; +import me.skymc.taboolib.Main; + +public class TLogger { + + public static final int VERBOSE = 0, FINEST = 1, FINE = 2, INFO = 3, WARN = 4, ERROR = 5, FATAL = 6; + + @Getter + private static TLogger globalLogger = new TLogger("§8[§3§lTabooLib§8][§r{1}§8] §f{2}", Main.getInst(), TLogger.FINE); + @Getter + private final String pattern; + @Getter + private Plugin plugin; + @Getter + @Setter + private int level; + + public TLogger(String pattern, Plugin plugin, int level) { + this.pattern = pattern; + this.plugin = plugin; + this.level = level; + } + + public void verbose(String msg) { + if (level <= VERBOSE) + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§f全部", ChatColor.translateAlternateColorCodes('&', msg))); + } + + public void finest(String msg) { + if (level <= FINEST) + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§e良好", ChatColor.translateAlternateColorCodes('&', msg))); + } + + public void fine(String msg) { + if (level <= FINE) + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§a正常", ChatColor.translateAlternateColorCodes('&', msg))); + } + + public void info(String msg) { + if (level <= INFO) + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§b信息", ChatColor.translateAlternateColorCodes('&', msg))); + } + + public void warn(String msg) { + if (level <= WARN) + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§6警告", "§6" + ChatColor.translateAlternateColorCodes('&', msg))); + } + + public void error(String msg) { + if (level <= ERROR) + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§c错误", "§c" + ChatColor.translateAlternateColorCodes('&', msg))); + } + + public void fatal(String msg) { + if (level <= FATAL) + Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§4致命错误", "§4" + ChatColor.translateAlternateColorCodes('&', msg))); + } +} diff --git a/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java b/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java index 4f19da4..37c9386 100644 --- a/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java +++ b/src/main/java/com/ilummc/tlib/resources/type/TLocaleTitle.java @@ -5,24 +5,26 @@ import java.util.Map; import javax.annotation.concurrent.Immutable; +import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.SerializableAs; +import org.bukkit.entity.Player; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import com.ilummc.tlib.TLib; +import com.ilummc.tlib.compat.PlaceholderHook; import com.ilummc.tlib.resources.TLocaleSendable; +import com.ilummc.tlib.util.Strings; -import lombok.Data; -import lombok.Getter; -import net.minecraft.server.v1_11_R1.EntityEvoker.e; +import me.skymc.taboolib.display.TitleUtils; /** * @author Bkm016 * @since 2018-04-22 */ +@Immutable @SerializableAs("TITLE") public class TLocaleTitle implements TLocaleSendable, ConfigurationSerializable { @@ -45,11 +47,16 @@ public class TLocaleTitle implements TLocaleSendable, ConfigurationSerializable @Override public void sendTo(CommandSender sender, String... args) { + if (sender instanceof Player) { + TitleUtils.sendTitle((Player) sender, replaceText(sender, title), replaceText(sender, subtitle), fadein, stay, fadeout); + } else { + TLib.getTLib().getLogger().error("该语言类型只能发送给玩家"); + } } @Override public String asString(String... args) { - return null; + return Strings.replaceWithOrder(title, args); } @Override @@ -79,5 +86,8 @@ public class TLocaleTitle implements TLocaleSendable, ConfigurationSerializable } return title; } - + + private String replaceText(CommandSender sender, String s) { + return ChatColor.translateAlternateColorCodes('&', usePlaceholder ? PlaceholderHook.replace(sender, s) : s); + } } From 381d96c5b10447e07dd73ead26135d44a6ad717b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9D=8F=E9=BB=91?= Date: Thu, 26 Apr 2018 18:21:06 +0800 Subject: [PATCH 20/44] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tlib/compat/PlaceholderApiHook.java | 40 ---- .../tlib/inject/DependencyInjector.java | 168 ----------------- .../ilummc/tlib/inject/TLibPluginManager.java | 174 ------------------ .../ilummc/tlib/resources/LocaleInstance.java | 65 ------- .../ilummc/tlib/resources/LocaleLoader.java | 76 -------- .../com/ilummc/tlib/resources/Sendable.java | 21 --- .../tlib/resources/SimpleChatMessage.java | 95 ---------- .../ilummc/tlib/resources/TLocaleLoader.java | 2 +- .../java/com/ilummc/tlib/util/TLogger.java | 65 ------- 9 files changed, 1 insertion(+), 705 deletions(-) delete mode 100644 src/main/java/com/ilummc/tlib/compat/PlaceholderApiHook.java delete mode 100644 src/main/java/com/ilummc/tlib/inject/DependencyInjector.java delete mode 100644 src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java delete mode 100644 src/main/java/com/ilummc/tlib/resources/LocaleInstance.java delete mode 100644 src/main/java/com/ilummc/tlib/resources/LocaleLoader.java delete mode 100644 src/main/java/com/ilummc/tlib/resources/Sendable.java delete mode 100644 src/main/java/com/ilummc/tlib/resources/SimpleChatMessage.java delete mode 100644 src/main/java/com/ilummc/tlib/util/TLogger.java diff --git a/src/main/java/com/ilummc/tlib/compat/PlaceholderApiHook.java b/src/main/java/com/ilummc/tlib/compat/PlaceholderApiHook.java deleted file mode 100644 index 728ee4c..0000000 --- a/src/main/java/com/ilummc/tlib/compat/PlaceholderApiHook.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.ilummc.tlib.compat; - -import me.clip.placeholderapi.PlaceholderAPI; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -public abstract class PlaceholderApiHook { - - private static PlaceholderApiHook impl; - - public static void init() { - if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) - impl = new PlaceholderImpl(); - else impl = new AbstractImpl(); - } - - public static String replace(CommandSender sender, String text) { - return sender instanceof Player ? impl.replace(((Player) sender), text) : text; - } - - abstract String replace(Player player, String text); - - private static class PlaceholderImpl extends PlaceholderApiHook { - - @Override - String replace(Player player, String text) { - return PlaceholderAPI.setPlaceholders(player, text); - } - } - - private static class AbstractImpl extends PlaceholderApiHook { - - @Override - String replace(Player player, String text) { - return text; - } - } - -} diff --git a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java b/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java deleted file mode 100644 index b528cf3..0000000 --- a/src/main/java/com/ilummc/tlib/inject/DependencyInjector.java +++ /dev/null @@ -1,168 +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.LocaleLoader; -import com.ilummc.tlib.util.Ref; -import com.ilummc.tlib.util.TLogger; -import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.java.JavaPlugin; - -import java.io.File; -import java.lang.reflect.Field; - -public class DependencyInjector { - - public static void inject(Plugin plugin, Object o) { - injectDependencies(plugin, o); - injectLogger(plugin, o); - injectConfig(plugin, o); - injectPluginInstance(plugin, o); - LocaleLoader.load(plugin, true); - } - - static void injectOnEnable(Plugin plugin) { - inject(plugin, plugin); - } - - static void onDisable(Plugin plugin) { - eject(plugin, plugin); - } - - public static void eject(Plugin plugin, Object o) { - try { - ejectConfig(plugin, o); - } catch (Throwable ignored) { - } - } - - private static void ejectConfig(Plugin plugin, Object o) { - for (Field field : Ref.getDeclaredFields(o.getClass())) { - Config config; - if ((config = field.getType().getAnnotation(Config.class)) != null && config.saveOnExit()) { - try { - field.setAccessible(true); - TConfigInjector.saveConfig(plugin, field.get(o)); - TLib.getTLib().getLogger().info("插件 " + plugin + " 的配置 " + config.name() + " 已保存"); - } catch (Exception e) { - TLib.getTLib().getLogger().warn("插件 " + plugin + " 的配置 " + config.name() + " 保存失败"); - e.printStackTrace(); - } - } - } - } - - private static void injectConfig(Plugin plugin, Object o) { - for (Field field : Ref.getDeclaredFields(o.getClass())) { - try { - Config config; - if ((config = field.getType().getAnnotation(Config.class)) != null) { - field.setAccessible(true); - Object obj = TConfigInjector.loadConfig(plugin, field.getType()); - if (obj != null) { - TLib.getTLib().getLogger().info("插件 " + plugin.getName() + " 的 " + config.name() + " 配置文件成功加载"); - field.set(o, obj); - if (config.listenChanges()) { - TLib.getTLib().getLogger().info("开始监听插件 " + plugin.getName() + " 的 " + config.name() + " 配置文件"); - TLib.getTLib().getConfigWatcher().addOnListen( - new File(plugin.getDataFolder(), config.name()), - obj, - object -> { - try { - Object newObj = TConfigInjector.loadConfig(plugin, object.getClass()); - for (Field f : newObj.getClass().getDeclaredFields()) { - f.setAccessible(true); - f.set(obj, f.get(newObj)); - } - TLib.getTLib().getLogger().info("插件 " + plugin.getName() + " 的 " + config.name() + " 配置文件成功重载"); - } catch (Exception ignored) { - TLib.getTLib().getLogger().warn("插件 " + plugin.getName() + " 的 " + 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(TLogger.class); - TLogger tLogger = new TLogger(logger.value(), plugin, logger.level()); - if (!field.isAccessible()) - field.setAccessible(true); - field.set(o, 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())) { - TLib.getTLib().getLogger().warn(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 = 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}; - } - } - if (dependencies.length != 0) { - TLib.getTLib().getLogger().info("正在加载 " + plugin.getName() + " 插件所需的依赖"); - for (Dependency dependency : dependencies) { - if (dependency.type() == Dependency.Type.PLUGIN) { - if (TDependency.requestPlugin(dependency.plugin())) { - TLib.getTLib().getLogger().info(" " + plugin.getName() + " 请求的插件 " + dependency.plugin() + " 加载成功。"); - } else { - TLib.getTLib().getLogger().warn(" " + plugin.getName() + " 请求的插件 " + dependency.plugin() + " 加载失败。"); - } - } - if (dependency.type() == Dependency.Type.LIBRARY) { - if (TDependency.requestLib(dependency.maven(), dependency.mavenRepo(), dependency.url())) { - TLib.getTLib().getLogger().info(" " + plugin.getName() + " 请求的库文件 " + String.join(":", dependency.maven()) + " 加载成功。"); - } else { - TLib.getTLib().getLogger().warn(" " + plugin.getName() + " 请求的库文件 " + String.join(":", dependency.maven()) + " 加载失败。"); - } - } - } - TLib.getTLib().getLogger().info("依赖加载完成"); - } - } - -} diff --git a/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java b/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java deleted file mode 100644 index 42f640d..0000000 --- a/src/main/java/com/ilummc/tlib/inject/TLibPluginManager.java +++ /dev/null @@ -1,174 +0,0 @@ -package com.ilummc.tlib.inject; - -import me.skymc.taboolib.Main; -import org.bukkit.Bukkit; -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.util.Set; - -public class TLibPluginManager implements PluginManager { - - private final PluginManager instance; - - private final Main main = (Main) Main.getInst(); - - public TLibPluginManager() { - instance = Bukkit.getPluginManager(); - } - - @Override - public void registerInterface(Class 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) disablePlugin(plugin); - } - 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 aClass, Listener listener, EventPriority eventPriority, EventExecutor eventExecutor, Plugin plugin) { - instance.registerEvent(aClass, listener, eventPriority, eventExecutor, plugin); - } - - @Override - public void registerEvent(Class 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) { - DependencyInjector.injectOnEnable(plugin); - instance.enablePlugin(plugin); - } - - @Override - public void disablePlugin(Plugin plugin) { - DependencyInjector.onDisable(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 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 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 getDefaultPermSubscriptions(boolean b) { - return instance.getDefaultPermSubscriptions(b); - } - - @Override - public Set getPermissions() { - return instance.getPermissions(); - } - - @Override - public boolean useTimings() { - return instance.useTimings(); - } -} diff --git a/src/main/java/com/ilummc/tlib/resources/LocaleInstance.java b/src/main/java/com/ilummc/tlib/resources/LocaleInstance.java deleted file mode 100644 index aec3862..0000000 --- a/src/main/java/com/ilummc/tlib/resources/LocaleInstance.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.ilummc.tlib.resources; - -import com.google.common.collect.ImmutableList; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.YamlConfiguration; - -import javax.annotation.concurrent.ThreadSafe; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Function; -import java.util.stream.Collectors; - -@ThreadSafe -class LocaleInstance { - - private static final Function TO_SENDABLE = o -> { - if (o instanceof Sendable) return ((Sendable) o); - else if (o instanceof String) return SimpleChatMessage.of(((String) o)); - else return SimpleChatMessage.of(String.valueOf(o)); - }; - - LocaleInstance() { - } - - private final Map> map = new ConcurrentHashMap<>(); - - void sendTo(String path, CommandSender sender) { - map.getOrDefault(path, ImmutableList.of(Sendable.EMPTY)).forEach(sendable -> sendable.sendTo(sender)); - } - - void sendTo(String path, CommandSender sender, String... args) { - map.getOrDefault(path, ImmutableList.of(Sendable.EMPTY)).forEach(sendable -> sendable.sendTo(sender, args)); - System.out.println(map.toString()); - } - - void load(YamlConfiguration configuration) { - configuration.getKeys(false).forEach(s -> { - Object object = configuration.get(s); - if (object instanceof ConfigurationSection) - loadRecursively(s, (ConfigurationSection) object); - else if (object instanceof Sendable) - map.put(s, Collections.singletonList((Sendable) object)); - else if (object instanceof List && !((List) object).isEmpty()) - map.put(s, ((List) object).stream().map(TO_SENDABLE).collect(Collectors.toList())); - else map.put(s, Collections.singletonList(SimpleChatMessage.of(String.valueOf(object)))); - }); - } - - private void loadRecursively(String path, ConfigurationSection section) { - section.getKeys(false).forEach(s -> { - Object object = section.get(path + "." + s); - if (object instanceof ConfigurationSection) - loadRecursively(path + "." + s, (ConfigurationSection) object); - else if (object instanceof Sendable) - map.put(path + "." + s, Collections.singletonList((Sendable) object)); - else if (object instanceof List && !((List) object).isEmpty()) - map.put(path + "." + s, ((List) object).stream().map(TO_SENDABLE).collect(Collectors.toList())); - else map.put(path + "." + s, Collections.singletonList(SimpleChatMessage.of(String.valueOf(object)))); - }); - } - -} diff --git a/src/main/java/com/ilummc/tlib/resources/LocaleLoader.java b/src/main/java/com/ilummc/tlib/resources/LocaleLoader.java deleted file mode 100644 index 9767d43..0000000 --- a/src/main/java/com/ilummc/tlib/resources/LocaleLoader.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.ilummc.tlib.resources; - -import com.ilummc.tlib.TLib; -import com.ilummc.tlib.inject.TConfigInjector; -import me.skymc.taboolib.Main; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.configuration.serialization.ConfigurationSerialization; -import org.bukkit.plugin.Plugin; - -import java.io.File; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.StandardOpenOption; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -public class LocaleLoader { - - private static final Map map = new HashMap<>(); - - static void sendTo(Plugin plugin, String path, CommandSender sender, String... args) { - Optional.ofNullable(map.get(plugin.getName())).ifPresent(localeInstance -> localeInstance.sendTo(path, sender, args)); - } - - static void sendTo(Plugin plugin, String path, CommandSender sender) { - Optional.ofNullable(map.get(plugin.getName())).ifPresent(localeInstance -> localeInstance.sendTo(path, sender)); - } - - public static void init() { - ConfigurationSerialization.registerClass(SimpleChatMessage.class); - ConfigurationSerialization.registerClass(SimpleChatMessage.class, "Message"); - ConfigurationSerialization.registerClass(SimpleChatMessage.class, "MESSAGE"); - ConfigurationSerialization.registerClass(SimpleChatMessage.class, "TEXT"); - ConfigurationSerialization.registerClass(SimpleChatMessage.class, "Text"); - } - - public static void load(Plugin plugin, boolean ignoreLoaded) { - try { - if ((!ignoreLoaded || !map.containsKey(plugin.getName())) && plugin == Main.getInst() || - plugin.getDescription().getDepend().contains("TabooLib") || plugin.getDescription().getSoftDepend().contains("TabooLib")) { - InputStream inputStream = null; - File file = null; - String lang = null; - for (String s : TLib.getTLib().getConfig().getLocale()) { - lang = s; - file = new File(plugin.getDataFolder(), "/lang/" + s + ".yml"); - if (file.exists()) { - inputStream = Files.newInputStream(file.toPath(), StandardOpenOption.READ); - break; - } else if ((inputStream = plugin.getClass().getResourceAsStream("/lang/" + s + ".yml")) != null) - break; - } - if (inputStream == null) return; - TLib.getTLib().getLogger().info("尝试加载 " + lang + ".yml 作为语言文件"); - YamlConfiguration configuration = YamlConfiguration.loadConfiguration(new InputStreamReader(inputStream, Charset.forName("utf-8"))); - LocaleInstance localeInstance = new LocaleInstance(); - localeInstance.load(configuration); - map.put(plugin.getName(), localeInstance); - TConfigInjector.fixUnicode(configuration); - if (!file.exists()) { - file.getParentFile().mkdirs(); - file.createNewFile(); - } - configuration.save(file); - TLib.getTLib().getLogger().info("成功加载 " + lang + " 语言文件"); - } - } catch (Exception e) { - TLib.getTLib().getLogger().error("载入语言文件发生异常:" + e.toString()); - } - } - -} diff --git a/src/main/java/com/ilummc/tlib/resources/Sendable.java b/src/main/java/com/ilummc/tlib/resources/Sendable.java deleted file mode 100644 index e033cb4..0000000 --- a/src/main/java/com/ilummc/tlib/resources/Sendable.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.ilummc.tlib.resources; - -import org.bukkit.command.CommandSender; - -public interface Sendable { - - Sendable EMPTY = new Sendable() { - @Override - public void sendTo(CommandSender sender) { - } - - @Override - public void sendTo(CommandSender sender, String... args) { - } - }; - - void sendTo(CommandSender sender); - - void sendTo(CommandSender sender, String... args); - -} diff --git a/src/main/java/com/ilummc/tlib/resources/SimpleChatMessage.java b/src/main/java/com/ilummc/tlib/resources/SimpleChatMessage.java deleted file mode 100644 index 7e8781d..0000000 --- a/src/main/java/com/ilummc/tlib/resources/SimpleChatMessage.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.ilummc.tlib.resources; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; -import com.ilummc.tlib.TLib; -import com.ilummc.tlib.compat.PlaceholderApiHook; -import com.ilummc.tlib.util.Strings; -import org.bukkit.ChatColor; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.serialization.ConfigurationSerializable; -import org.bukkit.configuration.serialization.SerializableAs; - -import javax.annotation.concurrent.Immutable; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - -@Immutable -@SerializableAs("TEXT") -@SuppressWarnings("unchecked") -public class SimpleChatMessage implements Sendable, ConfigurationSerializable { - - private final Object text; - - private final boolean usePlaceholder; - - private SimpleChatMessage(Object text, boolean usePlaceholder) { - this.usePlaceholder = usePlaceholder; - if (text instanceof String) - this.text = text; - else if (text instanceof List) - this.text = ImmutableList.copyOf(((List) text)); - else - throw new IllegalArgumentException("Param 'text' can only be an instance of String or String[] or List"); - } - - @Override - public void sendTo(CommandSender sender) { - if (text instanceof String) - sender.sendMessage(replaceMsg(sender, (String) text)); - else if (text instanceof List) - ((List) text).forEach(s -> sender.sendMessage(replaceMsg(sender, String.valueOf(s)))); - } - - @Override - public void sendTo(CommandSender sender, String... args) { - if (text instanceof String) - sender.sendMessage(replaceMsg(sender, Strings.replaceWithOrder((String) text, args))); - else if (text instanceof List) - ((List) text).forEach(s -> sender.sendMessage(replaceMsg(sender, Strings.replaceWithOrder(String.valueOf(s), args)))); - } - - private String replaceMsg(CommandSender sender, String s) { - return usePlaceholder ? PlaceholderApiHook.replace(sender, s) : s; - } - - @Override - public String toString() { - if (text instanceof String[]) return Arrays.toString((String[]) text); - else return text.toString(); - } - - @Override - public Map serialize() { - if (usePlaceholder) return Maps.newHashMap(ImmutableMap.of("text", text, "papi", true)); - return Maps.newHashMap(ImmutableMap.of("text", text)); - } - - public static SimpleChatMessage valueOf(Map map) { - if (map.containsKey("text")) { - Object object = map.get("text"); - Object objPapi = map.getOrDefault("papi", TLib.getTLib().getConfig().isEnablePapiByDefault()); - boolean papi = objPapi instanceof Boolean ? (boolean) objPapi : objPapi instanceof String && objPapi.equals("true"); - if (object instanceof List) - return new SimpleChatMessage(((List) object).stream() - .map(s -> ChatColor.translateAlternateColorCodes('&', s)) - .collect(Collectors.toList()), papi); - else if (object instanceof String[]) - return new SimpleChatMessage(Arrays.stream(((String[]) object)) - .map(s -> ChatColor.translateAlternateColorCodes('&', s)) - .collect(Collectors.toList()), papi); - else - return new SimpleChatMessage(ChatColor.translateAlternateColorCodes('&', Objects.toString(object)), papi); - } - return new SimpleChatMessage("§cError chat message loaded.", TLib.getTLib().getConfig().isEnablePapiByDefault()); - } - - public static SimpleChatMessage of(String s) { - return new SimpleChatMessage(ChatColor.translateAlternateColorCodes('&', s), TLib.getTLib().getConfig().isEnablePapiByDefault()); - } - -} diff --git a/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java b/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java index 966334a..86346fe 100644 --- a/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java +++ b/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java @@ -38,7 +38,7 @@ public class TLocaleLoader { } static String asString(Plugin plugin, String path) { - return Optional.ofNullable(map.get(plugin.getName())).get().asString(path); + return map.get(plugin.getName()).asString(path); } public static void init() { diff --git a/src/main/java/com/ilummc/tlib/util/TLogger.java b/src/main/java/com/ilummc/tlib/util/TLogger.java deleted file mode 100644 index bbbe2bf..0000000 --- a/src/main/java/com/ilummc/tlib/util/TLogger.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.ilummc.tlib.util; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.plugin.Plugin; - -import lombok.Getter; -import lombok.Setter; - -public class TLogger { - - public static final int VERBOSE = 0, FINEST = 1, FINE = 2, INFO = 3, WARN = 4, ERROR = 5, FATAL = 6; - - @Getter - private final String pattern; - - @Getter - private Plugin plugin; - - @Getter - @Setter - private int level; - - public TLogger(String pattern, Plugin plugin, int level) { - this.pattern = pattern; - this.plugin = plugin; - this.level = level; - } - - public void verbose(String msg) { - if (level <= VERBOSE) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§f全部", ChatColor.translateAlternateColorCodes('&', msg))); - } - - public void finest(String msg) { - if (level <= FINEST) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§e良好", ChatColor.translateAlternateColorCodes('&', msg))); - } - - public void fine(String msg) { - if (level <= FINE) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§a正常", ChatColor.translateAlternateColorCodes('&', msg))); - } - - public void info(String msg) { - if (level <= INFO) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§b信息", ChatColor.translateAlternateColorCodes('&', msg))); - } - - public void warn(String msg) { - if (level <= WARN) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§6警告", "§6" + ChatColor.translateAlternateColorCodes('&', msg))); - } - - public void error(String msg) { - if (level <= ERROR) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§c错误", "§c" + ChatColor.translateAlternateColorCodes('&', msg))); - } - - public void fatal(String msg) { - if (level <= FATAL) - Bukkit.getConsoleSender().sendMessage(Strings.replaceWithOrder(pattern, plugin.getName(), "§4致命错误", "§4" + ChatColor.translateAlternateColorCodes('&', msg))); - } - -} From 93e84b1b801f15545d9318ea1aa58b4098f5b7d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9D=8F=E9=BB=91?= Date: Thu, 26 Apr 2018 23:33:44 +0800 Subject: [PATCH 21/44] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ilummc/tlib/inject/TConfigInjector.java | 3 +- .../com/ilummc/tlib/resources/TLocale.java | 5 - .../tlib/resources/TLocaleInstance.java | 1 - .../ilummc/tlib/resources/TLocaleLoader.java | 9 +- .../versions/AnvilContainer_V1_11_R1.java | 2 + .../versions/AnvilContainer_V1_8_R3.java | 2 + .../anvil/versions/AnvilContainer_V1_9_4.java | 2 + .../me/skymc/taboolib/csvutils/CsvReader.java | 3 +- .../me/skymc/taboolib/csvutils/CsvWriter.java | 3 +- .../skymc/taboolib/display/ActionUtils.java | 76 +++++------- .../me/skymc/taboolib/display/TitleUtils.java | 106 +++++++--------- .../skymc/taboolib/events/DefaultEvent.java | 1 + .../skymc/taboolib/events/DefaultEvent2.java | 9 +- .../taboolib/events/PlayerJumpEvent.java | 9 +- .../taboolib/events/PlayerLoadedEvent.java | 1 + .../skymc/taboolib/fileutils/ConfigUtils.java | 4 - .../taboolib/itemnbtapi/NBTContainer.java | 6 +- .../skymc/taboolib/itemnbtapi/NBTEntity.java | 6 +- .../me/skymc/taboolib/itemnbtapi/NBTFile.java | 6 +- .../me/skymc/taboolib/itemnbtapi/NBTItem.java | 6 +- .../taboolib/itemnbtapi/NBTTileEntity.java | 6 +- .../me/skymc/taboolib/json/JSONArray.java | 3 +- .../me/skymc/taboolib/json/JSONException.java | 3 +- .../me/skymc/taboolib/json/JSONObject.java | 12 +- .../me/skymc/taboolib/json/JSONStringer.java | 3 +- .../me/skymc/taboolib/json/JSONTokener.java | 3 +- .../skymc/taboolib/mysql/MysqlConnection.java | 1 + .../mysql/protect/MySQLConnection.java | 1 + .../java/me/skymc/taboolib/nms/NMSUtils.java | 9 +- .../taboolib/nms/item/impl/_164ItemUtils.java | 113 +++++++++++++++--- .../nms/item/impl/_1710ItemUtils.java | 109 ++++++++++++++--- .../taboolib/nms/item/impl/_194ItemUtils.java | 109 ++++++++++++++--- .../me/skymc/taboolib/particle/EffLib.java | 8 +- .../taboolib/sign/TabooSignChangeEvent.java | 3 +- .../taboolib/string/language2/Language2.java | 69 +---------- .../language2/value/Language2Action.java | 1 + .../string/language2/value/Language2Json.java | 1 + .../taboolib/timecycle/TimeCycleEvent.java | 1 + .../timecycle/TimeCycleInitializeEvent.java | 1 + src/main/resources/plugin.yml | 6 +- 40 files changed, 444 insertions(+), 278 deletions(-) diff --git a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java index f3a6312..da6445e 100644 --- a/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java +++ b/src/main/java/com/ilummc/tlib/inject/TConfigInjector.java @@ -12,7 +12,6 @@ import java.util.Map; import java.util.stream.Collectors; import org.apache.commons.lang3.Validate; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.ConfigurationSerialization; @@ -169,7 +168,7 @@ public class TConfigInjector { return ((Collection) o).stream().map(this::serialize).collect(Collectors.toList()); } else if (o instanceof Map) { Map map = new LinkedHashMap<>(); - ((Map) o).forEach((o1, o2) -> map.put((String) o1, serialize(o2))); + ((Map) o).forEach((o1, o2) -> map.put(o1, serialize(o2))); return map; } else if (o instanceof ConfigurationSerializable) { Map map = new LinkedHashMap<>(); diff --git a/src/main/java/com/ilummc/tlib/resources/TLocale.java b/src/main/java/com/ilummc/tlib/resources/TLocale.java index 8842d60..fd90219 100644 --- a/src/main/java/com/ilummc/tlib/resources/TLocale.java +++ b/src/main/java/com/ilummc/tlib/resources/TLocale.java @@ -4,17 +4,12 @@ import java.lang.reflect.Field; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; -import org.bukkit.entity.HumanEntity; -import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; -import com.google.common.base.Strings; import com.ilummc.tlib.TLib; import com.ilummc.tlib.util.Ref; import me.skymc.taboolib.Main; -import me.skymc.taboolib.TabooLib; public final class TLocale { diff --git a/src/main/java/com/ilummc/tlib/resources/TLocaleInstance.java b/src/main/java/com/ilummc/tlib/resources/TLocaleInstance.java index 4768d7b..fff1c33 100644 --- a/src/main/java/com/ilummc/tlib/resources/TLocaleInstance.java +++ b/src/main/java/com/ilummc/tlib/resources/TLocaleInstance.java @@ -11,7 +11,6 @@ import javax.annotation.concurrent.ThreadSafe; import org.bukkit.command.CommandSender; import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import com.google.common.collect.ImmutableList; diff --git a/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java b/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java index 86346fe..8a65100 100644 --- a/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java +++ b/src/main/java/com/ilummc/tlib/resources/TLocaleLoader.java @@ -1,14 +1,8 @@ package com.ilummc.tlib.resources; -import java.io.BufferedInputStream; import java.io.File; -import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.FileReader; import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.channels.FileChannel; -import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.StandardOpenOption; import java.util.HashMap; @@ -16,7 +10,6 @@ import java.util.Map; import java.util.Optional; import org.bukkit.command.CommandSender; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.serialization.ConfigurationSerialization; import org.bukkit.plugin.Plugin; @@ -24,6 +17,7 @@ import org.bukkit.plugin.Plugin; import com.ilummc.tlib.TLib; import com.ilummc.tlib.inject.TConfigInjector; import com.ilummc.tlib.resources.type.TLocaleText; +import com.ilummc.tlib.resources.type.TLocaleTitle; import me.skymc.taboolib.Main; import me.skymc.taboolib.fileutils.ConfigUtils; @@ -43,6 +37,7 @@ public class TLocaleLoader { public static void init() { ConfigurationSerialization.registerClass(TLocaleText.class, "TEXT"); + ConfigurationSerialization.registerClass(TLocaleTitle.class, "TITLE"); } public static void load(Plugin plugin, boolean ignoreLoaded) { diff --git a/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_11_R1.java b/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_11_R1.java index 4c6c656..68cdcff 100644 --- a/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_11_R1.java +++ b/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_11_R1.java @@ -17,6 +17,7 @@ public class AnvilContainer_V1_11_R1 extends ContainerAnvil { super(player.inventory, player.world, new BlockPosition(0, 0, 0), player); } + @Override public boolean a(EntityHuman player) { return true; @@ -25,6 +26,7 @@ public class AnvilContainer_V1_11_R1 extends ContainerAnvil { /** * @deprecated 方法已过期,已有新的方法 */ + @Deprecated public static void openAnvil(Player p) { EntityPlayer player = ((CraftPlayer)p).getHandle(); diff --git a/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_8_R3.java b/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_8_R3.java index f5c0117..3b38d5e 100644 --- a/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_8_R3.java +++ b/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_8_R3.java @@ -17,6 +17,7 @@ public class AnvilContainer_V1_8_R3 extends ContainerAnvil { super(player.inventory, player.world, new BlockPosition(0, 0, 0), player); } + @Override public boolean a(EntityHuman player) { return true; @@ -25,6 +26,7 @@ public class AnvilContainer_V1_8_R3 extends ContainerAnvil { /** * @deprecated 方法已过期,已有新的方法 */ + @Deprecated public static void openAnvil(Player p) { EntityPlayer player = ((CraftPlayer)p).getHandle(); diff --git a/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_9_4.java b/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_9_4.java index 33a80f5..ed3abf4 100644 --- a/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_9_4.java +++ b/src/main/java/me/skymc/taboolib/anvil/versions/AnvilContainer_V1_9_4.java @@ -17,6 +17,7 @@ public class AnvilContainer_V1_9_4 extends ContainerAnvil { super(player.inventory, player.world, new BlockPosition(0, 0, 0), player); } + @Override public boolean a(EntityHuman player) { return true; @@ -25,6 +26,7 @@ public class AnvilContainer_V1_9_4 extends ContainerAnvil { /** * @deprecated 方法已过期,已有新的方法 */ + @Deprecated public static void openAnvil(Player p) { EntityPlayer player = ((CraftPlayer)p).getHandle(); diff --git a/src/main/java/me/skymc/taboolib/csvutils/CsvReader.java b/src/main/java/me/skymc/taboolib/csvutils/CsvReader.java index fdc1eb9..6d24bc7 100644 --- a/src/main/java/me/skymc/taboolib/csvutils/CsvReader.java +++ b/src/main/java/me/skymc/taboolib/csvutils/CsvReader.java @@ -979,7 +979,8 @@ public class CsvReader } } - protected void finalize() { + @Override + protected void finalize() { this.close(false); } diff --git a/src/main/java/me/skymc/taboolib/csvutils/CsvWriter.java b/src/main/java/me/skymc/taboolib/csvutils/CsvWriter.java index 8547c74..1253798 100644 --- a/src/main/java/me/skymc/taboolib/csvutils/CsvWriter.java +++ b/src/main/java/me/skymc/taboolib/csvutils/CsvWriter.java @@ -276,7 +276,8 @@ public class CsvWriter } } - protected void finalize() { + @Override + protected void finalize() { this.close(false); } diff --git a/src/main/java/me/skymc/taboolib/display/ActionUtils.java b/src/main/java/me/skymc/taboolib/display/ActionUtils.java index b9ef334..38524f8 100644 --- a/src/main/java/me/skymc/taboolib/display/ActionUtils.java +++ b/src/main/java/me/skymc/taboolib/display/ActionUtils.java @@ -2,65 +2,51 @@ package me.skymc.taboolib.display; import java.lang.reflect.Constructor; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.nms.NMSUtils; +/** + * @author Bkm016 + * @since 2018-04-26 + */ public class ActionUtils { - private static void sendPacket(Player player, Object packet) - { - try - { - Object handle = player.getClass().getMethod("getHandle", new Class[0]).invoke(player); - Object playerConnection = handle.getClass().getField("playerConnection").get(handle); - playerConnection.getClass().getMethod("sendPacket", new Class[]{getNMSClass("Packet")}).invoke(playerConnection, packet); + private static Class Packet = NMSUtils.getNMSClass("Packet"); + private static Class ChatComponentText = NMSUtils.getNMSClass("ChatComponentText"); + private static Class ChatMessageType = NMSUtils.getNMSClass("ChatMessageType"); + private static Class PacketPlayOutChat = NMSUtils.getNMSClass("PacketPlayOutChat"); + private static Class IChatBaseComponent = NMSUtils.getNMSClass("IChatBaseComponent"); + + public static void send(Player player, String action) { + if (player == null) { + return; } - catch (Exception ex) - { - ex.printStackTrace(); - } - } - - private static Class getNMSClass(String class_name) - { - String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; - try - { - return Class.forName("net.minecraft.server." + version + "." + class_name); - } - catch (ClassNotFoundException ex) - { - ex.printStackTrace(); - } - return null; - } - - public static void send(Player p, String msg) - { - if (msg == null) { - msg = ""; - } - try - { - Object ab = getNMSClass("ChatComponentText").getConstructor(new Class[]{String.class}).newInstance(msg); + try { + Object ab = ChatComponentText.getConstructor(String.class).newInstance(action); Constructor ac = null; Object abPacket = null; - // 如果版本大于 1.11.0 if (TabooLib.getVerint() > 11100) { - Class chatMessageType = getNMSClass("ChatMessageType"); - ac = getNMSClass("PacketPlayOutChat").getConstructor(getNMSClass("IChatBaseComponent"), chatMessageType); - abPacket = ac.newInstance(ab, chatMessageType.getMethod("a", Byte.TYPE).invoke(null, (byte) 2)); + ac = PacketPlayOutChat.getConstructor(IChatBaseComponent, ChatMessageType); + abPacket = ac.newInstance(ab, ChatMessageType.getMethod("a", Byte.TYPE).invoke(null, (byte) 2)); } else { - ac = getNMSClass("PacketPlayOutChat").getConstructor(getNMSClass("IChatBaseComponent"), Byte.TYPE); + ac = PacketPlayOutChat.getConstructor(IChatBaseComponent, Byte.TYPE); abPacket = ac.newInstance(ab, (byte) 2); } - sendPacket(p, abPacket); + sendPacket(player, abPacket); } - catch (Exception ex) - { - ex.printStackTrace(); + catch (Exception ignored) { + } + } + + private static void sendPacket(Player player, Object packet) { + try { + Object handle = player.getClass().getMethod("getHandle", new Class[0]).invoke(player); + Object playerConnection = handle.getClass().getField("playerConnection").get(handle); + playerConnection.getClass().getMethod("sendPacket", Packet).invoke(playerConnection, packet); + } + catch (Exception ignored) { } } } diff --git a/src/main/java/me/skymc/taboolib/display/TitleUtils.java b/src/main/java/me/skymc/taboolib/display/TitleUtils.java index 5cafc30..1589457 100644 --- a/src/main/java/me/skymc/taboolib/display/TitleUtils.java +++ b/src/main/java/me/skymc/taboolib/display/TitleUtils.java @@ -1,85 +1,69 @@ package me.skymc.taboolib.display; import java.lang.reflect.Constructor; +import java.lang.reflect.Method; import org.bukkit.entity.Player; +import me.skymc.taboolib.nms.NMSUtils; + +/** + * @author Bkm016 + * @since 2018-04-26 + */ public class TitleUtils { - - private static void sendPacket(Player player, Object packet) - { - try - { - Object handle = player.getClass().getMethod("getHandle", new Class[0]).invoke(player); - Object playerConnection = handle.getClass().getField("playerConnection").get(handle); - playerConnection.getClass().getMethod("sendPacket", new Class[]{getNMSClass("Packet")}).invoke(playerConnection, packet); - } - catch (Exception ex) - { - ex.printStackTrace(); - } - } - - private static Class getNMSClass(String class_name) - { - String version = org.bukkit.Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; - try - { - return Class.forName("net.minecraft.server." + version + "." + class_name); - } - catch (ClassNotFoundException ex) - { - ex.printStackTrace(); - } - return null; - } + + private static Class Packet = NMSUtils.getNMSClass("Packet"); + private static Class PacketPlayOutTitle = NMSUtils.getNMSClass("PacketPlayOutTitle"); + private static Class IChatBaseComponent = NMSUtils.getNMSClass("IChatBaseComponent"); + private static Class EnumTitleAction = PacketPlayOutTitle.getDeclaredClasses()[0]; public static void sendTitle(Player p, String title, String subtitle, int fadein, int stay, int fadeout) { sendTitle(p, title, fadein, stay, fadeout, subtitle, fadein, stay, fadeout); } - public static void sendTitle(Player p, String title, int fadeint, int stayt, int fadeoutt, String subtitle, int fadeinst, int stayst, int fadeoutst) - { - if (title == null) { - title = ""; - } - if (subtitle == null) { - subtitle = ""; - } - try - { - if (title != null) - { - Object e = getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0].getField("TIMES").get(null); - Object chatTitle = getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", new Class[]{String.class}).invoke(null, "{\"text\":\"" + title + "\"}"); - Constructor subtitleConstructor = getNMSClass("PacketPlayOutTitle").getConstructor(getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0], getNMSClass("IChatBaseComponent"), Integer.TYPE, Integer.TYPE, Integer.TYPE); - Object titlePacket = subtitleConstructor.newInstance(e, chatTitle, fadeint, stayt, fadeoutt); + public static void sendTitle(Player p, String title, int fadeint, int stayt, int fadeoutt, String subtitle, int fadeinst, int stayst, int fadeoutst) { + if (p == null) { + return; + } + try { + if (title != null) { + Object times = EnumTitleAction.getField("TIMES").get(null); + Object chatTitle = IChatBaseComponent.getDeclaredClasses()[0].getMethod("a", String.class).invoke(null, "{\"text\":\"" + title + "\"}"); + Constructor subtitleConstructor = PacketPlayOutTitle.getConstructor(EnumTitleAction, IChatBaseComponent, Integer.TYPE, Integer.TYPE, Integer.TYPE); + Object titlePacket = subtitleConstructor.newInstance(times, chatTitle, fadeint, stayt, fadeoutt); sendPacket(p, titlePacket); - e = getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0].getField("TITLE").get(null); - chatTitle = getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", new Class[]{String.class}).invoke(null, "{\"text\":\"" + title + "\"}"); - subtitleConstructor = getNMSClass("PacketPlayOutTitle").getConstructor(getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0], getNMSClass("IChatBaseComponent")); - titlePacket = subtitleConstructor.newInstance(e, chatTitle); + times = EnumTitleAction.getField("TITLE").get(null); + chatTitle = IChatBaseComponent.getDeclaredClasses()[0].getMethod("a", String.class).invoke(null, "{\"text\":\"" + title + "\"}"); + subtitleConstructor = PacketPlayOutTitle.getConstructor(EnumTitleAction, IChatBaseComponent); + titlePacket = subtitleConstructor.newInstance(times, chatTitle); sendPacket(p, titlePacket); } - if (subtitle != null) - { - Object e = getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0].getField("TIMES").get(null); - Object chatSubtitle = getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", new Class[]{String.class}).invoke(null, "{\"text\":\"" + title + "\"}"); - Constructor subtitleConstructor = getNMSClass("PacketPlayOutTitle").getConstructor(getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0], getNMSClass("IChatBaseComponent"), Integer.TYPE, Integer.TYPE, Integer.TYPE); - Object subtitlePacket = subtitleConstructor.newInstance(e, chatSubtitle, fadeinst, stayst, fadeoutst); + if (subtitle != null) { + Object times = EnumTitleAction.getField("TIMES").get(null); + Object chatSubtitle = IChatBaseComponent.getDeclaredClasses()[0].getMethod("a", String.class).invoke(null, "{\"text\":\"" + title + "\"}"); + Constructor subtitleConstructor = PacketPlayOutTitle.getConstructor(EnumTitleAction, IChatBaseComponent, Integer.TYPE, Integer.TYPE, Integer.TYPE); + Object subtitlePacket = subtitleConstructor.newInstance(times, chatSubtitle, fadeinst, stayst, fadeoutst); sendPacket(p, subtitlePacket); - e = getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0].getField("SUBTITLE").get(null); - chatSubtitle = getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", new Class[]{String.class}).invoke(null, "{\"text\":\"" + subtitle + "\"}"); - subtitleConstructor = getNMSClass("PacketPlayOutTitle").getConstructor(getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0], getNMSClass("IChatBaseComponent"), Integer.TYPE, Integer.TYPE, Integer.TYPE); - subtitlePacket = subtitleConstructor.newInstance(e, chatSubtitle, fadeinst, stayst, fadeoutst); + times = EnumTitleAction.getField("SUBTITLE").get(null); + chatSubtitle = IChatBaseComponent.getDeclaredClasses()[0].getMethod("a", String.class).invoke(null, "{\"text\":\"" + subtitle + "\"}"); + subtitleConstructor = PacketPlayOutTitle.getConstructor(EnumTitleAction, IChatBaseComponent, Integer.TYPE, Integer.TYPE, Integer.TYPE); + subtitlePacket = subtitleConstructor.newInstance(times, chatSubtitle, fadeinst, stayst, fadeoutst); sendPacket(p, subtitlePacket); } } - catch (Exception ex) - { - ex.printStackTrace(); + catch (Exception ignored) { + } + } + + private static void sendPacket(Player player, Object packet) { + try { + Object handle = player.getClass().getDeclaredMethod("getHandle").invoke(player); + Object playerConnection = handle.getClass().getDeclaredField("playerConnection").get(handle); + playerConnection.getClass().getDeclaredMethod("sendPacket", Packet).invoke(playerConnection, packet); + } catch (Exception ignored) { } } } diff --git a/src/main/java/me/skymc/taboolib/events/DefaultEvent.java b/src/main/java/me/skymc/taboolib/events/DefaultEvent.java index 171760a..cc24099 100644 --- a/src/main/java/me/skymc/taboolib/events/DefaultEvent.java +++ b/src/main/java/me/skymc/taboolib/events/DefaultEvent.java @@ -17,6 +17,7 @@ public class DefaultEvent extends Event { return this.player; } + @Override public HandlerList getHandlers() { return handlers; } diff --git a/src/main/java/me/skymc/taboolib/events/DefaultEvent2.java b/src/main/java/me/skymc/taboolib/events/DefaultEvent2.java index 324609b..1df26f6 100644 --- a/src/main/java/me/skymc/taboolib/events/DefaultEvent2.java +++ b/src/main/java/me/skymc/taboolib/events/DefaultEvent2.java @@ -21,7 +21,8 @@ public class DefaultEvent2 extends PlayerEvent return DefaultEvent2.handlers; } - public HandlerList getHandlers() { + @Override + public HandlerList getHandlers() { return DefaultEvent2.handlers; } @@ -34,11 +35,13 @@ public class DefaultEvent2 extends PlayerEvent this.cancelled = false; } - public boolean isCancelled() { + @Override + public boolean isCancelled() { return this.cancelled; } - public void setCancelled(final boolean cancelled) { + @Override + public void setCancelled(final boolean cancelled) { this.cancelled = cancelled; } } diff --git a/src/main/java/me/skymc/taboolib/events/PlayerJumpEvent.java b/src/main/java/me/skymc/taboolib/events/PlayerJumpEvent.java index 843590e..39d4c38 100644 --- a/src/main/java/me/skymc/taboolib/events/PlayerJumpEvent.java +++ b/src/main/java/me/skymc/taboolib/events/PlayerJumpEvent.java @@ -24,17 +24,20 @@ public class PlayerJumpEvent return this.player; } - public boolean isCancelled() + @Override +public boolean isCancelled() { return this.isCancelled; } - public void setCancelled(boolean e) + @Override +public void setCancelled(boolean e) { this.isCancelled = e; } - public HandlerList getHandlers() + @Override +public HandlerList getHandlers() { return handlers; } diff --git a/src/main/java/me/skymc/taboolib/events/PlayerLoadedEvent.java b/src/main/java/me/skymc/taboolib/events/PlayerLoadedEvent.java index 5a4f0a8..5b66380 100644 --- a/src/main/java/me/skymc/taboolib/events/PlayerLoadedEvent.java +++ b/src/main/java/me/skymc/taboolib/events/PlayerLoadedEvent.java @@ -18,6 +18,7 @@ public class PlayerLoadedEvent extends Event { return this.player; } + @Override public HandlerList getHandlers() { return handlers; } diff --git a/src/main/java/me/skymc/taboolib/fileutils/ConfigUtils.java b/src/main/java/me/skymc/taboolib/fileutils/ConfigUtils.java index 952c1c0..ead25ad 100644 --- a/src/main/java/me/skymc/taboolib/fileutils/ConfigUtils.java +++ b/src/main/java/me/skymc/taboolib/fileutils/ConfigUtils.java @@ -2,11 +2,9 @@ package me.skymc.taboolib.fileutils; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.InputStreamReader; import java.io.StringReader; -import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.Plugin; @@ -15,8 +13,6 @@ import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; import com.google.common.base.Charsets; import com.ilummc.tlib.TLib; -import me.skymc.taboolib.message.MsgUtils; - public class ConfigUtils { public static FileConfiguration decodeYAML(String args) { diff --git a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTContainer.java b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTContainer.java index 370acaa..988283a 100644 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTContainer.java +++ b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTContainer.java @@ -24,11 +24,13 @@ public class NBTContainer extends NBTCompound{ } } - protected Object getCompound() { + @Override + protected Object getCompound() { return nbt; } - protected void setCompound(Object tag) { + @Override + protected void setCompound(Object tag) { nbt = tag; } diff --git a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTEntity.java b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTEntity.java index a4e0566..43e4cee 100644 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTEntity.java +++ b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTEntity.java @@ -11,11 +11,13 @@ public class NBTEntity extends NBTCompound { ent = entity; } - protected Object getCompound() { + @Override + protected Object getCompound() { return NBTReflectionUtil.getEntityNBTTagCompound(NBTReflectionUtil.getNMSEntity(ent)); } - protected void setCompound(Object compound) { + @Override + protected void setCompound(Object compound) { NBTReflectionUtil.setEntityNBTTag(compound, NBTReflectionUtil.getNMSEntity(ent)); } diff --git a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTFile.java b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTFile.java index 64ad2b3..2228a8a 100644 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTFile.java +++ b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTFile.java @@ -35,11 +35,13 @@ public class NBTFile extends NBTCompound { return file; } - protected Object getCompound() { + @Override + protected Object getCompound() { return nbt; } - protected void setCompound(Object compound) { + @Override + protected void setCompound(Object compound) { nbt = compound; } diff --git a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTItem.java b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTItem.java index c9ddcd9..526612d 100644 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTItem.java +++ b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTItem.java @@ -11,11 +11,13 @@ public class NBTItem extends NBTCompound { bukkitItem = item.clone(); } - protected Object getCompound() { + @Override + protected Object getCompound() { return NBTReflectionUtil.getItemRootNBTTagCompound(NBTReflectionUtil.getNMSItemStack(bukkitItem)); } - protected void setCompound(Object compound) { + @Override + protected void setCompound(Object compound) { bukkitItem = NBTReflectionUtil.getBukkitItemStack(NBTReflectionUtil.setNBTTag(compound, NBTReflectionUtil.getNMSItemStack(bukkitItem))); } diff --git a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTTileEntity.java b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTTileEntity.java index 1ec3295..21024e9 100644 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTTileEntity.java +++ b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTTileEntity.java @@ -11,11 +11,13 @@ public class NBTTileEntity extends NBTCompound { this.tile = tile; } - protected Object getCompound() { + @Override + protected Object getCompound() { return NBTReflectionUtil.getTileEntityNBTTagCompound(tile); } - protected void setCompound(Object compound) { + @Override + protected void setCompound(Object compound) { NBTReflectionUtil.setTileEntityNBTTagCompound(tile, compound); } diff --git a/src/main/java/me/skymc/taboolib/json/JSONArray.java b/src/main/java/me/skymc/taboolib/json/JSONArray.java index ef74a8c..b0345cd 100644 --- a/src/main/java/me/skymc/taboolib/json/JSONArray.java +++ b/src/main/java/me/skymc/taboolib/json/JSONArray.java @@ -354,7 +354,8 @@ public class JSONArray { return jo; } - public String toString() { + @Override + public String toString() { try { return '[' + this.join(",") + ']'; } catch (Exception e) { diff --git a/src/main/java/me/skymc/taboolib/json/JSONException.java b/src/main/java/me/skymc/taboolib/json/JSONException.java index d6b2c53..5827e53 100644 --- a/src/main/java/me/skymc/taboolib/json/JSONException.java +++ b/src/main/java/me/skymc/taboolib/json/JSONException.java @@ -15,7 +15,8 @@ public class JSONException extends Exception { this.cause = cause; } - public Throwable getCause() { + @Override + public Throwable getCause() { return this.cause; } } diff --git a/src/main/java/me/skymc/taboolib/json/JSONObject.java b/src/main/java/me/skymc/taboolib/json/JSONObject.java index 7007bf7..19fdb2d 100644 --- a/src/main/java/me/skymc/taboolib/json/JSONObject.java +++ b/src/main/java/me/skymc/taboolib/json/JSONObject.java @@ -19,15 +19,18 @@ public class JSONObject { private static final class Null { - protected final Object clone() { + @Override + protected final Object clone() { return this; } - public boolean equals(Object object) { + @Override + public boolean equals(Object object) { return object == null || object == this; } - public String toString() { + @Override + public String toString() { return "null"; } } @@ -702,7 +705,8 @@ public class JSONObject { return ja; } - public String toString() { + @Override + public String toString() { try { return this.toString(0); } catch (Exception e) { diff --git a/src/main/java/me/skymc/taboolib/json/JSONStringer.java b/src/main/java/me/skymc/taboolib/json/JSONStringer.java index 8a32e82..dddfca5 100644 --- a/src/main/java/me/skymc/taboolib/json/JSONStringer.java +++ b/src/main/java/me/skymc/taboolib/json/JSONStringer.java @@ -8,7 +8,8 @@ public class JSONStringer extends JSONWriter { super(new StringWriter()); } - public String toString() { + @Override + public String toString() { return this.mode == 'd' ? this.writer.toString() : null; } } diff --git a/src/main/java/me/skymc/taboolib/json/JSONTokener.java b/src/main/java/me/skymc/taboolib/json/JSONTokener.java index dd68f9e..1bb311e 100644 --- a/src/main/java/me/skymc/taboolib/json/JSONTokener.java +++ b/src/main/java/me/skymc/taboolib/json/JSONTokener.java @@ -280,7 +280,8 @@ public class JSONTokener { return new JSONException(message + this.toString()); } - public String toString() { + @Override + public String toString() { return " at " + this.index + " [character " + this.character + " line " + this.line + "]"; } diff --git a/src/main/java/me/skymc/taboolib/mysql/MysqlConnection.java b/src/main/java/me/skymc/taboolib/mysql/MysqlConnection.java index 8f28b04..bec8274 100644 --- a/src/main/java/me/skymc/taboolib/mysql/MysqlConnection.java +++ b/src/main/java/me/skymc/taboolib/mysql/MysqlConnection.java @@ -285,6 +285,7 @@ public class MysqlConnection { * * @see Example: SQL_ClearTable("tablename"); */ + @Deprecated public void SQL_ClearTable(String table) { if (!isConnection()) { return; diff --git a/src/main/java/me/skymc/taboolib/mysql/protect/MySQLConnection.java b/src/main/java/me/skymc/taboolib/mysql/protect/MySQLConnection.java index c76d65d..1b2fdfe 100644 --- a/src/main/java/me/skymc/taboolib/mysql/protect/MySQLConnection.java +++ b/src/main/java/me/skymc/taboolib/mysql/protect/MySQLConnection.java @@ -804,6 +804,7 @@ public class MySQLConnection { this.type = type; } + @Override public String toString() { if (type instanceof ColumnInteger || type instanceof ColumnChar) { return "`" + name + "` " + type.toString().toLowerCase() + "(" + a + ")"; diff --git a/src/main/java/me/skymc/taboolib/nms/NMSUtils.java b/src/main/java/me/skymc/taboolib/nms/NMSUtils.java index 2541858..ec28b91 100644 --- a/src/main/java/me/skymc/taboolib/nms/NMSUtils.java +++ b/src/main/java/me/skymc/taboolib/nms/NMSUtils.java @@ -52,8 +52,7 @@ public class NMSUtils { public static Class getNMSClass(String className){ try{ return getNMSClassWithException(className); - }catch(Exception e){ - e.printStackTrace(); + }catch(Exception ignored){ } return null; } @@ -89,8 +88,7 @@ public class NMSUtils { public static Class getOBCClass(String className){ try{ return getOBCClassWithException(className); - }catch(Exception e){ - e.printStackTrace(); + }catch(Exception ignored){ } return null; } @@ -106,8 +104,7 @@ public class NMSUtils { public static Object getHandle(Object obj){ try{ return getMethodWithException(obj.getClass(), "getHandle").invoke(obj); - }catch(Exception e){ - e.printStackTrace(); + }catch(Exception ignored){ return null; } } diff --git a/src/main/java/me/skymc/taboolib/nms/item/impl/_164ItemUtils.java b/src/main/java/me/skymc/taboolib/nms/item/impl/_164ItemUtils.java index 98ef84d..c08b5ba 100644 --- a/src/main/java/me/skymc/taboolib/nms/item/impl/_164ItemUtils.java +++ b/src/main/java/me/skymc/taboolib/nms/item/impl/_164ItemUtils.java @@ -36,6 +36,7 @@ public class _164ItemUtils implements IDabItemUtils{ return false; } + @Override public boolean hasBanner(){ return banner; } @@ -43,18 +44,21 @@ public class _164ItemUtils implements IDabItemUtils{ public Class nmis = NMSUtils.getClass("net.minecraft.item.ItemStack"), cis = NMSUtils.getOBCClass("inventory.CraftItemStack"); public Method nmscopy = NMSUtils.getMethodSilent(cis, "asNMSCopy", ItemStack.class); + @Override public Object getNMSCopy(ItemStack is) throws Exception{ return nmscopy.invoke(null, is); } public Method hastag = NMSUtils.getMethodSilent(nmis, "func_77978_p"); + @Override public boolean hasTag(Object is) throws Exception{ return (boolean)hastag.invoke(is); } public Method acm = NMSUtils.getMethodSilent(cis, "asCraftMirror", nmis); + @Override public ItemStack asCraftMirror(Object nis) throws Exception{ return (ItemStack)acm.invoke(null, nis); } @@ -63,12 +67,14 @@ public class _164ItemUtils implements IDabItemUtils{ public Method abc = NMSUtils.getMethodSilent(cis, "asBukkitCopy", nmis); + @Override public ItemStack asBukkitCopy(Object nmis) throws Exception{ return (ItemStack)abc.invoke(null, nmis); } public Method gn = NMSUtils.getMethodSilent(nmis, "func_77977_a"); + @Override public String getName(ItemStack is){ try{ return (String)gn.invoke(getNMSCopy(is)); @@ -79,14 +85,17 @@ public class _164ItemUtils implements IDabItemUtils{ public Method gi = NMSUtils.getMethodSilent(nmis, "func_77973_b"), ia = getA(); + @Override public Object getItem(Object nis) throws Exception{ return gi.invoke(nis); } + @Override public Method getA(){ return NMSUtils.getMethodSilent(ni, "func_77658_a", nmis); } + @Override public String getRawName(ItemStack is){ try{ Object nis = getNMSCopy(is); @@ -98,6 +107,7 @@ public class _164ItemUtils implements IDabItemUtils{ public Method gin = NMSUtils.getMethodSilent(ni, "getName"); + @Override public String getItemName(ItemStack is){ try{ return (String)gin.invoke(gi.invoke(getNMSCopy(is))); @@ -108,6 +118,7 @@ public class _164ItemUtils implements IDabItemUtils{ public Object registry = getRegistry(); + @Override public Object getRegistry(){ try{ return NMSUtils.getFieldSilent(ni, "REGISTRY", "field_150901_e").get(null); @@ -120,6 +131,7 @@ public class _164ItemUtils implements IDabItemUtils{ public Field nmrsc = NMSUtils.getFieldSilent(nmrs, "field_82596_a"); + @Override public String getMinecraftName(ItemStack is){ String name = getItemName(is); if(nmrs == null){ return name; } @@ -139,22 +151,26 @@ public class _164ItemUtils implements IDabItemUtils{ public Class nbttc = NMSUtils.getClass("net.minecraft.nbt.NBTTagCompound"); public Field tag = NMSUtils.getField(nmis, "field_77990_d"); + @Override public Object getTag(Object is) throws Exception{ return tag.get(is); } + @Override public void setTag(Object is, Object tag1) throws Exception{ tag.set(is, tag1); } public Method nbtcie = NMSUtils.getMethodSilent(nbttc, "func_82582_d"); + @Override public boolean isEmpty(Object tag) throws Exception{ return (boolean)nbtcie.invoke(tag); } public Field nbttcm = NMSUtils.getField(nbttc, "field_74784_a"); + @Override public Object getMap(Object tag) throws Exception{ return nbttcm.get(tag); } @@ -167,32 +183,39 @@ public class _164ItemUtils implements IDabItemUtils{ public Method nbttcsl = NMSUtils.getMethodSilent(nbttc, "func_74772_a", String.class, long.class); public Method nbttcss1 = NMSUtils.getMethodSilent(nbttc, "func_74777_a", String.class, short.class); + @Override public void set(Object tag, String key, Object value) throws Exception{ nbttcs.invoke(tag, key, value); } + @Override public void setString(Object tag, String key, String value) throws Exception{ nbttcss.invoke(tag, key, value); } + @Override public void setShort(Object tag, String key, short value) throws Exception{ nbttcss1.invoke(tag, key, value); } + @Override public void setInt(Object tag, String key, int i) throws Exception{ nbttcsi.invoke(tag, key, i); } + @Override public void setDouble(Object tag, String key, double d) throws Exception{ nbttcsd.invoke(tag, key, d); } + @Override public void setLong(Object tag, String key, long l) throws Exception{ nbttcsl.invoke(tag, key, l); } public Method nbttchk = NMSUtils.getMethodSilent(nbttc, "func_74764_b", String.class); + @Override public boolean hasKey(Object tag, String key) throws Exception{ return (boolean)nbttchk.invoke(tag, key); } @@ -204,38 +227,46 @@ public class _164ItemUtils implements IDabItemUtils{ public Method nbttcgl = NMSUtils.getMethodSilent(nbttc, "func_74763_f", String.class); public Method nbttcgs1 = NMSUtils.getMethodSilent(nbttc, "func_74765_d", String.class); + @Override public Object get(Object tag, String key) throws Exception{ return nbttcg.invoke(tag, key); } + @Override public String getString(Object tag, String key) throws Exception{ return (String)nbttcgs.invoke(tag, key); } + @Override public int getInt(Object tag, String key) throws Exception{ return (int)nbttcgi.invoke(tag, key); } + @Override public double getDouble(Object tag, String key) throws Exception{ return (double)nbttcgd.invoke(tag, key); } + @Override public long getLong(Object tag, String key) throws Exception{ return (long)nbttcgl.invoke(tag, key); } + @Override public short getShort(Object tag, String key) throws Exception{ return (short)nbttcgs1.invoke(tag, key); } public Constructor nbttcc = NMSUtils.getConstructorSilent(nbttc); + @Override public Object getNewNBTTagCompound() throws Exception{ return nbttcc.newInstance(); } public Method hkot = NMSUtils.getMethodSilent(nbttc, "func_150297_b", String.class, int.class); + @Override public boolean hasAttributeModifiersKey(Object tag) throws Exception{ return (boolean)hkot.invoke(tag, "AttributeModifiers", 9); } @@ -247,38 +278,46 @@ public class _164ItemUtils implements IDabItemUtils{ public Method nbttla = NMSUtils.getMethodSilent(nbttl, "func_74742_a", nbtb); public Constructor nbttlc = NMSUtils.getConstructorSilent(nbttl); + @Override public Object getList(Object tag) throws Exception{ return gl.invoke(tag, "AttributeModifiers", 9); } + @Override public Object getList(Object tag, String name, int id) throws Exception{ return gl.invoke(tag, name, id); } + @Override public boolean getUnbreakable(Object tag) throws Exception{ return (boolean)gb.invoke(tag, "Unbreakable"); } + @Override public void setUnbreakable(Object tag, boolean value) throws Exception{ sb.invoke(tag, "Unbreakable", value); } + @Override public Object getNewNBTTagList() throws Exception{ return nbttlc.newInstance(); } + @Override public void addToList(Object taglist, Object nbt) throws Exception{ nbttla.invoke(taglist, nbt); } public Method gs = NMSUtils.getMethodSilent(nbttl, "func_74745_c"); + @Override public int getSize(Object list) throws Exception{ return (int)gs.invoke(list); } public Method g = NMSUtils.getMethodSilent(nbttl, "func_150305_b", int.class); + @Override public Object get(Object tlist, int i) throws Exception{ return g.invoke(tlist, i); } @@ -322,16 +361,19 @@ public class _164ItemUtils implements IDabItemUtils{ public Field nbtsd = NMSUtils.getField(nbts, "field_74752_a"); public Field nbtstd = NMSUtils.getField(nbtst, "field_74751_a"); + @Override public Object getNewNBTTagByte(byte value) throws Exception{ return nbtbc.newInstance(value); } + @Override public Object getNewNBTTagByteArray(byte[] value) throws Exception{ return nbtbac.newInstance(value); } + @Override public Object getData(Object nbt) throws Exception{ - int i = (int)((byte)gti.invoke(nbt)); + int i = ((byte)gti.invoke(nbt)); switch(i){ case NBTConstants.TYPE_BYTE: return nbtbd.get(nbt); @@ -359,6 +401,7 @@ public class _164ItemUtils implements IDabItemUtils{ return null; } + @Override @SuppressWarnings("unchecked") public Object createData(Object value) throws Exception{ if(value.getClass().equals(byte.class)){ return nbtbc.newInstance(value); } @@ -375,6 +418,7 @@ public class _164ItemUtils implements IDabItemUtils{ return null; } + @Override @SuppressWarnings({ "unchecked" }) public Map convertCompoundTagToValueMap(Object nbt) throws Exception{ Map ret = new HashMap<>(); @@ -389,6 +433,7 @@ public class _164ItemUtils implements IDabItemUtils{ return ret; } + @Override @SuppressWarnings("unchecked") public List convertListTagToValueList(Object nbttl) throws Exception{ List ret = new ArrayList<>(); @@ -402,6 +447,7 @@ public class _164ItemUtils implements IDabItemUtils{ return ret; } + @Override public Object convertValueMapToCompoundTag(Map map) throws Exception{ Map value = new HashMap<>(); for(Entry e : map.entrySet()){ @@ -412,6 +458,7 @@ public class _164ItemUtils implements IDabItemUtils{ return ret; } + @Override public Object convertValueListToListTag(List list) throws Exception{ List value = new ArrayList<>(); for(Object e : list){ @@ -425,6 +472,7 @@ public class _164ItemUtils implements IDabItemUtils{ return ret; } + @Override @Deprecated @SuppressWarnings("unchecked") public void convertListTagToJSON(Object nbttl, JSONArray ja, JSONArray helper) throws Exception{ @@ -437,6 +485,7 @@ public class _164ItemUtils implements IDabItemUtils{ } } + @Override @SuppressWarnings("unchecked") public void convertListTagToJSON(Object nbttl, JSONArray ja) throws Exception{ List list = (List)nbtld.get(nbttl); @@ -448,6 +497,7 @@ public class _164ItemUtils implements IDabItemUtils{ } } + @Override @Deprecated @SuppressWarnings("unchecked") public void convertCompoundTagToJSON(Object nbt, JSONObject jo, JSONObject helper) throws Exception{ @@ -461,6 +511,7 @@ public class _164ItemUtils implements IDabItemUtils{ } } + @Override @SuppressWarnings("unchecked") public void convertCompoundTagToJSON(Object nbt, JSONObject jo) throws Exception{ Map map = (Map)getMap(nbt); @@ -473,6 +524,7 @@ public class _164ItemUtils implements IDabItemUtils{ } } + @Override @Deprecated @SuppressWarnings("unchecked") public Object convertJSONToCompoundTag(JSONObject jo, JSONObject helper) throws Exception{ @@ -487,6 +539,7 @@ public class _164ItemUtils implements IDabItemUtils{ return ret; } + @Override @SuppressWarnings("unchecked") public Object convertJSONToCompoundTag(JSONObject jo) throws Exception{ Map value = new HashMap<>(); @@ -500,6 +553,7 @@ public class _164ItemUtils implements IDabItemUtils{ return ret; } + @Override @Deprecated @SuppressWarnings({ "rawtypes", "unchecked" }) public Object convertJSONToListTag(JSONArray ja, JSONArray helper) throws Exception{ @@ -515,6 +569,7 @@ public class _164ItemUtils implements IDabItemUtils{ return ret; } + @Override @SuppressWarnings({ "rawtypes", "unchecked" }) public Object convertJSONToListTag(JSONArray ja) throws Exception{ List value = new ArrayList(); @@ -529,9 +584,10 @@ public class _164ItemUtils implements IDabItemUtils{ return ret; } + @Override @Deprecated public Object getDataJSON(String key, Object nbt, JSONObject jo, JSONObject helper) throws Exception{ - int i = (int)((byte)gti.invoke(nbt)); + int i = ((byte)gti.invoke(nbt)); Object ret = null; Object help = i; switch(i){ @@ -584,8 +640,9 @@ public class _164ItemUtils implements IDabItemUtils{ return ret; } + @Override public JSONArray getDataJSON(Object nbt) throws Exception{ - int i = (int)((byte)gti.invoke(nbt)); + int i = ((byte)gti.invoke(nbt)); Object ret = null; switch(i){ case NBTConstants.TYPE_BYTE: @@ -632,8 +689,9 @@ public class _164ItemUtils implements IDabItemUtils{ return new JSONArray(new Object[]{ i, ret }); } + @Override public Object getDataJSON(Object nbt, JSONArray ja, JSONArray helper) throws Exception{ - int i = (int)((byte)gti.invoke(nbt)); + int i = ((byte)gti.invoke(nbt)); Object ret = null; Object help = i; switch(i){ @@ -685,6 +743,7 @@ public class _164ItemUtils implements IDabItemUtils{ return ret; } + @Override public Object createDataJSON(String key, JSONObject jo, JSONObject helper) throws Exception{ Object help = helper.get(key); Object ret = null; @@ -740,6 +799,7 @@ public class _164ItemUtils implements IDabItemUtils{ return ret; } + @Override public Object createDataJSON(String key, JSONObject jo) throws Exception{ JSONArray j = jo.getJSONArray(key); Object ret = null; @@ -775,7 +835,7 @@ public class _164ItemUtils implements IDabItemUtils{ return nbtbac.newInstance("", b); } case NBTConstants.TYPE_STRING: - ret = nbtstc.newInstance("", (String)j.get(1)); + ret = nbtstc.newInstance("", j.get(1)); break; case NBTConstants.TYPE_INT_ARRAY: JSONArray ja = jo.getJSONArray(key); @@ -791,6 +851,7 @@ public class _164ItemUtils implements IDabItemUtils{ return ret; } + @Override public byte getByte(Object o){ if(o.getClass().equals(Integer.class)){ return (byte)(int)o; } if(o.getClass().equals(Short.class)){ return (byte)(short)o; } @@ -798,40 +859,46 @@ public class _164ItemUtils implements IDabItemUtils{ return (byte)o; } + @Override public short getShort(Object o){ if(o.getClass().equals(Integer.class)){ return (short)(int)o; } - if(o.getClass().equals(Byte.class)){ return (short)(byte)o; } + if(o.getClass().equals(Byte.class)){ return (byte)o; } if(o.getClass().equals(Integer.class)){ return (short)(int)o; } return (short)o; } + @Override public int getInt(Object o){ - if(o.getClass().equals(Short.class)){ return (int)(short)o; } - if(o.getClass().equals(Byte.class)){ return (int)(byte)o; } + if(o.getClass().equals(Short.class)){ return (short)o; } + if(o.getClass().equals(Byte.class)){ return (byte)o; } return (int)o; } + @Override public double getDouble(Object o){ - if(o.getClass().equals(Float.class)){ return (double)(float)o; } - if(o.getClass().equals(Long.class)){ return (double)(long)o; } - if(o.getClass().equals(Integer.class)){ return (double)(int)o; } + if(o.getClass().equals(Float.class)){ return (float)o; } + if(o.getClass().equals(Long.class)){ return (long)o; } + if(o.getClass().equals(Integer.class)){ return (int)o; } return (double)o; } + @Override public float getFloat(Object o){ if(o.getClass().equals(Double.class)){ return (float)(double)o; } - if(o.getClass().equals(Long.class)){ return (float)(long)o; } - if(o.getClass().equals(Integer.class)){ return (float)(int)o; } + if(o.getClass().equals(Long.class)){ return (long)o; } + if(o.getClass().equals(Integer.class)){ return (int)o; } return (float)o; } + @Override public long getLong(Object o){ if(o.getClass().equals(Float.class)){ return (long)(float)o; } if(o.getClass().equals(Double.class)){ return (long)(double)o; } - if(o.getClass().equals(Integer.class)){ return (long)(int)o; } + if(o.getClass().equals(Integer.class)){ return (int)o; } return (long)o; } + @Override public Object createDataJSON(int key, JSONArray jo, JSONArray helper) throws Exception{ Object help = helper.get(key); Object ret = null; @@ -887,6 +954,7 @@ public class _164ItemUtils implements IDabItemUtils{ return ret; } + @Override public Object createDataJSON(int key, JSONArray jo) throws Exception{ JSONArray j = jo.getJSONArray(key); Object ret = null; @@ -922,7 +990,7 @@ public class _164ItemUtils implements IDabItemUtils{ return nbtbac.newInstance("", b); } case NBTConstants.TYPE_STRING: - ret = nbtstc.newInstance("", (String)j.get(1)); + ret = nbtstc.newInstance("", j.get(1)); break; case NBTConstants.TYPE_INT_ARRAY: JSONArray ja = jo.getJSONArray(key); @@ -938,9 +1006,10 @@ public class _164ItemUtils implements IDabItemUtils{ return ret; } + @Override public boolean compareBaseTag(Object tag, Object tag1) throws Exception{ - int i = (int)((byte)gti.invoke(tag)); - int i1 = (int)((byte)gti.invoke(tag1)); + int i = ((byte)gti.invoke(tag)); + int i1 = ((byte)gti.invoke(tag1)); if(i != i1) return false; switch(i){ @@ -989,6 +1058,7 @@ public class _164ItemUtils implements IDabItemUtils{ return false; } + @Override @SuppressWarnings("unchecked") public boolean compareCompoundTag(Object tag, Object tag1) throws Exception{ Map map = (Map)getMap(tag); @@ -1006,6 +1076,7 @@ public class _164ItemUtils implements IDabItemUtils{ return true; } + @Override @SuppressWarnings({ "unchecked", "rawtypes" }) public boolean compareListTag(Object tag, Object tag1) throws Exception{ List list = (List)nbtld.get(tag); @@ -1055,6 +1126,7 @@ public class _164ItemUtils implements IDabItemUtils{ return r; } + @Override public boolean compare(ItemStack is1, ItemStack is2){ if(is1.getType().equals(is2.getType())){ if(is1.getDurability() == is2.getDurability()){ @@ -1078,10 +1150,12 @@ public class _164ItemUtils implements IDabItemUtils{ return false; } + @Override public boolean canMerge(ItemStack add, ItemStack to){ return compare(add, to); } + @Override public boolean isModified(ItemStack is){ ItemStack is1 = is.clone(); is1.setAmount(1); @@ -1089,6 +1163,7 @@ public class _164ItemUtils implements IDabItemUtils{ return !is1.equals(is2); } + @Override public void sortByMaterial(List items){ items.sort(new MaterialComparator()); } @@ -1100,6 +1175,7 @@ public class _164ItemUtils implements IDabItemUtils{ } } + @Override public void sortByName(List items){ items.sort(new NameComparator()); } @@ -1117,6 +1193,7 @@ public class _164ItemUtils implements IDabItemUtils{ } } + @Override public void sortByAmount(List items){ items.sort(new AmountComparator()); } @@ -1136,6 +1213,7 @@ public class _164ItemUtils implements IDabItemUtils{ } } + @Override public ItemStack convertJSONToItemStack(JSONObject jo) throws Exception{ Material material = Material.valueOf(jo.getString("material")); int amount = jo.getInt("amount"); @@ -1151,6 +1229,7 @@ public class _164ItemUtils implements IDabItemUtils{ return is; } + @Override public JSONObject convertItemStackToJSON(ItemStack is) throws Exception{ JSONObject jo = new JSONObject(); jo.put("material", is.getType().name()); diff --git a/src/main/java/me/skymc/taboolib/nms/item/impl/_1710ItemUtils.java b/src/main/java/me/skymc/taboolib/nms/item/impl/_1710ItemUtils.java index 6392b8e..e8888e9 100644 --- a/src/main/java/me/skymc/taboolib/nms/item/impl/_1710ItemUtils.java +++ b/src/main/java/me/skymc/taboolib/nms/item/impl/_1710ItemUtils.java @@ -36,6 +36,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return false; } + @Override public boolean hasBanner(){ return banner; } @@ -43,18 +44,21 @@ public class _1710ItemUtils implements IDabItemUtils{ public Class nmis = NMSUtils.getClass("net.minecraft.item.ItemStack"), cis = NMSUtils.getOBCClass("inventory.CraftItemStack"); public Method nmscopy = NMSUtils.getMethodSilent(cis, "asNMSCopy", ItemStack.class); + @Override public Object getNMSCopy(ItemStack is) throws Exception{ return nmscopy.invoke(null, is); } public Method hastag = NMSUtils.getMethodSilent(nmis, "func_77942_o"); + @Override public boolean hasTag(Object is) throws Exception{ return (boolean)hastag.invoke(is); } public Method acm = NMSUtils.getMethodSilent(cis, "asCraftMirror", nmis); + @Override public ItemStack asCraftMirror(Object nis) throws Exception{ return (ItemStack)acm.invoke(null, nis); } @@ -63,12 +67,14 @@ public class _1710ItemUtils implements IDabItemUtils{ public Method abc = NMSUtils.getMethodSilent(cis, "asBukkitCopy", nmis); + @Override public ItemStack asBukkitCopy(Object nmis) throws Exception{ return (ItemStack)abc.invoke(null, nmis); } public Method gn = NMSUtils.getMethodSilent(nmis, "func_82833_r"); + @Override public String getName(ItemStack is){ try{ return (String)gn.invoke(getNMSCopy(is)); @@ -79,14 +85,17 @@ public class _1710ItemUtils implements IDabItemUtils{ public Method gi = NMSUtils.getMethodSilent(nmis, "func_77973_b"), ia = getA(); + @Override public Object getItem(Object nis) throws Exception{ return gi.invoke(nis); } + @Override public Method getA(){ return NMSUtils.getMethodSilent(ni, "func_77653_i", nmis); } + @Override public String getRawName(ItemStack is){ try{ Object nis = getNMSCopy(is); @@ -98,6 +107,7 @@ public class _1710ItemUtils implements IDabItemUtils{ public Method gin = NMSUtils.getMethodSilent(ni, "getName"); + @Override public String getItemName(ItemStack is){ try{ return (String)gin.invoke(gi.invoke(getNMSCopy(is))); @@ -108,6 +118,7 @@ public class _1710ItemUtils implements IDabItemUtils{ public Object registry = getRegistry(); + @Override public Object getRegistry(){ try{ return NMSUtils.getFieldSilent(ni, "REGISTRY", "field_150901_e").get(null); @@ -120,6 +131,7 @@ public class _1710ItemUtils implements IDabItemUtils{ public Field nmrsc = NMSUtils.getField(nmrs, "field_82596_a"); + @Override public String getMinecraftName(ItemStack is){ String name = getItemName(is); try{ @@ -138,22 +150,26 @@ public class _1710ItemUtils implements IDabItemUtils{ public Class nbttc = NMSUtils.getClass("net.minecraft.nbt.NBTTagCompound"); public Field tag = NMSUtils.getField(nmis, "field_77990_d"); + @Override public Object getTag(Object is) throws Exception{ return tag.get(is); } + @Override public void setTag(Object is, Object tag1) throws Exception{ tag.set(is, tag1); } public Method nbtcie = NMSUtils.getMethodSilent(nbttc, "func_82582_d"); + @Override public boolean isEmpty(Object tag) throws Exception{ return (boolean)nbtcie.invoke(tag); } public Field nbttcm = NMSUtils.getField(nbttc, "field_74784_a"); + @Override public Object getMap(Object tag) throws Exception{ return nbttcm.get(tag); } @@ -166,32 +182,39 @@ public class _1710ItemUtils implements IDabItemUtils{ public Method nbttcsl = NMSUtils.getMethodSilent(nbttc, "func_74772_a", String.class, long.class); public Method nbttcss1 = NMSUtils.getMethodSilent(nbttc, "func_74777_a", String.class, short.class); + @Override public void set(Object tag, String key, Object value) throws Exception{ nbttcs.invoke(tag, key, value); } + @Override public void setString(Object tag, String key, String value) throws Exception{ nbttcss.invoke(tag, key, value); } + @Override public void setShort(Object tag, String key, short value) throws Exception{ nbttcss1.invoke(tag, key, value); } + @Override public void setInt(Object tag, String key, int i) throws Exception{ nbttcsi.invoke(tag, key, i); } + @Override public void setDouble(Object tag, String key, double d) throws Exception{ nbttcsd.invoke(tag, key, d); } + @Override public void setLong(Object tag, String key, long l) throws Exception{ nbttcsl.invoke(tag, key, l); } public Method nbttchk = NMSUtils.getMethodSilent(nbttc, "func_74764_b", String.class); + @Override public boolean hasKey(Object tag, String key) throws Exception{ return (boolean)nbttchk.invoke(tag, key); } @@ -203,38 +226,46 @@ public class _1710ItemUtils implements IDabItemUtils{ public Method nbttcgl = NMSUtils.getMethodSilent(nbttc, "func_74763_f", String.class); public Method nbttcgs1 = NMSUtils.getMethodSilent(nbttc, "func_74765_d", String.class); + @Override public Object get(Object tag, String key) throws Exception{ return nbttcg.invoke(tag, key); } + @Override public String getString(Object tag, String key) throws Exception{ return (String)nbttcgs.invoke(tag, key); } + @Override public int getInt(Object tag, String key) throws Exception{ return (int)nbttcgi.invoke(tag, key); } + @Override public double getDouble(Object tag, String key) throws Exception{ return (double)nbttcgd.invoke(tag, key); } + @Override public long getLong(Object tag, String key) throws Exception{ return (long)nbttcgl.invoke(tag, key); } + @Override public short getShort(Object tag, String key) throws Exception{ return (short)nbttcgs1.invoke(tag, key); } public Constructor nbttcc = NMSUtils.getConstructorSilent(nbttc); + @Override public Object getNewNBTTagCompound() throws Exception{ return nbttcc.newInstance(); } public Method hkot = NMSUtils.getMethodSilent(nbttc, "func_150297_b", String.class, int.class); + @Override public boolean hasAttributeModifiersKey(Object tag) throws Exception{ return (boolean)hkot.invoke(tag, "AttributeModifiers", 9); } @@ -246,38 +277,46 @@ public class _1710ItemUtils implements IDabItemUtils{ public Method nbttla = NMSUtils.getMethodSilent(nbttl, "func_74742_a", nbtb); public Constructor nbttlc = NMSUtils.getConstructorSilent(nbttl); + @Override public Object getList(Object tag) throws Exception{ return gl.invoke(tag, "AttributeModifiers", 9); } + @Override public Object getList(Object tag, String name, int id) throws Exception{ return gl.invoke(tag, name, id); } + @Override public boolean getUnbreakable(Object tag) throws Exception{ return (boolean)gb.invoke(tag, "Unbreakable"); } + @Override public void setUnbreakable(Object tag, boolean value) throws Exception{ sb.invoke(tag, "Unbreakable", value); } + @Override public Object getNewNBTTagList() throws Exception{ return nbttlc.newInstance(); } + @Override public void addToList(Object taglist, Object nbt) throws Exception{ nbttla.invoke(taglist, nbt); } public Method gs = NMSUtils.getMethodSilent(nbttl, "func_74745_c"); + @Override public int getSize(Object list) throws Exception{ return (int)gs.invoke(list); } public Method g = NMSUtils.getMethodSilent(nbttl, "func_150305_b", int.class); + @Override public Object get(Object tlist, int i) throws Exception{ return g.invoke(tlist, i); } @@ -321,16 +360,19 @@ public class _1710ItemUtils implements IDabItemUtils{ public Field nbtsd = NMSUtils.getField(nbts, "field_74752_a"); public Field nbtstd = NMSUtils.getField(nbtst, "field_74751_a"); + @Override public Object getNewNBTTagByte(byte value) throws Exception{ return nbtbc.newInstance(value); } + @Override public Object getNewNBTTagByteArray(byte[] value) throws Exception{ return nbtbac.newInstance(value); } + @Override public Object getData(Object nbt) throws Exception{ - int i = (int)((byte)gti.invoke(nbt)); + int i = ((byte)gti.invoke(nbt)); switch(i){ case NBTConstants.TYPE_BYTE: return nbtbd.get(nbt); @@ -358,6 +400,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return null; } + @Override @SuppressWarnings("unchecked") public Object createData(Object value) throws Exception{ if(value.getClass().equals(byte.class)){ return nbtbc.newInstance(value); } @@ -374,6 +417,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return null; } + @Override @SuppressWarnings({ "unchecked" }) public Map convertCompoundTagToValueMap(Object nbt) throws Exception{ Map ret = new HashMap<>(); @@ -388,6 +432,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return ret; } + @Override @SuppressWarnings("unchecked") public List convertListTagToValueList(Object nbttl) throws Exception{ List ret = new ArrayList<>(); @@ -401,6 +446,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return ret; } + @Override public Object convertValueMapToCompoundTag(Map map) throws Exception{ Map value = new HashMap<>(); for(Entry e : map.entrySet()){ @@ -411,6 +457,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return ret; } + @Override public Object convertValueListToListTag(List list) throws Exception{ List value = new ArrayList<>(); for(Object e : list){ @@ -424,6 +471,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return ret; } + @Override @Deprecated @SuppressWarnings("unchecked") public void convertListTagToJSON(Object nbttl, JSONArray ja, JSONArray helper) throws Exception{ @@ -436,6 +484,7 @@ public class _1710ItemUtils implements IDabItemUtils{ } } + @Override @SuppressWarnings("unchecked") public void convertListTagToJSON(Object nbttl, JSONArray ja) throws Exception{ List list = (List)nbtld.get(nbttl); @@ -447,6 +496,7 @@ public class _1710ItemUtils implements IDabItemUtils{ } } + @Override @Deprecated @SuppressWarnings("unchecked") public void convertCompoundTagToJSON(Object nbt, JSONObject jo, JSONObject helper) throws Exception{ @@ -460,6 +510,7 @@ public class _1710ItemUtils implements IDabItemUtils{ } } + @Override @SuppressWarnings("unchecked") public void convertCompoundTagToJSON(Object nbt, JSONObject jo) throws Exception{ Map map = (Map)getMap(nbt); @@ -472,6 +523,7 @@ public class _1710ItemUtils implements IDabItemUtils{ } } + @Override @Deprecated @SuppressWarnings("unchecked") public Object convertJSONToCompoundTag(JSONObject jo, JSONObject helper) throws Exception{ @@ -486,6 +538,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return ret; } + @Override @SuppressWarnings("unchecked") public Object convertJSONToCompoundTag(JSONObject jo) throws Exception{ Map value = new HashMap<>(); @@ -499,6 +552,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return ret; } + @Override @Deprecated @SuppressWarnings({ "rawtypes", "unchecked" }) public Object convertJSONToListTag(JSONArray ja, JSONArray helper) throws Exception{ @@ -514,6 +568,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return ret; } + @Override @SuppressWarnings({ "rawtypes", "unchecked" }) public Object convertJSONToListTag(JSONArray ja) throws Exception{ List value = new ArrayList(); @@ -528,9 +583,10 @@ public class _1710ItemUtils implements IDabItemUtils{ return ret; } + @Override @Deprecated public Object getDataJSON(String key, Object nbt, JSONObject jo, JSONObject helper) throws Exception{ - int i = (int)((byte)gti.invoke(nbt)); + int i = ((byte)gti.invoke(nbt)); Object ret = null; Object help = i; switch(i){ @@ -583,8 +639,9 @@ public class _1710ItemUtils implements IDabItemUtils{ return ret; } + @Override public JSONArray getDataJSON(Object nbt) throws Exception{ - int i = (int)((byte)gti.invoke(nbt)); + int i = ((byte)gti.invoke(nbt)); Object ret = null; switch(i){ case NBTConstants.TYPE_BYTE: @@ -631,8 +688,9 @@ public class _1710ItemUtils implements IDabItemUtils{ return new JSONArray(new Object[]{ i, ret }); } + @Override public Object getDataJSON(Object nbt, JSONArray ja, JSONArray helper) throws Exception{ - int i = (int)((byte)gti.invoke(nbt)); + int i = ((byte)gti.invoke(nbt)); Object ret = null; Object help = i; switch(i){ @@ -684,6 +742,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return ret; } + @Override public Object createDataJSON(String key, JSONObject jo, JSONObject helper) throws Exception{ Object help = helper.get(key); Object ret = null; @@ -739,6 +798,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return ret; } + @Override public Object createDataJSON(String key, JSONObject jo) throws Exception{ JSONArray j = jo.getJSONArray(key); Object ret = null; @@ -790,6 +850,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return ret; } + @Override public byte getByte(Object o){ if(o.getClass().equals(Integer.class)){ return (byte)(int)o; } if(o.getClass().equals(Short.class)){ return (byte)(short)o; } @@ -797,40 +858,46 @@ public class _1710ItemUtils implements IDabItemUtils{ return (byte)o; } + @Override public short getShort(Object o){ if(o.getClass().equals(Integer.class)){ return (short)(int)o; } - if(o.getClass().equals(Byte.class)){ return (short)(byte)o; } + if(o.getClass().equals(Byte.class)){ return (byte)o; } if(o.getClass().equals(Integer.class)){ return (short)(int)o; } return (short)o; } + @Override public int getInt(Object o){ - if(o.getClass().equals(Short.class)){ return (int)(short)o; } - if(o.getClass().equals(Byte.class)){ return (int)(byte)o; } + if(o.getClass().equals(Short.class)){ return (short)o; } + if(o.getClass().equals(Byte.class)){ return (byte)o; } return (int)o; } + @Override public double getDouble(Object o){ - if(o.getClass().equals(Float.class)){ return (double)(float)o; } - if(o.getClass().equals(Long.class)){ return (double)(long)o; } - if(o.getClass().equals(Integer.class)){ return (double)(int)o; } + if(o.getClass().equals(Float.class)){ return (float)o; } + if(o.getClass().equals(Long.class)){ return (long)o; } + if(o.getClass().equals(Integer.class)){ return (int)o; } return (double)o; } + @Override public float getFloat(Object o){ if(o.getClass().equals(Double.class)){ return (float)(double)o; } - if(o.getClass().equals(Long.class)){ return (float)(long)o; } - if(o.getClass().equals(Integer.class)){ return (float)(int)o; } + if(o.getClass().equals(Long.class)){ return (long)o; } + if(o.getClass().equals(Integer.class)){ return (int)o; } return (float)o; } + @Override public long getLong(Object o){ if(o.getClass().equals(Float.class)){ return (long)(float)o; } if(o.getClass().equals(Double.class)){ return (long)(double)o; } - if(o.getClass().equals(Integer.class)){ return (long)(int)o; } + if(o.getClass().equals(Integer.class)){ return (int)o; } return (long)o; } + @Override public Object createDataJSON(int key, JSONArray jo, JSONArray helper) throws Exception{ Object help = helper.get(key); Object ret = null; @@ -886,6 +953,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return ret; } + @Override public Object createDataJSON(int key, JSONArray jo) throws Exception{ JSONArray j = jo.getJSONArray(key); Object ret = null; @@ -937,9 +1005,10 @@ public class _1710ItemUtils implements IDabItemUtils{ return ret; } + @Override public boolean compareBaseTag(Object tag, Object tag1) throws Exception{ - int i = (int)((byte)gti.invoke(tag)); - int i1 = (int)((byte)gti.invoke(tag1)); + int i = ((byte)gti.invoke(tag)); + int i1 = ((byte)gti.invoke(tag1)); if(i != i1) return false; switch(i){ @@ -988,6 +1057,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return false; } + @Override @SuppressWarnings("unchecked") public boolean compareCompoundTag(Object tag, Object tag1) throws Exception{ Map map = (Map)getMap(tag); @@ -1005,6 +1075,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return true; } + @Override @SuppressWarnings({ "unchecked", "rawtypes" }) public boolean compareListTag(Object tag, Object tag1) throws Exception{ List list = (List)nbtld.get(tag); @@ -1026,6 +1097,7 @@ public class _1710ItemUtils implements IDabItemUtils{ public Field amd = NMSUtils.getField(am, "field_111170_d"); + @Override public boolean compare(ItemStack is1, ItemStack is2){ if(is1.getType().equals(is2.getType())){ if(is1.getDurability() == is2.getDurability()){ @@ -1049,10 +1121,12 @@ public class _1710ItemUtils implements IDabItemUtils{ return false; } + @Override public boolean canMerge(ItemStack add, ItemStack to){ return compare(add, to); } + @Override public boolean isModified(ItemStack is){ ItemStack is1 = is.clone(); is1.setAmount(1); @@ -1060,6 +1134,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return !is1.equals(is2); } + @Override public void sortByMaterial(List items){ items.sort(new MaterialComparator()); } @@ -1071,6 +1146,7 @@ public class _1710ItemUtils implements IDabItemUtils{ } } + @Override public void sortByName(List items){ items.sort(new NameComparator()); } @@ -1088,6 +1164,7 @@ public class _1710ItemUtils implements IDabItemUtils{ } } + @Override public void sortByAmount(List items){ items.sort(new AmountComparator()); } @@ -1107,6 +1184,7 @@ public class _1710ItemUtils implements IDabItemUtils{ } } + @Override public ItemStack convertJSONToItemStack(JSONObject jo) throws Exception{ Material material = Material.valueOf(jo.getString("material")); int amount = jo.getInt("amount"); @@ -1122,6 +1200,7 @@ public class _1710ItemUtils implements IDabItemUtils{ return is; } + @Override public JSONObject convertItemStackToJSON(ItemStack is) throws Exception{ JSONObject jo = new JSONObject(); jo.put("material", is.getType().name()); diff --git a/src/main/java/me/skymc/taboolib/nms/item/impl/_194ItemUtils.java b/src/main/java/me/skymc/taboolib/nms/item/impl/_194ItemUtils.java index 3ee5c7a..71df5cf 100644 --- a/src/main/java/me/skymc/taboolib/nms/item/impl/_194ItemUtils.java +++ b/src/main/java/me/skymc/taboolib/nms/item/impl/_194ItemUtils.java @@ -35,6 +35,7 @@ public class _194ItemUtils implements IDabItemUtils{ return false; } + @Override public boolean hasBanner(){ return banner; } @@ -42,24 +43,28 @@ public class _194ItemUtils implements IDabItemUtils{ public Class nmis = NMSUtils.getNMSClassSilent("ItemStack"), cis = NMSUtils.getOBCClass("inventory.CraftItemStack"); public Method nmscopy = NMSUtils.getMethodSilent(cis, "asNMSCopy", ItemStack.class); + @Override public Object getNMSCopy(ItemStack is) throws Exception{ return nmscopy.invoke(null, is); } public Method hastag = NMSUtils.getMethodSilent(nmis, "hasTag"); + @Override public boolean hasTag(Object is) throws Exception{ return (boolean)hastag.invoke(is); } public Method acm = NMSUtils.getMethodSilent(cis, "asCraftMirror", nmis); + @Override public ItemStack asCraftMirror(Object nis) throws Exception{ return (ItemStack)acm.invoke(null, nis); } public Method abc = NMSUtils.getMethodSilent(cis, "asBukkitCopy", nmis); + @Override public ItemStack asBukkitCopy(Object nmis) throws Exception{ return (ItemStack)abc.invoke(null, nmis); } @@ -68,6 +73,7 @@ public class _194ItemUtils implements IDabItemUtils{ public Method gn = NMSUtils.getMethodSilent(nmis, "getName"); + @Override public String getName(ItemStack is){ try{ return (String)gn.invoke(getNMSCopy(is)); @@ -78,10 +84,12 @@ public class _194ItemUtils implements IDabItemUtils{ public Method gi = NMSUtils.getMethodSilent(nmis, "getItem"), ia = getA(); + @Override public Object getItem(Object nis) throws Exception{ return gi.invoke(nis); } + @Override public Method getA(){ Method m = NMSUtils.getMethodSilent(ni, "a", nmis); if(m == null){ @@ -90,6 +98,7 @@ public class _194ItemUtils implements IDabItemUtils{ return m; } + @Override public String getRawName(ItemStack is){ try{ Object nis = getNMSCopy(is); @@ -101,6 +110,7 @@ public class _194ItemUtils implements IDabItemUtils{ public Method gin = NMSUtils.getMethodSilent(ni, "getName"); + @Override public String getItemName(ItemStack is){ try{ return (String)gin.invoke(gi.invoke(getNMSCopy(is))); @@ -111,6 +121,7 @@ public class _194ItemUtils implements IDabItemUtils{ public Object registry = getRegistry(); + @Override public Object getRegistry(){ try{ return NMSUtils.getFieldSilent(ni, "REGISTRY").get(null); @@ -122,6 +133,7 @@ public class _194ItemUtils implements IDabItemUtils{ public Class nmrs = NMSUtils.getNMSClassSilent("RegistrySimple"); public Field nmrsc = NMSUtils.getField(nmrs, "c"); + @Override public String getMinecraftName(ItemStack is){ String name = getItemName(is); try{ @@ -140,22 +152,26 @@ public class _194ItemUtils implements IDabItemUtils{ public Class nbttc = NMSUtils.getNMSClassSilent("NBTTagCompound"); public Field tag = NMSUtils.getField(nmis, "tag"); + @Override public Object getTag(Object is) throws Exception{ return tag.get(is); } + @Override public void setTag(Object is, Object tag1) throws Exception{ tag.set(is, tag1); } public Method nbtcie = NMSUtils.getMethodSilent(nbttc, "isEmpty"); + @Override public boolean isEmpty(Object tag) throws Exception{ return (boolean)nbtcie.invoke(tag); } public Field nbttcm = NMSUtils.getField(nbttc, "map"); + @Override public Object getMap(Object tag) throws Exception{ return nbttcm.get(tag); } @@ -168,32 +184,39 @@ public class _194ItemUtils implements IDabItemUtils{ public Method nbttcsl = NMSUtils.getMethodSilent(nbttc, "setLong", String.class, long.class); public Method nbttcss1 = NMSUtils.getMethodSilent(nbttc, "setShort", String.class, short.class); + @Override public void set(Object tag, String key, Object value) throws Exception{ nbttcs.invoke(tag, key, value); } + @Override public void setString(Object tag, String key, String value) throws Exception{ nbttcss.invoke(tag, key, value); } + @Override public void setShort(Object tag, String key, short value) throws Exception{ nbttcss1.invoke(tag, key, value); } + @Override public void setInt(Object tag, String key, int i) throws Exception{ nbttcsi.invoke(tag, key, i); } + @Override public void setDouble(Object tag, String key, double d) throws Exception{ nbttcsd.invoke(tag, key, d); } + @Override public void setLong(Object tag, String key, long l) throws Exception{ nbttcsl.invoke(tag, key, l); } public Method nbttchk = NMSUtils.getMethodSilent(nbttc, "hasKey", String.class); + @Override public boolean hasKey(Object tag, String key) throws Exception{ return (boolean)nbttchk.invoke(tag, key); } @@ -205,38 +228,46 @@ public class _194ItemUtils implements IDabItemUtils{ public Method nbttcgl = NMSUtils.getMethodSilent(nbttc, "getLong", String.class); public Method nbttcgs1 = NMSUtils.getMethodSilent(nbttc, "getShort", String.class); + @Override public Object get(Object tag, String key) throws Exception{ return nbttcg.invoke(tag, key); } + @Override public String getString(Object tag, String key) throws Exception{ return (String)nbttcgs.invoke(tag, key); } + @Override public int getInt(Object tag, String key) throws Exception{ return (int)nbttcgi.invoke(tag, key); } + @Override public double getDouble(Object tag, String key) throws Exception{ return (double)nbttcgd.invoke(tag, key); } + @Override public long getLong(Object tag, String key) throws Exception{ return (long)nbttcgl.invoke(tag, key); } + @Override public short getShort(Object tag, String key) throws Exception{ return (short)nbttcgs1.invoke(tag, key); } public Constructor nbttcc = NMSUtils.getConstructorSilent(nbttc); + @Override public Object getNewNBTTagCompound() throws Exception{ return nbttcc.newInstance(); } public Method hkot = NMSUtils.getMethodSilent(nbttc, "hasKeyOfType", String.class, int.class); + @Override public boolean hasAttributeModifiersKey(Object tag) throws Exception{ return (boolean)hkot.invoke(tag, "AttributeModifiers", 9); } @@ -248,38 +279,46 @@ public class _194ItemUtils implements IDabItemUtils{ public Method nbttla = NMSUtils.getMethodSilent(nbttl, "add", nbtb); public Constructor nbttlc = NMSUtils.getConstructorSilent(nbttl); + @Override public Object getList(Object tag) throws Exception{ return gl.invoke(tag, "AttributeModifiers", 9); } + @Override public Object getList(Object tag, String name, int id) throws Exception{ return gl.invoke(tag, name, id); } + @Override public boolean getUnbreakable(Object tag) throws Exception{ return (boolean)gb.invoke(tag, "Unbreakable"); } + @Override public void setUnbreakable(Object tag, boolean value) throws Exception{ sb.invoke(tag, "Unbreakable", value); } + @Override public Object getNewNBTTagList() throws Exception{ return nbttlc.newInstance(); } + @Override public void addToList(Object taglist, Object nbt) throws Exception{ nbttla.invoke(taglist, nbt); } public Method gs = NMSUtils.getMethodSilent(nbttl, "size"); + @Override public int getSize(Object list) throws Exception{ return (int)gs.invoke(list); } public Method g = NMSUtils.getMethodSilent(nbttl, "get", int.class); + @Override public Object get(Object tlist, int i) throws Exception{ return g.invoke(tlist, i); } @@ -321,16 +360,19 @@ public class _194ItemUtils implements IDabItemUtils{ public Field nbtsd = NMSUtils.getField(nbts, "data"); public Field nbtstd = NMSUtils.getField(nbtst, "data"); + @Override public Object getNewNBTTagByte(byte value) throws Exception{ return nbtbc.newInstance(value); } + @Override public Object getNewNBTTagByteArray(byte[] value) throws Exception{ return nbtbac.newInstance(value); } + @Override public Object getData(Object nbt) throws Exception{ - int i = (int)((byte)gti.invoke(nbt)); + int i = ((byte)gti.invoke(nbt)); switch(i){ case NBTConstants.TYPE_BYTE: return nbtbd.get(nbt); @@ -358,6 +400,7 @@ public class _194ItemUtils implements IDabItemUtils{ return null; } + @Override @SuppressWarnings("unchecked") public Object createData(Object value) throws Exception{ if(value.getClass().equals(byte.class)){ return nbtbc.newInstance(value); } @@ -374,6 +417,7 @@ public class _194ItemUtils implements IDabItemUtils{ return null; } + @Override @SuppressWarnings({ "unchecked" }) public Map convertCompoundTagToValueMap(Object nbt) throws Exception{ Map ret = new HashMap<>(); @@ -388,6 +432,7 @@ public class _194ItemUtils implements IDabItemUtils{ return ret; } + @Override @SuppressWarnings("unchecked") public List convertListTagToValueList(Object nbttl) throws Exception{ List ret = new ArrayList<>(); @@ -401,6 +446,7 @@ public class _194ItemUtils implements IDabItemUtils{ return ret; } + @Override public Object convertValueMapToCompoundTag(Map map) throws Exception{ Map value = new HashMap<>(); for(Entry e : map.entrySet()){ @@ -411,6 +457,7 @@ public class _194ItemUtils implements IDabItemUtils{ return ret; } + @Override public Object convertValueListToListTag(List list) throws Exception{ List value = new ArrayList<>(); for(Object e : list){ @@ -424,6 +471,7 @@ public class _194ItemUtils implements IDabItemUtils{ return ret; } + @Override @SuppressWarnings("unchecked") @Deprecated public void convertListTagToJSON(Object nbttl, JSONArray ja, JSONArray helper) throws Exception{ @@ -436,6 +484,7 @@ public class _194ItemUtils implements IDabItemUtils{ } } + @Override @SuppressWarnings("unchecked") public void convertListTagToJSON(Object nbttl, JSONArray ja) throws Exception{ List list = (List)nbtld.get(nbttl); @@ -447,6 +496,7 @@ public class _194ItemUtils implements IDabItemUtils{ } } + @Override @SuppressWarnings("unchecked") @Deprecated public void convertCompoundTagToJSON(Object nbt, JSONObject jo, JSONObject helper) throws Exception{ @@ -460,6 +510,7 @@ public class _194ItemUtils implements IDabItemUtils{ } } + @Override @SuppressWarnings("unchecked") public void convertCompoundTagToJSON(Object nbt, JSONObject jo) throws Exception{ Map map = (Map)getMap(nbt); @@ -472,6 +523,7 @@ public class _194ItemUtils implements IDabItemUtils{ } } + @Override @SuppressWarnings("unchecked") @Deprecated public Object convertJSONToCompoundTag(JSONObject jo, JSONObject helper) throws Exception{ @@ -486,6 +538,7 @@ public class _194ItemUtils implements IDabItemUtils{ return ret; } + @Override @SuppressWarnings("unchecked") public Object convertJSONToCompoundTag(JSONObject jo) throws Exception{ Map value = new HashMap<>(); @@ -499,6 +552,7 @@ public class _194ItemUtils implements IDabItemUtils{ return ret; } + @Override @SuppressWarnings({ "rawtypes", "unchecked" }) @Deprecated public Object convertJSONToListTag(JSONArray ja, JSONArray helper) throws Exception{ @@ -514,6 +568,7 @@ public class _194ItemUtils implements IDabItemUtils{ return ret; } + @Override @SuppressWarnings({ "rawtypes", "unchecked" }) public Object convertJSONToListTag(JSONArray ja) throws Exception{ List value = new ArrayList(); @@ -528,9 +583,10 @@ public class _194ItemUtils implements IDabItemUtils{ return ret; } + @Override @Deprecated public Object getDataJSON(String key, Object nbt, JSONObject jo, JSONObject helper) throws Exception{ - int i = (int)((byte)gti.invoke(nbt)); + int i = ((byte)gti.invoke(nbt)); Object ret = null; Object help = i; switch(i){ @@ -583,8 +639,9 @@ public class _194ItemUtils implements IDabItemUtils{ return ret; } + @Override public JSONArray getDataJSON(Object nbt) throws Exception{ - int i = (int)((byte)gti.invoke(nbt)); + int i = ((byte)gti.invoke(nbt)); Object ret = null; switch(i){ case NBTConstants.TYPE_BYTE: @@ -631,9 +688,10 @@ public class _194ItemUtils implements IDabItemUtils{ return new JSONArray(new Object[]{ i, ret }); } + @Override @Deprecated public Object getDataJSON(Object nbt, JSONArray ja, JSONArray helper) throws Exception{ - int i = (int)((byte)gti.invoke(nbt)); + int i = ((byte)gti.invoke(nbt)); Object ret = null; Object help = i; switch(i){ @@ -685,6 +743,7 @@ public class _194ItemUtils implements IDabItemUtils{ return ret; } + @Override @Deprecated public Object createDataJSON(String key, JSONObject jo, JSONObject helper) throws Exception{ Object help = helper.get(key); @@ -741,6 +800,7 @@ public class _194ItemUtils implements IDabItemUtils{ return ret; } + @Override public Object createDataJSON(String key, JSONObject jo) throws Exception{ JSONArray j = jo.getJSONArray(key); Object ret = null; @@ -792,6 +852,7 @@ public class _194ItemUtils implements IDabItemUtils{ return ret; } + @Override public byte getByte(Object o){ if(o.getClass().equals(Integer.class)){ return (byte)(int)o; } if(o.getClass().equals(Short.class)){ return (byte)(short)o; } @@ -799,40 +860,46 @@ public class _194ItemUtils implements IDabItemUtils{ return (byte)o; } + @Override public short getShort(Object o){ if(o.getClass().equals(Integer.class)){ return (short)(int)o; } - if(o.getClass().equals(Byte.class)){ return (short)(byte)o; } + if(o.getClass().equals(Byte.class)){ return (byte)o; } if(o.getClass().equals(Integer.class)){ return (short)(int)o; } return (short)o; } + @Override public int getInt(Object o){ - if(o.getClass().equals(Short.class)){ return (int)(short)o; } - if(o.getClass().equals(Byte.class)){ return (int)(byte)o; } + if(o.getClass().equals(Short.class)){ return (short)o; } + if(o.getClass().equals(Byte.class)){ return (byte)o; } return (int)o; } + @Override public double getDouble(Object o){ - if(o.getClass().equals(Float.class)){ return (double)(float)o; } - if(o.getClass().equals(Long.class)){ return (double)(long)o; } - if(o.getClass().equals(Integer.class)){ return (double)(int)o; } + if(o.getClass().equals(Float.class)){ return (float)o; } + if(o.getClass().equals(Long.class)){ return (long)o; } + if(o.getClass().equals(Integer.class)){ return (int)o; } return (double)o; } + @Override public float getFloat(Object o){ if(o.getClass().equals(Double.class)){ return (float)(double)o; } - if(o.getClass().equals(Long.class)){ return (float)(long)o; } - if(o.getClass().equals(Integer.class)){ return (float)(int)o; } + if(o.getClass().equals(Long.class)){ return (long)o; } + if(o.getClass().equals(Integer.class)){ return (int)o; } return (float)o; } + @Override public long getLong(Object o){ if(o.getClass().equals(Float.class)){ return (long)(float)o; } if(o.getClass().equals(Double.class)){ return (long)(double)o; } - if(o.getClass().equals(Integer.class)){ return (long)(int)o; } + if(o.getClass().equals(Integer.class)){ return (int)o; } return (long)o; } + @Override @Deprecated public Object createDataJSON(int key, JSONArray jo, JSONArray helper) throws Exception{ Object help = helper.get(key); @@ -889,6 +956,7 @@ public class _194ItemUtils implements IDabItemUtils{ return ret; } + @Override public Object createDataJSON(int key, JSONArray jo) throws Exception{ JSONArray j = jo.getJSONArray(key); Object ret = null; @@ -940,9 +1008,10 @@ public class _194ItemUtils implements IDabItemUtils{ return ret; } + @Override public boolean compareBaseTag(Object tag, Object tag1) throws Exception{ - int i = (int)((byte)gti.invoke(tag)); - int i1 = (int)((byte)gti.invoke(tag1)); + int i = ((byte)gti.invoke(tag)); + int i1 = ((byte)gti.invoke(tag1)); if(i != i1) return false; switch(i){ @@ -991,6 +1060,7 @@ public class _194ItemUtils implements IDabItemUtils{ return false; } + @Override @SuppressWarnings("unchecked") public boolean compareCompoundTag(Object tag, Object tag1) throws Exception{ Map map = (Map)getMap(tag); @@ -1008,6 +1078,7 @@ public class _194ItemUtils implements IDabItemUtils{ return true; } + @Override @SuppressWarnings({ "unchecked", "rawtypes" }) public boolean compareListTag(Object tag, Object tag1) throws Exception{ List list = (List)nbtld.get(tag); @@ -1038,6 +1109,7 @@ public class _194ItemUtils implements IDabItemUtils{ return copy.isEmpty() && copy1.isEmpty(); } + @Override public boolean compare(ItemStack is1, ItemStack is2){ if(is1.getType().equals(is2.getType())){ if(is1.getDurability() == is2.getDurability()){ @@ -1061,10 +1133,12 @@ public class _194ItemUtils implements IDabItemUtils{ return false; } + @Override public boolean canMerge(ItemStack add, ItemStack to){ return compare(add, to); } + @Override public boolean isModified(ItemStack is){ ItemStack is1 = is.clone(); is1.setAmount(1); @@ -1072,6 +1146,7 @@ public class _194ItemUtils implements IDabItemUtils{ return !is1.equals(is2); } + @Override public void sortByMaterial(List items){ items.sort(new MaterialComparator()); } @@ -1083,6 +1158,7 @@ public class _194ItemUtils implements IDabItemUtils{ } } + @Override public void sortByName(List items){ items.sort(new NameComparator()); } @@ -1100,6 +1176,7 @@ public class _194ItemUtils implements IDabItemUtils{ } } + @Override public void sortByAmount(List items){ items.sort(new AmountComparator()); } @@ -1119,6 +1196,7 @@ public class _194ItemUtils implements IDabItemUtils{ } } + @Override public ItemStack convertJSONToItemStack(JSONObject jo) throws Exception{ Material material = Material.valueOf(jo.getString("material")); int amount = jo.getInt("amount"); @@ -1134,6 +1212,7 @@ public class _194ItemUtils implements IDabItemUtils{ return is; } + @Override public JSONObject convertItemStackToJSON(ItemStack is) throws Exception{ JSONObject jo = new JSONObject(); jo.put("material", is.getType().name()); diff --git a/src/main/java/me/skymc/taboolib/particle/EffLib.java b/src/main/java/me/skymc/taboolib/particle/EffLib.java index 1cc9a29..6c71c35 100644 --- a/src/main/java/me/skymc/taboolib/particle/EffLib.java +++ b/src/main/java/me/skymc/taboolib/particle/EffLib.java @@ -1177,7 +1177,7 @@ public enum EffLib { */ @Override public float getValueX() { - return (float) red / 255F; + return red / 255F; } /** @@ -1187,7 +1187,7 @@ public enum EffLib { */ @Override public float getValueY() { - return (float) green / 255F; + return green / 255F; } /** @@ -1197,7 +1197,7 @@ public enum EffLib { */ @Override public float getValueZ() { - return (float) blue / 255F; + return blue / 255F; } } @@ -1235,7 +1235,7 @@ public enum EffLib { */ @Override public float getValueX() { - return (float) note / 24F; + return note / 24F; } /** diff --git a/src/main/java/me/skymc/taboolib/sign/TabooSignChangeEvent.java b/src/main/java/me/skymc/taboolib/sign/TabooSignChangeEvent.java index 2a5b36e..a384d89 100644 --- a/src/main/java/me/skymc/taboolib/sign/TabooSignChangeEvent.java +++ b/src/main/java/me/skymc/taboolib/sign/TabooSignChangeEvent.java @@ -40,7 +40,8 @@ public class TabooSignChangeEvent return this.uuid; } - public HandlerList getHandlers() + @Override +public HandlerList getHandlers() { return handlers; } diff --git a/src/main/java/me/skymc/taboolib/string/language2/Language2.java b/src/main/java/me/skymc/taboolib/string/language2/Language2.java index f061773..ca3047c 100644 --- a/src/main/java/me/skymc/taboolib/string/language2/Language2.java +++ b/src/main/java/me/skymc/taboolib/string/language2/Language2.java @@ -20,58 +20,29 @@ public class Language2 { @Getter private FileConfiguration configuration; - @Getter private File languageFile; - @Getter private File languageFolder; - @Getter private Plugin plugin; - @Getter private String languageName; - /** - * 构造方法 - * - * @param plugin 插件 - */ public Language2(Plugin plugin) { this("zh_CN", plugin); } - /** - * 构造方法 - * - * @param languageName 语言文件 - * @param plugin 插件 - */ public Language2(String languageName, Plugin plugin) { this.languageName = languageName; this.plugin = plugin; - // 重载语言文件 reload(languageName); } - /** - * 获取语言文件 - * - * @param key 键 - * @return {@link Language2Value} - */ public Language2Value get(String key) { return new Language2Value(this, key); } - /** - * 获取语言文件 - * - * @param key 键 - * @param placeholder 替换变量,从 @$0 开始 - * @return {@link Language2Value} - */ public Language2Value get(String key, String... placeholder) { Language2Value value = new Language2Value(this, key); for (int i = 0 ; i < placeholder.length ; i++) { @@ -80,52 +51,27 @@ public class Language2 { return value; } - /** - * 重载语言文件 - */ public void reload() { reload(this.languageName); } - /** - * 重载语言文件 - * - * @param languageName 新语言文件名称 - */ public void reload(String languageName) { - // 初始化文件夹 createFolder(plugin); - // 格式化配置名 languageName = formatName(languageName); - // 获取文件 languageFile = new File(languageFolder, languageName); - // 文件不存在 if (!languageFile.exists()) { - // 如果语言文件不存在 if (plugin.getResource("Language2/" + languageName) == null) { try { throw new FileNotFoundException("语言文件 " + languageName + " 不存在"); + } catch (Exception ignored) { } - catch (Exception e) { - // TODO: handle exception - } - } - else { - // 释放资源 + } else { plugin.saveResource("Language2/" + languageName, true); } } - // 载入配置 configuration = ConfigUtils.load(plugin, languageFile); } - /** - * PlaceholderAPI 变量识别 - * - * @param player 玩家 - * @param string 文本 - * @return String - */ public String setPlaceholderAPI(Player player, String string) { if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null && player != null) { return PlaceholderAPI.setPlaceholders(player, string); @@ -133,21 +79,10 @@ public class Language2 { return string; } - /** - * 语言文件名称格式化 - * - * @param name 语言文件名称 - * @return String - */ private String formatName(String name) { return name.contains(".yml") ? name : name + ".yml"; } - /** - * 语言文件夹初始化 - * - * @param plugin - */ private void createFolder(Plugin plugin) { languageFolder = new File(plugin.getDataFolder(), "Language2"); if (!languageFolder.exists()) { diff --git a/src/main/java/me/skymc/taboolib/string/language2/value/Language2Action.java b/src/main/java/me/skymc/taboolib/string/language2/value/Language2Action.java index 10ede35..2b07307 100644 --- a/src/main/java/me/skymc/taboolib/string/language2/value/Language2Action.java +++ b/src/main/java/me/skymc/taboolib/string/language2/value/Language2Action.java @@ -67,6 +67,7 @@ public class Language2Action implements Language2Line { * * @param player 玩家 */ + @Override public void send(Player player) { // 检查版本 if (TabooLib.getVerint() < 10800) { diff --git a/src/main/java/me/skymc/taboolib/string/language2/value/Language2Json.java b/src/main/java/me/skymc/taboolib/string/language2/value/Language2Json.java index 36d5ed2..eae95e5 100644 --- a/src/main/java/me/skymc/taboolib/string/language2/value/Language2Json.java +++ b/src/main/java/me/skymc/taboolib/string/language2/value/Language2Json.java @@ -129,6 +129,7 @@ public class Language2Json implements Language2Line { * * @param player 玩家 */ + @Override public void send(Player player) { json.send(player); } diff --git a/src/main/java/me/skymc/taboolib/timecycle/TimeCycleEvent.java b/src/main/java/me/skymc/taboolib/timecycle/TimeCycleEvent.java index fcd0932..2797f25 100644 --- a/src/main/java/me/skymc/taboolib/timecycle/TimeCycleEvent.java +++ b/src/main/java/me/skymc/taboolib/timecycle/TimeCycleEvent.java @@ -17,6 +17,7 @@ public class TimeCycleEvent extends Event { return this.cycle; } + @Override public HandlerList getHandlers() { return handlers; } diff --git a/src/main/java/me/skymc/taboolib/timecycle/TimeCycleInitializeEvent.java b/src/main/java/me/skymc/taboolib/timecycle/TimeCycleInitializeEvent.java index 9c1037c..e8fa476 100644 --- a/src/main/java/me/skymc/taboolib/timecycle/TimeCycleInitializeEvent.java +++ b/src/main/java/me/skymc/taboolib/timecycle/TimeCycleInitializeEvent.java @@ -33,6 +33,7 @@ public class TimeCycleInitializeEvent extends Event { return this.cycle; } + @Override public HandlerList getHandlers() { return handlers; } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 712a7ae..fa7b0ca 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -15,9 +15,11 @@ commands: language2: aliases: [lang2] permission: taboolib.admin + tabooliblocale: + aliases: [taboolocale, tlocale] + permission: taboolib.admin taboolibrarymodule: aliases: [tlm] depend: [Vault] -softdepend: [PlaceholderAPI, Skript, TabooCode, MassiveLag] -loadbefore: [Skript] \ No newline at end of file +softdepend: [PlaceholderAPI, Skript, TabooCode, MassiveLag] \ No newline at end of file From f40039f9ceb741250346fd5d2c495013a3f263bb Mon Sep 17 00:00:00 2001 From: Izzel_Aliz Date: Sat, 28 Apr 2018 14:00:12 +0800 Subject: [PATCH 22/44] =?UTF-8?q?=E5=A4=A7=E6=A6=82=E5=B0=B1=E6=8A=8A?= =?UTF-8?q?=E8=AF=AD=E8=A8=80=E7=B3=BB=E7=BB=9F=E5=81=9A=E5=AE=8C=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/dictionaries/csh20.xml | 1 + .idea/inspectionProfiles/Project_Default.xml | 5 + .../inspectionProfiles/profiles_settings.xml | 23 ++++ src/main/java/com/ilummc/tlib/TLib.java | 6 ++ .../ilummc/tlib/inject/TConfigWatcher.java | 47 ++++---- .../com/ilummc/tlib/resources/TLocale.java | 52 +++++---- .../tlib/resources/TLocaleInstance.java | 90 ++++++++-------- .../ilummc/tlib/resources/TLocaleLoader.java | 101 +++++++++--------- .../tlib/resources/TLocaleSendable.java | 3 +- .../tlib/resources/type/TLocaleText.java | 1 + .../tlib/resources/type/TLocaleTitle.java | 2 +- src/main/resources/internalLang.yml | 5 + 12 files changed, 188 insertions(+), 148 deletions(-) create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 src/main/resources/internalLang.yml diff --git a/.idea/dictionaries/csh20.xml b/.idea/dictionaries/csh20.xml index e6ef750..47c7813 100644 --- a/.idea/dictionaries/csh20.xml +++ b/.idea/dictionaries/csh20.xml @@ -6,6 +6,7 @@ sendable unserialize unserializer + yaml \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 0f1df49..d5b4402 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -32,5 +32,10 @@