From d793444dd58502de5c7a22b91f2a676f45481846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9D=8F=E9=BB=91?= Date: Sat, 13 Oct 2018 21:36:49 +0800 Subject: [PATCH] =?UTF-8?q?TabooLib=20v4.55=20+=20=E5=AF=B9=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E6=9C=AC=E4=BD=93=E8=BF=9B=E8=A1=8C=E5=A4=A7=E9=9D=A2?= =?UTF-8?q?=E7=A7=AF=E6=95=B4=E6=94=B9=EF=BC=8C=E5=B0=86=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E8=BF=87=E5=A4=B1=E6=88=96=E4=B8=8D=E5=86=8D=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=9A=84=E5=B7=A5=E5=85=B7=E7=B1=BB=E8=BD=AC=E7=A7=BB=E8=87=B3?= =?UTF-8?q?=20TabooLibDeprecated.jar=20=E4=B8=AD=E3=80=82=20+=20=E5=AF=B9?= =?UTF-8?q?=20SimpleCommandBuilder=20=E8=BF=9B=E8=A1=8C=E4=BA=86=E5=BE=AE?= =?UTF-8?q?=E8=B0=83=EF=BC=8C=E5=8A=A8=E6=80=81=E6=B3=A8=E5=86=8C=E5=90=8E?= =?UTF-8?q?=E7=9A=84=E5=91=BD=E4=BB=A4=E5=89=8D=E7=BC=80=E5=B0=86=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E4=B8=BA=E6=B3=A8=E5=86=8C=E6=8F=92=E4=BB=B6=E3=80=82?= =?UTF-8?q?=20+=20=E5=AF=B9=20SimpleVersionControl=20=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E4=BA=86=E5=BE=AE=E8=B0=83=EF=BC=8C=E5=85=81=E8=AE=B8=E5=9C=A8?= =?UTF-8?q?=20translate=20=E7=B1=BB=E4=B8=AD=E9=80=89=E6=8B=A9=E6=89=80?= =?UTF-8?q?=E5=B1=9E=E6=8F=92=E4=BB=B6=E3=80=82=20+=20=E5=AF=B9=20ItemBuil?= =?UTF-8?q?der=20=E8=BF=9B=E8=A1=8C=E4=BA=86=E5=BE=AE=E8=B0=83=EF=BC=8C?= =?UTF-8?q?=E5=85=81=E8=AE=B8=E4=BD=BF=E7=94=A8=20ItemStack=20=E4=BD=9C?= =?UTF-8?q?=E4=B8=BA=E6=9E=84=E9=80=A0=E5=8F=82=E6=95=B0=E3=80=82=20+=20..?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 68 +- .../me/skymc/taboolib/TabooLibLoader.java | 23 +- .../taboolib/anvil/AnvilContainerAPI.java | 2 +- .../builder/SimpleCommandBuilder.java | 10 +- .../commands/internal/TCommandHandler.java | 22 +- .../commands/language/Language2Command.java | 2 +- .../commands/taboolib/TagDisplayCommand.java | 2 - .../taboolib/common/inject/TInjectLoader.java | 9 + .../loader}/Instantiable.java | 2 +- .../loader}/InstantiableLoader.java | 2 +- .../common/pathfinder/SimpleAiSelector.java | 2 +- .../versioncontrol/SimpleVersionControl.java | 6 +- .../skymc/taboolib/cooldown/CooldownPack.java | 60 - .../taboolib/cooldown/CooldownUtils.java | 47 - .../cooldown/seconds/CooldownPack2.java | 58 - .../cooldown/seconds/CooldownUtils2.java | 50 - .../me/skymc/taboolib/csvutils/CsvReader.java | 1065 --------- .../me/skymc/taboolib/csvutils/CsvWriter.java | 320 --- .../me/skymc/taboolib/damage/GetDamager.java | 14 - .../me/skymc/taboolib/damage/GetKiller.java | 13 - .../skymc/taboolib/display/ActionUtils.java | 49 - .../me/skymc/taboolib/display/TitleUtils.java | 66 - .../me/skymc/taboolib/economy/EcoUtils.java | 33 - .../enchantment/EnchantmentUtils.java | 19 - .../me/skymc/taboolib/entity/EntityTag.java | 279 --- .../me/skymc/taboolib/entity/EntityUtils.java | 111 - .../me/skymc/taboolib/entity/VectorUtils.java | 122 - .../skymc/taboolib/events/DefaultEvent.java | 28 - .../skymc/taboolib/fileutils/FileUtils.java | 14 + .../skymc/taboolib/inventory/DropUtils.java | 20 - .../taboolib/inventory/InventoryUtil.java | 120 - .../inventory/builder/ItemBuilder.java | 5 + .../speciaitem/AbstractSpecialItem.java | 46 - .../inventory/speciaitem/SpecialItem.java | 184 -- .../speciaitem/SpecialItemResult.java | 39 - .../me/skymc/taboolib/itagapi/TagPacket.java | 7 +- .../taboolib/itemnbtapi/NBTCompound.java | 196 -- .../taboolib/itemnbtapi/NBTContainer.java | 37 - .../skymc/taboolib/itemnbtapi/NBTEntity.java | 24 - .../me/skymc/taboolib/itemnbtapi/NBTFile.java | 48 - .../me/skymc/taboolib/itemnbtapi/NBTItem.java | 40 - .../me/skymc/taboolib/itemnbtapi/NBTList.java | 128 -- .../taboolib/itemnbtapi/NBTListCompound.java | 104 - .../itemnbtapi/NBTReflectionUtil.java | 1018 --------- .../taboolib/itemnbtapi/NBTTileEntity.java | 24 - .../me/skymc/taboolib/itemnbtapi/NBTType.java | 37 - .../itemnbtapi/utils/GsonWrapper.java | 28 - .../itemnbtapi/utils/MethodNames.java | 35 - src/main/java/me/skymc/taboolib/json/CDL.java | 155 -- .../java/me/skymc/taboolib/json/Cookie.java | 92 - .../me/skymc/taboolib/json/CookieList.java | 39 - .../java/me/skymc/taboolib/json/HTTP.java | 71 - .../me/skymc/taboolib/json/HTTPTokener.java | 37 - .../me/skymc/taboolib/json/JSONArray.java | 413 ---- .../me/skymc/taboolib/json/JSONException.java | 22 - .../java/me/skymc/taboolib/json/JSONML.java | 310 --- .../me/skymc/taboolib/json/JSONObject.java | 872 -------- .../me/skymc/taboolib/json/JSONReader.java | 50 - .../me/skymc/taboolib/json/JSONString.java | 6 - .../me/skymc/taboolib/json/JSONStringer.java | 15 - .../me/skymc/taboolib/json/JSONTokener.java | 283 --- .../me/skymc/taboolib/json/JSONWriter.java | 160 -- src/main/java/me/skymc/taboolib/json/XML.java | 338 --- .../me/skymc/taboolib/json/XMLTokener.java | 252 --- .../taboolib/jsonformatter/JSONFormatter.java | 465 ---- .../jsonformatter/click/ClickEvent.java | 9 - .../jsonformatter/click/OpenUrlEvent.java | 23 - .../jsonformatter/click/RunCommandEvent.java | 23 - .../click/SuggestCommandEvent.java | 23 - .../jsonformatter/hover/HoverEvent.java | 9 - .../hover/ShowAchievementEvent.java | 23 - .../jsonformatter/hover/ShowItemEvent.java | 81 - .../jsonformatter/hover/ShowTextEvent.java | 23 - .../taboolib/location/LocationUtils.java | 66 - .../skymc/taboolib/message/ChatCatcher.java | 77 - .../me/skymc/taboolib/message/MsgUtils.java | 73 - .../skymc/taboolib/methods/MethodsUtils.java | 49 - .../skymc/taboolib/mysql/MysqlConnection.java | 329 --- .../me/skymc/taboolib/mysql/MysqlUtils.java | 50 - .../mysql/protect/MySQLConnection.java | 773 ------- .../java/me/skymc/taboolib/nms/NMSUtil18.java | 1323 ----------- .../java/me/skymc/taboolib/nms/NMSUtil19.java | 1963 ----------------- .../java/me/skymc/taboolib/nms/NMSUtils.java | 379 ---- .../skymc/taboolib/nms/item/DabItemUtils.java | 453 ---- .../taboolib/nms/item/IDabItemUtils.java | 171 -- .../taboolib/nms/item/impl/_164ItemUtils.java | 1308 ----------- .../nms/item/impl/_1710ItemUtils.java | 1218 ---------- .../taboolib/nms/item/impl/_194ItemUtils.java | 1232 ----------- .../skymc/taboolib/nms/nbt/NBTConstants.java | 25 - .../skymc/taboolib/object/WeightCategory.java | 34 - .../me/skymc/taboolib/other/DateUtils.java | 80 - .../me/skymc/taboolib/other/MathUtils.java | 55 - .../me/skymc/taboolib/other/NumberUtils.java | 83 - .../me/skymc/taboolib/other/WeightUtils.java | 33 - .../me/skymc/taboolib/packet/PacketUtils.java | 93 - .../skymc/taboolib/particle/ParticlePack.java | 44 - .../taboolib/particle/ParticleUtils.java | 27 - .../taboolib/permission/PermissionUtils.java | 34 - .../me/skymc/taboolib/player/PlayerUtils.java | 139 -- .../me/skymc/taboolib/player/TargetUtils.java | 25 - .../skymc/taboolib/regen/WorldGuardUtils.java | 26 - .../me/skymc/taboolib/sign/SignUtils.java | 152 -- .../taboolib/sign/TabooSignChangeEvent.java | 48 - .../skymc/taboolib/skript/SkriptHandler.java | 25 - .../expression/ExpressionItemCache.java | 46 - .../expression/ExpressionTabooCodeItem.java | 51 - .../me/skymc/taboolib/skull/SkullUtils.java | 21 - .../skymc/taboolib/string/obfuscated/CT.java | 52 - .../skymc/taboolib/string/obfuscated/FZ.java | 59 - .../skymc/taboolib/string/obfuscated/RS.java | 48 - .../java/me/skymc/taboolib/team/TagAPI.java | 66 - .../me/skymc/taboolib/team/TagManager.java | 126 -- .../me/skymc/taboolib/thread/ThreadUtils.java | 86 - .../skymc/taboolib/timecycle/TimeCycle.java | 35 - .../taboolib/timecycle/TimeCycleEvent.java | 28 - .../timecycle/TimeCycleInitializeEvent.java | 46 - .../taboolib/timecycle/TimeCycleManager.java | 159 -- .../taboolib/translateuuid/TranslateUUID.java | 205 -- .../translateuuid/TranslateUUIDCommand.java | 81 - src/main/java/me/skymc/tlm/TLM.java | 102 - .../skymc/tlm/annotation/DisableConfig.java | 13 - .../me/skymc/tlm/command/TLMCommands.java | 68 - .../skymc/tlm/command/sub/TLMInvCommand.java | 201 -- .../skymc/tlm/command/sub/TLMKitCommand.java | 173 -- .../skymc/tlm/command/sub/TLMListCommand.java | 31 - .../tlm/command/sub/TLMReloadCommand.java | 48 - .../tlm/inventory/TLMInventoryHolder.java | 39 - .../skymc/tlm/module/ITabooLibraryModule.java | 25 - .../skymc/tlm/module/TabooLibraryModule.java | 100 - .../tlm/module/sub/ModuleCommandChanger.java | 55 - .../tlm/module/sub/ModuleInventorySave.java | 174 -- .../me/skymc/tlm/module/sub/ModuleKits.java | 166 -- .../skymc/tlm/module/sub/ModuleTimeCycle.java | 109 - .../resources/Addons/TabooLibDeprecated.jar | Bin 0 -> 354031 bytes 134 files changed, 129 insertions(+), 21103 deletions(-) rename src/main/java/me/skymc/taboolib/{object => common/loader}/Instantiable.java (89%) rename src/main/java/me/skymc/taboolib/{object => common/loader}/InstantiableLoader.java (98%) delete mode 100644 src/main/java/me/skymc/taboolib/cooldown/CooldownPack.java delete mode 100644 src/main/java/me/skymc/taboolib/cooldown/CooldownUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/cooldown/seconds/CooldownPack2.java delete mode 100644 src/main/java/me/skymc/taboolib/cooldown/seconds/CooldownUtils2.java delete mode 100644 src/main/java/me/skymc/taboolib/csvutils/CsvReader.java delete mode 100644 src/main/java/me/skymc/taboolib/csvutils/CsvWriter.java delete mode 100644 src/main/java/me/skymc/taboolib/damage/GetDamager.java delete mode 100644 src/main/java/me/skymc/taboolib/damage/GetKiller.java delete mode 100644 src/main/java/me/skymc/taboolib/display/ActionUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/display/TitleUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/economy/EcoUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/enchantment/EnchantmentUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/entity/EntityTag.java delete mode 100644 src/main/java/me/skymc/taboolib/entity/EntityUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/entity/VectorUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/events/DefaultEvent.java delete mode 100644 src/main/java/me/skymc/taboolib/inventory/DropUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/inventory/InventoryUtil.java delete mode 100644 src/main/java/me/skymc/taboolib/inventory/speciaitem/AbstractSpecialItem.java delete mode 100644 src/main/java/me/skymc/taboolib/inventory/speciaitem/SpecialItem.java delete mode 100644 src/main/java/me/skymc/taboolib/inventory/speciaitem/SpecialItemResult.java delete mode 100644 src/main/java/me/skymc/taboolib/itemnbtapi/NBTCompound.java delete mode 100644 src/main/java/me/skymc/taboolib/itemnbtapi/NBTContainer.java delete mode 100644 src/main/java/me/skymc/taboolib/itemnbtapi/NBTEntity.java delete mode 100644 src/main/java/me/skymc/taboolib/itemnbtapi/NBTFile.java delete mode 100644 src/main/java/me/skymc/taboolib/itemnbtapi/NBTItem.java delete mode 100644 src/main/java/me/skymc/taboolib/itemnbtapi/NBTList.java delete mode 100644 src/main/java/me/skymc/taboolib/itemnbtapi/NBTListCompound.java delete mode 100644 src/main/java/me/skymc/taboolib/itemnbtapi/NBTReflectionUtil.java delete mode 100644 src/main/java/me/skymc/taboolib/itemnbtapi/NBTTileEntity.java delete mode 100644 src/main/java/me/skymc/taboolib/itemnbtapi/NBTType.java delete mode 100644 src/main/java/me/skymc/taboolib/itemnbtapi/utils/GsonWrapper.java delete mode 100644 src/main/java/me/skymc/taboolib/itemnbtapi/utils/MethodNames.java delete mode 100644 src/main/java/me/skymc/taboolib/json/CDL.java delete mode 100644 src/main/java/me/skymc/taboolib/json/Cookie.java delete mode 100644 src/main/java/me/skymc/taboolib/json/CookieList.java delete mode 100644 src/main/java/me/skymc/taboolib/json/HTTP.java delete mode 100644 src/main/java/me/skymc/taboolib/json/HTTPTokener.java delete mode 100644 src/main/java/me/skymc/taboolib/json/JSONArray.java delete mode 100644 src/main/java/me/skymc/taboolib/json/JSONException.java delete mode 100644 src/main/java/me/skymc/taboolib/json/JSONML.java delete mode 100644 src/main/java/me/skymc/taboolib/json/JSONObject.java delete mode 100644 src/main/java/me/skymc/taboolib/json/JSONReader.java delete mode 100644 src/main/java/me/skymc/taboolib/json/JSONString.java delete mode 100644 src/main/java/me/skymc/taboolib/json/JSONStringer.java delete mode 100644 src/main/java/me/skymc/taboolib/json/JSONTokener.java delete mode 100644 src/main/java/me/skymc/taboolib/json/JSONWriter.java delete mode 100644 src/main/java/me/skymc/taboolib/json/XML.java delete mode 100644 src/main/java/me/skymc/taboolib/json/XMLTokener.java delete mode 100644 src/main/java/me/skymc/taboolib/jsonformatter/JSONFormatter.java delete mode 100644 src/main/java/me/skymc/taboolib/jsonformatter/click/ClickEvent.java delete mode 100644 src/main/java/me/skymc/taboolib/jsonformatter/click/OpenUrlEvent.java delete mode 100644 src/main/java/me/skymc/taboolib/jsonformatter/click/RunCommandEvent.java delete mode 100644 src/main/java/me/skymc/taboolib/jsonformatter/click/SuggestCommandEvent.java delete mode 100644 src/main/java/me/skymc/taboolib/jsonformatter/hover/HoverEvent.java delete mode 100644 src/main/java/me/skymc/taboolib/jsonformatter/hover/ShowAchievementEvent.java delete mode 100644 src/main/java/me/skymc/taboolib/jsonformatter/hover/ShowItemEvent.java delete mode 100644 src/main/java/me/skymc/taboolib/jsonformatter/hover/ShowTextEvent.java delete mode 100644 src/main/java/me/skymc/taboolib/location/LocationUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/message/ChatCatcher.java delete mode 100644 src/main/java/me/skymc/taboolib/message/MsgUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/methods/MethodsUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/mysql/MysqlConnection.java delete mode 100644 src/main/java/me/skymc/taboolib/mysql/MysqlUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/mysql/protect/MySQLConnection.java delete mode 100644 src/main/java/me/skymc/taboolib/nms/NMSUtil18.java delete mode 100644 src/main/java/me/skymc/taboolib/nms/NMSUtil19.java delete mode 100644 src/main/java/me/skymc/taboolib/nms/NMSUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/nms/item/DabItemUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/nms/item/IDabItemUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/nms/item/impl/_164ItemUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/nms/item/impl/_1710ItemUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/nms/item/impl/_194ItemUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/nms/nbt/NBTConstants.java delete mode 100644 src/main/java/me/skymc/taboolib/object/WeightCategory.java delete mode 100644 src/main/java/me/skymc/taboolib/other/DateUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/other/MathUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/other/NumberUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/other/WeightUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/packet/PacketUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/particle/ParticlePack.java delete mode 100644 src/main/java/me/skymc/taboolib/particle/ParticleUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/permission/PermissionUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/player/PlayerUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/player/TargetUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/regen/WorldGuardUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/sign/SignUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/sign/TabooSignChangeEvent.java delete mode 100644 src/main/java/me/skymc/taboolib/skript/SkriptHandler.java delete mode 100644 src/main/java/me/skymc/taboolib/skript/expression/ExpressionItemCache.java delete mode 100644 src/main/java/me/skymc/taboolib/skript/expression/ExpressionTabooCodeItem.java delete mode 100644 src/main/java/me/skymc/taboolib/skull/SkullUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/string/obfuscated/CT.java delete mode 100644 src/main/java/me/skymc/taboolib/string/obfuscated/FZ.java delete mode 100644 src/main/java/me/skymc/taboolib/string/obfuscated/RS.java delete mode 100644 src/main/java/me/skymc/taboolib/team/TagAPI.java delete mode 100644 src/main/java/me/skymc/taboolib/team/TagManager.java delete mode 100644 src/main/java/me/skymc/taboolib/thread/ThreadUtils.java delete mode 100644 src/main/java/me/skymc/taboolib/timecycle/TimeCycle.java delete mode 100644 src/main/java/me/skymc/taboolib/timecycle/TimeCycleEvent.java delete mode 100644 src/main/java/me/skymc/taboolib/timecycle/TimeCycleInitializeEvent.java delete mode 100644 src/main/java/me/skymc/taboolib/timecycle/TimeCycleManager.java delete mode 100644 src/main/java/me/skymc/taboolib/translateuuid/TranslateUUID.java delete mode 100644 src/main/java/me/skymc/taboolib/translateuuid/TranslateUUIDCommand.java delete mode 100644 src/main/java/me/skymc/tlm/TLM.java delete mode 100644 src/main/java/me/skymc/tlm/annotation/DisableConfig.java delete mode 100644 src/main/java/me/skymc/tlm/command/TLMCommands.java delete mode 100644 src/main/java/me/skymc/tlm/command/sub/TLMInvCommand.java delete mode 100644 src/main/java/me/skymc/tlm/command/sub/TLMKitCommand.java delete mode 100644 src/main/java/me/skymc/tlm/command/sub/TLMListCommand.java delete mode 100644 src/main/java/me/skymc/tlm/command/sub/TLMReloadCommand.java delete mode 100644 src/main/java/me/skymc/tlm/inventory/TLMInventoryHolder.java delete mode 100644 src/main/java/me/skymc/tlm/module/ITabooLibraryModule.java delete mode 100644 src/main/java/me/skymc/tlm/module/TabooLibraryModule.java delete mode 100644 src/main/java/me/skymc/tlm/module/sub/ModuleCommandChanger.java delete mode 100644 src/main/java/me/skymc/tlm/module/sub/ModuleInventorySave.java delete mode 100644 src/main/java/me/skymc/tlm/module/sub/ModuleKits.java delete mode 100644 src/main/java/me/skymc/tlm/module/sub/ModuleTimeCycle.java create mode 100644 src/main/resources/Addons/TabooLibDeprecated.jar diff --git a/pom.xml b/pom.xml index 49da20c..1e58f04 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.skymc TabooLib - 4.53 + 4.55 UTF-8 @@ -36,6 +36,42 @@ true + + org.apache.maven.plugins + maven-resources-plugin + 3.0.1 + + UTF-8 + false + + jar + + + + + net.alchim31.maven + scala-maven-plugin + 3.4.2 + + + + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + me.skymc.taboolib.socket.TabooLibServer + + + + org.apache.maven.plugins maven-shade-plugin @@ -59,29 +95,6 @@ - - net.alchim31.maven - scala-maven-plugin - 3.4.2 - - - - compile - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - me.skymc.taboolib.socket.TabooLibServer - - - - @@ -218,6 +231,13 @@ system ${basedir}/libs/BossBarAPI.jar + + deprecated + deprecated + 1 + system + ${basedir}/libs/TabooLibDeprecated.jar + \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/TabooLibLoader.java b/src/main/java/me/skymc/taboolib/TabooLibLoader.java index 05b0198..6664f14 100644 --- a/src/main/java/me/skymc/taboolib/TabooLibLoader.java +++ b/src/main/java/me/skymc/taboolib/TabooLibLoader.java @@ -4,9 +4,11 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.ilummc.tlib.TLib; import com.ilummc.tlib.annotations.Dependency; +import com.ilummc.tlib.dependency.TDependencyLoader; import com.ilummc.tlib.inject.TDependencyInjector; import com.ilummc.tlib.resources.TLocale; import me.skymc.taboolib.bstats.Metrics; +import me.skymc.taboolib.deprecated.TabooLibDeprecated; import me.skymc.taboolib.fileutils.FileUtils; import me.skymc.taboolib.listener.TListener; import me.skymc.taboolib.listener.TListenerHandler; @@ -32,11 +34,13 @@ import java.util.*; @TListener public class TabooLibLoader implements Listener { + static TabooLibDeprecated tabooLibDeprecated; static Map> pluginClasses = Maps.newHashMap(); static List loaders = Lists.newArrayList(); static void setup() { testInternet(); + setupAddons(); setupDataFolder(); setupDatabase(); setupLibraries(); @@ -44,15 +48,24 @@ public class TabooLibLoader implements Listener { static void register() { setupClasses(); - loadClasses(); registerListener(); registerMetrics(); + loadClasses(); + try { + tabooLibDeprecated = new TabooLibDeprecated(); + } catch (Exception e) { + e.printStackTrace(); + } } static void unregister() { unloadClasses(); } + public static TabooLibDeprecated getTabooLibDeprecated() { + return tabooLibDeprecated; + } + public static Optional> getPluginClasses(Plugin plugin) { return Optional.ofNullable(pluginClasses.get(plugin.getName())); } @@ -84,6 +97,14 @@ public class TabooLibLoader implements Listener { metrics.addCustomChart(new Metrics.SingleLineChart("plugins_using_taboolib", () -> Math.toIntExact(Arrays.stream(Bukkit.getPluginManager().getPlugins()).filter(plugin -> plugin.getDescription().getDepend().contains("TabooLib")).count()))); } + static void setupAddons() { + TabooLib.instance().saveResource("Addons/TabooLibDeprecated.jar", true); + File file = new File(TabooLib.instance().getDataFolder(), "Addons"); + if (file.exists()) { + Arrays.stream(file.listFiles()).forEach(listFile -> TDependencyLoader.addToPath(TabooLib.instance(), listFile)); + } + } + static void setupDataFolder() { Main.setPlayerDataFolder(FileUtils.folder(Main.getInst().getConfig().getString("DATAURL.PLAYER-DATA"))); Main.setServerDataFolder(FileUtils.folder(Main.getInst().getConfig().getString("DATAURL.SERVER-DATA"))); diff --git a/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java b/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java index 6bdd43f..904910c 100644 --- a/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java +++ b/src/main/java/me/skymc/taboolib/anvil/AnvilContainerAPI.java @@ -2,7 +2,7 @@ package me.skymc.taboolib.anvil; import com.ilummc.tlib.util.asm.AsmClassLoader; import me.skymc.taboolib.TabooLib; -import me.skymc.taboolib.object.Instantiable; +import me.skymc.taboolib.common.loader.Instantiable; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; diff --git a/src/main/java/me/skymc/taboolib/commands/builder/SimpleCommandBuilder.java b/src/main/java/me/skymc/taboolib/commands/builder/SimpleCommandBuilder.java index 9e7efbd..209d1eb 100644 --- a/src/main/java/me/skymc/taboolib/commands/builder/SimpleCommandBuilder.java +++ b/src/main/java/me/skymc/taboolib/commands/builder/SimpleCommandBuilder.java @@ -31,6 +31,7 @@ public class SimpleCommandBuilder { private String permissionMessage; private CompleterTab completerTab = EMPTY_COMPLETER_TAB; private CompleterCommand completerCommand = EMPTY_COMPLETER_COMMAND; + private boolean silence; SimpleCommandBuilder(String command, Plugin plugin) { this.command = command; @@ -38,6 +39,7 @@ public class SimpleCommandBuilder { this.description = ""; this.usage = "/" + command; this.aliases = new ArrayList<>(); + this.silence = false; } public static SimpleCommandBuilder create(String command, Plugin plugin) { @@ -79,6 +81,11 @@ public class SimpleCommandBuilder { return this; } + public SimpleCommandBuilder silence() { + this.silence = true; + return this; + } + public SimpleCommandBuilder build() { Preconditions.checkNotNull(completerCommand, "缺少 \"CompleterCommand\" 部分"); Preconditions.checkNotNull(completerTab, "缺少 \"CompleterTab\" 部分"); @@ -91,7 +98,8 @@ public class SimpleCommandBuilder { permission, permissionMessage, (sender, command, s, args) -> completerCommand.execute(sender, args), - (sender, command, s, args) -> completerTab.execute(sender, args)); + (sender, command, s, args) -> completerTab.execute(sender, args), + silence); return this; } } diff --git a/src/main/java/me/skymc/taboolib/commands/internal/TCommandHandler.java b/src/main/java/me/skymc/taboolib/commands/internal/TCommandHandler.java index 9cfe49d..ee7f365 100644 --- a/src/main/java/me/skymc/taboolib/commands/internal/TCommandHandler.java +++ b/src/main/java/me/skymc/taboolib/commands/internal/TCommandHandler.java @@ -16,7 +16,9 @@ import org.bukkit.plugin.Plugin; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Collection; import java.util.List; +import java.util.stream.Collectors; /** * @Author sky @@ -70,6 +72,10 @@ public class TCommandHandler implements Listener { return registerPluginCommand(plugin, command, description, usage, aliases, null, null, commandExecutor, tabCompleter); } + public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, List aliases, String permission, String permissionMessage, CommandExecutor commandExecutor, TabCompleter tabCompleter) { + return registerPluginCommand(plugin, command, description, usage, aliases, permission, permissionMessage, commandExecutor, tabCompleter, false); + } + /** * 向服务端动态注册命令 * @@ -81,10 +87,11 @@ public class TCommandHandler implements Listener { * @param permission 权限 * @param permissionMessage 权限提示 * @param commandExecutor 命令执行器 - * @param tabCompleter 补全执行器 + * @param tabCompleter 补全执行器 + * @param silence 是否屏蔽提示 * @return 注册结果(boolean) */ - public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, List aliases, String permission, String permissionMessage, CommandExecutor commandExecutor, TabCompleter tabCompleter) { + public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, List aliases, String permission, String permissionMessage, CommandExecutor commandExecutor, TabCompleter tabCompleter, boolean silence) { try { Constructor constructor = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class); constructor.setAccessible(true); @@ -93,17 +100,18 @@ public class TCommandHandler implements Listener { pluginCommand.setTabCompleter(tabCompleter); ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "description", description); ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "usageMessage", usage); - ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "aliases", aliases); - ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "activeAliases", aliases); + ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "aliases", aliases.stream().map(String::toLowerCase).collect(Collectors.toList())); + ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "activeAliases", aliases.stream().map(String::toLowerCase).collect(Collectors.toList())); ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "permission", permission); ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "permissionMessage", permissionMessage); - commandMap.register(command, pluginCommand); - if (!TabooLib.isTabooLib(plugin)) { + commandMap.register(plugin.getName(), pluginCommand); + if (!TabooLib.isTabooLib(plugin) && !silence) { TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE", plugin.getName(), command); } return true; } catch (Exception e) { - TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE-FAILED", plugin.getName(), command, e.getMessage()); + TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE-FAILED", plugin.getName(), command, e.toString()); + e.printStackTrace(); return false; } } diff --git a/src/main/java/me/skymc/taboolib/commands/language/Language2Command.java b/src/main/java/me/skymc/taboolib/commands/language/Language2Command.java index f21c1f5..6cc56cc 100644 --- a/src/main/java/me/skymc/taboolib/commands/language/Language2Command.java +++ b/src/main/java/me/skymc/taboolib/commands/language/Language2Command.java @@ -4,7 +4,7 @@ import com.ilummc.tlib.resources.TLocale; import me.skymc.taboolib.Main; import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.commands.builder.SimpleCommandBuilder; -import me.skymc.taboolib.object.Instantiable; +import me.skymc.taboolib.common.loader.Instantiable; import me.skymc.taboolib.string.language2.Language2Value; import org.bukkit.Bukkit; import org.bukkit.Material; diff --git a/src/main/java/me/skymc/taboolib/commands/taboolib/TagDisplayCommand.java b/src/main/java/me/skymc/taboolib/commands/taboolib/TagDisplayCommand.java index 6dd46a0..8808e6d 100644 --- a/src/main/java/me/skymc/taboolib/commands/taboolib/TagDisplayCommand.java +++ b/src/main/java/me/skymc/taboolib/commands/taboolib/TagDisplayCommand.java @@ -1,10 +1,8 @@ package me.skymc.taboolib.commands.taboolib; import com.ilummc.tlib.resources.TLocale; -import me.clip.placeholderapi.PlaceholderAPI; import me.skymc.taboolib.commands.SubCommand; import me.skymc.taboolib.itagapi.TagDataHandler; -import me.skymc.taboolib.team.TagAPI; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; diff --git a/src/main/java/me/skymc/taboolib/common/inject/TInjectLoader.java b/src/main/java/me/skymc/taboolib/common/inject/TInjectLoader.java index 002637c..0c0bcdb 100644 --- a/src/main/java/me/skymc/taboolib/common/inject/TInjectLoader.java +++ b/src/main/java/me/skymc/taboolib/common/inject/TInjectLoader.java @@ -3,6 +3,7 @@ package me.skymc.taboolib.common.inject; import com.google.common.collect.Maps; import com.ilummc.tlib.logger.TLogger; import me.skymc.taboolib.TabooLibLoader; +import me.skymc.taboolib.commands.builder.SimpleCommandBuilder; import me.skymc.taboolib.common.configuration.TConfiguration; import org.bukkit.plugin.Plugin; @@ -39,6 +40,14 @@ public class TInjectLoader implements TabooLibLoader.Loader { e.printStackTrace(); } }); + // SimpleCommandBuilder Inject + injectTypes.put(SimpleCommandBuilder.class, (plugin, field, args) -> { + try { + ((SimpleCommandBuilder) field.get(null)).build(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + }); } @Override diff --git a/src/main/java/me/skymc/taboolib/object/Instantiable.java b/src/main/java/me/skymc/taboolib/common/loader/Instantiable.java similarity index 89% rename from src/main/java/me/skymc/taboolib/object/Instantiable.java rename to src/main/java/me/skymc/taboolib/common/loader/Instantiable.java index fb7e32e..9ffadc4 100644 --- a/src/main/java/me/skymc/taboolib/object/Instantiable.java +++ b/src/main/java/me/skymc/taboolib/common/loader/Instantiable.java @@ -1,4 +1,4 @@ -package me.skymc.taboolib.object; +package me.skymc.taboolib.common.loader; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/src/main/java/me/skymc/taboolib/object/InstantiableLoader.java b/src/main/java/me/skymc/taboolib/common/loader/InstantiableLoader.java similarity index 98% rename from src/main/java/me/skymc/taboolib/object/InstantiableLoader.java rename to src/main/java/me/skymc/taboolib/common/loader/InstantiableLoader.java index 45e7c0d..62ae29b 100644 --- a/src/main/java/me/skymc/taboolib/object/InstantiableLoader.java +++ b/src/main/java/me/skymc/taboolib/common/loader/InstantiableLoader.java @@ -1,4 +1,4 @@ -package me.skymc.taboolib.object; +package me.skymc.taboolib.common.loader; import com.ilummc.tlib.util.Ref; import me.skymc.taboolib.TabooLibLoader; diff --git a/src/main/java/me/skymc/taboolib/common/pathfinder/SimpleAiSelector.java b/src/main/java/me/skymc/taboolib/common/pathfinder/SimpleAiSelector.java index f80d04d..ea74712 100644 --- a/src/main/java/me/skymc/taboolib/common/pathfinder/SimpleAiSelector.java +++ b/src/main/java/me/skymc/taboolib/common/pathfinder/SimpleAiSelector.java @@ -1,7 +1,7 @@ package me.skymc.taboolib.common.pathfinder; import me.skymc.taboolib.common.versioncontrol.SimpleVersionControl; -import me.skymc.taboolib.object.Instantiable; +import me.skymc.taboolib.common.loader.Instantiable; /** * @Author sky diff --git a/src/main/java/me/skymc/taboolib/common/versioncontrol/SimpleVersionControl.java b/src/main/java/me/skymc/taboolib/common/versioncontrol/SimpleVersionControl.java index 3e2f9bd..1f020cb 100644 --- a/src/main/java/me/skymc/taboolib/common/versioncontrol/SimpleVersionControl.java +++ b/src/main/java/me/skymc/taboolib/common/versioncontrol/SimpleVersionControl.java @@ -15,8 +15,6 @@ import java.util.ArrayList; import java.util.List; /** - * 我不信 ClassNotFound 的邪,自己写了一个发现还是一样。。。 - * * @Author sky * @Since 2018-09-19 21:05 */ @@ -64,6 +62,10 @@ public class SimpleVersionControl { } public Class translate() throws IOException { + return translate(plugin); + } + + public Class translate(Plugin plugin) throws IOException { ClassReader classReader = new ClassReader(FileUtils.getResource(plugin, target.replace(".", "/") + ".class")); ClassWriter classWriter = new ClassWriter(0); ClassVisitor classVisitor = new SimpleClassVisitor(this, classWriter); diff --git a/src/main/java/me/skymc/taboolib/cooldown/CooldownPack.java b/src/main/java/me/skymc/taboolib/cooldown/CooldownPack.java deleted file mode 100644 index 8066e7e..0000000 --- a/src/main/java/me/skymc/taboolib/cooldown/CooldownPack.java +++ /dev/null @@ -1,60 +0,0 @@ -package me.skymc.taboolib.cooldown; - -import java.util.HashMap; - -@Deprecated -public class CooldownPack { - - private String plugin; - private String name; - private int seconds; - - private HashMap data = new HashMap<>(); - - public CooldownPack(String n, int s) { - this.name = n; - this.seconds = s; - this.plugin = "null"; - } - - public String getPackName() { - return name; - } - - public int getPackSeconds() { - return seconds; - } - - public String getPlugin() { - return plugin; - } - - public void setPlugin(String p) { - this.plugin = p; - } - - public void unRegister(String player) { - data.remove(player); - } - - public int getCooldown(String player) { - if (!data.containsKey(player)) { - return 0; - } - int difference = (int) ((System.currentTimeMillis() - data.get(player)) / 1000); - - return difference >= seconds ? 0 : seconds - difference; - } - - public boolean isCooldown(String player, int cutseconds) { - if (!data.containsKey(player)) { - data.put(player, System.currentTimeMillis()); - return false; - } - if ((getCooldown(player) - (cutseconds*1000)) <= 0) { - data.put(player, System.currentTimeMillis()); - return false; - } - return true; - } -} diff --git a/src/main/java/me/skymc/taboolib/cooldown/CooldownUtils.java b/src/main/java/me/skymc/taboolib/cooldown/CooldownUtils.java deleted file mode 100644 index d63557e..0000000 --- a/src/main/java/me/skymc/taboolib/cooldown/CooldownUtils.java +++ /dev/null @@ -1,47 +0,0 @@ -package me.skymc.taboolib.cooldown; - -import com.ilummc.tlib.resources.TLocale; -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; - -@Deprecated -public class CooldownUtils implements Listener { - - private static ConcurrentHashMap packlist = new ConcurrentHashMap<>(); - - public static void register(CooldownPack pack) { - packlist.put(pack.getPackName(), pack); - TLocale.Logger.info("COOLDOWNPACK.PACK-REGISTER-ANONYMOUS", pack.getPackName(), String.valueOf(pack.getPackSeconds())); - } - - public static void register(CooldownPack pack, Plugin plugin) { - pack.setPlugin(plugin.getName()); - packlist.put(pack.getPackName(), pack); - TLocale.Logger.info("COOLDOWNPACK.PACK-REGISTER", pack.getPackName(), String.valueOf(pack.getPackSeconds()), plugin.getName()); - } - - public static void unregister(String name) { - packlist.remove(name); - TLocale.Logger.info("COOLDOWNPACK.PACK-UNREGISTER", name); - } - - private static void unregister(CooldownPack pack) { - packlist.remove(pack.getPackName()); - TLocale.Logger.info("COOLDOWNPACK.PACK-UNREGISTER-AUTO", pack.getPackName()); - } - - @EventHandler - public void quit(PlayerQuitEvent e) { - packlist.values().stream().filter(pack -> !pack.isCooldown(e.getPlayer().getName(), 0)).forEach(pack -> pack.unRegister(e.getPlayer().getName())); - } - - @EventHandler - public void disable(PluginDisableEvent e) { - packlist.values().stream().filter(pack -> pack.getPlugin().equals(e.getPlugin().getName())).forEach(CooldownUtils::unregister); - } -} diff --git a/src/main/java/me/skymc/taboolib/cooldown/seconds/CooldownPack2.java b/src/main/java/me/skymc/taboolib/cooldown/seconds/CooldownPack2.java deleted file mode 100644 index 3a54f60..0000000 --- a/src/main/java/me/skymc/taboolib/cooldown/seconds/CooldownPack2.java +++ /dev/null @@ -1,58 +0,0 @@ -package me.skymc.taboolib.cooldown.seconds; - -import java.util.HashMap; - -public class CooldownPack2 { - - private String plugin; - private String name; - private int seconds; - - private HashMap data = new HashMap<>(); - - public CooldownPack2(String n, int s) { - this.name = n; - this.seconds = s; - this.plugin = "null"; - } - - public String getPackName() { - return name; - } - - public int getPackSeconds() { - return seconds; - } - - public String getPlugin() { - return plugin; - } - - public void setPlugin(String p) { - this.plugin = p; - } - - public void unRegister(String player) { - data.remove(player); - } - - public int getCooldown(String player, int cutseconds) { - if (!data.containsKey(player)) { - return 0; - } - int difference = (int) ((System.currentTimeMillis() + cutseconds) - data.get(player)); - return difference >= seconds ? 0 : seconds - difference; - } - - public boolean isCooldown(String player, int cutseconds) { - if (!data.containsKey(player)) { - data.put(player, System.currentTimeMillis()); - return false; - } - if (getCooldown(player, cutseconds) <= 0) { - data.put(player, System.currentTimeMillis()); - return false; - } - return true; - } -} diff --git a/src/main/java/me/skymc/taboolib/cooldown/seconds/CooldownUtils2.java b/src/main/java/me/skymc/taboolib/cooldown/seconds/CooldownUtils2.java deleted file mode 100644 index 91cfcdf..0000000 --- a/src/main/java/me/skymc/taboolib/cooldown/seconds/CooldownUtils2.java +++ /dev/null @@ -1,50 +0,0 @@ -package me.skymc.taboolib.cooldown.seconds; - -import com.ilummc.tlib.resources.TLocale; -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<>(); - - public static ConcurrentHashMap getCooldownPacks() { - return packlist; - } - - public static void register(CooldownPack2 pack) { - packlist.put(pack.getPackName(), pack); - TLocale.Logger.info("COOLDOWNPACK.PACK-REGISTER-ANONYMOUS", pack.getPackName(), String.valueOf(pack.getPackSeconds())); - } - - public static void register(CooldownPack2 pack, Plugin plugin) { - pack.setPlugin(plugin.getName()); - packlist.put(pack.getPackName(), pack); - TLocale.Logger.info("COOLDOWNPACK.PACK-REGISTER", pack.getPackName(), String.valueOf(pack.getPackSeconds()), plugin.getName()); - } - - public static void unregister(String name) { - packlist.remove(name); - TLocale.Logger.info("COOLDOWNPACK.PACK-UNREGISTER", name); - } - - private static void unregister(CooldownPack2 pack) { - packlist.remove(pack.getPackName()); - TLocale.Logger.info("COOLDOWNPACK.PACK-UNREGISTER-AUTO", pack.getPackName()); - } - - @EventHandler - public void quit(PlayerQuitEvent e) { - packlist.values().stream().filter(pack -> !pack.isCooldown(e.getPlayer().getName(), 0)).forEach(pack -> pack.unRegister(e.getPlayer().getName())); - } - - @EventHandler - public void disable(PluginDisableEvent e) { - packlist.values().stream().filter(pack -> pack.getPlugin().equals(e.getPlugin().getName())).forEach(CooldownUtils2::unregister); - } -} diff --git a/src/main/java/me/skymc/taboolib/csvutils/CsvReader.java b/src/main/java/me/skymc/taboolib/csvutils/CsvReader.java deleted file mode 100644 index fda2878..0000000 --- a/src/main/java/me/skymc/taboolib/csvutils/CsvReader.java +++ /dev/null @@ -1,1065 +0,0 @@ -package me.skymc.taboolib.csvutils; - -import java.io.*; -import java.nio.charset.Charset; -import java.text.NumberFormat; -import java.util.HashMap; - -public class CsvReader { - - private Reader inputStream; - private String fileName; - private UserSettings userSettings; - private Charset charset; - private boolean useCustomRecordDelimiter; - private DataBuffer dataBuffer; - private ColumnBuffer columnBuffer; - private RawRecordBuffer rawBuffer; - private boolean[] isQualified; - private String rawRecord; - private HeadersHolder headersHolder; - private boolean startedColumn; - private boolean startedWithQualifier; - private boolean hasMoreData; - private char lastLetter; - private boolean hasReadNextLine; - private int columnsCount; - private long currentRecord; - private String[] values; - private boolean initialized; - private boolean closed; - public static final int ESCAPE_MODE_DOUBLED = 1; - public static final int ESCAPE_MODE_BACKSLASH = 2; - - public CsvReader(final String fileName, final char delimiter, final Charset charset) throws FileNotFoundException { - this.inputStream = null; - this.fileName = null; - this.userSettings = new UserSettings(); - this.charset = null; - this.useCustomRecordDelimiter = false; - this.dataBuffer = new DataBuffer(); - this.columnBuffer = new ColumnBuffer(); - this.rawBuffer = new RawRecordBuffer(); - this.isQualified = null; - this.rawRecord = ""; - this.headersHolder = new HeadersHolder(); - this.startedColumn = false; - this.startedWithQualifier = false; - this.hasMoreData = true; - this.lastLetter = '\0'; - this.hasReadNextLine = false; - this.columnsCount = 0; - this.currentRecord = 0L; - this.values = new String[10]; - this.initialized = false; - this.closed = false; - if (fileName == null) { - throw new IllegalArgumentException("Parameter fileName can not be null."); - } - if (charset == null) { - throw new IllegalArgumentException("Parameter charset can not be null."); - } - if (!new File(fileName).exists()) { - throw new FileNotFoundException("File " + fileName + " does not exist."); - } - this.fileName = fileName; - this.userSettings.Delimiter = delimiter; - this.charset = charset; - this.isQualified = new boolean[this.values.length]; - } - - public CsvReader(final String s, final char c) throws FileNotFoundException { - this(s, c, Charset.forName("ISO-8859-1")); - } - - public CsvReader(final String s) throws FileNotFoundException { - this(s, ','); - } - - public CsvReader(final Reader inputStream, final char delimiter) { - this.inputStream = null; - this.fileName = null; - this.userSettings = new UserSettings(); - this.charset = null; - this.useCustomRecordDelimiter = false; - this.dataBuffer = new DataBuffer(); - this.columnBuffer = new ColumnBuffer(); - this.rawBuffer = new RawRecordBuffer(); - this.isQualified = null; - this.rawRecord = ""; - this.headersHolder = new HeadersHolder(); - this.startedColumn = false; - this.startedWithQualifier = false; - this.hasMoreData = true; - this.lastLetter = '\0'; - this.hasReadNextLine = false; - this.columnsCount = 0; - this.currentRecord = 0L; - this.values = new String[10]; - this.initialized = false; - this.closed = false; - if (inputStream == null) { - throw new IllegalArgumentException("Parameter inputStream can not be null."); - } - this.inputStream = inputStream; - this.userSettings.Delimiter = delimiter; - this.initialized = true; - this.isQualified = new boolean[this.values.length]; - } - - public CsvReader(final Reader reader) { - this(reader, ','); - } - - public CsvReader(final InputStream inputStream, final char c, final Charset charset) { - this(new InputStreamReader(inputStream, charset), c); - } - - public CsvReader(final InputStream inputStream, final Charset charset) { - this(new InputStreamReader(inputStream, charset)); - } - - public boolean getCaptureRawRecord() { - return this.userSettings.CaptureRawRecord; - } - - public void setCaptureRawRecord(final boolean captureRawRecord) { - this.userSettings.CaptureRawRecord = captureRawRecord; - } - - public String getRawRecord() { - return this.rawRecord; - } - - public boolean getTrimWhitespace() { - return this.userSettings.TrimWhitespace; - } - - public void setTrimWhitespace(final boolean trimWhitespace) { - this.userSettings.TrimWhitespace = trimWhitespace; - } - - public char getDelimiter() { - return this.userSettings.Delimiter; - } - - public void setDelimiter(final char delimiter) { - this.userSettings.Delimiter = delimiter; - } - - public char getRecordDelimiter() { - return this.userSettings.RecordDelimiter; - } - - public void setRecordDelimiter(final char recordDelimiter) { - this.useCustomRecordDelimiter = true; - this.userSettings.RecordDelimiter = recordDelimiter; - } - - public char getTextQualifier() { - return this.userSettings.TextQualifier; - } - - public void setTextQualifier(final char textQualifier) { - this.userSettings.TextQualifier = textQualifier; - } - - public boolean getUseTextQualifier() { - return this.userSettings.UseTextQualifier; - } - - public void setUseTextQualifier(final boolean useTextQualifier) { - this.userSettings.UseTextQualifier = useTextQualifier; - } - - public char getComment() { - return this.userSettings.Comment; - } - - public void setComment(final char comment) { - this.userSettings.Comment = comment; - } - - public boolean getUseComments() { - return this.userSettings.UseComments; - } - - public void setUseComments(final boolean useComments) { - this.userSettings.UseComments = useComments; - } - - public int getEscapeMode() { - return this.userSettings.EscapeMode; - } - - public void setEscapeMode(final int escapeMode) throws IllegalArgumentException { - if (escapeMode != 1 && escapeMode != 2) { - throw new IllegalArgumentException("Parameter escapeMode must be a valid value."); - } - this.userSettings.EscapeMode = escapeMode; - } - - public boolean getSkipEmptyRecords() { - return this.userSettings.SkipEmptyRecords; - } - - public void setSkipEmptyRecords(final boolean skipEmptyRecords) { - this.userSettings.SkipEmptyRecords = skipEmptyRecords; - } - - public boolean getSafetySwitch() { - return this.userSettings.SafetySwitch; - } - - public void setSafetySwitch(final boolean safetySwitch) { - this.userSettings.SafetySwitch = safetySwitch; - } - - public int getColumnCount() { - return this.columnsCount; - } - - public long getCurrentRecord() { - return this.currentRecord - 1L; - } - - // TODO 2017-11-29 18:38:13 UPDATED - public long setCurrentRecord(long currentRecord) { - return this.currentRecord = currentRecord; - } - - public int getHeaderCount() { - return this.headersHolder.Length; - } - - public String[] getHeaders() throws IOException { - this.checkClosed(); - if (this.headersHolder.Headers == null) { - return null; - } - final String[] array = new String[this.headersHolder.Length]; - System.arraycopy(this.headersHolder.Headers, 0, array, 0, this.headersHolder.Length); - return array; - } - - private static char hexToDec(final char c) { - char c2; - if (c >= 'a') { - c2 = (char) (c - 'a' + '\n'); - } else if (c >= 'A') { - c2 = (char) (c - 'A' + '\n'); - } else { - c2 = (char) (c - '0'); - } - return c2; - } - - public String[] getValues() throws IOException { - this.checkClosed(); - final String[] array = new String[this.columnsCount]; - System.arraycopy(this.values, 0, array, 0, this.columnsCount); - return array; - } - - public String get(final int n) throws IOException { - this.checkClosed(); - if (n > -1 && n < this.columnsCount) { - return this.values[n]; - } - return ""; - } - - public String get(final String s) throws IOException { - this.checkClosed(); - return this.get(this.getIndex(s)); - } - - public static CsvReader parse(final String s) { - if (s == null) { - throw new IllegalArgumentException("Parameter data can not be null."); - } - return new CsvReader(new StringReader(s)); - } - - public void setHeaders(final String[] headers) { - this.headersHolder.Headers = headers; - this.headersHolder.IndexByName.clear(); - if (headers != null) { - this.headersHolder.Length = headers.length; - } else { - this.headersHolder.Length = 0; - } - for (int i = 0; i < this.headersHolder.Length; ++i) { - this.headersHolder.IndexByName.put(headers[i], i); - } - } - - public boolean readRecord() throws IOException { - this.checkClosed(); - this.columnsCount = 0; - this.rawBuffer.Position = 0; - this.dataBuffer.LineStart = this.dataBuffer.Position; - this.hasReadNextLine = false; - if (this.hasMoreData) { - do { - if (this.dataBuffer.Position == this.dataBuffer.Count) { - this.checkDataLength(); - } else { - this.startedWithQualifier = false; - char c = this.dataBuffer.Buffer[this.dataBuffer.Position]; - if (this.userSettings.UseTextQualifier && c == this.userSettings.TextQualifier) { - this.lastLetter = c; - this.startedColumn = true; - this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1; - this.startedWithQualifier = true; - int n = 0; - char textQualifier = this.userSettings.TextQualifier; - if (this.userSettings.EscapeMode == 2) { - textQualifier = '\\'; - } - int n2 = 0; - int n3 = 0; - int n4 = 0; - int n5 = 1; - int n6 = 0; - char c2 = '\0'; - final DataBuffer dataBuffer = this.dataBuffer; - ++dataBuffer.Position; - do { - if (this.dataBuffer.Position == this.dataBuffer.Count) { - this.checkDataLength(); - } else { - final char lastLetter = this.dataBuffer.Buffer[this.dataBuffer.Position]; - if (n2 != 0) { - this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1; - if (lastLetter == this.userSettings.Delimiter) { - this.endColumn(); - } else if ((!this.useCustomRecordDelimiter && (lastLetter == '\r' || lastLetter == '\n')) || (this.useCustomRecordDelimiter && lastLetter == this.userSettings.RecordDelimiter)) { - this.endColumn(); - this.endRecord(); - } - } else if (n4 != 0) { - ++n6; - switch (n5) { - case 1: { - c2 = (char) ((char) (c2 * '\u0010') + hexToDec(lastLetter)); - if (n6 == 4) { - n4 = 0; - break; - } - break; - } - case 2: { - c2 = (char) ((char) (c2 * '\b') + (char) (lastLetter - '0')); - if (n6 == 3) { - n4 = 0; - break; - } - break; - } - case 3: { - c2 = (char) ((char) (c2 * '\n') + (char) (lastLetter - '0')); - if (n6 == 3) { - n4 = 0; - break; - } - break; - } - case 4: { - c2 = (char) ((char) (c2 * '\u0010') + hexToDec(lastLetter)); - if (n6 == 2) { - n4 = 0; - break; - } - break; - } - } - if (n4 == 0) { - this.appendLetter(c2); - } else { - this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1; - } - } else if (lastLetter == this.userSettings.TextQualifier) { - if (n3 != 0) { - n3 = 0; - n = 0; - } else { - this.updateCurrentValue(); - if (this.userSettings.EscapeMode == 1) { - n3 = 1; - } - n = 1; - } - } else if (this.userSettings.EscapeMode == 2 && n3 != 0) { - switch (lastLetter) { - case 'n': { - this.appendLetter('\n'); - break; - } - case 'r': { - this.appendLetter('\r'); - break; - } - case 't': { - this.appendLetter('\t'); - break; - } - case 'b': { - this.appendLetter('\b'); - break; - } - case 'f': { - this.appendLetter('\f'); - break; - } - case 'e': { - this.appendLetter('\u001b'); - break; - } - case 'v': { - this.appendLetter('\u000b'); - break; - } - case 'a': { - this.appendLetter('\u0007'); - break; - } - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': { - n5 = 2; - n4 = 1; - n6 = 1; - c2 = (char) (lastLetter - '0'); - this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1; - break; - } - case 'D': - case 'O': - case 'U': - case 'X': - case 'd': - case 'o': - case 'u': - case 'x': { - switch (lastLetter) { - case 'U': - case 'u': { - n5 = 1; - break; - } - case 'X': - case 'x': { - n5 = 4; - break; - } - case 'O': - case 'o': { - n5 = 2; - break; - } - case 'D': - case 'd': { - n5 = 3; - break; - } - } - n4 = 1; - n6 = 0; - c2 = '\0'; - this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1; - break; - } - } - n3 = 0; - } else if (lastLetter == textQualifier) { - this.updateCurrentValue(); - n3 = 1; - } else if (n != 0) { - if (lastLetter == this.userSettings.Delimiter) { - this.endColumn(); - } else if ((!this.useCustomRecordDelimiter && (lastLetter == '\r' || lastLetter == '\n')) || (this.useCustomRecordDelimiter && lastLetter == this.userSettings.RecordDelimiter)) { - this.endColumn(); - this.endRecord(); - } else { - this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1; - n2 = 1; - } - n = 0; - } - this.lastLetter = lastLetter; - if (!this.startedColumn) { - continue; - } - final DataBuffer dataBuffer2 = this.dataBuffer; - ++dataBuffer2.Position; - if (this.userSettings.SafetySwitch && this.dataBuffer.Position - this.dataBuffer.ColumnStart + this.columnBuffer.Position > 100000) { - this.close(); - throw new IOException("Maximum column length of 100,000 exceeded in column " + NumberFormat.getIntegerInstance().format(this.columnsCount) + " in record " + NumberFormat.getIntegerInstance().format(this.currentRecord) + ". Set the SafetySwitch property to false" + " if you're expecting column lengths greater than 100,000 characters to" + " avoid this error."); - } - } - } while (this.hasMoreData && this.startedColumn); - } else if (c == this.userSettings.Delimiter) { - this.lastLetter = c; - this.endColumn(); - } else if (this.useCustomRecordDelimiter && c == this.userSettings.RecordDelimiter) { - if (this.startedColumn || this.columnsCount > 0 || !this.userSettings.SkipEmptyRecords) { - this.endColumn(); - this.endRecord(); - } else { - this.dataBuffer.LineStart = this.dataBuffer.Position + 1; - } - this.lastLetter = c; - } else if (!this.useCustomRecordDelimiter && (c == '\r' || c == '\n')) { - if (this.startedColumn || this.columnsCount > 0 || (!this.userSettings.SkipEmptyRecords && (c == '\r' || this.lastLetter != '\r'))) { - this.endColumn(); - this.endRecord(); - } else { - this.dataBuffer.LineStart = this.dataBuffer.Position + 1; - } - this.lastLetter = c; - } else if (this.userSettings.UseComments && this.columnsCount == 0 && c == this.userSettings.Comment) { - this.lastLetter = c; - this.skipLine(); - } else if (this.userSettings.TrimWhitespace && (c == ' ' || c == '\t')) { - this.startedColumn = true; - this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1; - } else { - this.startedColumn = true; - this.dataBuffer.ColumnStart = this.dataBuffer.Position; - int n7 = 0; - int n8 = 0; - int n9 = 1; - int n10 = 0; - char c3 = '\0'; - int n11 = 1; - do { - if (n11 == 0 && this.dataBuffer.Position == this.dataBuffer.Count) { - this.checkDataLength(); - } else { - if (n11 == 0) { - c = this.dataBuffer.Buffer[this.dataBuffer.Position]; - } - if (!this.userSettings.UseTextQualifier && this.userSettings.EscapeMode == 2 && c == '\\') { - if (n7 != 0) { - n7 = 0; - } else { - this.updateCurrentValue(); - n7 = 1; - } - } else if (n8 != 0) { - ++n10; - switch (n9) { - case 1: { - c3 = (char) ((char) (c3 * '\u0010') + hexToDec(c)); - if (n10 == 4) { - n8 = 0; - break; - } - break; - } - case 2: { - c3 = (char) ((char) (c3 * '\b') + (char) (c - '0')); - if (n10 == 3) { - n8 = 0; - break; - } - break; - } - case 3: { - c3 = (char) ((char) (c3 * '\n') + (char) (c - '0')); - if (n10 == 3) { - n8 = 0; - break; - } - break; - } - case 4: { - c3 = (char) ((char) (c3 * '\u0010') + hexToDec(c)); - if (n10 == 2) { - n8 = 0; - break; - } - break; - } - } - if (n8 == 0) { - this.appendLetter(c3); - } else { - this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1; - } - } else if (this.userSettings.EscapeMode == 2 && n7 != 0) { - switch (c) { - case 'n': { - this.appendLetter('\n'); - break; - } - case 'r': { - this.appendLetter('\r'); - break; - } - case 't': { - this.appendLetter('\t'); - break; - } - case 'b': { - this.appendLetter('\b'); - break; - } - case 'f': { - this.appendLetter('\f'); - break; - } - case 'e': { - this.appendLetter('\u001b'); - break; - } - case 'v': { - this.appendLetter('\u000b'); - break; - } - case 'a': { - this.appendLetter('\u0007'); - break; - } - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': { - n9 = 2; - n8 = 1; - n10 = 1; - c3 = (char) (c - '0'); - this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1; - break; - } - case 'D': - case 'O': - case 'U': - case 'X': - case 'd': - case 'o': - case 'u': - case 'x': { - switch (c) { - case 'U': - case 'u': { - n9 = 1; - break; - } - case 'X': - case 'x': { - n9 = 4; - break; - } - case 'O': - case 'o': { - n9 = 2; - break; - } - case 'D': - case 'd': { - n9 = 3; - break; - } - } - n8 = 1; - n10 = 0; - c3 = '\0'; - this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1; - break; - } - } - n7 = 0; - } else if (c == this.userSettings.Delimiter) { - this.endColumn(); - } else if ((!this.useCustomRecordDelimiter && (c == '\r' || c == '\n')) || (this.useCustomRecordDelimiter && c == this.userSettings.RecordDelimiter)) { - this.endColumn(); - this.endRecord(); - } - this.lastLetter = c; - n11 = 0; - if (!this.startedColumn) { - continue; - } - final DataBuffer dataBuffer3 = this.dataBuffer; - ++dataBuffer3.Position; - if (this.userSettings.SafetySwitch && this.dataBuffer.Position - this.dataBuffer.ColumnStart + this.columnBuffer.Position > 100000) { - this.close(); - throw new IOException("Maximum column length of 100,000 exceeded in column " + NumberFormat.getIntegerInstance().format(this.columnsCount) + " in record " + NumberFormat.getIntegerInstance().format(this.currentRecord) + ". Set the SafetySwitch property to false" + " if you're expecting column lengths greater than 100,000 characters to" + " avoid this error."); - } - } - } while (this.hasMoreData && this.startedColumn); - } - if (!this.hasMoreData) { - continue; - } - final DataBuffer dataBuffer4 = this.dataBuffer; - ++dataBuffer4.Position; - } - } while (this.hasMoreData && !this.hasReadNextLine); - if (this.startedColumn || this.lastLetter == this.userSettings.Delimiter) { - this.endColumn(); - this.endRecord(); - } - } - if (this.userSettings.CaptureRawRecord) { - if (this.hasMoreData) { - if (this.rawBuffer.Position == 0) { - this.rawRecord = new String(this.dataBuffer.Buffer, this.dataBuffer.LineStart, this.dataBuffer.Position - this.dataBuffer.LineStart - 1); - } else { - this.rawRecord = new String(this.rawBuffer.Buffer, 0, this.rawBuffer.Position) + new String(this.dataBuffer.Buffer, this.dataBuffer.LineStart, this.dataBuffer.Position - this.dataBuffer.LineStart - 1); - } - } else { - this.rawRecord = new String(this.rawBuffer.Buffer, 0, this.rawBuffer.Position); - } - } else { - this.rawRecord = ""; - } - return this.hasReadNextLine; - } - - public boolean readHeaders() throws IOException { - final boolean record = this.readRecord(); - this.headersHolder.Length = this.columnsCount; - this.headersHolder.Headers = new String[this.columnsCount]; - for (int i = 0; i < this.headersHolder.Length; ++i) { - final String value = this.get(i); - this.headersHolder.Headers[i] = value; - this.headersHolder.IndexByName.put(value, i); - } - if (record) { - --this.currentRecord; - } - this.columnsCount = 0; - return record; - } - - public String getHeader(final int n) throws IOException { - this.checkClosed(); - if (n > -1 && n < this.headersHolder.Length) { - return this.headersHolder.Headers[n]; - } - return ""; - } - - public boolean isQualified(final int n) throws IOException { - this.checkClosed(); - return n < this.columnsCount && n > -1 && this.isQualified[n]; - } - - private void checkDataLength() throws IOException { - if (!this.initialized) { - if (this.fileName != null) { - this.inputStream = new BufferedReader(new InputStreamReader(new FileInputStream(this.fileName), this.charset), 4096); - } - this.charset = null; - this.initialized = true; - } - this.updateCurrentValue(); - if (this.userSettings.CaptureRawRecord && this.dataBuffer.Count > 0) { - if (this.rawBuffer.Buffer.length - this.rawBuffer.Position < this.dataBuffer.Count - this.dataBuffer.LineStart) { - final char[] buffer = new char[this.rawBuffer.Buffer.length + Math.max(this.dataBuffer.Count - this.dataBuffer.LineStart, this.rawBuffer.Buffer.length)]; - System.arraycopy(this.rawBuffer.Buffer, 0, buffer, 0, this.rawBuffer.Position); - this.rawBuffer.Buffer = buffer; - } - System.arraycopy(this.dataBuffer.Buffer, this.dataBuffer.LineStart, this.rawBuffer.Buffer, this.rawBuffer.Position, this.dataBuffer.Count - this.dataBuffer.LineStart); - final RawRecordBuffer rawBuffer = this.rawBuffer; - rawBuffer.Position += this.dataBuffer.Count - this.dataBuffer.LineStart; - } - try { - this.dataBuffer.Count = this.inputStream.read(this.dataBuffer.Buffer, 0, this.dataBuffer.Buffer.length); - } catch (IOException ex) { - this.close(); - throw ex; - } - if (this.dataBuffer.Count == -1) { - this.hasMoreData = false; - } - this.dataBuffer.Position = 0; - this.dataBuffer.LineStart = 0; - this.dataBuffer.ColumnStart = 0; - } - - private void appendLetter(final char c) { - if (this.columnBuffer.Position == this.columnBuffer.Buffer.length) { - final char[] buffer = new char[this.columnBuffer.Buffer.length * 2]; - System.arraycopy(this.columnBuffer.Buffer, 0, buffer, 0, this.columnBuffer.Position); - this.columnBuffer.Buffer = buffer; - } - this.columnBuffer.Buffer[this.columnBuffer.Position++] = c; - this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1; - } - - private void updateCurrentValue() { - if (this.startedColumn && this.dataBuffer.ColumnStart < this.dataBuffer.Position) { - if (this.columnBuffer.Buffer.length - this.columnBuffer.Position < this.dataBuffer.Position - this.dataBuffer.ColumnStart) { - final char[] buffer = new char[this.columnBuffer.Buffer.length + Math.max(this.dataBuffer.Position - this.dataBuffer.ColumnStart, this.columnBuffer.Buffer.length)]; - System.arraycopy(this.columnBuffer.Buffer, 0, buffer, 0, this.columnBuffer.Position); - this.columnBuffer.Buffer = buffer; - } - System.arraycopy(this.dataBuffer.Buffer, this.dataBuffer.ColumnStart, this.columnBuffer.Buffer, this.columnBuffer.Position, this.dataBuffer.Position - this.dataBuffer.ColumnStart); - final ColumnBuffer columnBuffer = this.columnBuffer; - columnBuffer.Position += this.dataBuffer.Position - this.dataBuffer.ColumnStart; - } - this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1; - } - - public void endRecord() { - this.hasReadNextLine = true; - ++this.currentRecord; - } - - public int getIndex(final String s) throws IOException { - this.checkClosed(); - final Integer value = this.headersHolder.IndexByName.get(s); - if (value != null) { - return value; - } - return -1; - } - - public boolean skipRecord() throws IOException { - this.checkClosed(); - boolean record = false; - if (this.hasMoreData) { - record = this.readRecord(); - if (record) { - --this.currentRecord; - } - } - return record; - } - - public void endColumn() throws IOException { - String s = ""; - if (this.startedColumn) { - if (this.columnBuffer.Position == 0) { - if (this.dataBuffer.ColumnStart < this.dataBuffer.Position) { - int n = this.dataBuffer.Position - 1; - if (this.userSettings.TrimWhitespace && !this.startedWithQualifier) { - while (n >= this.dataBuffer.ColumnStart && (this.dataBuffer.Buffer[n] == ' ' || this.dataBuffer.Buffer[n] == '\t')) { - --n; - } - } - s = new String(this.dataBuffer.Buffer, this.dataBuffer.ColumnStart, n - this.dataBuffer.ColumnStart + 1); - } - } else { - this.updateCurrentValue(); - int n2 = this.columnBuffer.Position - 1; - if (this.userSettings.TrimWhitespace && !this.startedWithQualifier) { - while (n2 >= 0 && (this.columnBuffer.Buffer[n2] == ' ' || this.columnBuffer.Buffer[n2] == ' ')) { - --n2; - } - } - s = new String(this.columnBuffer.Buffer, 0, n2 + 1); - } - } - this.columnBuffer.Position = 0; - this.startedColumn = false; - if (this.columnsCount >= 100000 && this.userSettings.SafetySwitch) { - this.close(); - throw new IOException("Maximum column count of 100,000 exceeded in record " + NumberFormat.getIntegerInstance().format(this.currentRecord) + ". Set the SafetySwitch property to false" + " if you're expecting more than 100,000 columns per record to" + " avoid this error."); - } - if (this.columnsCount == this.values.length) { - final int n3 = this.values.length * 2; - final String[] values = new String[n3]; - System.arraycopy(this.values, 0, values, 0, this.values.length); - this.values = values; - final boolean[] isQualified = new boolean[n3]; - System.arraycopy(this.isQualified, 0, isQualified, 0, this.isQualified.length); - this.isQualified = isQualified; - } - this.values[this.columnsCount] = s; - this.isQualified[this.columnsCount] = this.startedWithQualifier; - ++this.columnsCount; - } - - public void close() { - if (!this.closed) { - this.close(true); - this.closed = true; - } - } - - private void close(final boolean b) { - if (!this.closed) { - if (b) { - this.charset = null; - this.headersHolder.Headers = null; - this.headersHolder.IndexByName = null; - this.dataBuffer.Buffer = null; - this.columnBuffer.Buffer = null; - this.rawBuffer.Buffer = null; - } - try { - if (this.initialized) { - this.inputStream.close(); - } - } catch (Exception ignored) { - } - this.inputStream = null; - this.closed = true; - } - } - - private void checkClosed() throws IOException { - if (this.closed) { - throw new IOException("This instance of the CsvReader class has already been closed."); - } - } - - public boolean skipLine() throws IOException { - this.checkClosed(); - this.columnsCount = 0; - boolean b = false; - if (this.hasMoreData) { - boolean b2 = false; - do { - if (this.dataBuffer.Position == this.dataBuffer.Count) { - this.checkDataLength(); - } else { - b = true; - final char lastLetter = this.dataBuffer.Buffer[this.dataBuffer.Position]; - if (lastLetter == '\r' || lastLetter == '\n') { - b2 = true; - } - this.lastLetter = lastLetter; - if (b2) { - continue; - } - final DataBuffer dataBuffer = this.dataBuffer; - ++dataBuffer.Position; - } - } while (this.hasMoreData && !b2); - this.columnBuffer.Position = 0; - this.dataBuffer.LineStart = this.dataBuffer.Position + 1; - } - this.rawBuffer.Position = 0; - this.rawRecord = ""; - return b; - } - - @Override - protected void finalize() { - this.close(false); - } - - private class StaticSettings { - public static final int MAX_BUFFER_SIZE = 1024; - public static final int MAX_FILE_BUFFER_SIZE = 4096; - public static final int INITIAL_COLUMN_COUNT = 10; - public static final int INITIAL_COLUMN_BUFFER_SIZE = 50; - } - - private class HeadersHolder { - public String[] Headers; - public int Length; - public HashMap IndexByName; - - public HeadersHolder() { - this.Headers = null; - this.Length = 0; - this.IndexByName = new HashMap<>(); - } - } - - private class UserSettings { - public boolean CaseSensitive; - public char TextQualifier; - public boolean TrimWhitespace; - public boolean UseTextQualifier; - public char Delimiter; - public char RecordDelimiter; - public char Comment; - public boolean UseComments; - public int EscapeMode; - public boolean SafetySwitch; - public boolean SkipEmptyRecords; - public boolean CaptureRawRecord; - - public UserSettings() { - this.CaseSensitive = true; - this.TextQualifier = '\"'; - this.TrimWhitespace = true; - this.UseTextQualifier = true; - this.Delimiter = ','; - this.RecordDelimiter = '\0'; - this.Comment = '#'; - this.UseComments = false; - this.EscapeMode = 1; - this.SafetySwitch = true; - this.SkipEmptyRecords = true; - this.CaptureRawRecord = true; - } - } - - private class Letters { - public static final char LF = '\n'; - public static final char CR = '\r'; - public static final char QUOTE = '\"'; - public static final char COMMA = ','; - public static final char SPACE = ' '; - public static final char TAB = '\t'; - public static final char POUND = '#'; - public static final char BACKSLASH = '\\'; - public static final char NULL = '\0'; - public static final char BACKSPACE = '\b'; - public static final char FORM_FEED = '\f'; - public static final char ESCAPE = '\u001b'; - public static final char VERTICAL_TAB = '\u000b'; - public static final char ALERT = '\u0007'; - } - - private class RawRecordBuffer { - public char[] Buffer; - public int Position; - - public RawRecordBuffer() { - this.Buffer = new char[500]; - this.Position = 0; - } - } - - private class ColumnBuffer { - public char[] Buffer; - public int Position; - - public ColumnBuffer() { - this.Buffer = new char[50]; - this.Position = 0; - } - } - - private class DataBuffer { - public char[] Buffer; - public int Position; - public int Count; - public int ColumnStart; - public int LineStart; - - public DataBuffer() { - this.Buffer = new char[1024]; - this.Position = 0; - this.Count = 0; - this.ColumnStart = 0; - this.LineStart = 0; - } - } - - private class ComplexEscape { - private static final int UNICODE = 1; - private static final int OCTAL = 2; - private static final int DECIMAL = 3; - private static final int HEX = 4; - } -} diff --git a/src/main/java/me/skymc/taboolib/csvutils/CsvWriter.java b/src/main/java/me/skymc/taboolib/csvutils/CsvWriter.java deleted file mode 100644 index 16923a2..0000000 --- a/src/main/java/me/skymc/taboolib/csvutils/CsvWriter.java +++ /dev/null @@ -1,320 +0,0 @@ -package me.skymc.taboolib.csvutils; - -import java.io.*; -import java.nio.charset.Charset; - -public class CsvWriter { - - private Writer outputStream; - private String fileName; - private boolean firstColumn; - private boolean useCustomRecordDelimiter; - private Charset charset; - private UserSettings userSettings; - private boolean initialized; - private boolean closed; - private String systemRecordDelimiter; - public static final int ESCAPE_MODE_DOUBLED = 1; - public static final int ESCAPE_MODE_BACKSLASH = 2; - - public CsvWriter(final String fileName, final char delimiter, final Charset charset) { - this.outputStream = null; - this.fileName = null; - this.firstColumn = true; - this.useCustomRecordDelimiter = false; - this.charset = null; - this.userSettings = new UserSettings(); - this.initialized = false; - this.closed = false; - this.systemRecordDelimiter = System.getProperty("line.separator"); - if (fileName == null) { - throw new IllegalArgumentException("Parameter fileName can not be null."); - } - if (charset == null) { - throw new IllegalArgumentException("Parameter charset can not be null."); - } - this.fileName = fileName; - this.userSettings.Delimiter = delimiter; - this.charset = charset; - } - - public CsvWriter(final String s) { - this(s, ',', Charset.forName("ISO-8859-1")); - } - - public CsvWriter(final Writer outputStream, final char delimiter) { - this.outputStream = null; - this.fileName = null; - this.firstColumn = true; - this.useCustomRecordDelimiter = false; - this.charset = null; - this.userSettings = new UserSettings(); - this.initialized = false; - this.closed = false; - this.systemRecordDelimiter = System.getProperty("line.separator"); - if (outputStream == null) { - throw new IllegalArgumentException("Parameter outputStream can not be null."); - } - this.outputStream = outputStream; - this.userSettings.Delimiter = delimiter; - this.initialized = true; - } - - public CsvWriter(final OutputStream outputStream, final char c, final Charset charset) { - this(new OutputStreamWriter(outputStream, charset), c); - } - - public char getDelimiter() { - return this.userSettings.Delimiter; - } - - public void setDelimiter(final char delimiter) { - this.userSettings.Delimiter = delimiter; - } - - public char getRecordDelimiter() { - return this.userSettings.RecordDelimiter; - } - - public void setRecordDelimiter(final char recordDelimiter) { - this.useCustomRecordDelimiter = true; - this.userSettings.RecordDelimiter = recordDelimiter; - } - - public char getTextQualifier() { - return this.userSettings.TextQualifier; - } - - public void setTextQualifier(final char textQualifier) { - this.userSettings.TextQualifier = textQualifier; - } - - public boolean getUseTextQualifier() { - return this.userSettings.UseTextQualifier; - } - - public void setUseTextQualifier(final boolean useTextQualifier) { - this.userSettings.UseTextQualifier = useTextQualifier; - } - - public int getEscapeMode() { - return this.userSettings.EscapeMode; - } - - public void setEscapeMode(final int escapeMode) { - this.userSettings.EscapeMode = escapeMode; - } - - public void setComment(final char comment) { - this.userSettings.Comment = comment; - } - - public char getComment() { - return this.userSettings.Comment; - } - - public boolean getForceQualifier() { - return this.userSettings.ForceQualifier; - } - - public void setForceQualifier(final boolean forceQualifier) { - this.userSettings.ForceQualifier = forceQualifier; - } - - public void write(String s, final boolean b) throws IOException { - this.checkClosed(); - this.checkInit(); - if (s == null) { - s = ""; - } - if (!this.firstColumn) { - this.outputStream.write(this.userSettings.Delimiter); - } - int forceQualifier = this.userSettings.ForceQualifier ? 1 : 0; - if (!b && s.length() > 0) { - s = s.trim(); - } - if (forceQualifier == 0 && this.userSettings.UseTextQualifier && (s.indexOf(this.userSettings.TextQualifier) > -1 || s.indexOf(this.userSettings.Delimiter) > -1 || (!this.useCustomRecordDelimiter && (s.indexOf(10) > -1 || s.indexOf(13) > -1)) || (this.useCustomRecordDelimiter && s.indexOf(this.userSettings.RecordDelimiter) > -1) || (this.firstColumn && s.length() > 0 && s.charAt(0) == this.userSettings.Comment) || (this.firstColumn && s.length() == 0))) { - forceQualifier = 1; - } - if (this.userSettings.UseTextQualifier && forceQualifier == 0 && s.length() > 0 && b) { - final char char1 = s.charAt(0); - if (char1 == ' ' || char1 == '\t') { - forceQualifier = 1; - } - if (forceQualifier == 0 && s.length() > 1) { - final char char2 = s.charAt(s.length() - 1); - if (char2 == ' ' || char2 == '\t') { - forceQualifier = 1; - } - } - } - if (forceQualifier != 0) { - this.outputStream.write(this.userSettings.TextQualifier); - if (this.userSettings.EscapeMode == 2) { - s = replace(s, "\\", "\\\\"); - s = replace(s, "" + this.userSettings.TextQualifier, "\\" + this.userSettings.TextQualifier); - } else { - s = replace(s, "" + this.userSettings.TextQualifier, "" + this.userSettings.TextQualifier + this.userSettings.TextQualifier); - } - } else if (this.userSettings.EscapeMode == 2) { - s = replace(s, "\\", "\\\\"); - s = replace(s, "" + this.userSettings.Delimiter, "\\" + this.userSettings.Delimiter); - if (this.useCustomRecordDelimiter) { - s = replace(s, "" + this.userSettings.RecordDelimiter, "\\" + this.userSettings.RecordDelimiter); - } else { - s = replace(s, "\r", "\\\r"); - s = replace(s, "\n", "\\\n"); - } - if (this.firstColumn && s.length() > 0 && s.charAt(0) == this.userSettings.Comment) { - if (s.length() > 1) { - s = "\\" + this.userSettings.Comment + s.substring(1); - } else { - s = "\\" + this.userSettings.Comment; - } - } - } - this.outputStream.write(s); - if (forceQualifier != 0) { - this.outputStream.write(this.userSettings.TextQualifier); - } - this.firstColumn = false; - } - - public void write(final String s) throws IOException { - this.write(s, false); - } - - public void writeComment(final String s) throws IOException { - this.checkClosed(); - this.checkInit(); - this.outputStream.write(this.userSettings.Comment); - this.outputStream.write(s); - if (this.useCustomRecordDelimiter) { - this.outputStream.write(this.userSettings.RecordDelimiter); - } else { - this.outputStream.write(this.systemRecordDelimiter); - } - this.firstColumn = true; - } - - public static String replace(final String s, final String s2, final String s3) { - final int length = s2.length(); - int i = s.indexOf(s2); - if (i > -1) { - final StringBuilder sb = new StringBuilder(); - int n; - for (n = 0; i != -1; i = s.indexOf(s2, n)) { - sb.append(s, n, i); - sb.append(s3); - n = i + length; - } - sb.append(s.substring(n)); - return sb.toString(); - } - return s; - } - - public void writeRecord(final String[] array) throws IOException { - this.writeRecord(array, false); - } - - public void endRecord() throws IOException { - this.checkClosed(); - this.checkInit(); - if (this.useCustomRecordDelimiter) { - this.outputStream.write(this.userSettings.RecordDelimiter); - } else { - this.outputStream.write(this.systemRecordDelimiter); - } - this.firstColumn = true; - } - - private void checkInit() throws IOException { - if (!this.initialized) { - if (this.fileName != null) { - this.outputStream = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(this.fileName), this.charset)); - } - this.initialized = true; - } - } - - public void flush() throws IOException { - this.outputStream.flush(); - } - - public void close() { - if (!this.closed) { - this.close(true); - this.closed = true; - } - } - - public void writeRecord(final String[] array, final boolean b) throws IOException { - if (array != null && array.length > 0) { - for (String anArray : array) { - this.write(anArray, b); - } - this.endRecord(); - } - } - - private void checkClosed() throws IOException { - if (this.closed) { - throw new IOException("This instance of the CsvWriter class has already been closed."); - } - } - - @Override - protected void finalize() { - this.close(false); - } - - private void close(final boolean b) { - if (!this.closed) { - if (b) { - this.charset = null; - } - try { - if (this.initialized) { - this.outputStream.close(); - } - } catch (Exception ignored) { - } - this.outputStream = null; - this.closed = true; - } - } - - private class UserSettings { - public char TextQualifier; - public boolean UseTextQualifier; - public char Delimiter; - public char RecordDelimiter; - public char Comment; - public int EscapeMode; - public boolean ForceQualifier; - - public UserSettings() { - this.TextQualifier = '\"'; - this.UseTextQualifier = true; - this.Delimiter = ','; - this.RecordDelimiter = '\0'; - this.Comment = '#'; - this.EscapeMode = 1; - this.ForceQualifier = false; - } - } - - private class Letters { - public static final char LF = '\n'; - public static final char CR = '\r'; - public static final char QUOTE = '\"'; - public static final char COMMA = ','; - public static final char SPACE = ' '; - public static final char TAB = '\t'; - public static final char POUND = '#'; - public static final char BACKSLASH = '\\'; - public static final char NULL = '\0'; - } -} diff --git a/src/main/java/me/skymc/taboolib/damage/GetDamager.java b/src/main/java/me/skymc/taboolib/damage/GetDamager.java deleted file mode 100644 index cb171d3..0000000 --- a/src/main/java/me/skymc/taboolib/damage/GetDamager.java +++ /dev/null @@ -1,14 +0,0 @@ -package me.skymc.taboolib.damage; - -import org.bukkit.entity.Player; -import org.bukkit.entity.Projectile; -import org.bukkit.event.entity.EntityDamageByEntityEvent; - -@Deprecated -public class GetDamager { - - public static Player get(EntityDamageByEntityEvent e) { - return DamageUtils.getAttackerInDamageEvent(e); - } - -} diff --git a/src/main/java/me/skymc/taboolib/damage/GetKiller.java b/src/main/java/me/skymc/taboolib/damage/GetKiller.java deleted file mode 100644 index 0fcc95b..0000000 --- a/src/main/java/me/skymc/taboolib/damage/GetKiller.java +++ /dev/null @@ -1,13 +0,0 @@ -package me.skymc.taboolib.damage; - -import org.bukkit.entity.Player; -import org.bukkit.event.entity.EntityDeathEvent; - -@Deprecated -public class GetKiller { - - public static Player get(EntityDeathEvent e) { - return e.getEntity().getKiller(); - } - -} diff --git a/src/main/java/me/skymc/taboolib/display/ActionUtils.java b/src/main/java/me/skymc/taboolib/display/ActionUtils.java deleted file mode 100644 index 530224b..0000000 --- a/src/main/java/me/skymc/taboolib/display/ActionUtils.java +++ /dev/null @@ -1,49 +0,0 @@ -package me.skymc.taboolib.display; - -import me.skymc.taboolib.TabooLib; -import me.skymc.taboolib.nms.NMSUtils; -import org.bukkit.entity.Player; - -import java.lang.reflect.Constructor; - -/** - * @author Bkm016 - * @since 2018-04-26 - */ -public class ActionUtils { - - 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; - } - try { - Object ab = ChatComponentText.getConstructor(String.class).newInstance(action); - Constructor ac; - Object abPacket; - if (TabooLib.getVerint() > 11100) { - ac = PacketPlayOutChat.getConstructor(IChatBaseComponent, ChatMessageType); - abPacket = ac.newInstance(ab, ChatMessageType.getMethod("a", Byte.TYPE).invoke(null, (byte) 2)); - } else { - ac = PacketPlayOutChat.getConstructor(IChatBaseComponent, Byte.TYPE); - abPacket = ac.newInstance(ab, (byte) 2); - } - sendPacket(player, abPacket); - } 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) { - } - } -} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/display/TitleUtils.java b/src/main/java/me/skymc/taboolib/display/TitleUtils.java deleted file mode 100644 index 28cfb42..0000000 --- a/src/main/java/me/skymc/taboolib/display/TitleUtils.java +++ /dev/null @@ -1,66 +0,0 @@ -package me.skymc.taboolib.display; - -import me.skymc.taboolib.nms.NMSUtils; -import org.bukkit.entity.Player; - -import java.lang.reflect.Constructor; - -/** - * @author Bkm016 - * @since 2018-04-26 - */ -public class TitleUtils { - - 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 (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); - - 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 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); - - 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 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/economy/EcoUtils.java b/src/main/java/me/skymc/taboolib/economy/EcoUtils.java deleted file mode 100644 index 9d4fb41..0000000 --- a/src/main/java/me/skymc/taboolib/economy/EcoUtils.java +++ /dev/null @@ -1,33 +0,0 @@ -package me.skymc.taboolib.economy; - -import me.skymc.taboolib.Main; -import net.milkbowl.vault.economy.Economy; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.plugin.RegisteredServiceProvider; - -public class EcoUtils { - - public static void setupEconomy() { - RegisteredServiceProvider l = Bukkit.getServer().getServicesManager().getRegistration(Economy.class); - if (l != null) { - Main.setEconomy(l.getProvider()); - } - } - - public static void remove(OfflinePlayer p, double d) { - Main.getEconomy().withdrawPlayer(p, d); - } - - public static void add(OfflinePlayer p, double d) { - Main.getEconomy().depositPlayer(p, d); - } - - public static double get(OfflinePlayer p) { - return Main.getEconomy().getBalance(p); - } - - public static void create(OfflinePlayer p) { - Main.getEconomy().createPlayerAccount(p); - } -} diff --git a/src/main/java/me/skymc/taboolib/enchantment/EnchantmentUtils.java b/src/main/java/me/skymc/taboolib/enchantment/EnchantmentUtils.java deleted file mode 100644 index c1d05cc..0000000 --- a/src/main/java/me/skymc/taboolib/enchantment/EnchantmentUtils.java +++ /dev/null @@ -1,19 +0,0 @@ -package me.skymc.taboolib.enchantment; - -import org.bukkit.enchantments.Enchantment; - -import java.lang.reflect.Field; - -public class EnchantmentUtils { - - public static void setAcceptingNew(boolean value) { - try { - Field f = Enchantment.class.getDeclaredField("acceptingNew"); - f.setAccessible(true); - f.set(null, value); - } - catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/src/main/java/me/skymc/taboolib/entity/EntityTag.java b/src/main/java/me/skymc/taboolib/entity/EntityTag.java deleted file mode 100644 index f24ea66..0000000 --- a/src/main/java/me/skymc/taboolib/entity/EntityTag.java +++ /dev/null @@ -1,279 +0,0 @@ -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; - -/** - * 伪 - MetaData - * - * @author sky - * @since 2018-03-11 11:43:41 - */ -public class EntityTag { - - private static EntityTag inst; - private static ConcurrentHashMap> entityData = new ConcurrentHashMap<>(); - - private EntityTag() { - new BukkitRunnable() { - - @Override - public void run() { - for (UUID uuid : entityData.keySet()) { - if (EntityUtils.getEntityWithUUID(uuid) == null) { - entityData.remove(uuid); - } - } - } - }.runTaskTimerAsynchronously(Main.getInst(), 20 * 180, 20 * 180); - } - - public static EntityTag getInst() { - if (inst == null) { - synchronized (EntityTag.class) { - if (inst == null) { - inst = new EntityTag(); - } - } - } - return inst; - } - - /** - * 设置标签 - * - * @param entity 实体 - * @param key 键 - * @param value 值 - */ - public void set(String key, Object value, Entity entity) { - if (contains(entity)) { - entityData.get(entity.getUniqueId()).put(key, value); - } else { - ConcurrentHashMap map = new ConcurrentHashMap<>(); - map.put(key, value); - entityData.put(entity.getUniqueId(), map); - } - } - - /** - * 设置标签 - * - * @param key 键 - * @param value 值 - */ - public void set(String key, Object value, Entity... entities) { - for (Entity entity : entities) { - set(key, value, entity); - } - } - - /** - * 设置标签 - * - * @param key 键 - * @param value 值 - */ - public void set(String key, Object value, List entities) { - for (Entity entity : entities) { - set(key, value, entity); - } - } - - /** - * 移除标签 - * - * @param key 键 - * @param entity 实体 - */ - public Object remove(String key, Entity entity) { - if (contains(entity)) { - entityData.get(entity.getUniqueId()).remove(key); - if (entityData.get(entity.getUniqueId()).size() == 0) { - return entityData.remove(entity.getUniqueId()); - } - } - return null; - } - - /** - * 移除标签 - * - * @param key 键 - * @param entities 实体 - */ - public void remove(String key, Entity... entities) { - for (Entity entity : entities) { - remove(key, entity); - } - } - - /** - * 移除标签 - * - * @param key 键 - * @param entities 实体 - */ - public void remove(String key, List entities) { - for (Entity entity : entities) { - remove(key, entity); - } - } - - /** - * 检查数据 - * - * @param entity 实体 - * @return boolean - */ - public boolean contains(Entity entity) { - return entityData.containsKey(entity.getUniqueId()); - } - - /** - * 检查标签 - * - * @param key 键 - * @param entity 实体 - * @return boolean - */ - public boolean hasKey(String key, Entity entity) { - return contains(entity) && entityData.get(entity.getUniqueId()).containsKey(key); - } - - /** - * 获取数据 - * - * @param key 键 - * @param entity 实体 - * @return Object - */ - public Object get(String key, Entity entity) { - if (contains(entity)) { - return entityData.get(entity.getUniqueId()).get(key); - } - return null; - } - - /** - * 获取数据 - * - * @param key 键 - * @param entity 值 - * @return String - */ - public String getString(String key, Entity entity) { - Object object = get(key, entity); - if (object instanceof String) { - return (String) object; - } - return null; - } - - /** - * 获取数据 - * - * @param key 键 - * @param entity 值 - * @return int - */ - public int getInteger(String key, Entity entity) { - Object object = get(key, entity); - if (object != null) { - return (int) object; - } - return 0; - } - - /** - * 获取数据 - * - * @param key 键 - * @param entity 值 - * @return long - */ - public long getLong(String key, Entity entity) { - Object object = get(key, entity); - if (object != null) { - return (long) object; - } - return 0L; - } - - /** - * 获取数据 - * - * @param key 键 - * @param entity 实体 - * @return boolean - */ - public boolean getBoolean(String key, Entity entity) { - Object object = get(key, entity); - return object != null && (boolean) object; - } - - /** - * 获取数据 - * - * @param key 键 - * @param entity 实体 - * @return double - */ - public double getDouble(String key, Entity entity) { - Object object = get(key, entity); - if (object != null) { - return (double) object; - } - return 0D; - } - - /** - * 获取数据 - * - * @param key 键 - * @param entity 实体 - * @return float - */ - public double getFloat(String key, Entity entity) { - Object object = get(key, entity); - if (object != null) { - return (float) object; - } - return 0F; - } - - /** - * 获取数据 - * - * @param key 键 - * @param entity 实体 - * @return short - */ - public short getShort(String key, Entity entity) { - Object object = get(key, entity); - if (object != null) { - return (short) object; - } - return (short) 0; - } - - /** - * 获取数据 - * - * @param key 键 - * @param entity 实体 - * @return byte - */ - public byte getByte(String key, Entity entity) { - Object object = get(key, entity); - if (object != null) { - return (byte) object; - } - return (byte) 0; - } -} diff --git a/src/main/java/me/skymc/taboolib/entity/EntityUtils.java b/src/main/java/me/skymc/taboolib/entity/EntityUtils.java deleted file mode 100644 index d324e00..0000000 --- a/src/main/java/me/skymc/taboolib/entity/EntityUtils.java +++ /dev/null @@ -1,111 +0,0 @@ -package me.skymc.taboolib.entity; - -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.ProtocolLibrary; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.wrappers.WrappedDataWatcher; -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.TabooLib; -import me.skymc.taboolib.listener.TListener; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntitySpawnEvent; - -import java.lang.reflect.InvocationTargetException; -import java.util.UUID; - -/** - * @author sky - */ -@TListener(condition = "check") -public class EntityUtils implements Listener { - - private static Entity lastSpawnedEntity = null; - - public static Entity getLastSpawnedEntity() { - return lastSpawnedEntity; - } - - public static boolean check() { - return TabooLib.getVerint() > 10700; - } - - /** - * 根据 UUID 获取生物 - * - * @param u - * @return - */ - public static Entity getEntityWithUUID(UUID u) { - return Bukkit.getWorlds().stream().flatMap(w -> w.getLivingEntities().stream()).filter(e -> e.getUniqueId().equals(u)).findFirst().orElse(null); - } - - /** - * 根据 UUID 获取生物(单世界) - * - * @param u - * @param world - * @return - */ - public static Entity getEntityWithUUID(UUID u, World world) { - return world.getLivingEntities().stream().filter(e -> e.getUniqueId().equals(u)).findFirst().orElse(null); - } - - /** - * 设置生物发光(ProcotolLib) - * - * @param player - * @param entity - */ - public static void addGlow(Player player, Entity entity) { - if (Bukkit.getPluginManager().getPlugin("ProtocolLib") == null) { - TLocale.sendToConsole("ENTITY-UTILS.NOTFOUND-PROTOCOLLIB"); - } - PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); - packet.getIntegers().write(0, entity.getEntityId()); - WrappedDataWatcher watcher = new WrappedDataWatcher(); - WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.get(Byte.class); - watcher.setEntity(player); - watcher.setObject(0, serializer, (byte) (0x40)); - packet.getWatchableCollectionModifier().write(0, watcher.getWatchableObjects()); - try { - ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } - } - - /** - * 取消生物发光(ProcotolLib) - * - * @param player - * @param entity - */ - public static void delGlow(Player player, Entity entity) { - if (Bukkit.getPluginManager().getPlugin("ProtocolLib") == null) { - TLocale.sendToConsole("ENTITY-UTILS.NOTFOUND-PROTOCOLLIB"); - } - PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); - packet.getIntegers().write(0, entity.getEntityId()); - WrappedDataWatcher watcher = new WrappedDataWatcher(); - WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.get(Byte.class); - watcher.setEntity(player); - watcher.setObject(0, serializer, (byte) (0x0)); - packet.getWatchableCollectionModifier().write(0, watcher.getWatchableObjects()); - try { - ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } - } - - @EventHandler - public void spawn(EntitySpawnEvent e) { - lastSpawnedEntity = e.getEntity(); - } - -} diff --git a/src/main/java/me/skymc/taboolib/entity/VectorUtils.java b/src/main/java/me/skymc/taboolib/entity/VectorUtils.java deleted file mode 100644 index e174206..0000000 --- a/src/main/java/me/skymc/taboolib/entity/VectorUtils.java +++ /dev/null @@ -1,122 +0,0 @@ -package me.skymc.taboolib.entity; - -import me.skymc.taboolib.other.NumberUtils; -import org.bukkit.Location; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Item; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.util.Vector; - -import java.util.stream.IntStream; - -/** - * @Author sky - * @Since 2018-06-24 16:32 - */ -public class VectorUtils { - - /** - * 物品丢弃 - *

- * 常用参数: - * itemDrop(player, itemStack, 0.2, 0.5) - * - * @param player 玩家 - * @param itemStack 丢弃物品 - * @param bulletSpread 视角偏移 - * @param radius 距离 - * @return {@link Item} - */ - public static Item itemDrop(Player player, ItemStack itemStack, double bulletSpread, double radius) { - Location location = player.getLocation().add(0, 1.5, 0); - Item item = player.getWorld().dropItem(location, itemStack); - - double yaw = Math.toRadians(-player.getLocation().getYaw() - 90.0F); - double pitch = Math.toRadians(-player.getLocation().getPitch()); - double x; - double y; - double z; - - if (bulletSpread > 0) { - double[] spread = {1.0D, 1.0D, 1.0D}; - IntStream.range(0, 3).forEach(t -> spread[t] = ((NumberUtils.getRandom().nextDouble() - NumberUtils.getRandom().nextDouble()) * bulletSpread * 0.1D)); - x = Math.cos(pitch) * Math.cos(yaw) + spread[0]; - y = Math.sin(pitch) + spread[1]; - z = -Math.sin(yaw) * Math.cos(pitch) + spread[2]; - } else { - x = Math.cos(pitch) * Math.cos(yaw); - y = Math.sin(pitch); - z = -Math.sin(yaw) * Math.cos(pitch); - } - - Vector dirVel = new Vector(x, y, z); - item.setVelocity(dirVel.normalize().multiply(radius)); - return item; - } - - /** - * 生物抛射 - *

- * 常用参数: - * entityPush(entity, location, 15) - * - * @param entity 目标生物 - * @param to 目标坐标 - * @param velocity 力量 - */ - public static void entityPush(Entity entity, Location to, double velocity) { - Location from = entity.getLocation(); - - Vector test = to.clone().subtract(from).toVector(); - double elevation = test.getY(); - - Double launchAngle = calculateLaunchAngle(from, to, velocity, elevation, 20.0D); - double distance = Math.sqrt(Math.pow(test.getX(), 2.0D) + Math.pow(test.getZ(), 2.0D)); - if (distance == 0.0D) { - return; - } - if (launchAngle == null) { - launchAngle = Math.atan((40.0D * elevation + Math.pow(velocity, 2.0D)) / (40.0D * elevation + 2.0D * Math.pow(velocity, 2.0D))); - } - double hangTime = calculateHangTime(launchAngle, velocity, elevation, 20.0D); - - test.setY(Math.tan(launchAngle) * distance); - test = normalizeVector(test); - - Vector noise = Vector.getRandom(); - noise = noise.multiply(1 / 10.0D); - test.add(noise); - - velocity = velocity + 1.188D * Math.pow(hangTime, 2.0D) + (NumberUtils.getRandom().nextDouble() - 0.8D) / 2.0D; - test = test.multiply(velocity / 20.0D); - - entity.setVelocity(test); - } - - // ********************************* - // - // Private Methods - // - // ********************************* - - private static double calculateHangTime(double launchAngle, double v, double elev, double g) { - double a = v * Math.sin(launchAngle); - double b = -2.0D * g * elev; - return Math.pow(a, 2.0D) + b < 0.0D ? 0.0D : (a + Math.sqrt(Math.pow(a, 2.0D) + b)) / g; - } - - private static Vector normalizeVector(Vector victor) { - double mag = Math.sqrt(Math.pow(victor.getX(), 2.0D) + Math.pow(victor.getY(), 2.0D) + Math.pow(victor.getZ(), 2.0D)); - return mag != 0.0D ? victor.multiply(1.0D / mag) : victor.multiply(0); - } - - private static Double calculateLaunchAngle(Location from, Location to, double v, double elevation, double g) { - Vector vector = from.clone().subtract(to).toVector(); - double distance = Math.sqrt(Math.pow(vector.getX(), 2.0D) + Math.pow(vector.getZ(), 2.0D)); - double v2 = Math.pow(v, 2.0D); - double v4 = Math.pow(v, 4.0D); - double check = g * (g * Math.pow(distance, 2.0D) + 2.0D * elevation * v2); - return v4 < check ? null : Math.atan((v2 - Math.sqrt(v4 - check)) / (g * distance)); - } -} diff --git a/src/main/java/me/skymc/taboolib/events/DefaultEvent.java b/src/main/java/me/skymc/taboolib/events/DefaultEvent.java deleted file mode 100644 index cc24099..0000000 --- a/src/main/java/me/skymc/taboolib/events/DefaultEvent.java +++ /dev/null @@ -1,28 +0,0 @@ -package me.skymc.taboolib.events; - -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -public class DefaultEvent extends Event { - - private static final HandlerList handlers = new HandlerList(); - private Player player; - - public DefaultEvent(Player player) { - this.player = player; - } - - public Player getPlayer() { - return this.player; - } - - @Override - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } -} diff --git a/src/main/java/me/skymc/taboolib/fileutils/FileUtils.java b/src/main/java/me/skymc/taboolib/fileutils/FileUtils.java index f11b99f..5c3ad6a 100644 --- a/src/main/java/me/skymc/taboolib/fileutils/FileUtils.java +++ b/src/main/java/me/skymc/taboolib/fileutils/FileUtils.java @@ -160,6 +160,20 @@ public class FileUtils { } } + /** + * 释放资源文件 + * + * @param plugin 所属插件 + * @param path 地址 + * @param replace 是否替换 + */ + public static void releaseResource(Plugin plugin, String path, boolean replace) { + File file = new File(plugin.getDataFolder(), path); + if (!file.exists() || replace) { + inputStreamToFile(getResource(plugin, path), file); + } + } + /** * 检测文件并创建 * diff --git a/src/main/java/me/skymc/taboolib/inventory/DropUtils.java b/src/main/java/me/skymc/taboolib/inventory/DropUtils.java deleted file mode 100644 index 0da14da..0000000 --- a/src/main/java/me/skymc/taboolib/inventory/DropUtils.java +++ /dev/null @@ -1,20 +0,0 @@ -package me.skymc.taboolib.inventory; - -import me.skymc.taboolib.entity.VectorUtils; -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 java.util.stream.IntStream; - -@Deprecated -public class DropUtils { - - public static Item drop(Player player, ItemStack itemStack, double bulletSpread, double radius) { - return VectorUtils.itemDrop(player, itemStack, bulletSpread, radius); - } - -} diff --git a/src/main/java/me/skymc/taboolib/inventory/InventoryUtil.java b/src/main/java/me/skymc/taboolib/inventory/InventoryUtil.java deleted file mode 100644 index 67bd4da..0000000 --- a/src/main/java/me/skymc/taboolib/inventory/InventoryUtil.java +++ /dev/null @@ -1,120 +0,0 @@ -package me.skymc.taboolib.inventory; - -import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; - -import java.util.Arrays; -import java.util.LinkedList; - -/** - * @author sky - */ -public class InventoryUtil { - - public final static LinkedList SLOT_OF_CENTENTS = new LinkedList<>(Arrays.asList( - 10, 11, 12, 13, 14, 15, 16, - 19, 20, 21, 22, 23, 24, 25, - 28, 29, 30, 31, 32, 33, 34, - 37, 38, 39, 40, 41, 42, 43)); - - @Deprecated - public static boolean isEmpey(Player p) { - return isEmpty(p, 0); - } - - /** - * 检查背包是否有空位 - * - * @param p 玩家 - * @param i 起始位置 - */ - public static boolean isEmpty(Player p, int i) { - while (i < 35) { - if (p.getInventory().getItem(i) == null) { - return true; - } - i++; - } - return false; - } - - /** - * 检测玩家是否有指定物品 - * - * @param player 玩家 - * @param item 物品 - * @param amount 数量 - * @param remove 是否删除 - */ - public static boolean hasItem(Player player, ItemStack item, int amount, boolean remove) { - int hasAmount = 0; - for (ItemStack _item : player.getInventory()) { - if (item.isSimilar(_item)) { - hasAmount += _item.getAmount(); - } - } - if (hasAmount < amount) { - return false; - } - int requireAmount = amount; - for (int i = 0; i < player.getInventory().getSize() && remove; i++) { - ItemStack _item = player.getInventory().getItem(i); - if (_item != null && _item.isSimilar(item)) { - if (_item.getAmount() < requireAmount) { - player.getInventory().setItem(i, null); - requireAmount -= _item.getAmount(); - } else if (_item.getAmount() == requireAmount) { - player.getInventory().setItem(i, null); - return true; - } else { - _item.setAmount(_item.getAmount() - requireAmount); - return true; - } - } - } - return true; - } - - @Deprecated - public static boolean hasItem(Inventory targetInventory, ItemStack targetItem, Integer amount) { - int inventoryAmount = 0; - for (ItemStack item : targetInventory) { - if (item != null) { - if (item.isSimilar(targetItem)) { - inventoryAmount += item.getAmount(); - } - } - } - return inventoryAmount >= amount; - } - - @Deprecated - public static boolean takeItem2(Inventory inv, ItemStack takeitem, Integer amount) { - for (int i = 0; i < inv.getSize(); ++i) { - if (amount <= 0) { - return true; - } - - ItemStack item = inv.getItem(i); - if (item == null) { - continue; - } - if (!item.isSimilar(takeitem)) { - continue; - } - if (item.getAmount() >= amount) { - if (item.getAmount() - amount == 0) { - inv.setItem(i, null); - } else { - item.setAmount(item.getAmount() - amount); - } - return true; - } else { - amount -= item.getAmount(); - inv.setItem(i, null); - } - } - return false; - } -} diff --git a/src/main/java/me/skymc/taboolib/inventory/builder/ItemBuilder.java b/src/main/java/me/skymc/taboolib/inventory/builder/ItemBuilder.java index 6e3a7d5..b418223 100644 --- a/src/main/java/me/skymc/taboolib/inventory/builder/ItemBuilder.java +++ b/src/main/java/me/skymc/taboolib/inventory/builder/ItemBuilder.java @@ -42,6 +42,11 @@ public class ItemBuilder { itemMeta = itemStack.getItemMeta(); } + public ItemBuilder(ItemStack itemStack) { + this.itemStack = itemStack; + this.itemMeta = itemStack.getItemMeta(); + } + public ItemBuilder(OfflinePlayer player) { this(Material.SKULL_ITEM, 1, 3); this.skullOwner(player.getName()); diff --git a/src/main/java/me/skymc/taboolib/inventory/speciaitem/AbstractSpecialItem.java b/src/main/java/me/skymc/taboolib/inventory/speciaitem/AbstractSpecialItem.java deleted file mode 100644 index b29164a..0000000 --- a/src/main/java/me/skymc/taboolib/inventory/speciaitem/AbstractSpecialItem.java +++ /dev/null @@ -1,46 +0,0 @@ -package me.skymc.taboolib.inventory.speciaitem; - -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.plugin.Plugin; - -/** - * @author sky - * @since 2018年2月17日 下午8:35:42 - */ -public interface AbstractSpecialItem { - - /** - * 当接口被载入 - */ - default void onEnable() {} - - /** - * 当接口被卸载 - */ - default void onDisable() {} - - /** - * 获取识别名称 - * - * @return String - */ - String getName(); - - /** - * 获取载入插件 - * - * @return {@link Plugin} - */ - Plugin getPlugin(); - - /** - * 是否进行点击事件 - * - * @param player 玩家 - * @param currentItem 点击物品 - * @param cursorItem 持有物品 - * @return {@link SpecialItemResult[]} - */ - SpecialItemResult[] isCorrectClick(Player player, ItemStack currentItem, ItemStack cursorItem); -} diff --git a/src/main/java/me/skymc/taboolib/inventory/speciaitem/SpecialItem.java b/src/main/java/me/skymc/taboolib/inventory/speciaitem/SpecialItem.java deleted file mode 100644 index 6a5c9c8..0000000 --- a/src/main/java/me/skymc/taboolib/inventory/speciaitem/SpecialItem.java +++ /dev/null @@ -1,184 +0,0 @@ -package me.skymc.taboolib.inventory.speciaitem; - -import me.skymc.taboolib.Main; -import me.skymc.taboolib.inventory.ItemUtils; -import me.skymc.taboolib.message.MsgUtils; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -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; - -/** - * @author sky - * @since 2018年2月17日 下午8:34:12 - */ -public class SpecialItem implements Listener { - - private static SpecialItem specialItem = null; - - private final List ITEM_DATA = new CopyOnWriteArrayList<>(); - - private boolean isLoaded; - - /** - * 构造方法 - */ - private SpecialItem() { - - } - - /** - * 获取工具对象 - * - * @return {@link SpecialItem} - */ - public static SpecialItem getInst() { - if (specialItem == null) { - synchronized (SpecialItem.class) { - if (specialItem == null) { - specialItem = new SpecialItem(); - // 注册监听器 - Bukkit.getPluginManager().registerEvents(specialItem, Main.getInst()); - } - } - } - return specialItem; - } - - public boolean isLoaded() { - return isLoaded; - } - - /** - * 注册接口 - * - * @param item 接口对象 - */ - public void register(AbstractSpecialItem item) { - if (contains(item.getName())) { - MsgUtils.warn("特殊物品接口已存在, 检查名称 &4" + item.getName() + " &c是否重复"); - } else { - ITEM_DATA.add(item); - if (isLoaded) { - item.onEnable(); - } - } - } - - /** - * 注销接口 - * - * @param name 注册名称 - */ - public void cancel(String name) { - for (AbstractSpecialItem specialitem : ITEM_DATA) { - if (specialitem.getName() != null && specialitem.getName().equals(specialitem.getName())) { - specialitem.onDisable(); - ITEM_DATA.remove(specialitem); - } - } - } - - /** - * 注销接口 - * - * @param plugin 注册插件 - */ - public void cancel(Plugin plugin) { - for (AbstractSpecialItem specialitem : ITEM_DATA) { - if (specialitem.getPlugin() != null && specialitem.getPlugin().equals(plugin)) { - specialitem.onDisable(); - ITEM_DATA.remove(specialitem); - } - } - } - - /** - * 判断名称是否存在 - * - * @param name 注册名称 - * @return boolean - */ - public boolean contains(String name) { - for (AbstractSpecialItem specialitem : ITEM_DATA) { - if (specialitem.getName().equals(name)) { - return true; - } - } - return false; - } - - /** - * 载入所有已注册接口 - */ - public void loadItems() { - ITEM_DATA.forEach(AbstractSpecialItem::onEnable); - isLoaded = true; - } - - /** - * 注销所有已注册接口 - */ - public void unloadItems() { - ITEM_DATA.forEach(AbstractSpecialItem::onDisable); - ITEM_DATA.clear(); - } - - @EventHandler - public void onDisable(PluginDisableEvent e) { - cancel(e.getPlugin()); - } - - @EventHandler(priority = EventPriority.MONITOR) - public void click(InventoryClickEvent e) { - if (e.isCancelled()) { - return; - } - if (ItemUtils.isNull(e.getCurrentItem()) || ItemUtils.isNull(e.getCursor())) { - return; - } - Player player = (Player) e.getWhoClicked(); - for (AbstractSpecialItem specialItem : ITEM_DATA) { - for (SpecialItemResult result : specialItem.isCorrectClick(player, e.getCurrentItem(), e.getCursor())) { - if (result == null) { - break; - } - switch (result) { - case CANCEL: - e.setCancelled(true); - break; - case BREAK: - return; - case REMOVE_ITEM_CURRENT: - e.setCurrentItem(null); - break; - case REMOVE_ITEM_CURSOR: - e.getWhoClicked().setItemOnCursor(null); - break; - case REMOVE_ITEM_CURRENT_AMOUNT_1: - if (e.getCurrentItem().getAmount() > 1) { - e.getCurrentItem().setAmount(e.getCurrentItem().getAmount() - 1); - } else { - e.setCurrentItem(null); - } - break; - case REMOVE_ITEM_CURSOR_AMOUNT_1: - if (e.getCursor().getAmount() > 1) { - e.getCursor().setAmount(e.getCursor().getAmount() - 1); - } else { - e.getWhoClicked().setItemOnCursor(null); - } - break; - default: - } - } - } - } -} diff --git a/src/main/java/me/skymc/taboolib/inventory/speciaitem/SpecialItemResult.java b/src/main/java/me/skymc/taboolib/inventory/speciaitem/SpecialItemResult.java deleted file mode 100644 index 4e06ae2..0000000 --- a/src/main/java/me/skymc/taboolib/inventory/speciaitem/SpecialItemResult.java +++ /dev/null @@ -1,39 +0,0 @@ -package me.skymc.taboolib.inventory.speciaitem; - -/** - * @author sky - * @since 2018年2月17日 下午8:55:36 - */ -public enum SpecialItemResult { - - /** - * 停止接口检测 - */ - BREAK, - - /** - * 取消点击事件 - */ - CANCEL, - - /** - * 移除点击物品 - */ - REMOVE_ITEM_CURRENT, - - /** - * 移除鼠标物品 - */ - REMOVE_ITEM_CURSOR, - - /** - * 移除一个点击物品 - */ - REMOVE_ITEM_CURRENT_AMOUNT_1, - - /** - * 移除一个鼠标物品 - */ - REMOVE_ITEM_CURSOR_AMOUNT_1 - -} diff --git a/src/main/java/me/skymc/taboolib/itagapi/TagPacket.java b/src/main/java/me/skymc/taboolib/itagapi/TagPacket.java index d4d19f8..ca76c61 100644 --- a/src/main/java/me/skymc/taboolib/itagapi/TagPacket.java +++ b/src/main/java/me/skymc/taboolib/itagapi/TagPacket.java @@ -37,7 +37,7 @@ class TagPacket implements Listener { } public static void inst() { - assert !loaded : "TagAPI is already instanced!"; + Preconditions.checkArgument(!loaded, "TagAPI is already instanced!"); loaded = true; Bukkit.getServer().getOnlinePlayers().forEach(player -> entityIdMap.put(player.getEntityId(), player)); @@ -79,7 +79,6 @@ class TagPacket implements Listener { Preconditions.checkState(Main.getInst().isEnabled(), "Not Enabled!"); Preconditions.checkNotNull(player, "player"); Preconditions.checkNotNull(forWhom, "forWhom"); - if (player != forWhom && player.getWorld() == forWhom.getWorld() && forWhom.canSee(player)) { forWhom.hidePlayer(player); Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(Main.getInst(), () -> forWhom.showPlayer(player), 2); @@ -90,13 +89,11 @@ class TagPacket implements Listener { Preconditions.checkState(Main.getInst().isEnabled(), "Not Enabled!"); Preconditions.checkNotNull(player, "player"); Preconditions.checkNotNull(forWhom, "forWhom"); - forWhom.forEach(playerFor -> refreshPlayer(player, playerFor)); } private static WrappedGameProfile getSentName(int sentEntityId, WrappedGameProfile sent, Player destinationPlayer) { - Preconditions.checkState(Bukkit.getServer().isPrimaryThread(), "Can only process events on main thread."); - +// Preconditions.checkState(Bukkit.getServer().isPrimaryThread(), "Can only process events on main thread."); Player namedPlayer = entityIdMap.get(sentEntityId); if (namedPlayer == null) { // They probably were dead when we reloaded diff --git a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTCompound.java b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTCompound.java deleted file mode 100644 index d02e435..0000000 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTCompound.java +++ /dev/null @@ -1,196 +0,0 @@ -package me.skymc.taboolib.itemnbtapi; - -import me.skymc.taboolib.TabooLib; - -import java.util.Set; - -public class NBTCompound { - - private String compundName; - private NBTCompound parent; - - protected NBTCompound(NBTCompound owner, String name) { - this.compundName = name; - this.parent = owner; - } - - public String getName() { - return compundName; - } - - protected Object getCompound() { - return parent.getCompound(); - } - - protected void setCompound(Object compound) { - parent.setCompound(compound); - } - - public NBTCompound getParent() { - return parent; - } - - public void mergeCompound(NBTCompound comp){ - NBTReflectionUtil.addOtherNBTCompound(this, comp); - } - - public void setString(String key, String value) { - NBTReflectionUtil.setString(this, key, value); - } - - public String getString(String key) { - return NBTReflectionUtil.getString(this, key); - } - - protected String getContent(String key) { - return NBTReflectionUtil.getContent(this, key); - } - - public void setInteger(String key, Integer value) { - NBTReflectionUtil.setInt(this, key, value); - } - - public Integer getInteger(String key) { - return NBTReflectionUtil.getInt(this, key); - } - - public void setDouble(String key, Double value) { - NBTReflectionUtil.setDouble(this, key, value); - } - - public Double getDouble(String key) { - return NBTReflectionUtil.getDouble(this, key); - } - - public void setByte(String key, Byte value) { - NBTReflectionUtil.setByte(this, key, value); - } - - public Byte getByte(String key) { - return NBTReflectionUtil.getByte(this, key); - } - - public void setShort(String key, Short value) { - NBTReflectionUtil.setShort(this, key, value); - } - - public Short getShort(String key) { - return NBTReflectionUtil.getShort(this, key); - } - - public void setLong(String key, Long value) { - NBTReflectionUtil.setLong(this, key, value); - } - - public Long getLong(String key) { - return NBTReflectionUtil.getLong(this, key); - } - - public void setFloat(String key, Float value) { - NBTReflectionUtil.setFloat(this, key, value); - } - - public Float getFloat(String key) { - return NBTReflectionUtil.getFloat(this, key); - } - - public void setByteArray(String key, byte[] value) { - NBTReflectionUtil.setByteArray(this, key, value); - } - - public byte[] getByteArray(String key) { - return NBTReflectionUtil.getByteArray(this, key); - } - - public void setIntArray(String key, int[] value) { - NBTReflectionUtil.setIntArray(this, key, value); - } - - public int[] getIntArray(String key) { - return NBTReflectionUtil.getIntArray(this, key); - } - - public void setBoolean(String key, Boolean value) { - NBTReflectionUtil.setBoolean(this, key, value); - } - - protected void set(String key, Object val) { - NBTReflectionUtil.set(this, key, val); - } - - public Boolean getBoolean(String key) { - return NBTReflectionUtil.getBoolean(this, key); - } - - public void setObject(String key, Object value) { - NBTReflectionUtil.setObject(this, key, value); - } - - public T getObject(String key, Class type) { - return NBTReflectionUtil.getObject(this, key, type); - } - - public Boolean hasKey(String key) { - return NBTReflectionUtil.hasKey(this, key); - } - - public void removeKey(String key) { - NBTReflectionUtil.remove(this, key); - } - - public Set getKeys() { - return NBTReflectionUtil.getKeys(this); - } - - public NBTCompound addCompound(String name) { - NBTReflectionUtil.addNBTTagCompound(this, name); - return getCompound(name); - } - - public NBTCompound getCompound(String name) { - NBTCompound next = new NBTCompound(this, name); - if (NBTReflectionUtil.valideCompound(next)) { - return next; - } - return null; - } - - public NBTList getList(String name, NBTType type) { - return NBTReflectionUtil.getList(this, name, type); - } - - public NBTType getType(String name) { - if (TabooLib.getVerint() == 10700) { - return NBTType.NBTTagEnd; - } - return NBTType.valueOf(NBTReflectionUtil.getType(this, name)); - } - - @Override - public String toString() { - StringBuilder result = new StringBuilder(); - for (String key : getKeys()) { - result.append(toString(key)); - } - return result.toString(); - } - - public String toString(String key) { - StringBuilder result = new StringBuilder(); - NBTCompound compound = this; - while (compound.getParent() != null) { - result.append(" "); - compound = compound.getParent(); - } - if (this.getType(key) == NBTType.NBTTagCompound) { - return this.getCompound(key).toString(); - } else { - return result + "-" + key + ": " + getContent(key) + System.lineSeparator(); - } - } - - public String asNBTString(){ - return getCompound() == null ? "" : getCompound().toString(); - } - -} diff --git a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTContainer.java b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTContainer.java deleted file mode 100644 index 119a0d8..0000000 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTContainer.java +++ /dev/null @@ -1,37 +0,0 @@ -package me.skymc.taboolib.itemnbtapi; - -public class NBTContainer extends NBTCompound { - - private Object nbt; - - public NBTContainer() { - super(null, null); - nbt = NBTReflectionUtil.getNewNBTTag(); - } - - protected NBTContainer(Object nbt) { - super(null, null); - this.nbt = nbt; - } - - public NBTContainer(String nbtString) throws IllegalArgumentException { - super(null, null); - try { - nbt = NBTReflectionUtil.parseNBT(nbtString); - } catch (Exception ex) { - ex.printStackTrace(); - throw new IllegalArgumentException("Malformed Json: " + ex.getMessage()); - } - } - - @Override - protected Object getCompound() { - return nbt; - } - - @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 deleted file mode 100644 index 43e4cee..0000000 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTEntity.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.skymc.taboolib.itemnbtapi; - -import org.bukkit.entity.Entity; - -public class NBTEntity extends NBTCompound { - - private final Entity ent; - - public NBTEntity(Entity entity) { - super(null, null); - ent = entity; - } - - @Override - protected Object getCompound() { - return NBTReflectionUtil.getEntityNBTTagCompound(NBTReflectionUtil.getNMSEntity(ent)); - } - - @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 deleted file mode 100644 index 2bc2faa..0000000 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTFile.java +++ /dev/null @@ -1,48 +0,0 @@ -package me.skymc.taboolib.itemnbtapi; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; - -public class NBTFile extends NBTCompound { - - private final File file; - private Object nbt; - - public NBTFile(File file) throws IOException { - super(null, null); - this.file = file; - if (file.exists()) { - FileInputStream inputsteam = new FileInputStream(file); - nbt = NBTReflectionUtil.readNBTFile(inputsteam); - } else { - nbt = NBTReflectionUtil.getNewNBTTag(); - save(); - } - } - - public void save() throws IOException { - if (!file.exists()) { - file.getParentFile().mkdirs(); - file.createNewFile(); - } - FileOutputStream outStream = new FileOutputStream(file); - NBTReflectionUtil.saveNBTFile(nbt, outStream); - } - - public File getFile() { - return file; - } - - @Override - protected Object getCompound() { - return nbt; - } - - @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 deleted file mode 100644 index a2ce653..0000000 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTItem.java +++ /dev/null @@ -1,40 +0,0 @@ -package me.skymc.taboolib.itemnbtapi; - -import org.bukkit.inventory.ItemStack; - -public class NBTItem extends NBTCompound { - - private ItemStack bukkitItem; - - public NBTItem(ItemStack item) { - super(null, null); - bukkitItem = item.clone(); - } - - public static NBTContainer convertItemtoNBT(ItemStack item) { - return NBTReflectionUtil.convertNMSItemtoNBTCompound(NBTReflectionUtil.getNMSItemStack(item)); - } - - public static ItemStack convertNBTtoItem(NBTCompound comp) { - return NBTReflectionUtil.getBukkitItemStack(NBTReflectionUtil.convertNBTCompoundtoNMSItem(comp)); - } - - public ItemStack getItem() { - return bukkitItem; - } - - protected void setItem(ItemStack item) { - bukkitItem = item; - } - - @Override - protected Object getCompound() { - return NBTReflectionUtil.getItemRootNBTTagCompound(NBTReflectionUtil.getNMSItemStack(bukkitItem)); - } - - @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/NBTList.java b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTList.java deleted file mode 100644 index 86f1a8a..0000000 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTList.java +++ /dev/null @@ -1,128 +0,0 @@ -package me.skymc.taboolib.itemnbtapi; - -import me.skymc.taboolib.itemnbtapi.utils.MethodNames; -import me.skymc.taboolib.message.MsgUtils; - -import java.lang.reflect.Method; - -public class NBTList { - - private String listName; - private NBTCompound parent; - private NBTType type; - private Object listObject; - - protected NBTList(NBTCompound owner, String name, NBTType type, Object list) { - parent = owner; - listName = name; - this.type = type; - this.listObject = list; - if (!(type == NBTType.NBTTagString || type == NBTType.NBTTagCompound)) { - System.err.println("List types != String/Compound are currently not implemented!"); - } - } - - protected void save() { - parent.set(listName, listObject); - } - - public NBTListCompound addCompound() { - if (type != NBTType.NBTTagCompound) { - new Throwable("Using Compound method on a non Compound list!").printStackTrace(); - return null; - } - try { - Method method = listObject.getClass().getMethod("add", NBTReflectionUtil.getNBTBase()); - Object compound = NBTReflectionUtil.getNBTTagCompound().newInstance(); - method.invoke(listObject, compound); - return new NBTListCompound(this, compound); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - public NBTListCompound getCompound(int id) { - if (type != NBTType.NBTTagCompound) { - new Throwable("Using Compound method on a non Compound list!").printStackTrace(); - return null; - } - try { - Method method = listObject.getClass().getMethod("get", int.class); - Object compound = method.invoke(listObject, id); - return new NBTListCompound(this, compound); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - public String getString(int i) { - if (type != NBTType.NBTTagString) { - new Throwable("Using String method on a non String list!").printStackTrace(); - return null; - } - try { - Method method = listObject.getClass().getMethod("getString", int.class); - return (String) method.invoke(listObject, i); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - @SuppressWarnings("unchecked") - public void addString(String s) { - if (type != NBTType.NBTTagString) { - new Throwable("Using String method on a non String list!").printStackTrace(); - return; - } - try { - Method method = listObject.getClass().getMethod("add", NBTReflectionUtil.getNBTBase()); - method.invoke(listObject, NBTReflectionUtil.getNBTTagString().getConstructor(String.class).newInstance(s)); - save(); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - @SuppressWarnings("unchecked") - public void setString(int i, String s) { - if (type != NBTType.NBTTagString) { - new Throwable("Using String method on a non String list!").printStackTrace(); - return; - } - try { - Method method = listObject.getClass().getMethod("a", int.class, NBTReflectionUtil.getNBTBase()); - method.invoke(listObject, i, NBTReflectionUtil.getNBTTagString().getConstructor(String.class).newInstance(s)); - save(); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public void remove(int i) { - try { - Method method = listObject.getClass().getMethod(MethodNames.getRemoveMethodName(), int.class); - method.invoke(listObject, i); - save(); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public int size() { - try { - Method method = listObject.getClass().getMethod("size"); - return (int) method.invoke(listObject); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return -1; - } - - public NBTType getType() { - return type; - } - -} diff --git a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTListCompound.java b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTListCompound.java deleted file mode 100644 index 750f968..0000000 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTListCompound.java +++ /dev/null @@ -1,104 +0,0 @@ -package me.skymc.taboolib.itemnbtapi; - -import me.skymc.taboolib.message.MsgUtils; - -import java.util.HashSet; -import java.util.Set; - -public class NBTListCompound { - - private NBTList owner; - private Object compound; - - protected NBTListCompound(NBTList parent, Object obj) { - owner = parent; - compound = obj; - } - - public void setString(String key, String value) { - if (value == null) { - remove(key); - return; - } - try { - compound.getClass().getMethod("setString", String.class, String.class).invoke(compound, key, value); - owner.save(); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public void setInteger(String key, int value) { - try { - compound.getClass().getMethod("setInt", String.class, int.class).invoke(compound, key, value); - owner.save(); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public int getInteger(String value) { - try { - return (int) compound.getClass().getMethod("getInt", String.class).invoke(compound, value); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return 0; - } - - public void setDouble(String key, double value) { - try { - compound.getClass().getMethod("setDouble", String.class, double.class).invoke(compound, key, value); - owner.save(); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public double getDouble(String key) { - try { - return (double) compound.getClass().getMethod("getDouble", String.class).invoke(compound, key); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return 0; - } - - - public String getString(String key) { - try { - return (String) compound.getClass().getMethod("getString", String.class).invoke(compound, key); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return ""; - } - - public boolean hasKey(String key) { - try { - return (boolean) compound.getClass().getMethod("hasKey", String.class).invoke(compound, key); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return false; - } - - @SuppressWarnings("unchecked") - public Set getKeys() { - try { - return (Set) compound.getClass().getMethod("c").invoke(compound); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return new HashSet<>(); - } - - public void remove(String key) { - try { - compound.getClass().getMethod("remove", String.class).invoke(compound, key); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - -} diff --git a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTReflectionUtil.java b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTReflectionUtil.java deleted file mode 100644 index 01fd1ca..0000000 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTReflectionUtil.java +++ /dev/null @@ -1,1018 +0,0 @@ -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; -import java.io.OutputStream; -import java.lang.reflect.Method; -import java.util.Set; -import java.util.Stack; - -// TODO: finish codestyle cleanup -sgdc3 -public class NBTReflectionUtil { - - private static final String version = TabooLib.getVersion(); - - @SuppressWarnings("rawtypes") - private static Class getCraftItemStack() { - - try { - return Class.forName("org.bukkit.craftbukkit." + version + ".inventory.CraftItemStack"); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - return null; - } - } - - @SuppressWarnings("rawtypes") - private static Class getCraftEntity() { - try { - return Class.forName("org.bukkit.craftbukkit." + version + ".entity.CraftEntity"); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - return null; - } - } - - @SuppressWarnings("rawtypes") - protected static Class getNBTBase() { - try { - return Class.forName("net.minecraft.server." + version + ".NBTBase"); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - return null; - } - } - - @SuppressWarnings("rawtypes") - protected static Class getNBTTagString() { - try { - return Class.forName("net.minecraft.server." + version + ".NBTTagString"); - } catch (Exception ex) { - - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - return null; - } - } - - @SuppressWarnings("rawtypes") - protected static Class getNMSItemStack() { - try { - return Class.forName("net.minecraft.server." + version + ".ItemStack"); - } catch (Exception ex) { - - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - return null; - } - } - - @SuppressWarnings("rawtypes") - protected static Class getNBTTagCompound() { - try { - return Class.forName("net.minecraft.server." + version + ".NBTTagCompound"); - } catch (Exception ex) { - - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - return null; - } - } - - @SuppressWarnings("rawtypes") - protected static Class getNBTCompressedStreamTools() { - try { - return Class.forName("net.minecraft.server." + version + ".NBTCompressedStreamTools"); - } catch (Exception ex) { - - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - return null; - } - } - - @SuppressWarnings("rawtypes") - protected static Class getMojangsonParser() { - try { - return Class.forName("net.minecraft.server." + version + ".MojangsonParser"); - } catch (Exception ex) { - - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - return null; - } - } - - @SuppressWarnings("rawtypes") - protected static Class getTileEntity() { - try { - return Class.forName("net.minecraft.server." + version + ".TileEntity"); - } catch (Exception ex) { - - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - return null; - } - } - - @SuppressWarnings("rawtypes") - protected static Class getCraftWorld() { - try { - return Class.forName("org.bukkit.craftbukkit." + version + ".CraftWorld"); - } catch (Exception ex) { - - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - return null; - } - } - - public static Object getNewNBTTag() { - String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; - try { - @SuppressWarnings("rawtypes") - Class c = Class.forName("net.minecraft.server." + version + ".NBTTagCompound"); - return c.newInstance(); - } catch (Exception ex) { - - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - return null; - } - } - - private static Object getNewBlockPosition(int x, int y, int z) { - String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; - try { - @SuppressWarnings("rawtypes") - Class clazz = Class.forName("net.minecraft.server." + version + ".BlockPosition"); - return clazz.getConstructor(int.class, int.class, int.class).newInstance(x, y, z); - } catch (Exception ex) { - - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - return null; - } - } - - public static Object setNBTTag(Object NBTTag, Object NMSItem) { - try { - Method method; - method = NMSItem.getClass().getMethod("setTag", NBTTag.getClass()); - method.invoke(NMSItem, NBTTag); - return NMSItem; - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - @SuppressWarnings("unchecked") - public static Object getNMSItemStack(ItemStack item) { - @SuppressWarnings("rawtypes") - Class clazz = getCraftItemStack(); - Method method; - try { - method = clazz.getMethod("asNMSCopy", ItemStack.class); - return method.invoke(clazz, item); - } catch (Exception e) { - MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage()); - } - return null; - } - - @SuppressWarnings("unchecked") - public static Object getNMSEntity(Entity entity) { - @SuppressWarnings("rawtypes") - Class clazz = getCraftEntity(); - Method method; - try { - method = clazz.getMethod("getHandle"); - return method.invoke(getCraftEntity().cast(entity)); - } catch (Exception e) { - MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage()); - } - return null; - } - - @SuppressWarnings({"unchecked"}) - public static Object parseNBT(String json) { - @SuppressWarnings("rawtypes") - Class cis = getMojangsonParser(); - java.lang.reflect.Method method; - try { - method = cis.getMethod("parse", String.class); - return method.invoke(null, json); - } catch (Exception e) { - MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage()); - } - return null; - } - - @SuppressWarnings({"unchecked"}) - public static Object readNBTFile(FileInputStream stream) { - @SuppressWarnings("rawtypes") - Class clazz = getNBTCompressedStreamTools(); - Method method; - try { - method = clazz.getMethod("a", InputStream.class); - return method.invoke(clazz, stream); - } catch (Exception e) { - MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage()); - } - return null; - } - - @SuppressWarnings({"unchecked"}) - public static Object saveNBTFile(Object nbt, FileOutputStream stream) { - @SuppressWarnings("rawtypes") - Class clazz = getNBTCompressedStreamTools(); - Method method; - try { - method = clazz.getMethod("a", getNBTTagCompound(), OutputStream.class); - return method.invoke(clazz, nbt, stream); - } catch (Exception e) { - MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage()); - } - return null; - } - - @SuppressWarnings({"unchecked"}) - public static ItemStack getBukkitItemStack(Object item) { - @SuppressWarnings("rawtypes") - Class clazz = getCraftItemStack(); - Method method; - try { - method = clazz.getMethod("asCraftMirror", item.getClass()); - Object answer = method.invoke(clazz, item); - return (ItemStack) answer; - } catch (Exception e) { - MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage()); - } - return null; - } - - @SuppressWarnings({"unchecked"}) - public static Object getItemRootNBTTagCompound(Object nmsitem) { - @SuppressWarnings("rawtypes") - Class clazz = nmsitem.getClass(); - Method method; - try { - method = clazz.getMethod("getTag"); - return method.invoke(nmsitem); - } catch (Exception e) { - MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage()); - } - return null; - } - - @SuppressWarnings({"unchecked"}) - public static Object convertNBTCompoundtoNMSItem(NBTCompound nbtcompound) { - @SuppressWarnings("rawtypes") - Class clazz = getNMSItemStack(); - try { - return clazz.getConstructor(getNBTTagCompound()).newInstance(nbtcompound.getCompound()); - } catch (Exception e) { - MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage()); - } - return null; - } - - @SuppressWarnings({"unchecked"}) - public static NBTContainer convertNMSItemtoNBTCompound(Object nmsitem) { - @SuppressWarnings("rawtypes") - Class clazz = nmsitem.getClass(); - Method method; - try { - method = clazz.getMethod("save", getNBTTagCompound()); - Object answer = method.invoke(nmsitem, getNewNBTTag()); - return new NBTContainer(answer); - } catch (Exception e) { - MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage()); - } - return null; - } - - @SuppressWarnings({"unchecked"}) - public static Object getEntityNBTTagCompound(Object nmsitem) { - @SuppressWarnings("rawtypes") - Class c = nmsitem.getClass(); - Method method; - try { - method = c.getMethod(MethodNames.getEntityNbtGetterMethodName(), getNBTTagCompound()); - Object nbt = getNBTTagCompound().newInstance(); - Object answer = method.invoke(nmsitem, nbt); - if (answer == null) { - answer = nbt; - } - return answer; - } catch (Exception e) { - MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage()); - } - return null; - } - - public static Object setEntityNBTTag(Object NBTTag, Object NMSItem) { - try { - Method method; - method = NMSItem.getClass().getMethod(MethodNames.getEntityNbtSetterMethodName(), getNBTTagCompound()); - method.invoke(NMSItem, NBTTag); - return NMSItem; - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - public static Object getTileEntityNBTTagCompound(BlockState tile) { - Method method; - try { - Object pos = getNewBlockPosition(tile.getX(), tile.getY(), tile.getZ()); - Object cworld = getCraftWorld().cast(tile.getWorld()); - Object nmsworld = cworld.getClass().getMethod("getHandle").invoke(cworld); - Object o = nmsworld.getClass().getMethod("getTileEntity", pos.getClass()).invoke(nmsworld, pos); - method = getTileEntity().getMethod(MethodNames.getTileDataMethodName(), getNBTTagCompound()); - Object tag = getNBTTagCompound().newInstance(); - Object answer = method.invoke(o, tag); - if (answer == null) { - answer = tag; - } - return answer; - } catch (Exception e) { - MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage()); - } - return null; - } - - public static void setTileEntityNBTTagCompound(BlockState tile, Object comp) { - Method method; - try { - Object pos = getNewBlockPosition(tile.getX(), tile.getY(), tile.getZ()); - Object cworld = getCraftWorld().cast(tile.getWorld()); - Object nmsworld = cworld.getClass().getMethod("getHandle").invoke(cworld); - Object o = nmsworld.getClass().getMethod("getTileEntity", pos.getClass()).invoke(nmsworld, pos); - method = getTileEntity().getMethod("a", getNBTTagCompound()); - method.invoke(o, comp); - } catch (Exception e) { - MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage()); - } - } - - - @SuppressWarnings("unchecked") - public static Object getSubNBTTagCompound(Object compound, String name) { - @SuppressWarnings("rawtypes") - Class c = compound.getClass(); - Method method; - try { - method = c.getMethod("getCompound", String.class); - return method.invoke(compound, name); - } catch (Exception e) { - MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage()); - } - return null; - } - - public static void addNBTTagCompound(NBTCompound comp, String name) { - if (name == null) { - remove(comp, name); - return; - } - Object nbttag = comp.getCompound(); - if (nbttag == null) { - nbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return; - } - Object workingtag = gettoCompount(nbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("set", String.class, getNBTBase()); - method.invoke(workingtag, name, getNBTTagCompound().newInstance()); - comp.setCompound(nbttag); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public static Boolean valideCompound(NBTCompound comp) { - Object root = comp.getCompound(); - if (root == null) { - root = getNewNBTTag(); - } - return (gettoCompount(root, comp)) != null; - } - - private static Object gettoCompount(Object nbttag, NBTCompound comp) { - Stack structure = new Stack<>(); - while (comp.getParent() != null) { - structure.add(comp.getName()); - comp = comp.getParent(); - } - while (!structure.isEmpty()) { - nbttag = getSubNBTTagCompound(nbttag, structure.pop()); - if (nbttag == null) { - return null; - } - } - return nbttag; - } - - public static void addOtherNBTCompound(NBTCompound comp, NBTCompound nbtcompound) { - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("a", getNBTTagCompound()); - method.invoke(workingtag, nbtcompound.getCompound()); - comp.setCompound(rootnbttag); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public static void setString(NBTCompound comp, String key, String text) { - if (text == null) { - remove(comp, key); - return; - } - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("setString", String.class, String.class); - method.invoke(workingtag, key, text); - comp.setCompound(rootnbttag); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public static String getString(NBTCompound comp, String key) { - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return null; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("getString", String.class); - return (String) method.invoke(workingtag, key); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - public static String getContent(NBTCompound comp, String key) { - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return null; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("get", String.class); - return method.invoke(workingtag, key).toString(); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - public static void setInt(NBTCompound comp, String key, Integer i) { - if (i == null) { - remove(comp, key); - return; - } - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("setInt", String.class, int.class); - method.invoke(workingtag, key, i); - comp.setCompound(rootnbttag); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public static Integer getInt(NBTCompound comp, String key) { - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return null; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("getInt", String.class); - return (Integer) method.invoke(workingtag, key); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - public static void setByteArray(NBTCompound comp, String key, byte[] b) { - if (b == null) { - remove(comp, key); - return; - } - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("setByteArray", String.class, byte[].class); - method.invoke(workingtag, key, b); - comp.setCompound(rootnbttag); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public static byte[] getByteArray(NBTCompound comp, String key) { - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return null; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("getByteArray", String.class); - return (byte[]) method.invoke(workingtag, key); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - public static void setIntArray(NBTCompound comp, String key, int[] i) { - if (i == null) { - remove(comp, key); - return; - } - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("setIntArray", String.class, int[].class); - method.invoke(workingtag, key, i); - comp.setCompound(rootnbttag); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public static int[] getIntArray(NBTCompound comp, String key) { - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return null; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("getIntArray", String.class); - return (int[]) method.invoke(workingtag, key); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - public static void setFloat(NBTCompound comp, String key, Float f) { - if (f == null) { - remove(comp, key); - return; - } - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("setFloat", String.class, float.class); - method.invoke(workingtag, key, f); - comp.setCompound(rootnbttag); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public static Float getFloat(NBTCompound comp, String key) { - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return null; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("getFloat", String.class); - return (Float) method.invoke(workingtag, key); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - public static void setLong(NBTCompound comp, String key, Long f) { - if (f == null) { - remove(comp, key); - return; - } - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("setLong", String.class, long.class); - method.invoke(workingtag, key, f); - comp.setCompound(rootnbttag); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public static Long getLong(NBTCompound comp, String key) { - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return null; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("getLong", String.class); - return (Long) method.invoke(workingtag, key); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - public static void setShort(NBTCompound comp, String key, Short f) { - if (f == null) { - remove(comp, key); - return; - } - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("setShort", String.class, short.class); - method.invoke(workingtag, key, f); - comp.setCompound(rootnbttag); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public static Short getShort(NBTCompound comp, String key) { - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return null; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("getShort", String.class); - return (Short) method.invoke(workingtag, key); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - public static void setByte(NBTCompound comp, String key, Byte f) { - if (f == null) { - remove(comp, key); - return; - } - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("setByte", String.class, byte.class); - method.invoke(workingtag, key, f); - comp.setCompound(rootnbttag); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public static Byte getByte(NBTCompound comp, String key) { - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return null; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("getByte", String.class); - return (Byte) method.invoke(workingtag, key); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - public static void setDouble(NBTCompound comp, String key, Double d) { - if (d == null) { - remove(comp, key); - return; - } - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("setDouble", String.class, double.class); - method.invoke(workingtag, key, d); - comp.setCompound(rootnbttag); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public static Double getDouble(NBTCompound comp, String key) { - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return null; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("getDouble", String.class); - return (Double) method.invoke(workingtag, key); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - public static byte getType(NBTCompound comp, String key) { - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return 0; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod(MethodNames.getTypeMethodName(), String.class); - return (byte) method.invoke(workingtag, key); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return 0; - } - - public static void setBoolean(NBTCompound comp, String key, Boolean d) { - if (d == null) { - remove(comp, key); - return; - } - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("setBoolean", String.class, boolean.class); - method.invoke(workingtag, key, d); - comp.setCompound(rootnbttag); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public static Boolean getBoolean(NBTCompound comp, String key) { - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return null; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("getBoolean", String.class); - return (Boolean) method.invoke(workingtag, key); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - public static void set(NBTCompound comp, String key, Object val) { - if (val == null) { - remove(comp, key); - return; - } - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - new Throwable("InvalideCompound").printStackTrace(); - return; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("set", String.class, getNBTBase()); - method.invoke(workingtag, key, val); - comp.setCompound(rootnbttag); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public static NBTList getList(NBTCompound comp, String key, NBTType type) { - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return null; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("getList", String.class, int.class); - return new NBTList(comp, key, type, method.invoke(workingtag, key, type.getId())); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - public static void setObject(NBTCompound comp, String key, Object value) { - try { - String json = GsonWrapper.getString(value); - setString(comp, key, json); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public static T getObject(NBTCompound comp, String key, Class type) { - String json = getString(comp, key); - if (json == null) { - return null; - } - return GsonWrapper.deserializeJson(json, type); - } - - public static void remove(NBTCompound comp, String key) { - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("remove", String.class); - method.invoke(workingtag, key); - comp.setCompound(rootnbttag); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - } - - public static Boolean hasKey(NBTCompound comp, String key) { - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return null; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("hasKey", String.class); - return (Boolean) method.invoke(workingtag, key); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - - @SuppressWarnings("unchecked") - public static Set getKeys(NBTCompound comp) { - Object rootnbttag = comp.getCompound(); - if (rootnbttag == null) { - rootnbttag = getNewNBTTag(); - } - if (!valideCompound(comp)) { - return null; - } - Object workingtag = gettoCompount(rootnbttag, comp); - Method method; - try { - method = workingtag.getClass().getMethod("c"); - return (Set) method.invoke(workingtag); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - } - return null; - } - -} diff --git a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTTileEntity.java b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTTileEntity.java deleted file mode 100644 index 3b25d70..0000000 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTTileEntity.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.skymc.taboolib.itemnbtapi; - -import org.bukkit.block.BlockState; - -public class NBTTileEntity extends NBTCompound { - - private final BlockState tile; - - public NBTTileEntity(BlockState tile) { - super(null, null); - this.tile = tile; - } - - @Override - protected Object getCompound() { - return NBTReflectionUtil.getTileEntityNBTTagCompound(tile); - } - - @Override - protected void setCompound(Object compound) { - NBTReflectionUtil.setTileEntityNBTTagCompound(tile, compound); - } - -} diff --git a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTType.java b/src/main/java/me/skymc/taboolib/itemnbtapi/NBTType.java deleted file mode 100644 index 1d3d4e2..0000000 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/NBTType.java +++ /dev/null @@ -1,37 +0,0 @@ -package me.skymc.taboolib.itemnbtapi; - -public enum NBTType { - - NBTTagEnd(0), - NBTTagByte(1), - NBTTagShort(2), - NBTTagInt(3), - NBTTagLong(4), - NBTTagFloat(5), - NBTTagDouble(6), - NBTTagByteArray(7), - NBTTagIntArray(11), - NBTTagString(8), - NBTTagList(9), - NBTTagCompound(10); - - NBTType(int i) { - id = i; - } - - private final int id; - - public int getId() { - return id; - } - - public static NBTType valueOf(int id) { - for (NBTType t : values()) { - if (t.getId() == id) { - return t; - } - } - return NBTType.NBTTagEnd; - } - -} diff --git a/src/main/java/me/skymc/taboolib/itemnbtapi/utils/GsonWrapper.java b/src/main/java/me/skymc/taboolib/itemnbtapi/utils/GsonWrapper.java deleted file mode 100644 index 581a6d7..0000000 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/utils/GsonWrapper.java +++ /dev/null @@ -1,28 +0,0 @@ -package me.skymc.taboolib.itemnbtapi.utils; - -import com.google.gson.Gson; -import me.skymc.taboolib.message.MsgUtils; - -public class GsonWrapper { - - private static final Gson gson = new Gson(); - - public static String getString(Object obj) { - return gson.toJson(obj); - } - - public static T deserializeJson(String json, Class type) { - try { - if (json == null) { - return null; - } - - T obj = gson.fromJson(json, type); - return type.cast(obj); - } catch (Exception ex) { - MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage()); - return null; - } - } - -} diff --git a/src/main/java/me/skymc/taboolib/itemnbtapi/utils/MethodNames.java b/src/main/java/me/skymc/taboolib/itemnbtapi/utils/MethodNames.java deleted file mode 100644 index 7c02ebe..0000000 --- a/src/main/java/me/skymc/taboolib/itemnbtapi/utils/MethodNames.java +++ /dev/null @@ -1,35 +0,0 @@ -package me.skymc.taboolib.itemnbtapi.utils; - -import me.skymc.taboolib.TabooLib; - -public class MethodNames { - - public static String getEntityNbtGetterMethodName() { - return "b"; - } - - public static String getEntityNbtSetterMethodName() { - return "a"; - } - - public static String getTileDataMethodName() { - if (TabooLib.getVerint() <= 10800) { - return "b"; - } - return "save"; - } - - public static String getTypeMethodName() { - if (TabooLib.getVerint() <= 10800) { - return "b"; - } - return "d"; - } - - public static String getRemoveMethodName() { - if (TabooLib.getVerint() <= 10800) { - return "a"; - } - return "remove"; - } -} diff --git a/src/main/java/me/skymc/taboolib/json/CDL.java b/src/main/java/me/skymc/taboolib/json/CDL.java deleted file mode 100644 index 22b7947..0000000 --- a/src/main/java/me/skymc/taboolib/json/CDL.java +++ /dev/null @@ -1,155 +0,0 @@ -package me.skymc.taboolib.json; - -public class CDL { - - private static String getValue(JSONTokener x) throws JSONException { - char c; - char q; - StringBuffer sb; - do { - c = x.next(); - } while (c == ' ' || c == '\t'); - switch (c) { - case 0: - return null; - case '"': - case '\'': - q = c; - sb = new StringBuffer(); - for (; ; ) { - c = x.next(); - if (c == q) { - break; - } - if (c == 0 || c == '\n' || c == '\r') { - throw x.syntaxError("Missing close quote '" + q + "'."); - } - sb.append(c); - } - return sb.toString(); - case ',': - x.back(); - return ""; - default: - x.back(); - return x.nextTo(','); - } - } - - public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException { - JSONArray ja = new JSONArray(); - for (; ; ) { - String value = getValue(x); - char c = x.next(); - if (value == null || - (ja.length() == 0 && value.length() == 0 && c != ',')) { - return null; - } - ja.put(value); - while (c != ',') { - if (c != ' ') { - if (c == '\n' || c == '\r' || c == 0) { - return ja; - } - throw x.syntaxError("Bad character '" + c + "' (" + - (int) c + ")."); - } - c = x.next(); - } - } - } - - public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x) - throws JSONException { - JSONArray ja = rowToJSONArray(x); - return ja != null ? ja.toJSONObject(names) : null; - } - - public static String rowToString(JSONArray ja) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < ja.length(); i += 1) { - if (i > 0) { - sb.append(','); - } - Object object = ja.opt(i); - if (object != null) { - String string = object.toString(); - if (string.length() > 0 && (string.indexOf(',') >= 0 || - string.indexOf('\n') >= 0 || string.indexOf('\r') >= 0 || - string.indexOf(0) >= 0 || string.charAt(0) == '"')) { - sb.append('"'); - int length = string.length(); - for (int j = 0; j < length; j += 1) { - char c = string.charAt(j); - if (c >= ' ' && c != '"') { - sb.append(c); - } - } - sb.append('"'); - } else { - sb.append(string); - } - } - } - sb.append('\n'); - return sb.toString(); - } - - public static JSONArray toJSONArray(String string) throws JSONException { - return toJSONArray(new JSONTokener(string)); - } - - public static JSONArray toJSONArray(JSONTokener x) throws JSONException { - return toJSONArray(rowToJSONArray(x), x); - } - - public static JSONArray toJSONArray(JSONArray names, String string) - throws JSONException { - return toJSONArray(names, new JSONTokener(string)); - } - - public static JSONArray toJSONArray(JSONArray names, JSONTokener x) - throws JSONException { - if (names == null || names.length() == 0) { - return null; - } - JSONArray ja = new JSONArray(); - for (; ; ) { - JSONObject jo = rowToJSONObject(names, x); - if (jo == null) { - break; - } - ja.put(jo); - } - if (ja.length() == 0) { - return null; - } - return ja; - } - - public static String toString(JSONArray ja) throws JSONException { - JSONObject jo = ja.optJSONObject(0); - if (jo != null) { - JSONArray names = jo.names(); - if (names != null) { - return rowToString(names) + toString(names, ja); - } - } - return null; - } - - public static String toString(JSONArray names, JSONArray ja) - throws JSONException { - if (names == null || names.length() == 0) { - return null; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < ja.length(); i += 1) { - JSONObject jo = ja.optJSONObject(i); - if (jo != null) { - sb.append(rowToString(jo.toJSONArray(names))); - } - } - return sb.toString(); - } -} diff --git a/src/main/java/me/skymc/taboolib/json/Cookie.java b/src/main/java/me/skymc/taboolib/json/Cookie.java deleted file mode 100644 index d1e014f..0000000 --- a/src/main/java/me/skymc/taboolib/json/Cookie.java +++ /dev/null @@ -1,92 +0,0 @@ -package me.skymc.taboolib.json; - -public class Cookie { - - public static String escape(String string) { - char c; - String s = string.trim(); - StringBuilder sb = new StringBuilder(); - int length = s.length(); - for (int i = 0; i < length; i += 1) { - c = s.charAt(i); - if (c < ' ' || c == '+' || c == '%' || c == '=' || c == ';') { - sb.append('%'); - sb.append(Character.forDigit((char) ((c >>> 4) & 0x0f), 16)); - sb.append(Character.forDigit((char) (c & 0x0f), 16)); - } else { - sb.append(c); - } - } - return sb.toString(); - } - - public static JSONObject toJSONObject(String string) throws JSONException { - String name; - JSONObject jo = new JSONObject(); - Object value; - JSONTokener x = new JSONTokener(string); - jo.put("name", x.nextTo('=')); - x.next('='); - jo.put("value", x.nextTo(';')); - x.next(); - while (x.more()) { - name = unescape(x.nextTo("=;")); - if (x.next() != '=') { - if ("secure".equals(name)) { - value = Boolean.TRUE; - } else { - throw x.syntaxError("Missing '=' in cookie parameter."); - } - } else { - value = unescape(x.nextTo(';')); - x.next(); - } - jo.put(name, value); - } - return jo; - } - - public static String toString(JSONObject jo) throws JSONException { - StringBuilder sb = new StringBuilder(); - - sb.append(escape(jo.getString("name"))); - sb.append("="); - sb.append(escape(jo.getString("value"))); - if (jo.has("expires")) { - sb.append(";expires="); - sb.append(jo.getString("expires")); - } - if (jo.has("domain")) { - sb.append(";domain="); - sb.append(escape(jo.getString("domain"))); - } - if (jo.has("path")) { - sb.append(";path="); - sb.append(escape(jo.getString("path"))); - } - if (jo.optBoolean("secure")) { - sb.append(";secure"); - } - return sb.toString(); - } - - public static String unescape(String string) { - int length = string.length(); - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; ++i) { - char c = string.charAt(i); - if (c == '+') { - c = ' '; - } else if (c == '%' && i + 2 < length) { - int d = JSONTokener.dehexchar(string.charAt(i + 1)); - int e = JSONTokener.dehexchar(string.charAt(i + 2)); - if (d >= 0 && e >= 0) { - c = (char) (d * 16 + e); - i += 2; - } - } - sb.append(c); - } - return sb.toString(); - } -} diff --git a/src/main/java/me/skymc/taboolib/json/CookieList.java b/src/main/java/me/skymc/taboolib/json/CookieList.java deleted file mode 100644 index 439ed6f..0000000 --- a/src/main/java/me/skymc/taboolib/json/CookieList.java +++ /dev/null @@ -1,39 +0,0 @@ -package me.skymc.taboolib.json; - -import java.util.Iterator; - -public class CookieList { - - public static JSONObject toJSONObject(String string) throws JSONException { - JSONObject jo = new JSONObject(); - JSONTokener x = new JSONTokener(string); - while (x.more()) { - String name = Cookie.unescape(x.nextTo('=')); - x.next('='); - jo.put(name, Cookie.unescape(x.nextTo(';'))); - x.next(); - } - return jo; - } - - @SuppressWarnings("rawtypes") - public static String toString(JSONObject jo) throws JSONException { - boolean b = false; - Iterator keys = jo.keys(); - String string; - StringBuilder sb = new StringBuilder(); - while (keys.hasNext()) { - string = keys.next().toString(); - if (!jo.isNull(string)) { - if (b) { - sb.append(';'); - } - sb.append(Cookie.escape(string)); - sb.append("="); - sb.append(Cookie.escape(jo.getString(string))); - b = true; - } - } - return sb.toString(); - } -} diff --git a/src/main/java/me/skymc/taboolib/json/HTTP.java b/src/main/java/me/skymc/taboolib/json/HTTP.java deleted file mode 100644 index b0b4552..0000000 --- a/src/main/java/me/skymc/taboolib/json/HTTP.java +++ /dev/null @@ -1,71 +0,0 @@ -package me.skymc.taboolib.json; - -import java.util.Iterator; - -public class HTTP { - - public static final String CRLF = "\r\n"; - - public static JSONObject toJSONObject(String string) throws JSONException { - JSONObject jo = new JSONObject(); - HTTPTokener x = new HTTPTokener(string); - String token; - - token = x.nextToken(); - if (token.toUpperCase().startsWith("HTTP")) { - jo.put("HTTP-Version", token); - jo.put("Status-Code", x.nextToken()); - jo.put("Reason-Phrase", x.nextTo('\0')); - x.next(); - } else { - jo.put("Method", token); - jo.put("Request-URI", x.nextToken()); - jo.put("HTTP-Version", x.nextToken()); - } - while (x.more()) { - String name = x.nextTo(':'); - x.next(':'); - jo.put(name, x.nextTo('\0')); - x.next(); - } - return jo; - } - - @SuppressWarnings("rawtypes") - public static String toString(JSONObject jo) throws JSONException { - Iterator keys = jo.keys(); - String string; - StringBuilder sb = new StringBuilder(); - if (jo.has("Status-Code") && jo.has("Reason-Phrase")) { - sb.append(jo.getString("HTTP-Version")); - sb.append(' '); - sb.append(jo.getString("Status-Code")); - sb.append(' '); - sb.append(jo.getString("Reason-Phrase")); - } else if (jo.has("Method") && jo.has("Request-URI")) { - sb.append(jo.getString("Method")); - sb.append(' '); - sb.append('"'); - sb.append(jo.getString("Request-URI")); - sb.append('"'); - sb.append(' '); - sb.append(jo.getString("HTTP-Version")); - } else { - throw new JSONException("Not enough material for an HTTP header."); - } - sb.append(CRLF); - while (keys.hasNext()) { - string = keys.next().toString(); - if (!"HTTP-Version".equals(string) && !"Status-Code".equals(string) && - !"Reason-Phrase".equals(string) && !"Method".equals(string) && - !"Request-URI".equals(string) && !jo.isNull(string)) { - sb.append(string); - sb.append(": "); - sb.append(jo.getString(string)); - sb.append(CRLF); - } - } - sb.append(CRLF); - return sb.toString(); - } -} diff --git a/src/main/java/me/skymc/taboolib/json/HTTPTokener.java b/src/main/java/me/skymc/taboolib/json/HTTPTokener.java deleted file mode 100644 index d04b607..0000000 --- a/src/main/java/me/skymc/taboolib/json/HTTPTokener.java +++ /dev/null @@ -1,37 +0,0 @@ -package me.skymc.taboolib.json; - -public class HTTPTokener extends JSONTokener { - - public HTTPTokener(String string) { - super(string); - } - - public String nextToken() throws JSONException { - char c; - char q; - StringBuilder sb = new StringBuilder(); - do { - c = next(); - } while (Character.isWhitespace(c)); - if (c == '"' || c == '\'') { - q = c; - for (; ; ) { - c = next(); - if (c < ' ') { - throw syntaxError("Unterminated string."); - } - if (c == q) { - return sb.toString(); - } - sb.append(c); - } - } - for (; ; ) { - if (c == 0 || Character.isWhitespace(c)) { - return sb.toString(); - } - sb.append(c); - c = next(); - } - } -} diff --git a/src/main/java/me/skymc/taboolib/json/JSONArray.java b/src/main/java/me/skymc/taboolib/json/JSONArray.java deleted file mode 100644 index 6277d3a..0000000 --- a/src/main/java/me/skymc/taboolib/json/JSONArray.java +++ /dev/null @@ -1,413 +0,0 @@ -package me.skymc.taboolib.json; - -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Map; - -@SuppressWarnings({"rawtypes", "unchecked"}) -public class JSONArray { - - private final ArrayList myArrayList; - - public JSONArray() { - this.myArrayList = new ArrayList(); - } - - public JSONArray(JSONTokener x) throws JSONException { - this(); - if (x.nextClean() != '[') { - throw x.syntaxError("A JSONArray text must start with '['"); - } - if (x.nextClean() != ']') { - x.back(); - for (; ; ) { - if (x.nextClean() == ',') { - x.back(); - this.myArrayList.add(JSONObject.NULL); - } else { - x.back(); - this.myArrayList.add(x.nextValue()); - } - switch (x.nextClean()) { - case ';': - case ',': - if (x.nextClean() == ']') { - return; - } - x.back(); - break; - case ']': - return; - default: - throw x.syntaxError("Expected a ',' or ']'"); - } - } - } - } - - public JSONArray(String source) throws JSONException { - this(new JSONTokener(source)); - } - - public JSONArray(Collection collection) { - this.myArrayList = new ArrayList(); - if (collection != null) { - for (Object aCollection : collection) { - this.myArrayList.add(JSONObject.wrap(aCollection)); - } - } - } - - public JSONArray(Object array) throws JSONException { - this(); - if (array.getClass().isArray()) { - int length = Array.getLength(array); - for (int i = 0; i < length; i += 1) { - this.put(JSONObject.wrap(Array.get(array, i))); - } - } else { - throw new JSONException("JSONArray initial value should be a string or collection or array."); - } - } - - public Object get(int index) throws JSONException { - Object object = this.opt(index); - if (object == null) { - throw new JSONException("JSONArray[" + index + "] not found."); - } - return object; - } - - public boolean getBoolean(int index) throws JSONException { - Object object = this.get(index); - if (object.equals(Boolean.FALSE) || - (object instanceof String && - "false".equalsIgnoreCase((String) object))) { - return false; - } else if (object.equals(Boolean.TRUE) || - (object instanceof String && - "true".equalsIgnoreCase((String) object))) { - return true; - } - throw new JSONException("JSONArray[" + index + "] is not a boolean."); - } - - public double getDouble(int index) throws JSONException { - Object object = this.get(index); - try { - return object instanceof Number - ? ((Number) object).doubleValue() - : Double.parseDouble((String) object); - } catch (Exception e) { - throw new JSONException("JSONArray[" + index + - "] is not a number."); - } - } - - public int getInt(int index) throws JSONException { - Object object = this.get(index); - try { - return object instanceof Number - ? ((Number) object).intValue() - : Integer.parseInt((String) object); - } catch (Exception e) { - throw new JSONException("JSONArray[" + index + - "] is not a number."); - } - } - - public JSONArray getJSONArray(int index) throws JSONException { - Object object = this.get(index); - if (object instanceof JSONArray) { - return (JSONArray) object; - } - throw new JSONException("JSONArray[" + index + - "] is not a JSONArray."); - } - - public JSONObject getJSONObject(int index) throws JSONException { - Object object = this.get(index); - if (object instanceof JSONObject) { - return (JSONObject) object; - } - throw new JSONException("JSONArray[" + index + - "] is not a JSONObject."); - } - - public long getLong(int index) throws JSONException { - Object object = this.get(index); - try { - return object instanceof Number - ? ((Number) object).longValue() - : Long.parseLong((String) object); - } catch (Exception e) { - throw new JSONException("JSONArray[" + index + - "] is not a number."); - } - } - - public String getString(int index) throws JSONException { - Object object = this.get(index); - if (object instanceof String) { - return (String) object; - } - throw new JSONException("JSONArray[" + index + "] not a string."); - } - - public boolean isNull(int index) { - return JSONObject.NULL.equals(this.opt(index)); - } - - public String join(String separator) throws JSONException { - int len = this.length(); - StringBuilder sb = new StringBuilder(); - - for (int i = 0; i < len; i += 1) { - if (i > 0) { - sb.append(separator); - } - sb.append(JSONObject.valueToString(this.myArrayList.get(i))); - } - return sb.toString(); - } - - public int length() { - return this.myArrayList.size(); - } - - public Object opt(int index) { - return (index < 0 || index >= this.length()) - ? null - : this.myArrayList.get(index); - } - - public boolean optBoolean(int index) { - return this.optBoolean(index, false); - } - - public boolean optBoolean(int index, boolean defaultValue) { - try { - return this.getBoolean(index); - } catch (Exception e) { - return defaultValue; - } - } - - public double optDouble(int index) { - return this.optDouble(index, Double.NaN); - } - - public double optDouble(int index, double defaultValue) { - try { - return this.getDouble(index); - } catch (Exception e) { - return defaultValue; - } - } - - public int optInt(int index) { - return this.optInt(index, 0); - } - - public int optInt(int index, int defaultValue) { - try { - return this.getInt(index); - } catch (Exception e) { - return defaultValue; - } - } - - public JSONArray optJSONArray(int index) { - Object o = this.opt(index); - return o instanceof JSONArray ? (JSONArray) o : null; - } - - public JSONObject optJSONObject(int index) { - Object o = this.opt(index); - return o instanceof JSONObject ? (JSONObject) o : null; - } - - public long optLong(int index) { - return this.optLong(index, 0); - } - - public long optLong(int index, long defaultValue) { - try { - return this.getLong(index); - } catch (Exception e) { - return defaultValue; - } - } - - public String optString(int index) { - return this.optString(index, ""); - } - - public String optString(int index, String defaultValue) { - Object object = this.opt(index); - return JSONObject.NULL.equals(object) - ? defaultValue : object - .toString(); - } - - public JSONArray put(boolean value) { - this.put(value ? Boolean.TRUE : Boolean.FALSE); - return this; - } - - public JSONArray put(Collection value) { - this.put(new JSONArray(value)); - return this; - } - - public JSONArray put(double value) throws JSONException { - Double d = value; - JSONObject.testValidity(d); - this.put(d); - return this; - } - - public JSONArray put(int value) { - this.put(new Integer(value)); - return this; - } - - public JSONArray put(long value) { - this.put(new Long(value)); - return this; - } - - public JSONArray put(Map value) { - this.put(new JSONObject(value)); - return this; - } - - public JSONArray put(Object value) { - this.myArrayList.add(value); - return this; - } - - public JSONArray put(int index, boolean value) throws JSONException { - this.put(index, value ? Boolean.TRUE : Boolean.FALSE); - return this; - } - - public JSONArray put(int index, Collection value) throws JSONException { - this.put(index, new JSONArray(value)); - return this; - } - - public JSONArray put(int index, double value) throws JSONException { - this.put(index, new Double(value)); - return this; - } - - public JSONArray put(int index, int value) throws JSONException { - this.put(index, new Integer(value)); - return this; - } - - public JSONArray put(int index, long value) throws JSONException { - this.put(index, new Long(value)); - return this; - } - - public JSONArray put(int index, Map value) throws JSONException { - this.put(index, new JSONObject(value)); - return this; - } - - public JSONArray put(int index, Object value) throws JSONException { - JSONObject.testValidity(value); - if (index < 0) { - throw new JSONException("JSONArray[" + index + "] not found."); - } - if (index < this.length()) { - this.myArrayList.set(index, value); - } else { - while (index != this.length()) { - this.put(JSONObject.NULL); - } - this.put(value); - } - return this; - } - - public Object remove(int index) { - Object o = this.opt(index); - this.myArrayList.remove(index); - return o; - } - - public JSONObject toJSONObject(JSONArray names) throws JSONException { - if (names == null || names.length() == 0 || this.length() == 0) { - return null; - } - JSONObject jo = new JSONObject(); - for (int i = 0; i < names.length(); i += 1) { - jo.put(names.getString(i), this.opt(i)); - } - return jo; - } - - @Override - public String toString() { - try { - return '[' + this.join(",") + ']'; - } catch (Exception e) { - return null; - } - } - - public String toString(int indentFactor) throws JSONException { - StringWriter sw = new StringWriter(); - synchronized (sw.getBuffer()) { - return this.write(sw, indentFactor, 0).toString(); - } - } - - public Writer write(Writer writer) throws JSONException { - return this.write(writer, 0, 0); - } - - Writer write(Writer writer, int indentFactor, int indent) - throws JSONException { - try { - boolean commanate = false; - int length = this.length(); - writer.write('['); - - if (length == 1) { - JSONObject.writeValue(writer, this.myArrayList.get(0), - indentFactor, indent); - } else if (length != 0) { - final int newindent = indent + indentFactor; - - for (int i = 0; i < length; i += 1) { - if (commanate) { - writer.write(','); - } - if (indentFactor > 0) { - writer.write('\n'); - } - JSONObject.indent(writer, newindent); - JSONObject.writeValue(writer, this.myArrayList.get(i), - indentFactor, newindent); - commanate = true; - } - if (indentFactor > 0) { - writer.write('\n'); - } - JSONObject.indent(writer, indent); - } - writer.write(']'); - return writer; - } catch (IOException e) { - throw new JSONException(e); - } - } -} diff --git a/src/main/java/me/skymc/taboolib/json/JSONException.java b/src/main/java/me/skymc/taboolib/json/JSONException.java deleted file mode 100644 index 5827e53..0000000 --- a/src/main/java/me/skymc/taboolib/json/JSONException.java +++ /dev/null @@ -1,22 +0,0 @@ -package me.skymc.taboolib.json; - - -public class JSONException extends Exception { - - private static final long serialVersionUID = 0; - private Throwable cause; - - public JSONException(String message) { - super(message); - } - - public JSONException(Throwable cause) { - super(cause.getMessage()); - this.cause = cause; - } - - @Override - public Throwable getCause() { - return this.cause; - } -} diff --git a/src/main/java/me/skymc/taboolib/json/JSONML.java b/src/main/java/me/skymc/taboolib/json/JSONML.java deleted file mode 100644 index 2a3ca14..0000000 --- a/src/main/java/me/skymc/taboolib/json/JSONML.java +++ /dev/null @@ -1,310 +0,0 @@ -package me.skymc.taboolib.json; - -import java.util.Iterator; - -@SuppressWarnings({"rawtypes"}) -public class JSONML { - - private static Object parse(XMLTokener x, boolean arrayForm, JSONArray ja) throws JSONException { - String attribute; - char c; - String closeTag; - int i; - JSONArray newja; - JSONObject newjo; - Object token; - String tagName; - - while (true) { - if (!x.more()) { - throw x.syntaxError("Bad XML"); - } - token = x.nextContent(); - if (token == XML.LT) { - token = x.nextToken(); - if (token instanceof Character) { - if (token == XML.SLASH) { - token = x.nextToken(); - if (!(token instanceof String)) { - throw new JSONException( - "Expected a closing name instead of '" + - token + "'."); - } - if (x.nextToken() != XML.GT) { - throw x.syntaxError("Misshaped close tag"); - } - return token; - } else if (token == XML.BANG) { - c = x.next(); - switch (c) { - case '-': - if (x.next() == '-') { - x.skipPast("-->"); - } else { - x.back(); - } - break; - case '[': - token = x.nextToken(); - if ("CDATA".equals(token) && x.next() == '[') { - if (ja != null) { - ja.put(x.nextCDATA()); - } - } else { - throw x.syntaxError("Expected 'CDATA['"); - } - break; - default: - i = 1; - do { - token = x.nextMeta(); - if (token == null) { - throw x.syntaxError("Missing '>' after ' 0); - break; - } - } else if (token == XML.QUEST) { - x.skipPast("?>"); - } else { - throw x.syntaxError("Misshaped tag"); - } - } else { - if (!(token instanceof String)) { - throw x.syntaxError("Bad tagName '" + token + "'."); - } - tagName = (String) token; - newja = new JSONArray(); - newjo = new JSONObject(); - if (arrayForm) { - newja.put(tagName); - if (ja != null) { - ja.put(newja); - } - } else { - newjo.put("tagName", tagName); - if (ja != null) { - ja.put(newjo); - } - } - token = null; - for (; ; ) { - if (token == null) { - token = x.nextToken(); - } - if (token == null) { - throw x.syntaxError("Misshaped tag"); - } - if (!(token instanceof String)) { - break; - } - attribute = (String) token; - if (!arrayForm && ("tagName".equals(attribute) || "childNode".equals(attribute))) { - throw x.syntaxError("Reserved attribute."); - } - token = x.nextToken(); - if (token == XML.EQ) { - token = x.nextToken(); - if (!(token instanceof String)) { - throw x.syntaxError("Missing value"); - } - newjo.accumulate(attribute, XML.stringToValue((String) token)); - token = null; - } else { - newjo.accumulate(attribute, ""); - } - } - if (arrayForm && newjo.length() > 0) { - newja.put(newjo); - } - if (token == XML.SLASH) { - if (x.nextToken() != XML.GT) { - throw x.syntaxError("Misshaped tag"); - } - if (ja == null) { - if (arrayForm) { - return newja; - } else { - return newjo; - } - } - } else { - if (token != XML.GT) { - throw x.syntaxError("Misshaped tag"); - } - closeTag = (String) parse(x, arrayForm, newja); - if (closeTag != null) { - if (!closeTag.equals(tagName)) { - throw x.syntaxError("Mismatched '" + tagName + - "' and '" + closeTag + "'"); - } - if (!arrayForm && newja.length() > 0) { - newjo.put("childNodes", newja); - } - if (ja == null) { - if (arrayForm) { - return newja; - } else { - return newjo; - } - } - } - } - } - } else { - if (ja != null) { - ja.put(token instanceof String - ? XML.stringToValue((String) token) - : token); - } - } - } - } - - public static JSONArray toJSONArray(String string) throws JSONException { - return toJSONArray(new XMLTokener(string)); - } - - public static JSONArray toJSONArray(XMLTokener x) throws JSONException { - return (JSONArray) parse(x, true, null); - } - - public static JSONObject toJSONObject(XMLTokener x) throws JSONException { - return (JSONObject) parse(x, false, null); - } - - public static JSONObject toJSONObject(String string) throws JSONException { - return toJSONObject(new XMLTokener(string)); - } - - public static String toString(JSONArray ja) throws JSONException { - int i; - JSONObject jo; - String key; - Iterator keys; - int length; - Object object; - StringBuilder sb = new StringBuilder(); - String tagName; - String value; - tagName = ja.getString(0); - XML.noSpace(tagName); - tagName = XML.escape(tagName); - sb.append('<'); - sb.append(tagName); - - object = ja.opt(1); - if (object instanceof JSONObject) { - i = 2; - jo = (JSONObject) object; - keys = jo.keys(); - while (keys.hasNext()) { - key = keys.next().toString(); - XML.noSpace(key); - value = jo.optString(key); - if (value != null) { - sb.append(' '); - sb.append(XML.escape(key)); - sb.append('='); - sb.append('"'); - sb.append(XML.escape(value)); - sb.append('"'); - } - } - } else { - i = 1; - } - length = ja.length(); - if (i >= length) { - sb.append('/'); - sb.append('>'); - } else { - sb.append('>'); - do { - object = ja.get(i); - i += 1; - if (object != null) { - if (object instanceof String) { - sb.append(XML.escape(object.toString())); - } else if (object instanceof JSONObject) { - sb.append(toString((JSONObject) object)); - } else if (object instanceof JSONArray) { - sb.append(toString((JSONArray) object)); - } - } - } while (i < length); - sb.append('<'); - sb.append('/'); - sb.append(tagName); - sb.append('>'); - } - return sb.toString(); - } - - public static String toString(JSONObject jo) throws JSONException { - StringBuilder sb = new StringBuilder(); - int i; - JSONArray ja; - String key; - Iterator keys; - int length; - Object object; - String tagName; - String value; - tagName = jo.optString("tagName"); - if (tagName == null) { - return XML.escape(jo.toString()); - } - XML.noSpace(tagName); - tagName = XML.escape(tagName); - sb.append('<'); - sb.append(tagName); - keys = jo.keys(); - while (keys.hasNext()) { - key = keys.next().toString(); - if (!"tagName".equals(key) && !"childNodes".equals(key)) { - XML.noSpace(key); - value = jo.optString(key); - if (value != null) { - sb.append(' '); - sb.append(XML.escape(key)); - sb.append('='); - sb.append('"'); - sb.append(XML.escape(value)); - sb.append('"'); - } - } - } - ja = jo.optJSONArray("childNodes"); - if (ja == null) { - sb.append('/'); - sb.append('>'); - } else { - sb.append('>'); - length = ja.length(); - for (i = 0; i < length; i += 1) { - object = ja.get(i); - if (object != null) { - if (object instanceof String) { - sb.append(XML.escape(object.toString())); - } else if (object instanceof JSONObject) { - sb.append(toString((JSONObject) object)); - } else if (object instanceof JSONArray) { - sb.append(toString((JSONArray) object)); - } else { - sb.append(object.toString()); - } - } - } - sb.append('<'); - sb.append('/'); - sb.append(tagName); - sb.append('>'); - } - return sb.toString(); - } -} diff --git a/src/main/java/me/skymc/taboolib/json/JSONObject.java b/src/main/java/me/skymc/taboolib/json/JSONObject.java deleted file mode 100644 index f335cf8..0000000 --- a/src/main/java/me/skymc/taboolib/json/JSONObject.java +++ /dev/null @@ -1,872 +0,0 @@ -package me.skymc.taboolib.json; - -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.*; - -@SuppressWarnings({"rawtypes", "unchecked"}) -public class JSONObject { - - private static final class Null { - - @Override - protected final Object clone() { - return this; - } - - @Override - public boolean equals(Object object) { - return object == null || object == this; - } - - @Override - public String toString() { - return "null"; - } - } - - private final Map map; - - public static final Object NULL = new Null(); - - public JSONObject() { - this.map = new HashMap(); - } - - public JSONObject(JSONObject jo, String[] names) { - this(); - for (String name : names) { - try { - this.putOnce(name, jo.opt(name)); - } catch (Exception ignore) { - } - } - } - - public JSONObject(JSONTokener x) throws JSONException { - this(); - char c; - String key; - - if (x.nextClean() != '{') { - throw x.syntaxError("A JSONObject text must begin with '{'"); - } - for (; ; ) { - c = x.nextClean(); - switch (c) { - case 0: - throw x.syntaxError("A JSONObject text must end with '}'"); - case '}': - return; - default: - x.back(); - key = x.nextValue().toString(); - } - c = x.nextClean(); - if (c == '=') { - if (x.next() != '>') { - x.back(); - } - } else if (c != ':') { - throw x.syntaxError("Expected a ':' after a key"); - } - this.putOnce(key, x.nextValue()); - switch (x.nextClean()) { - case ';': - case ',': - if (x.nextClean() == '}') { - return; - } - x.back(); - break; - case '}': - return; - default: - throw x.syntaxError("Expected a ',' or '}'"); - } - } - } - - public JSONObject(Map map) { - this.map = new HashMap(); - if (map != null) { - for (Object o : map.entrySet()) { - Map.Entry e = (Map.Entry) o; - Object value = e.getValue(); - if (value != null) { - this.map.put(e.getKey(), wrap(value)); - } - } - } - } - - public JSONObject(Object bean) { - this(); - this.populateMap(bean); - } - - public JSONObject(Object object, String[] names) { - this(); - Class c = object.getClass(); - for (String name : names) { - try { - this.putOpt(name, c.getField(name).get(object)); - } catch (Exception ignore) { - } - } - } - - public JSONObject(String source) throws JSONException { - this(new JSONTokener(source)); - } - - public JSONObject(String baseName, Locale locale) throws JSONException { - this(); - ResourceBundle bundle = ResourceBundle.getBundle(baseName, locale, - Thread.currentThread().getContextClassLoader()); - Enumeration keys = bundle.getKeys(); - while (keys.hasMoreElements()) { - Object key = keys.nextElement(); - if (key instanceof String) { - String[] path = ((String) key).split("\\."); - int last = path.length - 1; - JSONObject target = this; - for (int i = 0; i < last; i += 1) { - String segment = path[i]; - JSONObject nextTarget = target.optJSONObject(segment); - if (nextTarget == null) { - nextTarget = new JSONObject(); - target.put(segment, nextTarget); - } - target = nextTarget; - } - target.put(path[last], bundle.getString((String) key)); - } - } - } - - public void accumulate(String key, Object value) throws JSONException { - testValidity(value); - Object object = this.opt(key); - if (object == null) { - this.put(key, value instanceof JSONArray - ? new JSONArray().put(value) - : value); - } else if (object instanceof JSONArray) { - ((JSONArray) object).put(value); - } else { - this.put(key, new JSONArray().put(object).put(value)); - } - } - - public JSONObject append(String key, Object value) throws JSONException { - testValidity(value); - Object object = this.opt(key); - if (object == null) { - this.put(key, new JSONArray().put(value)); - } else if (object instanceof JSONArray) { - this.put(key, ((JSONArray) object).put(value)); - } else { - throw new JSONException("JSONObject[" + key + - "] is not a JSONArray."); - } - return this; - } - - public static String doubleToString(double d) { - if (Double.isInfinite(d) || Double.isNaN(d)) { - return "null"; - } - String string = Double.toString(d); - if (string.indexOf('.') > 0 && string.indexOf('e') < 0 && - string.indexOf('E') < 0) { - while (string.endsWith("0")) { - string = string.substring(0, string.length() - 1); - } - if (string.endsWith(".")) { - string = string.substring(0, string.length() - 1); - } - } - return string; - } - - public Object get(String key) throws JSONException { - if (key == null) { - throw new JSONException("Null key."); - } - Object object = this.opt(key); - if (object == null) { - throw new JSONException("JSONObject[" + quote(key) + - "] not found."); - } - return object; - } - - public boolean getBoolean(String key) throws JSONException { - Object object = this.get(key); - if (object.equals(Boolean.FALSE) || - (object instanceof String && - "false".equalsIgnoreCase((String) object))) { - return false; - } else if (object.equals(Boolean.TRUE) || - (object instanceof String && - "true".equalsIgnoreCase((String) object))) { - return true; - } - throw new JSONException("JSONObject[" + quote(key) + - "] is not a Boolean."); - } - - public double getDouble(String key) throws JSONException { - Object object = this.get(key); - try { - return object instanceof Number - ? ((Number) object).doubleValue() - : Double.parseDouble((String) object); - } catch (Exception e) { - throw new JSONException("JSONObject[" + quote(key) + - "] is not a number."); - } - } - - public int getInt(String key) throws JSONException { - Object object = this.get(key); - try { - return object instanceof Number - ? ((Number) object).intValue() - : Integer.parseInt((String) object); - } catch (Exception e) { - throw new JSONException("JSONObject[" + quote(key) + - "] is not an int."); - } - } - - public JSONArray getJSONArray(String key) throws JSONException { - Object object = this.get(key); - if (object instanceof JSONArray) { - return (JSONArray) object; - } - throw new JSONException("JSONObject[" + quote(key) + - "] is not a JSONArray."); - } - - public JSONObject getJSONObject(String key) throws JSONException { - Object object = this.get(key); - if (object instanceof JSONObject) { - return (JSONObject) object; - } - throw new JSONException("JSONObject[" + quote(key) + - "] is not a JSONObject."); - } - - public long getLong(String key) throws JSONException { - Object object = this.get(key); - try { - return object instanceof Number - ? ((Number) object).longValue() - : Long.parseLong((String) object); - } catch (Exception e) { - throw new JSONException("JSONObject[" + quote(key) + - "] is not a long."); - } - } - - public static String[] getNames(JSONObject jo) { - int length = jo.length(); - if (length == 0) { - return null; - } - Iterator iterator = jo.keys(); - String[] names = new String[length]; - int i = 0; - while (iterator.hasNext()) { - names[i] = (String) iterator.next(); - i += 1; - } - return names; - } - - public static String[] getNames(Object object) { - if (object == null) { - return null; - } - Class klass = object.getClass(); - Field[] fields = klass.getFields(); - int length = fields.length; - if (length == 0) { - return null; - } - String[] names = new String[length]; - for (int i = 0; i < length; i += 1) { - names[i] = fields[i].getName(); - } - return names; - } - - public String getString(String key) throws JSONException { - Object object = this.get(key); - if (object instanceof String) { - return (String) object; - } - throw new JSONException("JSONObject[" + quote(key) + - "] not a string."); - } - - public boolean has(String key) { - return this.map.containsKey(key); - } - - public static Object stringToValue(String string) { - Double d; - if ("".equals(string)) { - return string; - } - if ("true".equalsIgnoreCase(string)) { - return Boolean.TRUE; - } - if ("false".equalsIgnoreCase(string)) { - return Boolean.FALSE; - } - if ("null".equalsIgnoreCase(string)) { - return JSONObject.NULL; - } - char b = string.charAt(0); - if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') { - try { - if (string.indexOf('.') > -1 || - string.indexOf('e') > -1 || string.indexOf('E') > -1) { - d = Double.valueOf(string); - if (!d.isInfinite() && !d.isNaN()) { - return d; - } - } else { - Long myLong = new Long(string); - if (myLong == myLong.intValue()) { - return myLong.intValue(); - } else { - return myLong; - } - } - } catch (Exception ignore) { - } - } - return string; - } - - public boolean isNull(String key) { - return JSONObject.NULL.equals(this.opt(key)); - } - - public Iterator keys() { - return this.map.keySet().iterator(); - } - - public int length() { - return this.map.size(); - } - - public JSONArray names() { - JSONArray ja = new JSONArray(); - Iterator keys = this.keys(); - while (keys.hasNext()) { - ja.put(keys.next()); - } - return ja.length() == 0 ? null : ja; - } - - public static String numberToString(Number number) - throws JSONException { - if (number == null) { - throw new JSONException("Null pointer"); - } - testValidity(number); - String string = number.toString(); - if (string.indexOf('.') > 0 && string.indexOf('e') < 0 && - string.indexOf('E') < 0) { - while (string.endsWith("0")) { - string = string.substring(0, string.length() - 1); - } - if (string.endsWith(".")) { - string = string.substring(0, string.length() - 1); - } - } - return string; - } - - public Object opt(String key) { - return key == null ? null : this.map.get(key); - } - - public boolean optBoolean(String key) { - return this.optBoolean(key, false); - } - - public boolean optBoolean(String key, boolean defaultValue) { - try { - return this.getBoolean(key); - } catch (Exception e) { - return defaultValue; - } - } - - public double optDouble(String key) { - return this.optDouble(key, Double.NaN); - } - - public double optDouble(String key, double defaultValue) { - try { - return this.getDouble(key); - } catch (Exception e) { - return defaultValue; - } - } - - public int optInt(String key) { - return this.optInt(key, 0); - } - - public int optInt(String key, int defaultValue) { - try { - return this.getInt(key); - } catch (Exception e) { - return defaultValue; - } - } - - public JSONArray optJSONArray(String key) { - Object o = this.opt(key); - return o instanceof JSONArray ? (JSONArray) o : null; - } - - public JSONObject optJSONObject(String key) { - Object object = this.opt(key); - return object instanceof JSONObject ? (JSONObject) object : null; - } - - public long optLong(String key) { - return this.optLong(key, 0); - } - - public long optLong(String key, long defaultValue) { - try { - return this.getLong(key); - } catch (Exception e) { - return defaultValue; - } - } - - public String optString(String key) { - return this.optString(key, ""); - } - - public String optString(String key, String defaultValue) { - Object object = this.opt(key); - return NULL.equals(object) ? defaultValue : object.toString(); - } - - public static String valueToString(Object value) throws JSONException { - if (value == null || value == null) { - return "null"; - } - if (value instanceof JSONString) { - Object object; - try { - object = ((JSONString) value).toJSONString(); - } catch (Exception e) { - throw new JSONException(e); - } - if (object != null) { - return (String) object; - } - throw new JSONException("Bad value from toJSONString: " + object); - } - if (value instanceof Number) { - return numberToString((Number) value); - } - if (value instanceof Boolean || value instanceof JSONObject || - value instanceof JSONArray) { - return value.toString(); - } - if (value instanceof Map) { - return new JSONObject((Map) value).toString(); - } - if (value instanceof Collection) { - return new JSONArray((Collection) value).toString(); - } - if (value.getClass().isArray()) { - return new JSONArray(value).toString(); - } - return quote(value.toString()); - } - - public JSONObject put(String key, boolean value) throws JSONException { - this.put(key, value ? Boolean.TRUE : Boolean.FALSE); - return this; - } - - public JSONObject put(String key, Collection value) throws JSONException { - this.put(key, new JSONArray(value)); - return this; - } - - public JSONObject put(String key, double value) throws JSONException { - this.put(key, new Double(value)); - return this; - } - - public JSONObject put(String key, int value) throws JSONException { - this.put(key, new Integer(value)); - return this; - } - - public JSONObject put(String key, long value) throws JSONException { - this.put(key, new Long(value)); - return this; - } - - public JSONObject put(String key, Map value) throws JSONException { - this.put(key, new JSONObject(value)); - return this; - } - - public JSONObject put(String key, Object value) throws JSONException { - if (key == null) { - throw new JSONException("Null key."); - } - if (value != null) { - testValidity(value); - this.map.put(key, value); - } else { - this.remove(key); - } - return this; - } - - public JSONObject putOnce(String key, Object value) throws JSONException { - if (key != null && value != null) { - if (this.opt(key) != null) { - throw new JSONException("Duplicate key \"" + key + "\""); - } - this.put(key, value); - } - return this; - } - - public JSONObject putOpt(String key, Object value) throws JSONException { - if (key != null && value != null) { - this.put(key, value); - } - return this; - } - - public static String quote(String string) { - StringWriter sw = new StringWriter(); - synchronized (sw.getBuffer()) { - try { - return quote(string, sw).toString(); - } catch (IOException ignored) { - return ""; - } - } - } - - public static Writer quote(String string, Writer w) throws IOException { - if (string == null || string.length() == 0) { - w.write("\"\""); - return w; - } - - char b; - char c = 0; - String hhhh; - int i; - int len = string.length(); - - w.write('"'); - for (i = 0; i < len; i += 1) { - b = c; - c = string.charAt(i); - switch (c) { - case '\\': - case '"': - w.write('\\'); - w.write(c); - break; - case '/': - if (b == '<') { - w.write('\\'); - } - w.write(c); - break; - case '\b': - w.write("\\b"); - break; - case '\t': - w.write("\\t"); - break; - case '\n': - w.write("\\n"); - break; - case '\f': - w.write("\\f"); - break; - case '\r': - w.write("\\r"); - break; - default: - if (c < ' ' || (c >= '\u0080' && c < '\u00a0') - || (c >= '\u2000' && c < '\u2100')) { - hhhh = "000" + Integer.toHexString(c); - w.write("\\u" + hhhh.substring(hhhh.length() - 4)); - } else { - w.write(c); - } - } - } - w.write('"'); - return w; - } - - public Object remove(String key) { - return this.map.remove(key); - } - - static void writeValue(Writer writer, Object value, int indentFactor, int indent) throws JSONException, IOException { - if (value == null) { - writer.write("null"); - } else if (value instanceof JSONObject) { - ((JSONObject) value).write(writer, indentFactor, indent); - } else if (value instanceof JSONArray) { - ((JSONArray) value).write(writer, indentFactor, indent); - } else if (value instanceof Map) { - new JSONObject((Map) value).write(writer, indentFactor, indent); - } else if (value instanceof Collection) { - new JSONArray((Collection) value).write(writer, indentFactor, - indent); - } else if (value.getClass().isArray()) { - new JSONArray(value).write(writer, indentFactor, indent); - } else if (value instanceof Number) { - writer.write(numberToString((Number) value)); - } else if (value instanceof Boolean) { - writer.write(value.toString()); - } else if (value instanceof JSONString) { - Object o; - try { - o = ((JSONString) value).toJSONString(); - } catch (Exception e) { - throw new JSONException(e); - } - writer.write(o != null ? o.toString() : quote(value.toString())); - } else { - quote(value.toString(), writer); - } - } - - public static void testValidity(Object o) throws JSONException { - if (o != null) { - if (o instanceof Double) { - if (((Double) o).isInfinite() || ((Double) o).isNaN()) { - throw new JSONException( - "JSON does not allow non-finite numbers."); - } - } else if (o instanceof Float) { - if (((Float) o).isInfinite() || ((Float) o).isNaN()) { - throw new JSONException( - "JSON does not allow non-finite numbers."); - } - } - } - } - - public JSONArray toJSONArray(JSONArray names) throws JSONException { - if (names == null || names.length() == 0) { - return null; - } - JSONArray ja = new JSONArray(); - for (int i = 0; i < names.length(); i += 1) { - ja.put(this.opt(names.getString(i))); - } - return ja; - } - - @Override - public String toString() { - try { - return this.toString(0); - } catch (Exception e) { - return null; - } - } - - public String toString(int indentFactor) throws JSONException { - StringWriter w = new StringWriter(); - synchronized (w.getBuffer()) { - return this.write(w, indentFactor, 0).toString(); - } - } - - static void indent(Writer writer, int indent) throws IOException { - for (int i = 0; i < indent; i += 1) { - writer.write(' '); - } - } - - public static Object wrap(Object object) { - try { - if (object == null) { - return NULL; - } - if (object instanceof JSONObject || object instanceof JSONArray || - NULL.equals(object) || object instanceof JSONString || - object instanceof Byte || object instanceof Character || - object instanceof Short || object instanceof Integer || - object instanceof Long || object instanceof Boolean || - object instanceof Float || object instanceof Double || - object instanceof String || object instanceof Enum) { - return object; - } - - if (object instanceof Collection) { - return new JSONArray((Collection) object); - } - if (object.getClass().isArray()) { - return new JSONArray(object); - } - if (object instanceof Map) { - return new JSONObject((Map) object); - } - Package objectPackage = object.getClass().getPackage(); - String objectPackageName = objectPackage != null - ? objectPackage.getName() - : ""; - if ( - objectPackageName.startsWith("java.") || - objectPackageName.startsWith("javax.") || - object.getClass().getClassLoader() == null - ) { - return object.toString(); - } - return new JSONObject(object); - } catch (Exception exception) { - return null; - } - } - - public Writer write(Writer writer) throws JSONException { - return this.write(writer, 0, 0); - } - - public JSONObject increment(String key) throws JSONException { - Object value = this.opt(key); - if (value == null) { - this.put(key, 1); - } else if (value instanceof Integer) { - this.put(key, (Integer) value + 1); - } else if (value instanceof Long) { - this.put(key, (Long) value + 1); - } else if (value instanceof Double) { - this.put(key, (Double) value + 1); - } else if (value instanceof Float) { - this.put(key, (Float) value + 1); - } else { - throw new JSONException("Unable to increment [" + quote(key) + "]."); - } - return this; - } - - private void populateMap(Object bean) { - Class klass = bean.getClass(); - boolean includeSuperClass = klass.getClassLoader() != null; - - Method[] methods = includeSuperClass - ? klass.getMethods() - : klass.getDeclaredMethods(); - for (Method method1 : methods) { - try { - Method method = method1; - if (Modifier.isPublic(method.getModifiers())) { - String name = method.getName(); - String key = ""; - if (name.startsWith("get")) { - if ("getClass".equals(name) || - "getDeclaringClass".equals(name)) { - key = ""; - } else { - key = name.substring(3); - } - } else if (name.startsWith("is")) { - key = name.substring(2); - } - if (key.length() > 0 && - Character.isUpperCase(key.charAt(0)) && - method.getParameterTypes().length == 0) { - if (key.length() == 1) { - key = key.toLowerCase(); - } else if (!Character.isUpperCase(key.charAt(1))) { - key = key.substring(0, 1).toLowerCase() + - key.substring(1); - } - - Object result = method.invoke(bean, (Object[]) null); - if (result != null) { - this.map.put(key, wrap(result)); - } - } - } - } catch (Exception ignore) { - } - } - } - - Writer write(Writer writer, int indentFactor, int indent) - throws JSONException { - try { - boolean commanate = false; - final int length = this.length(); - Iterator keys = this.keys(); - writer.write('{'); - - if (length == 1) { - Object key = keys.next(); - writer.write(quote(key.toString())); - writer.write(':'); - if (indentFactor > 0) { - writer.write(' '); - } - writeValue(writer, this.map.get(key), indentFactor, indent); - } else if (length != 0) { - final int newindent = indent + indentFactor; - while (keys.hasNext()) { - Object key = keys.next(); - if (commanate) { - writer.write(','); - } - if (indentFactor > 0) { - writer.write('\n'); - } - indent(writer, newindent); - writer.write(quote(key.toString())); - writer.write(':'); - if (indentFactor > 0) { - writer.write(' '); - } - writeValue(writer, this.map.get(key), indentFactor, - newindent); - commanate = true; - } - if (indentFactor > 0) { - writer.write('\n'); - } - indent(writer, indent); - } - writer.write('}'); - return writer; - } catch (IOException exception) { - throw new JSONException(exception); - } - } -} diff --git a/src/main/java/me/skymc/taboolib/json/JSONReader.java b/src/main/java/me/skymc/taboolib/json/JSONReader.java deleted file mode 100644 index 393cdd0..0000000 --- a/src/main/java/me/skymc/taboolib/json/JSONReader.java +++ /dev/null @@ -1,50 +0,0 @@ -package me.skymc.taboolib.json; - -import java.util.regex.Pattern; - -/** - * @Author sky - * @Since 2018-07-01 11:10 - */ -public class JSONReader { - - private static Pattern pattern = Pattern.compile("[\t\n]"); - - public static String formatJson(String content) { - StringBuilder builder = new StringBuilder(); - int index = 0; - int count = 0; - while (index < content.length()) { - char ch = content.charAt(index); - if (ch == '{' || ch == '[') { - builder.append(ch); - builder.append('\n'); - count++; - for (int i = 0; i < count; i++) { - builder.append('\t'); - } - } else if (ch == '}' || ch == ']') { - builder.append('\n'); - count--; - for (int i = 0; i < count; i++) { - builder.append('\t'); - } - builder.append(ch); - } else if (ch == ',') { - builder.append(ch); - builder.append('\n'); - for (int i = 0; i < count; i++) { - builder.append('\t'); - } - } else { - builder.append(ch); - } - index++; - } - return compactJson(builder.toString()); - } - - private static String compactJson(String content) { - return pattern.matcher(content).replaceAll("").trim(); - } -} diff --git a/src/main/java/me/skymc/taboolib/json/JSONString.java b/src/main/java/me/skymc/taboolib/json/JSONString.java deleted file mode 100644 index c7842f6..0000000 --- a/src/main/java/me/skymc/taboolib/json/JSONString.java +++ /dev/null @@ -1,6 +0,0 @@ -package me.skymc.taboolib.json; - -public interface JSONString { - - String toJSONString(); -} diff --git a/src/main/java/me/skymc/taboolib/json/JSONStringer.java b/src/main/java/me/skymc/taboolib/json/JSONStringer.java deleted file mode 100644 index dddfca5..0000000 --- a/src/main/java/me/skymc/taboolib/json/JSONStringer.java +++ /dev/null @@ -1,15 +0,0 @@ -package me.skymc.taboolib.json; - -import java.io.StringWriter; - -public class JSONStringer extends JSONWriter { - - public JSONStringer() { - super(new StringWriter()); - } - - @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 deleted file mode 100644 index d659a66..0000000 --- a/src/main/java/me/skymc/taboolib/json/JSONTokener.java +++ /dev/null @@ -1,283 +0,0 @@ -package me.skymc.taboolib.json; - - -import java.io.*; - -public class JSONTokener { - - private long character; - private boolean eof; - private long index; - private long line; - private char previous; - private Reader reader; - private boolean usePrevious; - - public JSONTokener(Reader reader) { - this.reader = reader.markSupported() - ? reader - : new BufferedReader(reader); - this.eof = false; - this.usePrevious = false; - this.previous = 0; - this.index = 0; - this.character = 1; - this.line = 1; - } - - public JSONTokener(InputStream inputStream) { - this(new InputStreamReader(inputStream)); - } - - public JSONTokener(String s) { - this(new StringReader(s)); - } - - public void back() throws JSONException { - if (this.usePrevious || this.index <= 0) { - throw new JSONException("Stepping back two steps is not supported"); - } - this.index -= 1; - this.character -= 1; - this.usePrevious = true; - this.eof = false; - } - - public static int dehexchar(char c) { - if (c >= '0' && c <= '9') { - return c - '0'; - } - if (c >= 'A' && c <= 'F') { - return c - ('A' - 10); - } - if (c >= 'a' && c <= 'f') { - return c - ('a' - 10); - } - return -1; - } - - public boolean end() { - return this.eof && !this.usePrevious; - } - - public boolean more() throws JSONException { - this.next(); - if (this.end()) { - return false; - } - this.back(); - return true; - } - - public char next() throws JSONException { - int c; - if (this.usePrevious) { - this.usePrevious = false; - c = this.previous; - } else { - try { - c = this.reader.read(); - } catch (IOException exception) { - throw new JSONException(exception); - } - - if (c <= 0) { - this.eof = true; - c = 0; - } - } - this.index += 1; - if (this.previous == '\r') { - this.line += 1; - this.character = c == '\n' ? 0 : 1; - } else if (c == '\n') { - this.line += 1; - this.character = 0; - } else { - this.character += 1; - } - this.previous = (char) c; - return this.previous; - } - - public char next(char c) throws JSONException { - char n = this.next(); - if (n != c) { - throw this.syntaxError("Expected '" + c + "' and instead saw '" + - n + "'"); - } - return n; - } - - public String next(int n) throws JSONException { - if (n == 0) { - return ""; - } - - char[] chars = new char[n]; - int pos = 0; - - while (pos < n) { - chars[pos] = this.next(); - if (this.end()) { - throw this.syntaxError("Substring bounds error"); - } - pos += 1; - } - return new String(chars); - } - - public char nextClean() throws JSONException { - for (; ; ) { - char c = this.next(); - if (c == 0 || c > ' ') { - return c; - } - } - } - - public String nextString(char quote) throws JSONException { - char c; - StringBuilder sb = new StringBuilder(); - for (; ; ) { - c = this.next(); - switch (c) { - case 0: - case '\n': - case '\r': - throw this.syntaxError("Unterminated string"); - case '\\': - c = this.next(); - switch (c) { - case 'b': - sb.append('\b'); - break; - case 't': - sb.append('\t'); - break; - case 'n': - sb.append('\n'); - break; - case 'f': - sb.append('\f'); - break; - case 'r': - sb.append('\r'); - break; - case 'u': - sb.append((char) Integer.parseInt(this.next(4), 16)); - break; - case '"': - case '\'': - case '\\': - case '/': - sb.append(c); - break; - default: - throw this.syntaxError("Illegal escape."); - } - break; - default: - if (c == quote) { - return sb.toString(); - } - sb.append(c); - } - } - } - - public String nextTo(char delimiter) throws JSONException { - StringBuilder sb = new StringBuilder(); - for (; ; ) { - char c = this.next(); - if (c == delimiter || c == 0 || c == '\n' || c == '\r') { - if (c != 0) { - this.back(); - } - return sb.toString().trim(); - } - sb.append(c); - } - } - - public String nextTo(String delimiters) throws JSONException { - char c; - StringBuilder sb = new StringBuilder(); - for (; ; ) { - c = this.next(); - if (delimiters.indexOf(c) >= 0 || c == 0 || - c == '\n' || c == '\r') { - if (c != 0) { - this.back(); - } - return sb.toString().trim(); - } - sb.append(c); - } - } - - public Object nextValue() throws JSONException { - char c = this.nextClean(); - String string; - - switch (c) { - case '"': - case '\'': - return this.nextString(c); - case '{': - this.back(); - return new JSONObject(this); - case '[': - this.back(); - return new JSONArray(this); - } - - StringBuilder sb = new StringBuilder(); - while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) { - sb.append(c); - c = this.next(); - } - this.back(); - - string = sb.toString().trim(); - if ("".equals(string)) { - throw this.syntaxError("Missing value"); - } - return JSONObject.stringToValue(string); - } - - public char skipTo(char to) throws JSONException { - char c; - try { - long startIndex = this.index; - long startCharacter = this.character; - long startLine = this.line; - this.reader.mark(1000000); - do { - c = this.next(); - if (c == 0) { - this.reader.reset(); - this.index = startIndex; - this.character = startCharacter; - this.line = startLine; - return c; - } - } while (c != to); - } catch (IOException exc) { - throw new JSONException(exc); - } - - this.back(); - return c; - } - - public JSONException syntaxError(String message) { - return new JSONException(message + this.toString()); - } - - @Override - public String toString() { - return " at " + this.index + " [character " + this.character + " line " + - this.line + "]"; - } -} diff --git a/src/main/java/me/skymc/taboolib/json/JSONWriter.java b/src/main/java/me/skymc/taboolib/json/JSONWriter.java deleted file mode 100644 index 399056d..0000000 --- a/src/main/java/me/skymc/taboolib/json/JSONWriter.java +++ /dev/null @@ -1,160 +0,0 @@ -package me.skymc.taboolib.json; - -import java.io.IOException; -import java.io.Writer; - -public class JSONWriter { - - private static final int maxdepth = 200; - - private boolean comma; - - protected char mode; - - private final JSONObject[] stack; - - private int top; - - protected Writer writer; - - public JSONWriter(Writer w) { - this.comma = false; - this.mode = 'i'; - this.stack = new JSONObject[maxdepth]; - this.top = 0; - this.writer = w; - } - - private JSONWriter append(String string) throws JSONException { - if (string == null) { - throw new JSONException("Null pointer"); - } - if (this.mode == 'o' || this.mode == 'a') { - try { - if (this.comma && this.mode == 'a') { - this.writer.write(','); - } - this.writer.write(string); - } catch (IOException e) { - throw new JSONException(e); - } - if (this.mode == 'o') { - this.mode = 'k'; - } - this.comma = true; - return this; - } - throw new JSONException("Value out of sequence."); - } - - public JSONWriter array() throws JSONException { - if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') { - this.push(null); - this.append("["); - this.comma = false; - return this; - } - throw new JSONException("Misplaced array."); - } - - private JSONWriter end(char mode, char c) throws JSONException { - if (this.mode != mode) { - throw new JSONException(mode == 'a' - ? "Misplaced endArray." - : "Misplaced endObject."); - } - this.pop(mode); - try { - this.writer.write(c); - } catch (IOException e) { - throw new JSONException(e); - } - this.comma = true; - return this; - } - - public JSONWriter endArray() throws JSONException { - return this.end('a', ']'); - } - - public JSONWriter endObject() throws JSONException { - return this.end('k', '}'); - } - - public JSONWriter key(String string) throws JSONException { - if (string == null) { - throw new JSONException("Null key."); - } - if (this.mode == 'k') { - try { - this.stack[this.top - 1].putOnce(string, Boolean.TRUE); - if (this.comma) { - this.writer.write(','); - } - this.writer.write(JSONObject.quote(string)); - this.writer.write(':'); - this.comma = false; - this.mode = 'o'; - return this; - } catch (IOException e) { - throw new JSONException(e); - } - } - throw new JSONException("Misplaced key."); - } - - public JSONWriter object() throws JSONException { - if (this.mode == 'i') { - this.mode = 'o'; - } - if (this.mode == 'o' || this.mode == 'a') { - this.append("{"); - this.push(new JSONObject()); - this.comma = false; - return this; - } - throw new JSONException("Misplaced object."); - - } - - private void pop(char c) throws JSONException { - if (this.top <= 0) { - throw new JSONException("Nesting error."); - } - char m = this.stack[this.top - 1] == null ? 'a' : 'k'; - if (m != c) { - throw new JSONException("Nesting error."); - } - this.top -= 1; - this.mode = this.top == 0 - ? 'd' - : this.stack[this.top - 1] == null - ? 'a' - : 'k'; - } - - private void push(JSONObject jo) throws JSONException { - if (this.top >= maxdepth) { - throw new JSONException("Nesting too deep."); - } - this.stack[this.top] = jo; - this.mode = jo == null ? 'a' : 'k'; - this.top += 1; - } - - public JSONWriter value(boolean b) throws JSONException { - return this.append(b ? "true" : "false"); - } - - public JSONWriter value(double d) throws JSONException { - return this.value(new Double(d)); - } - - public JSONWriter value(long l) throws JSONException { - return this.append(Long.toString(l)); - } - - public JSONWriter value(Object object) throws JSONException { - return this.append(JSONObject.valueToString(object)); - } -} diff --git a/src/main/java/me/skymc/taboolib/json/XML.java b/src/main/java/me/skymc/taboolib/json/XML.java deleted file mode 100644 index 6d98271..0000000 --- a/src/main/java/me/skymc/taboolib/json/XML.java +++ /dev/null @@ -1,338 +0,0 @@ -package me.skymc.taboolib.json; - - -import java.util.Iterator; - -@SuppressWarnings({"rawtypes"}) -public class XML { - - public static final Character AMP = '&'; - - public static final Character APOS = '\''; - - public static final Character BANG = '!'; - - public static final Character EQ = '='; - - public static final Character GT = '>'; - - public static final Character LT = '<'; - - public static final Character QUEST = '?'; - - public static final Character QUOT = '"'; - - public static final Character SLASH = '/'; - - public static String escape(String string) { - StringBuilder sb = new StringBuilder(); - for (int i = 0, length = string.length(); i < length; i++) { - char c = string.charAt(i); - switch (c) { - case '&': - sb.append("&"); - break; - case '<': - sb.append("<"); - break; - case '>': - sb.append(">"); - break; - case '"': - sb.append("""); - break; - case '\'': - sb.append("'"); - break; - default: - sb.append(c); - } - } - return sb.toString(); - } - - public static void noSpace(String string) throws JSONException { - int i, length = string.length(); - if (length == 0) { - throw new JSONException("Empty string."); - } - for (i = 0; i < length; i += 1) { - if (Character.isWhitespace(string.charAt(i))) { - throw new JSONException("'" + string + - "' contains a space character."); - } - } - } - - private static boolean parse(XMLTokener x, JSONObject context, - String name) throws JSONException { - char c; - int i; - JSONObject jsonobject = null; - String string; - String tagName; - Object token; - token = x.nextToken(); - if (token == BANG) { - c = x.next(); - if (c == '-') { - if (x.next() == '-') { - x.skipPast("-->"); - return false; - } - x.back(); - } else if (c == '[') { - token = x.nextToken(); - if ("CDATA".equals(token)) { - if (x.next() == '[') { - string = x.nextCDATA(); - if (string.length() > 0) { - context.accumulate("content", string); - } - return false; - } - } - throw x.syntaxError("Expected 'CDATA['"); - } - i = 1; - do { - token = x.nextMeta(); - if (token == null) { - throw x.syntaxError("Missing '>' after ' 0); - return false; - } else if (token == QUEST) { - x.skipPast("?>"); - return false; - } else if (token == SLASH) { - token = x.nextToken(); - if (name == null) { - throw x.syntaxError("Mismatched close tag " + token); - } - if (!token.equals(name)) { - throw x.syntaxError("Mismatched " + name + " and " + token); - } - if (x.nextToken() != GT) { - throw x.syntaxError("Misshaped close tag"); - } - return true; - - } else if (token instanceof Character) { - throw x.syntaxError("Misshaped tag"); - } else { - tagName = (String) token; - token = null; - jsonobject = new JSONObject(); - for (; ; ) { - if (token == null) { - token = x.nextToken(); - } - if (token instanceof String) { - string = (String) token; - token = x.nextToken(); - if (token == EQ) { - token = x.nextToken(); - if (!(token instanceof String)) { - throw x.syntaxError("Missing value"); - } - jsonobject.accumulate(string, - XML.stringToValue((String) token)); - token = null; - } else { - jsonobject.accumulate(string, ""); - } - } else if (token == SLASH) { - if (x.nextToken() != GT) { - throw x.syntaxError("Misshaped tag"); - } - if (jsonobject.length() > 0) { - context.accumulate(tagName, jsonobject); - } else { - context.accumulate(tagName, ""); - } - return false; - } else if (token == GT) { - for (; ; ) { - token = x.nextContent(); - if (token == null) { - if (tagName != null) { - throw x.syntaxError("Unclosed tag " + tagName); - } - return false; - } else if (token instanceof String) { - string = (String) token; - if (string.length() > 0) { - jsonobject.accumulate("content", - XML.stringToValue(string)); - } - } else if (token == LT) { - if (parse(x, jsonobject, tagName)) { - if (jsonobject.length() == 0) { - context.accumulate(tagName, ""); - } else if (jsonobject.length() == 1 && - jsonobject.opt("content") != null) { - context.accumulate(tagName, - jsonobject.opt("content")); - } else { - context.accumulate(tagName, jsonobject); - } - return false; - } - } - } - } else { - throw x.syntaxError("Misshaped tag"); - } - } - } - } - - public static Object stringToValue(String string) { - if ("".equals(string)) { - return string; - } - if ("true".equalsIgnoreCase(string)) { - return Boolean.TRUE; - } - if ("false".equalsIgnoreCase(string)) { - return Boolean.FALSE; - } - if ("null".equalsIgnoreCase(string)) { - return JSONObject.NULL; - } - if ("0".equals(string)) { - return 0; - } - try { - char initial = string.charAt(0); - boolean negative = false; - if (initial == '-') { - initial = string.charAt(1); - negative = true; - } - if (initial == '0' && string.charAt(negative ? 2 : 1) == '0') { - return string; - } - if ((initial >= '0' && initial <= '9')) { - if (string.indexOf('.') >= 0) { - return Double.valueOf(string); - } else if (string.indexOf('e') < 0 && string.indexOf('E') < 0) { - Long myLong = new Long(string); - if (myLong == myLong.intValue()) { - return myLong.intValue(); - } else { - return myLong; - } - } - } - } catch (Exception ignore) { - } - return string; - } - - public static JSONObject toJSONObject(String string) throws JSONException { - JSONObject jo = new JSONObject(); - XMLTokener x = new XMLTokener(string); - while (x.more() && x.skipPast("<")) { - parse(x, jo, null); - } - return jo; - } - - public static String toString(Object object) throws JSONException { - return toString(object, null); - } - - public static String toString(Object object, String tagName) throws JSONException { - StringBuilder sb = new StringBuilder(); - int i; - JSONArray ja; - JSONObject jo; - String key; - Iterator keys; - int length; - String string; - Object value; - if (object instanceof JSONObject) { - if (tagName != null) { - sb.append('<'); - sb.append(tagName); - sb.append('>'); - } - jo = (JSONObject) object; - keys = jo.keys(); - while (keys.hasNext()) { - key = keys.next().toString(); - value = jo.opt(key); - if (value == null) { - value = ""; - } - if ("content".equals(key)) { - if (value instanceof JSONArray) { - ja = (JSONArray) value; - length = ja.length(); - for (i = 0; i < length; i += 1) { - if (i > 0) { - sb.append('\n'); - } - sb.append(escape(ja.get(i).toString())); - } - } else { - sb.append(escape(value.toString())); - } - } else if (value instanceof JSONArray) { - ja = (JSONArray) value; - length = ja.length(); - for (i = 0; i < length; i += 1) { - value = ja.get(i); - if (value instanceof JSONArray) { - sb.append('<'); - sb.append(key); - sb.append('>'); - sb.append(toString(value)); - sb.append("'); - } else { - sb.append(toString(value, key)); - } - } - } else if ("".equals(value)) { - sb.append('<'); - sb.append(key); - sb.append("/>"); - } else { - sb.append(toString(value, key)); - } - } - if (tagName != null) { - sb.append("'); - } - return sb.toString(); - } else { - if (object.getClass().isArray()) { - object = new JSONArray(object); - } - if (object instanceof JSONArray) { - ja = (JSONArray) object; - length = ja.length(); - for (i = 0; i < length; i += 1) { - sb.append(toString(ja.opt(i), tagName == null ? "array" : tagName)); - } - return sb.toString(); - } else { - string = escape(object.toString()); - return (tagName == null) ? "\"" + string + "\"" : - (string.length() == 0) ? "<" + tagName + "/>" : - "<" + tagName + ">" + string + ""; - } - } - } -} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/json/XMLTokener.java b/src/main/java/me/skymc/taboolib/json/XMLTokener.java deleted file mode 100644 index c242bd0..0000000 --- a/src/main/java/me/skymc/taboolib/json/XMLTokener.java +++ /dev/null @@ -1,252 +0,0 @@ -package me.skymc.taboolib.json; - -@SuppressWarnings({"rawtypes", "unchecked"}) -public class XMLTokener extends JSONTokener { - - public static final java.util.HashMap entity; - - static { - entity = new java.util.HashMap(8); - entity.put("amp", XML.AMP); - entity.put("apos", XML.APOS); - entity.put("gt", XML.GT); - entity.put("lt", XML.LT); - entity.put("quot", XML.QUOT); - } - - public XMLTokener(String s) { - super(s); - } - - public String nextCDATA() throws JSONException { - char c; - int i; - StringBuilder sb = new StringBuilder(); - for (; ; ) { - c = next(); - if (end()) { - throw syntaxError("Unclosed CDATA"); - } - sb.append(c); - i = sb.length() - 3; - if (i >= 0 && sb.charAt(i) == ']' && - sb.charAt(i + 1) == ']' && sb.charAt(i + 2) == '>') { - sb.setLength(i); - return sb.toString(); - } - } - } - - public Object nextContent() throws JSONException { - char c; - StringBuffer sb; - do { - c = next(); - } while (Character.isWhitespace(c)); - if (c == 0) { - return null; - } - if (c == '<') { - return XML.LT; - } - sb = new StringBuffer(); - for (; ; ) { - if (c == '<' || c == 0) { - back(); - return sb.toString().trim(); - } - if (c == '&') { - sb.append(nextEntity(c)); - } else { - sb.append(c); - } - c = next(); - } - } - - public Object nextEntity(char ampersand) throws JSONException { - StringBuilder sb = new StringBuilder(); - for (; ; ) { - char c = next(); - if (Character.isLetterOrDigit(c) || c == '#') { - sb.append(Character.toLowerCase(c)); - } else if (c == ';') { - break; - } else { - throw syntaxError("Missing ';' in XML entity: &" + sb); - } - } - String string = sb.toString(); - Object object = entity.get(string); - return object != null ? object : ampersand + string + ";"; - } - - public Object nextMeta() throws JSONException { - char c; - char q; - do { - c = next(); - } while (Character.isWhitespace(c)); - switch (c) { - case 0: - throw syntaxError("Misshaped meta tag"); - case '<': - return XML.LT; - case '>': - return XML.GT; - case '/': - return XML.SLASH; - case '=': - return XML.EQ; - case '!': - return XML.BANG; - case '?': - return XML.QUEST; - case '"': - case '\'': - q = c; - for (; ; ) { - c = next(); - if (c == 0) { - throw syntaxError("Unterminated string"); - } - if (c == q) { - return Boolean.TRUE; - } - } - default: - for (; ; ) { - c = next(); - if (Character.isWhitespace(c)) { - return Boolean.TRUE; - } - switch (c) { - case 0: - case '<': - case '>': - case '/': - case '=': - case '!': - case '?': - case '"': - case '\'': - back(); - return Boolean.TRUE; - } - } - } - } - - public Object nextToken() throws JSONException { - char c; - char q; - StringBuffer sb; - do { - c = next(); - } while (Character.isWhitespace(c)); - switch (c) { - case 0: - throw syntaxError("Misshaped element"); - case '<': - throw syntaxError("Misplaced '<'"); - case '>': - return XML.GT; - case '/': - return XML.SLASH; - case '=': - return XML.EQ; - case '!': - return XML.BANG; - case '?': - return XML.QUEST; - case '"': - case '\'': - q = c; - sb = new StringBuffer(); - for (; ; ) { - c = next(); - if (c == 0) { - throw syntaxError("Unterminated string"); - } - if (c == q) { - return sb.toString(); - } - if (c == '&') { - sb.append(nextEntity(c)); - } else { - sb.append(c); - } - } - default: - sb = new StringBuffer(); - for (; ; ) { - sb.append(c); - c = next(); - if (Character.isWhitespace(c)) { - return sb.toString(); - } - switch (c) { - case 0: - return sb.toString(); - case '>': - case '/': - case '=': - case '!': - case '?': - case '[': - case ']': - back(); - return sb.toString(); - case '<': - case '"': - case '\'': - throw syntaxError("Bad character in a name"); - } - } - } - } - - public boolean skipPast(String to) throws JSONException { - boolean b; - char c; - int i; - int j; - int offset = 0; - int length = to.length(); - char[] circle = new char[length]; - - for (i = 0; i < length; i += 1) { - c = next(); - if (c == 0) { - return false; - } - circle[i] = c; - } - for (; ; ) { - j = offset; - b = true; - for (i = 0; i < length; i += 1) { - if (circle[j] != to.charAt(i)) { - b = false; - break; - } - j += 1; - if (j >= length) { - j -= length; - } - } - if (b) { - return true; - } - c = next(); - if (c == 0) { - return false; - } - circle[offset] = c; - offset += 1; - if (offset >= length) { - offset -= length; - } - } - } -} diff --git a/src/main/java/me/skymc/taboolib/jsonformatter/JSONFormatter.java b/src/main/java/me/skymc/taboolib/jsonformatter/JSONFormatter.java deleted file mode 100644 index 6ac0c21..0000000 --- a/src/main/java/me/skymc/taboolib/jsonformatter/JSONFormatter.java +++ /dev/null @@ -1,465 +0,0 @@ -package me.skymc.taboolib.jsonformatter; - -import com.ilummc.tlib.resources.TLocale; -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; - -/** - * @author Unknown - */ -@Deprecated -public class JSONFormatter { - - public static void sendRawMessage(Player player, String message) { - TLocale.Tellraw.send(player, message); - } - - private JSONArray ja = new JSONArray(); - private Builder builder = new Builder(); - private String color = ""; - private List all = new ArrayList<>(); - private boolean newline = true; - - public JSONFormatter() { - } - - public JSONFormatter(boolean newline) { - this.newline = newline; - } - - public JSONFormatter append(JSONFormatter json) { - if (json.ja.length() == 0) { - return this; - } - try { - if (newline && json.newline) { - all.addAll(json.all); - } - for (int i = 0; i < json.ja.length(); i++) { - add(json.ja.get(i)); - } - } catch (Exception e) { - e.printStackTrace(); - } - return this; - } - - public int getSize() { - if (newline) { - return 1; - } - return all.size() + 1; - } - - public JSONFormatter newLine() { - if (newline) { - append("\n"); - } else { - all.add(ja); - ja = new JSONArray(); - } - resetAll(); - return this; - } - - public JSONFormatter newLine(int amount) { - for (int i = 0; i < amount; i++) { - newLine(); - } - return this; - } - - public void clear() { - ja = new JSONArray(); - builder = new Builder(); - color = ""; - } - - public JSONFormatter resetAll() { - return resetColors().resetModifiers(); - } - - public JSONFormatter resetColors() { - color = ""; - return this; - } - - public JSONFormatter resetModifiers() { - builder = new Builder(); - return this; - } - - public String toJSON() { - JSONObject jo = new JSONObject(); - try { - if (ja.length() > 0) { - jo.put("extra", ja); - } - jo.put("text", ""); - } catch (Exception e) { - e.printStackTrace(); - } - return jo.toString(); - } - - public List toJSONList() { - List list = new ArrayList<>(); - try { - for (JSONArray ja : all) { - JSONObject jo = new JSONObject(); - if (ja.length() > 0) { - jo.put("extra", ja); - } - jo.put("text", ""); - list.add(jo.toString()); - } - JSONObject jo = new JSONObject(); - if (ja.length() > 0) { - jo.put("extra", ja); - } - jo.put("text", ""); - list.add(jo.toString()); - return list; - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - public Object toSerialized() { - try { - return a.invoke(null, toJSON()); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - public List toSerializedList() { - List list = new ArrayList<>(); - try { - for (String s : toJSONList()) { - list.add(a.invoke(null, s)); - } - return list; - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - public JSONFormatter send(Player player) { - JSONFormatter.send(player, this); - return this; - } - - private void add(Object jo) { - if (ja == null) { - ja = new JSONArray(); - } - if (jo != null) { - ja.put(jo); - } - } - - private JSONFormatter append(String text, BuilderMaker bm) { - builder = new Builder(builder); - for (int i = 0; i < text.length(); i++) { - char c = text.charAt(i); - switch (c) { - case '§': { - if ((i + 1) == text.length()) { - builder.append(c); - continue; - } - ChatColor cc = ChatColor.getByChar(text.charAt(i + 1)); - if (cc == null) { - builder.append(c); - break; - } - add(bm.make()); - switch (cc) { - case BOLD: - builder = new Builder(builder); - builder.bold = true; - break; - case ITALIC: - builder = new Builder(builder); - builder.italic = true; - break; - case MAGIC: - builder = new Builder(builder); - builder.magic = true; - break; - case RESET: - builder = new Builder(); - color = ""; - break; - case STRIKETHROUGH: - builder = new Builder(builder); - builder.strikethrough = true; - break; - case UNDERLINE: - builder = new Builder(builder); - builder.underline = true; - break; - default: { - builder = new Builder(); - color = cc.name().toLowerCase(); - break; - } - } - i++; - break; - } - default: { - builder.append(c); - } - } - } - add(bm.make()); - return this; - } - - public JSONFormatter append(String text) { - return append(text, new BuilderMaker() { - @Override - public JSONObject make() { - return builder.toString(color); - } - }); - } - - public JSONFormatter appendHover(String text, final HoverEvent hevent) { - return append(text, new BuilderMaker() { - @Override - public JSONObject make() { - return builder.toStringHover(color, hevent); - } - }); - } - - public JSONFormatter appendClick(String text, final ClickEvent cevent) { - return append(text, new BuilderMaker() { - @Override - public JSONObject make() { - return builder.toStringClick(color, cevent); - } - }); - } - - public JSONFormatter appendHoverClick(String text, final HoverEvent hevent, final ClickEvent cevent) { - return append(text, new BuilderMaker() { - @Override - public JSONObject make() { - return builder.toStringHoverClick(color, hevent, cevent); - } - }); - } - - public Object getPacket() { - try { - return ppocc.newInstance(toSerialized()); - } catch (Exception ignored) { - } - return null; - } - - public List getPacketList() { - List list = new ArrayList<>(); - try { - for (Object o : toSerializedList()) { - list.add(ppocc.newInstance(o)); - } - return list; - } catch (Exception ignored) { - } - return null; - } - - private static Class cs = NMSUtils.getNMSClassSilent("ChatSerializer", "IChatBaseComponent"); - private static Class icbc = NMSUtils.getNMSClassSilent("IChatBaseComponent"); - private static Class ppoc = NMSUtils.getNMSClassSilent("PacketPlayOutChat"); - private static Class pc = NMSUtils.getNMSClassSilent("PlayerConnection"); - private static Class p = NMSUtils.getNMSClassSilent("Packet"); - private static Class ep = NMSUtils.getNMSClassSilent("EntityPlayer"); - private static Method a = NMSUtils.getMethodSilent(cs, "a", String.class), sp = NMSUtils.getMethodSilent(pc, "sendPacket", p); - private static Field ppc = NMSUtils.getFieldSilent(ep, "playerConnection"); - private static Constructor ppocc = NMSUtils.getConstructorSilent(ppoc, icbc); - private static boolean b = check(cs, icbc, ppoc, pc, p, ep, a, sp, ppc, ppocc); - - private static boolean check(Object... o) { - for (Object a : o) { - if (a == null) { - return false; - } - } - return true; - } - - private static void send(Player player, JSONFormatter jf) { - if (!jf.newline) { - send1(player, jf); - } else if (b) { - try { - Object entityplayer = NMSUtils.getHandle(player); - Object ppco = ppc.get(entityplayer); - sp.invoke(ppco, jf.getPacket()); - } catch (Exception e) { - Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + player.getName() + " " + jf.toJSON()); - } - } else { - Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + player.getName() + " " + jf.toJSON()); - } - } - - private static void send1(Player player, JSONFormatter jf) { - if (b) { - try { - Object entityplayer = NMSUtils.getHandle(player); - Object ppco = ppc.get(entityplayer); - List packets = jf.getPacketList(); - List jsons = null; - for (int i = 0; i < packets.size(); i++) { - try { - sp.invoke(ppco, packets.get(i)); - } catch (Exception e) { - if (jsons == null) { - jsons = jf.toJSONList(); - } - Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + player.getName() + " " + jsons.get(i)); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } else { - for (String json : jf.toJSONList()) { - Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + player.getName() + " " + json); - } - } - } - - private class Builder { - - private StringBuilder sb = new StringBuilder(); - private boolean bold = false, italic = false, magic = false, strikethrough = false, underline = false, changed = false; - - public Builder() { - } - - public Builder(Builder b) { - bold = b.bold; - italic = b.italic; - magic = b.magic; - strikethrough = b.strikethrough; - underline = b.underline; - } - - public void append(char c) { - sb.append(c); - changed = true; - } - - private JSONObject toString(String color, BuilderHelper bh) { - String string = sb.toString(); - if (!changed) { - return null; - } - if (string.length() == 0) { - return null; - } - JSONObject jo = new JSONObject(); - try { - if (!"".equals(color)) { - jo.put("color", color); - } - if (bold) { - jo.put("bold", true); - } - if (italic) { - jo.put("italic", true); - } - if (magic) { - jo.put("obfuscated", true); - } - if (strikethrough) { - jo.put("strikethrough", true); - } - if (underline) { - jo.put("underlined", true); - } - bh.add(jo); - jo.put("text", string); - } catch (Exception e) { - e.printStackTrace(); - } - return jo; - } - - public JSONObject toString(String color) { - return toString(color, new BuilderHelper() { - @Override - public void add(JSONObject jo) { - } - }); - } - - public JSONObject toStringHover(String color, final HoverEvent event) { - return toString(color, new BuilderHelper() { - @Override - public void add(JSONObject jo) throws Exception { - if (event.getEvent().length() > 1) { - jo.put("hoverEvent", event.getEvent()); - } - } - }); - } - - public JSONObject toStringClick(String color, final ClickEvent event) { - return toString(color, new BuilderHelper() { - @Override - public void add(JSONObject jo) throws Exception { - if (event.getEvent().length() > 1) { - jo.put("clickEvent", event.getEvent()); - } - } - }); - } - - public JSONObject toStringHoverClick(String color, final HoverEvent hevent, final ClickEvent cevent) { - return toString(color, new BuilderHelper() { - @Override - public void add(JSONObject jo) throws Exception { - if (hevent.getEvent().length() > 1) { - jo.put("hoverEvent", hevent.getEvent()); - } - if (cevent.getEvent().length() > 1) { - jo.put("clickEvent", cevent.getEvent()); - } - } - }); - } - - } - - private abstract class BuilderMaker { - public abstract JSONObject make(); - } - - private abstract class BuilderHelper { - public abstract void add(JSONObject jo) throws Exception; - } -} diff --git a/src/main/java/me/skymc/taboolib/jsonformatter/click/ClickEvent.java b/src/main/java/me/skymc/taboolib/jsonformatter/click/ClickEvent.java deleted file mode 100644 index 6ec1f8a..0000000 --- a/src/main/java/me/skymc/taboolib/jsonformatter/click/ClickEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package me.skymc.taboolib.jsonformatter.click; - -import me.skymc.taboolib.json.JSONObject; - -public abstract class ClickEvent{ - - public abstract JSONObject getEvent(); - -} diff --git a/src/main/java/me/skymc/taboolib/jsonformatter/click/OpenUrlEvent.java b/src/main/java/me/skymc/taboolib/jsonformatter/click/OpenUrlEvent.java deleted file mode 100644 index 8ab37a4..0000000 --- a/src/main/java/me/skymc/taboolib/jsonformatter/click/OpenUrlEvent.java +++ /dev/null @@ -1,23 +0,0 @@ -package me.skymc.taboolib.jsonformatter.click; - -import me.skymc.taboolib.json.JSONObject; - -public class OpenUrlEvent extends ClickEvent{ - - private JSONObject object = new JSONObject(); - - public OpenUrlEvent(String suggest){ - try{ - object.put("action", "open_url"); - object.put("value", suggest); - }catch(Exception e){ - e.printStackTrace(); - } - } - - @Override - public JSONObject getEvent(){ - return object; - } - -} diff --git a/src/main/java/me/skymc/taboolib/jsonformatter/click/RunCommandEvent.java b/src/main/java/me/skymc/taboolib/jsonformatter/click/RunCommandEvent.java deleted file mode 100644 index 7494750..0000000 --- a/src/main/java/me/skymc/taboolib/jsonformatter/click/RunCommandEvent.java +++ /dev/null @@ -1,23 +0,0 @@ -package me.skymc.taboolib.jsonformatter.click; - -import me.skymc.taboolib.json.JSONObject; - -public class RunCommandEvent extends ClickEvent{ - - private JSONObject object = new JSONObject(); - - public RunCommandEvent(String command){ - try{ - object.put("action", "run_command"); - object.put("value", command); - }catch(Exception e){ - e.printStackTrace(); - } - } - - @Override - public JSONObject getEvent(){ - return object; - } - -} diff --git a/src/main/java/me/skymc/taboolib/jsonformatter/click/SuggestCommandEvent.java b/src/main/java/me/skymc/taboolib/jsonformatter/click/SuggestCommandEvent.java deleted file mode 100644 index 01496df..0000000 --- a/src/main/java/me/skymc/taboolib/jsonformatter/click/SuggestCommandEvent.java +++ /dev/null @@ -1,23 +0,0 @@ -package me.skymc.taboolib.jsonformatter.click; - -import me.skymc.taboolib.json.JSONObject; - -public class SuggestCommandEvent extends ClickEvent{ - - private JSONObject object = new JSONObject(); - - public SuggestCommandEvent(String suggest){ - try{ - object.put("action", "suggest_command"); - object.put("value", suggest); - }catch(Exception e){ - e.printStackTrace(); - } - } - - @Override - public JSONObject getEvent(){ - return object; - } - -} diff --git a/src/main/java/me/skymc/taboolib/jsonformatter/hover/HoverEvent.java b/src/main/java/me/skymc/taboolib/jsonformatter/hover/HoverEvent.java deleted file mode 100644 index 24f4c1d..0000000 --- a/src/main/java/me/skymc/taboolib/jsonformatter/hover/HoverEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package me.skymc.taboolib.jsonformatter.hover; - -import me.skymc.taboolib.json.JSONObject; - -public abstract class HoverEvent{ - - public abstract JSONObject getEvent(); - -} diff --git a/src/main/java/me/skymc/taboolib/jsonformatter/hover/ShowAchievementEvent.java b/src/main/java/me/skymc/taboolib/jsonformatter/hover/ShowAchievementEvent.java deleted file mode 100644 index 58c3c20..0000000 --- a/src/main/java/me/skymc/taboolib/jsonformatter/hover/ShowAchievementEvent.java +++ /dev/null @@ -1,23 +0,0 @@ -package me.skymc.taboolib.jsonformatter.hover; - -import me.skymc.taboolib.json.JSONObject; - -public class ShowAchievementEvent extends HoverEvent{ - - private JSONObject object = new JSONObject(); - - public ShowAchievementEvent(String achievement){ - try{ - object.put("action", "show_achievement"); - object.put("value", achievement); - }catch(Exception e){ - e.printStackTrace(); - } - } - - @Override - public JSONObject getEvent(){ - return object; - } - -} diff --git a/src/main/java/me/skymc/taboolib/jsonformatter/hover/ShowItemEvent.java b/src/main/java/me/skymc/taboolib/jsonformatter/hover/ShowItemEvent.java deleted file mode 100644 index 54e02a5..0000000 --- a/src/main/java/me/skymc/taboolib/jsonformatter/hover/ShowItemEvent.java +++ /dev/null @@ -1,81 +0,0 @@ -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.json.tellraw.TellrawJson; -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; - -public class ShowItemEvent extends HoverEvent { - - private JSONObject object = new JSONObject(); - - public Object getItemTag(ItemStack item) { - try { - return DabItemUtils.getInstance().getTag(DabItemUtils.getInstance().getNMSCopy(item)); - } catch (Exception e) { - return null; - } - } - - @SuppressWarnings("deprecation") - public ShowItemEvent(ItemStack is) { - if (TabooLib.getVerint() > 10700) { - try { - object.put("action", "show_item"); - object.put("value", TellrawJson.create().getItemComponent(is)); - } catch (Exception ignored) { - } - } - try { - object.put("action", "show_item"); - StringBuilder tag = new StringBuilder(); - Object itemTag = getItemTag(is); - if (itemTag != null) { - tag.append(",tag:").append(itemTag); - } else { - ItemMeta im = is.getItemMeta(); - List lore = im.hasLore() ? im.getLore() : new ArrayList<>(); - Map enchants = is.getItemMeta().getEnchants(); - tag.append(",tag:{display:{Name:").append(enchants.size() > 0 ? "§b§o" : "§f").append(ItemUtils.getCustomName(is)); - if (lore.size() > 0) { - tag.append(",Lore:["); - for (String s : lore) { - tag.append("\"").append(s).append("\","); - } - tag.delete(tag.length() - 1, tag.length()); - tag.append("]"); - } - tag.append("}"); - if (enchants.size() > 0) { - if (tag.length() > 6) { - tag.append(","); - } - tag.append("ench:["); - for (Entry e : enchants.entrySet()) { - tag.append("{id:").append(e.getKey().getId()).append(",lvl:").append(e.getValue()).append("},"); - } - tag.delete(tag.length() - 1, tag.length()); - tag.append("]"); - } - tag.append("}"); - } - object.put("value", "{id:" + (TabooLib.getVerint() > 10700 ? DabItemUtils.getMinecraftName(is) : is.getTypeId()) + ",Count:" + is.getAmount() + tag.toString() + "}"); - } catch (Exception ignored) { - } - } - - @Override - public JSONObject getEvent() { - return object; - } - -} diff --git a/src/main/java/me/skymc/taboolib/jsonformatter/hover/ShowTextEvent.java b/src/main/java/me/skymc/taboolib/jsonformatter/hover/ShowTextEvent.java deleted file mode 100644 index 7bd316f..0000000 --- a/src/main/java/me/skymc/taboolib/jsonformatter/hover/ShowTextEvent.java +++ /dev/null @@ -1,23 +0,0 @@ -package me.skymc.taboolib.jsonformatter.hover; - -import me.skymc.taboolib.json.JSONObject; - -public class ShowTextEvent extends HoverEvent{ - - private JSONObject object = new JSONObject(); - - public ShowTextEvent(String text){ - try{ - object.put("action", "show_text"); - object.put("value", text); - }catch(Exception e){ - e.printStackTrace(); - } - } - - @Override - public JSONObject getEvent(){ - return object; - } - -} diff --git a/src/main/java/me/skymc/taboolib/location/LocationUtils.java b/src/main/java/me/skymc/taboolib/location/LocationUtils.java deleted file mode 100644 index 23dc1be..0000000 --- a/src/main/java/me/skymc/taboolib/location/LocationUtils.java +++ /dev/null @@ -1,66 +0,0 @@ -package me.skymc.taboolib.location; - -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; - -public class LocationUtils { - - /** - * 序列化 - * - * @param location - * @return - */ - public static String fromString(Location location) { - return location.getWorld().getName() + "," + location.getX() + "," + location.getY() + "," + location.getZ() + "," + location.getYaw() + "," + location.getPitch(); - } - - /** - * 反序列化 - * - * @param string - * @return - */ - public static Location toString(String string) { - Location location = new Location(null, 0, 0, 0); - try { - location.setWorld(Bukkit.getWorld(string.split(",")[0])); - location.setX(Double.valueOf(string.split(",")[1])); - location.setY(Double.valueOf(string.split(",")[2])); - location.setZ(Double.valueOf(string.split(",")[3])); - location.setYaw(Float.valueOf(string.split(",")[4])); - location.setPitch(Float.valueOf(string.split(",")[5])); - } catch (Exception e) { - // TODO: handle exception - } - return location; - } - - public static double getBetween(Location l1, Location l2) { - if (l1.getWorld().equals(l2.getWorld())) { - return Math.ceil(l1.distance(l2)); - } - return -1D; - } - - @Deprecated - public static Block findBlockByLocation(Location l) { - while (l.getY() < 255 && l.getBlock().getType() != Material.AIR) { - l.add(0, 1, 0); - } - return l.getY() < 255 && l.getBlock().getType() == Material.AIR ? l.getBlock() : null; - } - - @Deprecated - public static String formatToString(Location l) { - return l.getWorld().getName() + "," + String.valueOf(l.getX()).replace(".", "#") + "," + String.valueOf(l.getY()).replace(".", "#") + "," + String.valueOf(l.getZ()).replace(".", "#"); - } - - @Deprecated - public static Location parsedToLocation(String string) { - String[] values = string.split(","); - return new Location(Bukkit.getWorld(values[0]), Double.valueOf(values[1].replace("#", ".")), Double.valueOf(values[2].replace("#", ".")), Double.valueOf(values[3].replace("#", "."))); - } -} diff --git a/src/main/java/me/skymc/taboolib/message/ChatCatcher.java b/src/main/java/me/skymc/taboolib/message/ChatCatcher.java deleted file mode 100644 index c0fd373..0000000 --- a/src/main/java/me/skymc/taboolib/message/ChatCatcher.java +++ /dev/null @@ -1,77 +0,0 @@ -package me.skymc.taboolib.message; - -import me.skymc.taboolib.listener.TListener; -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; - -@TListener -public class ChatCatcher implements Listener { - - private static HashMap> playerdata = new HashMap<>(); - - public static HashMap> getPlayerdata() { - return playerdata; - } - - public static boolean contains(Player player) { - return playerdata.containsKey(player.getName()) && playerdata.get(player.getName()).size() > 0; - } - - public static void call(Player player, Catcher catcher) { - if (!playerdata.containsKey(player.getName())) { - playerdata.put(player.getName(), new LinkedList<>()); - } - playerdata.get(player.getName()).add(catcher.before()); - } - - @EventHandler - public void quit(PlayerQuitEvent e) { - playerdata.remove(e.getPlayer().getName()); - } - - @EventHandler - public void chat(AsyncPlayerChatEvent e) { - if (playerdata.containsKey(e.getPlayer().getName()) && playerdata.get(e.getPlayer().getName()).size() > 0) { - e.setCancelled(true); - - if ("quit()".equalsIgnoreCase(e.getMessage())) { - // 退出引导 - playerdata.get(e.getPlayer().getName()).removeFirst().cancel(); - // 清理数据 - clearData(e.getPlayer()); - } else { - Catcher catcher = playerdata.get(e.getPlayer().getName()).getFirst(); - // 如果终止引导 - if (!catcher.after(e.getMessage())) { - // 移除 - playerdata.get(e.getPlayer().getName()).removeFirst(); - // 清理 - clearData(e.getPlayer()); - } else { - catcher.before(); - } - } - } - } - - private void clearData(Player player) { - if (playerdata.containsKey(player.getName()) && playerdata.get(player.getName()).size() == 0) { - playerdata.remove(player.getName()); - } - } - - public interface Catcher { - - Catcher before(); - - boolean after(String message); - - void cancel(); - } -} diff --git a/src/main/java/me/skymc/taboolib/message/MsgUtils.java b/src/main/java/me/skymc/taboolib/message/MsgUtils.java deleted file mode 100644 index 9ed7c56..0000000 --- a/src/main/java/me/skymc/taboolib/message/MsgUtils.java +++ /dev/null @@ -1,73 +0,0 @@ -package me.skymc.taboolib.message; - -import me.skymc.taboolib.Main; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.plugin.Plugin; - -@Deprecated -public class MsgUtils { - - public static void send(CommandSender sender, String s) { - sender.sendMessage(Main.getPrefix() + s.replaceAll("&", "§")); - } - - public static void send(org.bukkit.entity.Player player, String s) { - player.sendMessage(Main.getPrefix() + s.replaceAll("&", "§")); - } - - public static void send(String s) { - Bukkit.getConsoleSender().sendMessage(Main.getPrefix() + s.replaceAll("&", "§")); - } - - public static void warn(String s) { - warn(s, Main.getInst()); - } - - public static void send(String s, Plugin plugin) { - Bukkit.getConsoleSender().sendMessage("§8[§3" + plugin.getName() + "§8] §7" + s.replaceAll("&", "§")); - } - - public static void warn(String s, Plugin plugin) { - Bukkit.getConsoleSender().sendMessage("§4[§c" + plugin.getName() + "§4][WARN #!] §c" + s.replaceAll("&", "§")); - } - - @Deprecated - public static void Console(String s) { - Bukkit.getConsoleSender().sendMessage(Main.getPrefix() + s.replaceAll("&", "§")); - } - - @Deprecated - public static void System(String s) { - System.out.println("[TabooLib] " + s); - } - - @Deprecated - public static void Sender(CommandSender p, String s) { - p.sendMessage(Main.getPrefix() + s.replaceAll("&", "§")); - } - - @Deprecated - public static void Player(org.bukkit.entity.Player p, String s) { - p.sendMessage(Main.getPrefix() + s.replaceAll("&", "§")); - } - - @Deprecated - public static String noPe() { - String s = Main.getInst().getConfig().getString("NO-PERMISSION-MESSAGE").replaceAll("&", "§"); - if ("".equals(s)) { - s = "§cCONFIG ERROR §8(NO-PERMISSION-MESSAGE)"; - } - return s; - } - - @Deprecated - public static String noClaim(String a) { - String s = Main.getInst().getConfig().getString("NO-CLAIM-MESSAGE").replaceAll("&", "§").replaceAll("%s%", a); - if ("".equals(s)) { - s = "§cCONFIG ERROR §8(NO-CLAIM-MESSAGE)"; - } - return s; - } - -} diff --git a/src/main/java/me/skymc/taboolib/methods/MethodsUtils.java b/src/main/java/me/skymc/taboolib/methods/MethodsUtils.java deleted file mode 100644 index 7040bf9..0000000 --- a/src/main/java/me/skymc/taboolib/methods/MethodsUtils.java +++ /dev/null @@ -1,49 +0,0 @@ -package me.skymc.taboolib.methods; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -@Deprecated -public class MethodsUtils { - - public static boolean checkUser(String packagename, String current) { - return current.substring(0, 8).equals(packagename); - } - - @SuppressWarnings("rawtypes") - public static Object[] a(T classname, String methodname, Class[] classes, Object[] objects) { - if (!checkUser(new String(new byte[]{'m', 'e', '.', 's', 'k', 'y', 'm', 'c'}), new Exception().getStackTrace()[1].getClassName())) { - throw new Error("未经允许的方法调用"); - } - - Class clazz = classname.getClass(); - Method method = null; - try { - method = clazz.getDeclaredMethod(methodname, classes); - method.setAccessible(true); - return new Object[]{method.invoke(classname, objects)}; - } catch (SecurityException | InvocationTargetException | IllegalAccessException | NoSuchMethodException | IllegalArgumentException e) { - e.printStackTrace(); - } - return null; - } - - public static Object b(T classname, String fieldname) { - if (!checkUser(new String(new byte[]{'m', 'e', '.', 's', 'k', 'y', 'm', 'c'}), new Exception().getStackTrace()[1].getClassName())) { - throw new Error("未经允许的方法调用"); - } - - Class clazz = classname.getClass(); - Field field = null; - Object object = null; - try { - field = clazz.getDeclaredField(fieldname); - field.setAccessible(true); - object = field.get(classname); - } catch (NoSuchFieldException | IllegalAccessException | IllegalArgumentException | SecurityException e) { - e.printStackTrace(); - } - return object; - } -} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/mysql/MysqlConnection.java b/src/main/java/me/skymc/taboolib/mysql/MysqlConnection.java deleted file mode 100644 index f1ae225..0000000 --- a/src/main/java/me/skymc/taboolib/mysql/MysqlConnection.java +++ /dev/null @@ -1,329 +0,0 @@ -package me.skymc.taboolib.mysql; - -import java.sql.*; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executors; - -@Deprecated -public class MysqlConnection { - - /** - * Create by Bkm016 - *

- * 2017-7-22 23:25:55 - */ - - private Connection connection = null; - - private Statement statement = null; - - private Boolean isConnection = false; - - public MysqlConnection(String ip, String port, String table, String user, String pass) { - try { - Class.forName("com.mysql.jdbc.Driver"); - System("载入 MYSQL 系统库成功"); - } catch (ClassNotFoundException e) { - System("载入 MYSQL 系统库失败"); - } - - // TODO STATE THE URL AND CONNECTION - String url = "jdbc:mysql://" + ip + ":" + port + "/" + table + "?characterEncoding=utf-8"; - - // TODO CONNECTION - try { - connection = DriverManager.getConnection(url, user, pass); - statement = connection.createStatement(); - - isConnection = true; - System("连接 MYSQL 数据库成功"); - - Executors.newFixedThreadPool(1).execute(() -> { - while (isConnection) { - try { - if (connection.isClosed()) { - connection = DriverManager.getConnection(url, user, pass); - System("数据库连接关闭, 正在重新连接... [Connection Closed]"); - } - - Thread.sleep(30000); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - } catch (SQLException e) { - System("连接 MYSQL 数据库失败 详细信息: " + e.getLocalizedMessage()); - } - } - - public void closeConnection() { - try { - if (statement != null) { - statement.close(); - } - if (connection != null) { - connection.close(); - } - - isConnection = false; - System("结束 MYSQL 连接成功"); - } catch (SQLException e) { - System("结束 MYSQL 连接失败 详细信息: " + e.getLocalizedMessage()); - } - } - - public Connection getConnection() { - return this.connection; - } - - public Boolean isConnection() { - try { - if (statement.isClosed()) { - statement = null; - statement = connection.createStatement(); - System("数据库连接关闭, 正在重新连接... [Statement Closed]"); - } - } catch (SQLException e) { - e.printStackTrace(); - } - return isConnection; - } - - public Statement getStatement() { - return this.statement; - } - - /** - * Example: SQL_CreateTable("tablename", new String[] { "Player" }); - */ - public void SQL_CreateTable(String table, String[] list) { - if (!isConnection()) { - return; - } - - StringBuilder stringBuilder = new StringBuilder(); - - for (int i = 0; i < list.length; i++) { - if (i + 1 < list.length) { - stringBuilder.append("`").append(checkString(list[i])).append("` varchar(255), "); - } else { - stringBuilder.append("`").append(checkString(list[i])).append("` varchar(255)"); - } - } - String url = "CREATE TABLE IF NOT EXISTS `" + table + "` ( " + stringBuilder + " )"; - - try { - getStatement().execute(url); - } catch (SQLException e) { - System("执行 MYSQL 任务出错 详细信息: " + e.getLocalizedMessage()); - System("任务: " + url); - } - } - - /** - * Example: SQL_SetValues("tablename", new String[] { "Player" }, new String[] { "BlackSKY" }); - */ - public void SQL_SetValues(String table, String[] list, String[] values) { - if (!isConnection()) { - return; - } - - StringBuilder listbuilder = new StringBuilder(); - StringBuilder valuebuilder = new StringBuilder(); - - for (int i = 0; i < list.length; i++) { - if (i + 1 < list.length) { - listbuilder.append("`").append(checkString(list[i])).append("`, "); - valuebuilder.append("'").append(checkString(values[i])).append("', "); - } else { - listbuilder.append("`").append(checkString(list[i])).append("`"); - valuebuilder.append("'").append(checkString(values[i])).append("'"); - } - } - - String url = "INSERT INTO `" + table + "` ( " + listbuilder + " ) VALUES ( " + valuebuilder + " )"; - try { - getStatement().execute(url); - } catch (SQLException e) { - System("执行 MYSQL 任务出错 详细信息: " + e.getLocalizedMessage()); - System("任务: " + url); - for (int i = 0; i < e.getStackTrace().length && i < 5; i++) { - String name = e.getStackTrace()[i].getClassName(); - - System("(" + i + ")位置: " + name.substring(0, name.lastIndexOf("."))); - System(" 类名: " + e.getStackTrace()[i].getFileName().replaceAll(".java", "")); - System(" 行数: " + e.getStackTrace()[i].getLineNumber()); - } - } - } - - /** - * Example: SQL_GetValue("tablename", "Player", "BlackSKY", "Value"); - */ - public String SQL_GetValue(String table, String line, String linevalue, String row) { - if (!isConnection()) { - return null; - } - - String url = "SELECT * FROM " + checkString(table) + " WHERE `" + checkString(line) + "` = '" + checkString(linevalue) + "'"; - try { - ResultSet resultSet = getStatement().executeQuery(url); - while (resultSet.next()) { - return resultSet.getString(row); - } - resultSet.close(); - } catch (SQLException e) { - System("执行 MYSQL 任务出错 详细信息: " + e.getLocalizedMessage()); - System("任务: " + url); - } - return null; - } - - /** - * Example: SQL_GetValues("tablename", "Player"); - */ - public List SQL_GetValues(String table, String row) { - if (!isConnection()) { - return null; - } - - List list = new ArrayList<>(); - - String url = "SELECT * FROM " + checkString(table); - try { - ResultSet resultSet = getStatement().executeQuery(url); - while (resultSet.next()) { - if (resultSet.getString(row) == null) { - continue; - } - list.add(resultSet.getString(row)); - } - resultSet.close(); - } catch (SQLException e) { - System("执行 MYSQL 任务出错 详细信息: " + e.getLocalizedMessage()); - System("任务: " + url); - } - return list; - } - - /** - * Example: SQL_isExists("tablename", "Player", "BlackSKY"); - */ - public boolean SQL_isExists(String table, String row, String value) { - if (!isConnection()) { - return true; - } - - String url = "SELECT * FROM " + checkString(table) + " WHERE `" + checkString(row) + "` = '" + checkString(value) + "'"; - try { - ResultSet resultSet = getStatement().executeQuery(url); - while (resultSet.next()) { - return true; - } - resultSet.close(); - } catch (SQLException e) { - System("执行 MYSQL 任务出错 详细信息: " + e.getLocalizedMessage()); - System("任务: " + url); - } - return false; - } - - /** - * Example: SQL_UpdateValue("tablename", "Player", "BlackSKY", "Value", "10") - */ - public void SQL_UpdateValue(String table, String line, String linevalue, String row, String value) { - if (!isConnection()) { - return; - } - - String url = "UPDATE `" + checkString(table) + "` SET `" + checkString(row) + "` = '" + checkString(value) + "' WHERE `" + checkString(line) + "` = '" + checkString(linevalue) + "'"; - try { - getStatement().execute(url); - } catch (SQLException e) { - System("执行 MYSQL 任务出错 详细信息: " + e.getLocalizedMessage()); - System("任务: " + url); - } - } - - /** - * Example: SQL_DeleteValue("tablename", "BlackSKY"); - */ - public void SQL_DeleteValue(String table, String line, String linevalue) { - if (!isConnection()) { - return; - } - - String url = "DELETE FROM `" + checkString(table) + "` WHERE `" + checkString(line) + "` = '" + checkString(linevalue) + "'"; - try { - getStatement().execute(url); - } catch (SQLException e) { - System("执行 MYSQL 任务出错 详细信息: " + e.getLocalizedMessage()); - System("任务: " + url); - } - } - - /** - * Example: SQL_ClearTable("tablename"); - * @deprecated 即将过期 - */ - @Deprecated - public void SQL_ClearTable(String table) { - if (!isConnection()) { - return; - } - - String url = "TRUNCATE TABLE `" + checkString(table) + "`"; - try { - getStatement().execute(url); - } catch (SQLException e) { - System("执行 MYSQL 任务出错 详细信息: " + e.getLocalizedMessage()); - System("任务: " + url); - } - } - - public void SQL_execute(String url) { - if (!isConnection()) { - return; - } - - try { - getStatement().execute(url); - } catch (SQLException e) { - System("执行 MYSQL 任务出错 详细信息: " + e.getLocalizedMessage()); - System("任务: " + url); - } - } - - public ResultSet SQL_executeQuery(String url) { - if (!isConnection()) { - return null; - } - - try { - return getStatement().executeQuery(url); - } catch (SQLException e) { - System("执行 MYSQL 任务出错 详细信息: " + e.getLocalizedMessage()); - System("任务: " + url); - return null; - } - } - - public void SQL_clearTable(String table) { - SQL_execute("DELETE FROM " + checkString(table) + ";"); - } - - public void SQL_deleteTable(String table) { - SQL_execute("DROP TABLE " + checkString(table) + ";"); - } - - private void System(String string) { - System.out.println("[TabooLib - MYSQL] " + string); - } - - private String checkString(String string) { - return string.replace("`", "").replace("'", "").replace("\"", ""); - } - -} diff --git a/src/main/java/me/skymc/taboolib/mysql/MysqlUtils.java b/src/main/java/me/skymc/taboolib/mysql/MysqlUtils.java deleted file mode 100644 index e7aaf4a..0000000 --- a/src/main/java/me/skymc/taboolib/mysql/MysqlUtils.java +++ /dev/null @@ -1,50 +0,0 @@ -package me.skymc.taboolib.mysql; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.mysql.protect.MySQLConnection; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.plugin.Plugin; - -import java.sql.Connection; -import java.util.concurrent.CopyOnWriteArrayList; - -public class MysqlUtils { - - public final static CopyOnWriteArrayList CONNECTIONS = new CopyOnWriteArrayList<>(); - - @Deprecated - public static MysqlConnection getMysqlConnectionFromConfiguration(FileConfiguration conf, String key) { - return new MysqlConnection(conf.getString(key + ".host"), conf.getString(key + ".port"), conf.getString(key + ".database"), conf.getString(key + ".user"), conf.getString(key + ".pass")); - } - - public static MySQLConnection getMySQLConnectionFromConfiguration(FileConfiguration conf, String key) { - return getMySQLConnectionFromConfiguration(conf, key, 60, Main.getInst()); - } - - public static MySQLConnection getMySQLConnectionFromConfiguration(FileConfiguration conf, String key, int recheck, Plugin plugin) { - MySQLConnection connection = getMySQLConnectionExists(conf, key); - if (connection == null) { - connection = new MySQLConnection(conf.getString(key + ".url"), conf.getString(key + ".user"), conf.getString(key + ".port"), conf.getString(key + ".password"), conf.getString(key + ".database"), recheck, plugin); - if (connection.isConnection()) { - CONNECTIONS.add(connection); - TLocale.Logger.info("MYSQL-CONNECTION.SUCCESS-REGISTERED", plugin.getName()); - } - } else { - TLocale.Logger.info("MYSQL-CONNECTION.SUCCESS-REGISTERED-EXISTS", plugin.getName(), connection.getPlugin().getName()); - } - return connection; - } - - private static MySQLConnection getMySQLConnectionExists(FileConfiguration conf, String key) { - return CONNECTIONS.stream().filter(connection -> isSameConnection(conf, key, connection)).findFirst().orElse(null); - } - - private static boolean isSameConnection(FileConfiguration conf, String key, MySQLConnection connection) { - return conversionHost(connection.getUrl()).equals(conversionHost(conf.getString(key + ".url", "localhost"))) && connection.getDatabase().equals(conf.getString(key + ".database")); - } - - private static String conversionHost(String host) { - return "localhost".equals(host) ? "127.0.0.1" : host; - } -} diff --git a/src/main/java/me/skymc/taboolib/mysql/protect/MySQLConnection.java b/src/main/java/me/skymc/taboolib/mysql/protect/MySQLConnection.java deleted file mode 100644 index 4ff774d..0000000 --- a/src/main/java/me/skymc/taboolib/mysql/protect/MySQLConnection.java +++ /dev/null @@ -1,773 +0,0 @@ -package me.skymc.taboolib.mysql.protect; - -import com.ilummc.tlib.resources.TLocale; -import com.ilummc.tlib.util.Strings; -import me.skymc.taboolib.Main; -import org.bukkit.plugin.Plugin; - -import java.sql.*; -import java.util.*; - -/** - * @author sky - */ -@Deprecated -public class MySQLConnection { - - private String url; - private String user; - private String port; - private String password; - private String database; - private String connectionUrl; - private Connection connection; - private Plugin plugin; - private boolean fallReconnection = true; - private int recheck = 10; - private Thread recheckThread; - - public MySQLConnection(String url, String user, String port, String password, String database) { - this(url, user, port, password, database, 10, Main.getInst()); - } - - public MySQLConnection(String url, String user, String port, String password, String database, int recheck, Plugin plugin) { - // 检查驱动 - if (!loadDriverMySQL()) { - TLocale.Logger.error("MYSQL-CONNECTION.FAIL-NOTFOUND-DRIVE"); - return; - } - - // 设置信息 - this.plugin = plugin; - this.recheck = recheck; - - // 设置数据 - this.url = url == null ? "localhost" : url; - this.user = user == null ? "root" : user; - this.port = port == null ? "3306" : port; - this.password = password == null ? "" : password; - this.database = database == null ? "test" : database; - this.connectionUrl = Strings.replaceWithOrder("jdbc:mysql://{0}:{1}/{2}?characterEncoding=utf-8&useSSL=false", this.url, this.port, this.database); - - // 连接数据库 - connect(); - - // 断线检测 - recheckThread = new Thread(() -> { - while (!Main.isDisable()) { - try { - Thread.sleep(getReCheckSeconds() * 1000); - - if (connection == null) { - TLocale.Logger.error("MYSQL-CONNECTION.FAIL-NOTFOUND-CONNECTION", plugin.getName()); - } else { - isExists("taboolib"); - } - } catch (Exception e) { - TLocale.Logger.error("MYSQL-CONNECTION.FAIL-COMMAND-NORMAL", e.toString()); - } - } - }); - - // 启动检测 - if (isConnection()) { - recheckThread.start(); - TLocale.Logger.info("MYSQL-CONNECTION.SUCCESS-REGISTERED-LISTENER"); - } - } - - public String getUrl() { - return url; - } - - public String getUser() { - return user; - } - - public String getPort() { - return port; - } - - public String getPassword() { - return password; - } - - public String getDatabase() { - return database; - } - - public String getConnectionUrl() { - return connectionUrl; - } - - public Connection getConnection() { - return connection; - } - - public Plugin getPlugin() { - return plugin; - } - - public void setPlugin(Plugin plugin) { - this.plugin = plugin; - } - - public boolean isFallReconnection() { - return fallReconnection; - } - - public void setFallReconnection(boolean fallReconnection) { - this.fallReconnection = fallReconnection; - } - - public int getRecheck() { - return recheck; - } - - public Thread getRecheckThread() { - return recheckThread; - } - - public int getReCheckSeconds() { - return recheck; - } - - public void setReCheckSeconds(int s) { - this.recheck = s; - } - - public boolean isConnection() { - try { - if (connection == null || connection.isClosed()) { - return false; - } - } catch (SQLException e) { - return false; - } - return true; - } - - @SuppressWarnings("deprecation") - public void closeConnection() { - try { - connection.close(); - } catch (Exception ignored) { - } - try { - recheckThread.stop(); - } catch (Exception ignored) { - } - } - - public boolean deleteTable(String name) { - return execute("drop table if exists " + name); - } - - /** - * 2018年1月17日 新增, TabooLib 版本 3.25 - */ - public boolean truncateTable(String name) { - return execute("truncate table " + name); - } - - public boolean clearTable(String name) { - return execute("delete from " + name); - } - - public boolean renameTable(String name, String newName) { - return execute(Strings.replaceWithOrder("rename table `{0}` to `{1}`", name, newName)); - } - - public boolean deleteColumn(String name, String column) { - return execute(Strings.replaceWithOrder("alter table `{0}` drop `{1}`", name, column)); - } - - public void addColumn(String name, Column... columns) { - Arrays.stream(columns).map(column -> Strings.replaceWithOrder("alter table {0} add {1}", name, column.toString())).forEach(this::execute); - } - - public boolean addColumn(String name, String column) { - if (!column.contains("/")) { - return execute(Strings.replaceWithOrder("alter table {0} add `{1}` text", name, column)); - } - return execute(Strings.replaceWithOrder("alter table {0} add `{1}` {2}", name, column.split("/")[0], column.split("/")[1])); - } - - public boolean editColumn(String name, String oldColumn, Column newColumn) { - return execute(Strings.replaceWithOrder("alter table {0} change `{1}` {2}", name, oldColumn, newColumn.toString())); - } - - public boolean editColumn(String name, String oldColumn, String newColumn) { - if (!newColumn.contains("/")) { - return execute(Strings.replaceWithOrder("alter table {0} change `{1}` `{2}` text", name, oldColumn, newColumn)); - } - return execute(Strings.replaceWithOrder("alter table {0} change `{1}` `{2}` {3}", name, oldColumn, newColumn.split("/")[0], newColumn.split("/")[1])); - } - - /** - * 删除数据 - * - * @param name 名称 - * @param column 参考列 - * @param columnValue 参考值 - * @return boolean - */ - public boolean deleteValue(String name, String column, Object columnValue) { - PreparedStatement preparedStatement = null; - try { - preparedStatement = connection.prepareStatement(Strings.replaceWithOrder("delete from `{0}` where `{1}` = ?", name, column)); - preparedStatement.setObject(1, columnValue); - preparedStatement.executeUpdate(); - } catch (Exception e) { - printException(e); - } finally { - freeResult(null, preparedStatement); - } - return false; - } - - /** - * 写入数据 - * - * @param name 名称 - * @param column 参考列 - * @param columnValue 参考值 - * @param valueColumn 数据列 - * @param value 数据值 - * @return boolean - */ - public boolean setValue(String name, String column, Object columnValue, String valueColumn, Object value) { - return setValue(name, column, columnValue, valueColumn, value, false); - } - - /** - * 写入数据 - * - * @param name 名称 - * @param column 参考列 - * @param columnValue 参考值 - * @param valueColumn 数据列 - * @param value 数据值 - * @param append 是否追加(数据列类型必须为数字) - * @return boolean - */ - public boolean setValue(String name, String column, Object columnValue, String valueColumn, Object value, boolean append) { - PreparedStatement preparedStatement = null; - try { - if (append) { - preparedStatement = connection.prepareStatement(Strings.replaceWithOrder("update `{0}` set `{1}` = `{2}` + ? where `{3}` = ?", name, valueColumn, valueColumn, column)); - } else { - preparedStatement = connection.prepareStatement(Strings.replaceWithOrder("update `{0}` set `{1}` = ? where `{2}` = ?", name, valueColumn, column)); - } - preparedStatement.setObject(1, value); - preparedStatement.setObject(2, columnValue); - preparedStatement.executeUpdate(); - } catch (Exception e) { - printException(e); - } finally { - freeResult(null, preparedStatement); - } - return false; - } - - /** - * 插入数据 - * - * @param name 名称 - * @param values 值 - * @return boolean - */ - public boolean intoValue(String name, Object... values) { - StringBuilder sb = new StringBuilder(); - Arrays.stream(values).map(value -> "?, ").forEach(sb::append); - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - try { - preparedStatement = connection.prepareStatement(Strings.replaceWithOrder("insert into `{0}` values(null, {1})", name, sb.substring(0, sb.length() - 2))); - for (int i = 0; i < values.length; i++) { - preparedStatement.setObject(i + 1, values[i]); - } - preparedStatement.executeUpdate(); - } catch (Exception e) { - printException(e); - } finally { - freeResult(null, preparedStatement); - } - return false; - } - - /** - * 创建数据表 - * - * @param name 名称 - * @param columns 列表 - * @return boolean - */ - public boolean createTable(String name, Column... columns) { - StringBuilder sb = new StringBuilder(); - Arrays.stream(columns).forEach(column -> sb.append(column.toString()).append(", ")); - return execute(Strings.replaceWithOrder("create table if not exists {0} (id int(1) not null primary key auto_increment, {1})", name, sb.substring(0, sb.length() - 2))); - } - - /** - * 创建数据表 - * - * @param name 名称 - * @param columns 列表 - * @return boolean - */ - public boolean createTable(String name, String... columns) { - StringBuilder sb = new StringBuilder(); - for (String column : columns) { - if (!column.contains("/")) { - sb.append("`").append(column).append("` text, "); - } else { - sb.append("`").append(column.split("/")[0]).append("` ").append(column.split("/")[1]).append(", "); - } - } - return execute(Strings.replaceWithOrder("create table if not exists {0} (id int(1) not null primary key auto_increment, {1})", name, sb.substring(0, sb.length() - 2))); - } - - /** - * 检查数据表是否存在 - * - * @param name 名称 - * @return boolean - */ - public boolean isExists(String name) { - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - try { - preparedStatement = connection.prepareStatement("select table_name FROM information_schema.TABLES where table_name = ?"); - preparedStatement.setString(1, name); - resultSet = preparedStatement.executeQuery(); - while (resultSet.next()) { - return true; - } - } catch (Exception e) { - printException(e); - } finally { - freeResult(resultSet, preparedStatement); - } - return false; - } - - /** - * 检查数据是否存在 - * - * @param name 名称 - * @param column 列表名 - * @param columnValue 列表值 - * @return boolean - */ - public boolean isExists(String name, String column, Object columnValue) { - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - try { - preparedStatement = connection.prepareStatement(Strings.replaceWithOrder("select * from `{0}` where `{1}` = ?", name, column)); - preparedStatement.setObject(1, columnValue); - resultSet = preparedStatement.executeQuery(); - while (resultSet.next()) { - return true; - } - } catch (Exception e) { - printException(e); - } finally { - freeResult(resultSet, preparedStatement); - } - return false; - } - - /** - * 获取所有列表名称(不含主键) - * - * @param name 名称 - * @return {@link List} - */ - public List getColumns(String name) { - return getColumns(name, false); - } - - /** - * 获取所有列表名称 - * - * @param name 名称 - * @param primary 是否获取主键 - * @return {@link List} - */ - public List getColumns(String name, boolean primary) { - List list = new ArrayList<>(); - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - try { - preparedStatement = connection.prepareStatement("select column_name from information_schema.COLUMNS where table_name = ?"); - preparedStatement.setString(1, name); - resultSet = preparedStatement.executeQuery(); - while (resultSet.next()) { - list.add(resultSet.getString(1)); - } - } catch (Exception e) { - printException(e); - } finally { - freeResult(resultSet, preparedStatement); - } - // 是否获取主键 - if (!primary) { - list.remove("id"); - } - return list; - } - - /** - * 获取单项数据 - * - * @param name 名称 - * @param column 参考列 - * @param columnValue 参考值 - * @param valueColumn 数据列 - * @return Object - */ - public Object getValue(String name, String column, Object columnValue, String valueColumn) { - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - try { - preparedStatement = connection.prepareStatement(Strings.replaceWithOrder("select * from `{0}` where `{1}` = ? limit 1", name, column)); - preparedStatement.setObject(1, columnValue); - resultSet = preparedStatement.executeQuery(); - while (resultSet.next()) { - return resultSet.getObject(valueColumn); - } - } catch (Exception e) { - printException(e); - } finally { - freeResult(resultSet, preparedStatement); - } - return null; - } - - /** - * 获取单项数据(根据主键倒叙排列后的最后一项) - * - * @param name 名称 - * @param column 参考列 - * @param columnValue 参考值 - * @param valueColumn 数据列 - * @return Object - */ - public Object getValueLast(String name, String column, Object columnValue, String valueColumn) { - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - try { - preparedStatement = connection.prepareStatement(Strings.replaceWithOrder("select * from `{0}` where `{1}` = ? order by id desc limit 1", name, column)); - preparedStatement.setObject(1, columnValue); - resultSet = preparedStatement.executeQuery(); - while (resultSet.next()) { - return resultSet.getObject(valueColumn); - } - } catch (Exception e) { - printException(e); - } finally { - freeResult(resultSet, preparedStatement); - } - return null; - } - - /** - * 获取多项数据(根据主键倒叙排列后的最后一项) - * - * @param name 名称 - * @param column 参考列 - * @param columnValue 参考值 - * @param valueColumn 数据列 - * @return {@link HashMap} - */ - public HashMap getValueLast(String name, String column, Object columnValue, String... valueColumn) { - HashMap map = new HashMap<>(); - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - try { - preparedStatement = connection.prepareStatement(Strings.replaceWithOrder("select * from `{0}` where `{1}` = ? order by id desc limit 1", name, column)); - preparedStatement.setObject(1, columnValue); - resultSet = preparedStatement.executeQuery(); - while (resultSet.next()) { - for (String _column : valueColumn) { - map.put(_column, resultSet.getObject(_column)); - } - break; - } - } catch (Exception e) { - printException(e); - } finally { - freeResult(resultSet, preparedStatement); - } - return map; - } - - /** - * 获取多项数据(单项多列) - * - * @param name 名称 - * @param column 参考列 - * @param columnValue 参考值 - * @param valueColumn 数据列 - * @return {@link HashMap} - */ - public HashMap getValue(String name, String column, Object columnValue, String... valueColumn) { - HashMap map = new HashMap<>(); - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - try { - preparedStatement = connection.prepareStatement(Strings.replaceWithOrder("select * from `{0}` where `{1}` = ? limit 1", name, column)); - preparedStatement.setObject(1, columnValue); - resultSet = preparedStatement.executeQuery(); - while (resultSet.next()) { - for (String _column : valueColumn) { - map.put(_column, resultSet.getObject(_column)); - } - break; - } - } catch (Exception e) { - printException(e); - } finally { - freeResult(resultSet, preparedStatement); - } - return map; - } - - /** - * 获取多项数据(单列多列) - * - * @param name 名称 - * @param column 参考列 - * @param size 获取数量(-1 为无限制) - * @return {@link List} - */ - public List getValues(String name, String column, int size) { - return getValues(name, column, size, false); - } - - /** - * 获取多项数据(单列多列) - * - * @param name 名称 - * @param column 参考列 - * @param size 获取数量(-1 位无限制) - * @param desc 是否倒序 - * @return {@link List} - */ - public List getValues(String name, String column, int size, boolean desc) { - List list = new LinkedList<>(); - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - try { - if (desc) { - preparedStatement = connection.prepareStatement(Strings.replaceWithOrder("select * from `{0}` order by `{1}` desc {2}", name, column, size < 0 ? "" : " limit " + size)); - } else { - preparedStatement = connection.prepareStatement(Strings.replaceWithOrder("select * from `{0}` order by `{1}` {2}", name, column, size < 0 ? "" : " limit " + size)); - } - resultSet = preparedStatement.executeQuery(); - while (resultSet.next()) { - list.add(resultSet.getObject(column)); - } - } catch (Exception e) { - printException(e); - } finally { - freeResult(resultSet, preparedStatement); - } - return list; - } - - /** - * 获取多线数据(多项多列) - * - * @param name 名称 - * @param sortColumn 参考列(该列类型必须为数字) - * @param size 获取数量(-1 为无限制) - * @param valueColumn 获取数据列 - * @return {@link LinkedList} - */ - public LinkedList> getValues(String name, String sortColumn, int size, String... valueColumn) { - return getValues(name, sortColumn, size, false, valueColumn); - } - - /** - * 获取多项数据(多项多列) - * - * @param name 名称 - * @param sortColumn 参考列(该列类型必须为数字) - * @param size 获取数量(-1 为无限制) - * @param desc 是否倒序 - * @param valueColumn 获取数据列 - * @return {@link LinkedList} - */ - public LinkedList> getValues(String name, String sortColumn, int size, boolean desc, String... valueColumn) { - LinkedList> list = new LinkedList<>(); - PreparedStatement preparedStatement = null; - ResultSet resultSet = null; - try { - if (desc) { - preparedStatement = connection.prepareStatement(Strings.replaceWithOrder("select * from `{0}` order by `{1}` desc{2}", name, sortColumn, size < 0 ? "" : " limit " + size)); - } else { - preparedStatement = connection.prepareStatement(Strings.replaceWithOrder("select * from `{0}` order by `{1}`{2}", name, sortColumn, size < 0 ? "" : " limit " + size)); - } - resultSet = preparedStatement.executeQuery(); - while (resultSet.next()) { - HashMap map = new HashMap<>(); - for (String _column : valueColumn) { - map.put(_column, resultSet.getObject(_column)); - } - list.add(map); - } - } catch (Exception e) { - printException(e); - } finally { - freeResult(resultSet, preparedStatement); - } - return list; - } - - public boolean execute(String sql) { - PreparedStatement preparedStatement = null; - try { - preparedStatement = connection.prepareStatement(sql); - preparedStatement.execute(); - return true; - } catch (SQLException e) { - printExceptionDetail(e); - return false; - } finally { - freeResult(null, preparedStatement); - } - } - - public boolean connect() { - TLocale.Logger.info("MYSQL-CONNECTION.NOTIFY-CONNECTING", connectionUrl); - try { - long time = System.currentTimeMillis(); - connection = DriverManager.getConnection(connectionUrl, this.user, this.password); - TLocale.Logger.info("MYSQL-CONNECTION.NOTIFY-CONNECTED", String.valueOf(System.currentTimeMillis() - time)); - return true; - } catch (SQLException e) { - printExceptionDetail(e); - return false; - } - } - - public void print(String message) { - System.out.println("[TabooLib - MySQL] " + message); - } - - private void printException(Exception e) { - TLocale.Logger.error("MYSQL-CONNECTION.FAIL-COMMAND-NORMAL", e.toString()); - reconnection(e); - } - - private void printExceptionDetail(SQLException e) { - TLocale.Logger.error("MYSQL-CONNECTION.FAIL-COMMAND-DETAIL", String.valueOf(e.getErrorCode()), e.toString()); - reconnection(e); - } - - private void reconnection(Exception e) { - if (fallReconnection && e.getMessage().contains("closed")) { - connect(); - } - } - - private boolean loadDriverMySQL() { - try { - Class.forName("com.mysql.jdbc.Driver"); - return true; - } catch (ClassNotFoundException e) { - return false; - } - } - - private void freeResult(ResultSet resultSet, PreparedStatement preparedStatement) { - try { - if (resultSet != null) { - resultSet.close(); - } - } catch (Exception ignored) { - } - try { - if (preparedStatement != null) { - preparedStatement.close(); - } - } catch (Exception ignored) { - } - } - - public enum ColumnInteger { - - TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT - } - - public enum ColumnFloat { - - FLOAT, DOUBLE - } - - public enum ColumnChar { - - CHAR, VARCHAR - } - - public enum ColumnString { - - TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT - } - - public static class Column { - - private String name; - private Object type; - private int a; - private int b; - - public Column(String name) { - this.name = name; - this.type = ColumnString.TEXT; - } - - public Column(String name, ColumnInteger type) { - this(name); - this.type = type; - this.a = 12; - } - - public Column(String name, ColumnInteger type, int m) { - this(name); - this.type = type; - this.a = m; - } - - public Column(String name, ColumnFloat type, int m, int d) { - this(name); - this.type = type; - this.a = m; - this.b = d; - } - - public Column(String name, ColumnChar type, int n) { - this(name); - this.type = type; - this.a = n; - } - - public Column(String name, ColumnString type) { - this(name); - this.type = type; - } - - @Override - public String toString() { - if (type instanceof ColumnInteger || type instanceof ColumnChar) { - return Strings.replaceWithOrder("`{0}` {1}({2})", name, type.toString().toLowerCase(), a); - } else if (type instanceof ColumnFloat) { - return Strings.replaceWithOrder("`{0}` {1}({2},{3})", name, type.toString().toLowerCase(), a, b); - } else { - return Strings.replaceWithOrder("`{0}` {1}", name, type.toString().toLowerCase()); - } - } - } -} diff --git a/src/main/java/me/skymc/taboolib/nms/NMSUtil18.java b/src/main/java/me/skymc/taboolib/nms/NMSUtil18.java deleted file mode 100644 index fcdf616..0000000 --- a/src/main/java/me/skymc/taboolib/nms/NMSUtil18.java +++ /dev/null @@ -1,1323 +0,0 @@ -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; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -/** - * @author Unknown - */ -@SuppressWarnings({"rawtypes", "unchecked"}) -public class NMSUtil18 { - - protected static boolean failed = false; - - protected static String versionPrefix = ""; - - protected final static int NBT_TYPE_COMPOUND = 10; - protected final static int NBT_TYPE_INT_ARRAY = 11; - protected final static int NBT_TYPE_DOUBLE = 6; - protected final static int NBT_TYPE_FLOAT = 5; - protected final static int NBT_TYPE_STRING = 8; - - protected static int WITHER_SKULL_TYPE = 66; - protected static int FIREWORK_TYPE = 76; - - protected static Class class_ItemStack; - protected static Class class_NBTBase; - protected static Class class_NBTTagCompound; - protected static Class class_NBTTagList; - protected static Class class_NBTTagByte; - protected static Class class_NBTTagString; - protected static Class class_CraftTask; - protected static Class class_CraftInventoryCustom; - protected static Class class_CraftItemStack; - protected static Class class_CraftBlockState; - protected static Class class_CraftLivingEntity; - protected static Class class_CraftWorld; - protected static Class class_Entity; - protected static Class class_EntityCreature; - protected static Class class_EntityLiving; - protected static Class class_DataWatcher; - protected static Class class_DamageSource; - protected static Class class_EntityDamageSource; - protected static Class class_World; - protected static Class class_WorldServer; - protected static Class class_Packet; - protected static Class class_EnumSkyBlock; - protected static Class class_PacketPlayOutMapChunkBulk; - protected static Class class_EntityPainting; - protected static Class class_EntityItemFrame; - protected static Class class_EntityMinecartRideable; - protected static Class class_EntityTNTPrimed; - protected static Class class_AxisAlignedBB; - protected static Class class_PathPoint; - protected static Class class_PathEntity; - protected static Class class_EntityFirework; - protected static Class class_CraftSkull; - protected static Class class_CraftBanner; - protected static Class class_CraftMetaSkull; - protected static Class class_CraftMetaBanner; - protected static Class class_GameProfile; - protected static Class class_GameProfileProperty; - protected static Class class_BlockPosition; - protected static Class class_NBTCompressedStreamTools; - protected static Class class_TileEntity; - protected static Class class_TileEntitySign; - protected static Class class_TileEntityContainer; - protected static Class class_ChestLock; - protected static Class class_EnumDirection; - protected static Class class_EntityHorse; - protected static Class class_EntityWitherSkull; - protected static Class class_PacketPlayOutAttachEntity; - protected static Class class_PacketPlayOutEntityDestroy; - protected static Class class_PacketPlayOutSpawnEntity; - protected static Class class_PacketPlayOutSpawnEntityLiving; - protected static Class class_PacketPlayOutEntityMetadata; - protected static Class class_PacketPlayOutEntityStatus; - protected static Class class_EntityFallingBlock; - protected static Class class_EntityArmorStand; - protected static Class class_EntityPlayer; - protected static Class class_PlayerConnection; - protected static Class class_Chunk; - protected static Class class_CraftPlayer; - protected static Class class_CraftChunk; - protected static Class class_CraftEntity; - protected static Class class_EntityProjectile; - protected static Class class_EntityFireball; - protected static Class class_EntityArrow; - protected static Class class_CraftArrow; - - protected static Method class_NBTTagList_addMethod; - protected static Method class_NBTTagList_getMethod; - protected static Method class_NBTTagList_getDoubleMethod; - protected static Method class_NBTTagList_sizeMethod; - protected static Method class_NBTTagCompound_setMethod; - protected static Method class_DataWatcher_watchMethod; - protected static Method class_World_getEntitiesMethod; - protected static Method class_Entity_setSilentMethod; - protected static Method class_Entity_setYawPitchMethod; - protected static Method class_Entity_getBukkitEntityMethod; - protected static Method class_EntityLiving_damageEntityMethod; - protected static Method class_DamageSource_getMagicSourceMethod; - protected static Method class_EntityDamageSource_setThornsMethod; - protected static Method class_AxisAlignedBB_createBBMethod; - protected static Method class_World_explodeMethod; - protected static Method class_NBTTagCompound_setBooleanMethod; - protected static Method class_NBTTagCompound_setStringMethod; - protected static Method class_NBTTagCompound_setIntMethod; - protected static Method class_NBTTagCompound_removeMethod; - protected static Method class_NBTTagCompound_getStringMethod; - protected static Method class_NBTTagCompound_getIntMethod; - protected static Method class_NBTTagCompound_getByteMethod; - protected static Method class_NBTTagCompound_getMethod; - protected static Method class_NBTTagCompound_getCompoundMethod; - protected static Method class_NBTTagCompound_getShortMethod; - protected static Method class_NBTTagCompound_getByteArrayMethod; - protected static Method class_NBTTagCompound_getListMethod; - protected static Method class_TileEntity_loadMethod; - protected static Method class_TileEntity_saveMethod; - protected static Method class_TileEntity_updateMethod; - protected static Method class_World_addEntityMethod; - protected static Method class_CraftMetaBanner_getPatternsMethod; - protected static Method class_CraftMetaBanner_setPatternsMethod; - protected static Method class_CraftMetaBanner_getBaseColorMethod; - protected static Method class_CraftMetaBanner_setBaseColorMethod; - protected static Method class_CraftBanner_getPatternsMethod; - protected static Method class_CraftBanner_setPatternsMethod; - protected static Method class_CraftBanner_getBaseColorMethod; - protected static Method class_CraftBanner_setBaseColorMethod; - protected static Method class_NBTCompressedStreamTools_loadFileMethod; - protected static Method class_ItemStack_createStackMethod; - protected static Method class_CraftItemStack_asBukkitCopyMethod; - protected static Method class_CraftItemStack_copyMethod; - protected static Method class_CraftItemStack_mirrorMethod; - protected static Method class_NBTTagCompound_hasKeyMethod; - protected static Method class_CraftWorld_getTileEntityAtMethod; - protected static Method class_CraftWorld_spawnMethod; - protected static Method class_Entity_setLocationMethod; - protected static Method class_Entity_getIdMethod; - protected static Method class_Entity_getDataWatcherMethod; - protected static Method class_Server_getOnlinePlayers; - protected static Method class_Entity_getBoundingBox; - protected static Method class_TileEntityContainer_setLock; - protected static Method class_TileEntityContainer_getLock; - protected static Method class_ChestLock_isEmpty; - protected static Method class_ChestLock_getString; - protected static Method class_ArmorStand_setInvisible; - protected static Method class_ArmorStand_setMarker; - protected static Method class_ArmorStand_setGravity; - protected static Method class_ArmorStand_setSmall; - protected static Method class_CraftPlayer_getHandleMethod; - protected static Method class_CraftChunk_getHandleMethod; - protected static Method class_CraftEntity_getHandleMethod; - protected static Method class_CraftLivingEntity_getHandleMethod; - protected static Method class_CraftWorld_getHandleMethod; - protected static Method class_EntityPlayer_openSignMethod; - - protected static Constructor class_NBTTagList_consructor; - protected static Constructor class_NBTTagList_legacy_consructor; - protected static Constructor class_CraftInventoryCustom_constructor; - protected static Constructor class_NBTTagByte_constructor; - protected static Constructor class_NBTTagByte_legacy_constructor; - protected static Constructor class_EntityFireworkConstructor; - protected static Constructor class_EntityPaintingConstructor; - protected static Constructor class_EntityItemFrameConstructor; - protected static Constructor class_BlockPositionConstructor; - protected static Constructor class_PacketSpawnEntityConstructor; - protected static Constructor class_PacketSpawnLivingEntityConstructor; - protected static Constructor class_PacketPlayOutEntityMetadata_Constructor; - protected static Constructor class_PacketPlayOutEntityStatus_Constructor; - protected static Constructor class_PacketPlayOutEntityDestroy_Constructor; - protected static Constructor class_ChestLock_Constructor; - protected static Constructor class_ArmorStand_Constructor; - - protected static Field class_Entity_invulnerableField; - protected static Field class_Entity_motXField; - protected static Field class_Entity_motYField; - protected static Field class_Entity_motZField; - protected static Field class_WorldServer_entitiesByUUIDField; - protected static Field class_ItemStack_tagField; - protected static Field class_DamageSource_MagicField; - protected static Field class_Firework_ticksFlownField; - protected static Field class_Firework_expectedLifespanField; - protected static Field class_CraftSkull_profile; - protected static Field class_CraftMetaSkull_profile; - protected static Field class_GameProfile_properties; - protected static Field class_GameProfileProperty_value; - protected static Field class_ItemStack_count; - protected static Field class_EntityTNTPrimed_source; - protected static Field class_NBTTagList_list; - protected static Field class_AxisAlignedBB_minXField; - protected static Field class_AxisAlignedBB_minYField; - protected static Field class_AxisAlignedBB_minZField; - protected static Field class_AxisAlignedBB_maxXField; - protected static Field class_AxisAlignedBB_maxYField; - protected static Field class_AxisAlignedBB_maxZField; - protected static Field class_EntityFallingBlock_hurtEntitiesField; - protected static Field class_EntityFallingBlock_fallHurtMaxField; - protected static Field class_EntityFallingBlock_fallHurtAmountField; - protected static Field class_EntityArmorStand_disabledSlotsField; - protected static Field class_EntityPlayer_playerConnectionField; - protected static Field class_PlayerConnection_floatCountField; - protected static Field class_Chunk_doneField; - protected static Field class_CraftItemStack_getHandleField; - protected static Field class_EntityArrow_lifeField = null; - protected static Field class_EntityArrow_fromPlayerField; - protected static Field class_EntityArrow_damageField; - protected static Field class_CraftWorld_environmentField; - - static { - // Find classes Bukkit hides from us. :-D - // Much thanks to @DPOHVAR for sharing the PowerNBT code that powers the reflection approach. - String className = Bukkit.getServer().getClass().getName(); - String[] packages = className.split("\\."); - if (packages.length == 5) { - versionPrefix = packages[3] + "."; - } - - try { - class_Entity = fixBukkitClass("net.minecraft.server.Entity"); - class_EntityLiving = fixBukkitClass("net.minecraft.server.EntityLiving"); - class_ItemStack = fixBukkitClass("net.minecraft.server.ItemStack"); - class_DataWatcher = fixBukkitClass("net.minecraft.server.DataWatcher"); - class_NBTBase = fixBukkitClass("net.minecraft.server.NBTBase"); - class_NBTTagCompound = fixBukkitClass("net.minecraft.server.NBTTagCompound"); - class_NBTTagList = fixBukkitClass("net.minecraft.server.NBTTagList"); - class_NBTTagString = fixBukkitClass("net.minecraft.server.NBTTagString"); - class_NBTTagByte = fixBukkitClass("net.minecraft.server.NBTTagByte"); - class_CraftWorld = fixBukkitClass("org.bukkit.craftbukkit.CraftWorld"); - class_CraftInventoryCustom = fixBukkitClass("org.bukkit.craftbukkit.inventory.CraftInventoryCustom"); - class_CraftItemStack = fixBukkitClass("org.bukkit.craftbukkit.inventory.CraftItemStack"); - class_CraftBlockState = fixBukkitClass("org.bukkit.craftbukkit.block.CraftBlockState"); - class_CraftTask = fixBukkitClass("org.bukkit.craftbukkit.scheduler.CraftTask"); - class_CraftLivingEntity = fixBukkitClass("org.bukkit.craftbukkit.entity.CraftLivingEntity"); - class_Packet = fixBukkitClass("net.minecraft.server.Packet"); - class_World = fixBukkitClass("net.minecraft.server.World"); - class_WorldServer = fixBukkitClass("net.minecraft.server.WorldServer"); - class_EnumSkyBlock = (Class) fixBukkitClass("net.minecraft.server.EnumSkyBlock"); - class_EntityPainting = fixBukkitClass("net.minecraft.server.EntityPainting"); - class_EntityCreature = fixBukkitClass("net.minecraft.server.EntityCreature"); - class_EntityItemFrame = fixBukkitClass("net.minecraft.server.EntityItemFrame"); - class_EntityMinecartRideable = fixBukkitClass("net.minecraft.server.EntityMinecartRideable"); - class_EntityTNTPrimed = fixBukkitClass("net.minecraft.server.EntityTNTPrimed"); - class_AxisAlignedBB = fixBukkitClass("net.minecraft.server.AxisAlignedBB"); - class_DamageSource = fixBukkitClass("net.minecraft.server.DamageSource"); - class_EntityDamageSource = fixBukkitClass("net.minecraft.server.EntityDamageSource"); - class_PathEntity = fixBukkitClass("net.minecraft.server.PathEntity"); - class_PathPoint = fixBukkitClass("net.minecraft.server.PathPoint"); - class_EntityFirework = fixBukkitClass("net.minecraft.server.EntityFireworks"); - class_CraftSkull = fixBukkitClass("org.bukkit.craftbukkit.block.CraftSkull"); - class_CraftMetaSkull = fixBukkitClass("org.bukkit.craftbukkit.inventory.CraftMetaSkull"); - class_NBTCompressedStreamTools = fixBukkitClass("net.minecraft.server.NBTCompressedStreamTools"); - class_TileEntity = fixBukkitClass("net.minecraft.server.TileEntity"); - class_EntityHorse = fixBukkitClass("net.minecraft.server.EntityHorse"); - class_EntityWitherSkull = fixBukkitClass("net.minecraft.server.EntityWitherSkull"); - class_PacketPlayOutAttachEntity = fixBukkitClass("net.minecraft.server.PacketPlayOutAttachEntity"); - class_PacketPlayOutEntityDestroy = fixBukkitClass("net.minecraft.server.PacketPlayOutEntityDestroy"); - class_PacketPlayOutSpawnEntity = fixBukkitClass("net.minecraft.server.PacketPlayOutSpawnEntity"); - class_PacketPlayOutSpawnEntityLiving = fixBukkitClass("net.minecraft.server.PacketPlayOutSpawnEntityLiving"); - class_PacketPlayOutEntityMetadata = fixBukkitClass("net.minecraft.server.PacketPlayOutEntityMetadata"); - class_PacketPlayOutEntityStatus = fixBukkitClass("net.minecraft.server.PacketPlayOutEntityStatus"); - class_EntityFallingBlock = fixBukkitClass("net.minecraft.server.EntityFallingBlock"); - class_EntityArmorStand = fixBukkitClass("net.minecraft.server.EntityArmorStand"); - class_EntityPlayer = fixBukkitClass("net.minecraft.server.EntityPlayer"); - class_PlayerConnection = fixBukkitClass("net.minecraft.server.PlayerConnection"); - class_Chunk = fixBukkitClass("net.minecraft.server.Chunk"); - class_CraftPlayer = fixBukkitClass("org.bukkit.craftbukkit.entity.CraftPlayer"); - class_CraftChunk = fixBukkitClass("org.bukkit.craftbukkit.CraftChunk"); - class_CraftEntity = fixBukkitClass("org.bukkit.craftbukkit.entity.CraftEntity"); - class_TileEntitySign = fixBukkitClass("net.minecraft.server.TileEntitySign"); - - class_EntityProjectile = NMSUtil18.getBukkitClass("net.minecraft.server.EntityProjectile"); - class_EntityFireball = NMSUtil18.getBukkitClass("net.minecraft.server.EntityFireball"); - class_EntityArrow = NMSUtil18.getBukkitClass("net.minecraft.server.EntityArrow"); - class_CraftArrow = NMSUtil18.getBukkitClass("org.bukkit.craftbukkit.entity.CraftArrow"); - - class_NBTTagList_addMethod = class_NBTTagList.getMethod("add", class_NBTBase); - class_NBTTagList_getMethod = class_NBTTagList.getMethod("get", Integer.TYPE); - class_NBTTagList_getDoubleMethod = class_NBTTagList.getMethod("d", Integer.TYPE); - class_NBTTagList_sizeMethod = class_NBTTagList.getMethod("size"); - class_NBTTagCompound_setMethod = class_NBTTagCompound.getMethod("set", String.class, class_NBTBase); - class_DataWatcher_watchMethod = class_DataWatcher.getMethod("watch", Integer.TYPE, Object.class); - class_World_getEntitiesMethod = class_World.getMethod("getEntities", class_Entity, class_AxisAlignedBB); - class_CraftWorld_getTileEntityAtMethod = class_CraftWorld.getMethod("getTileEntityAt", Integer.TYPE, Integer.TYPE, Integer.TYPE); - class_CraftWorld_spawnMethod = class_CraftWorld.getMethod("spawn", Location.class, Class.class, CreatureSpawnEvent.SpawnReason.class); - class_Entity_getBukkitEntityMethod = class_Entity.getMethod("getBukkitEntity"); - class_Entity_setYawPitchMethod = class_Entity.getDeclaredMethod("setYawPitch", Float.TYPE, Float.TYPE); - class_Entity_setYawPitchMethod.setAccessible(true); - class_Entity_setSilentMethod = class_Entity.getDeclaredMethod("b", Boolean.TYPE); - class_AxisAlignedBB_createBBMethod = class_AxisAlignedBB.getMethod("a", Double.TYPE, Double.TYPE, Double.TYPE, Double.TYPE, Double.TYPE, Double.TYPE); - class_World_explodeMethod = class_World.getMethod("createExplosion", class_Entity, Double.TYPE, Double.TYPE, Double.TYPE, Float.TYPE, Boolean.TYPE, Boolean.TYPE); - class_NBTTagCompound_setBooleanMethod = class_NBTTagCompound.getMethod("setBoolean", String.class, Boolean.TYPE); - class_NBTTagCompound_setStringMethod = class_NBTTagCompound.getMethod("setString", String.class, String.class); - class_NBTTagCompound_setIntMethod = class_NBTTagCompound.getMethod("setInt", String.class, Integer.TYPE); - class_NBTTagCompound_removeMethod = class_NBTTagCompound.getMethod("remove", String.class); - class_NBTTagCompound_getStringMethod = class_NBTTagCompound.getMethod("getString", String.class); - class_NBTTagCompound_getShortMethod = class_NBTTagCompound.getMethod("getShort", String.class); - class_NBTTagCompound_getIntMethod = class_NBTTagCompound.getMethod("getInt", String.class); - class_NBTTagCompound_getByteMethod = class_NBTTagCompound.getMethod("getByte", String.class); - class_NBTTagCompound_getByteArrayMethod = class_NBTTagCompound.getMethod("getByteArray", String.class); - class_NBTTagCompound_getListMethod = class_NBTTagCompound.getMethod("getList", String.class, Integer.TYPE); - class_CraftItemStack_copyMethod = class_CraftItemStack.getMethod("asNMSCopy", ItemStack.class); - class_CraftItemStack_asBukkitCopyMethod = class_CraftItemStack.getMethod("asBukkitCopy", class_ItemStack); - class_CraftItemStack_mirrorMethod = class_CraftItemStack.getMethod("asCraftMirror", class_ItemStack); - class_ItemStack_createStackMethod = class_ItemStack.getMethod("createStack", class_NBTTagCompound); - class_NBTTagCompound_hasKeyMethod = class_NBTTagCompound.getMethod("hasKey", String.class); - class_NBTTagCompound_getMethod = class_NBTTagCompound.getMethod("get", String.class); - class_NBTTagCompound_getCompoundMethod = class_NBTTagCompound.getMethod("getCompound", String.class); - class_EntityLiving_damageEntityMethod = class_EntityLiving.getMethod("damageEntity", class_DamageSource, Float.TYPE); - class_DamageSource_getMagicSourceMethod = class_DamageSource.getMethod("b", class_Entity, class_Entity); - class_World_addEntityMethod = class_World.getMethod("addEntity", class_Entity, CreatureSpawnEvent.SpawnReason.class); - class_NBTCompressedStreamTools_loadFileMethod = class_NBTCompressedStreamTools.getMethod("a", InputStream.class); - class_TileEntity_loadMethod = class_TileEntity.getMethod("a", class_NBTTagCompound); - class_TileEntity_saveMethod = class_TileEntity.getMethod("b", class_NBTTagCompound); - class_TileEntity_updateMethod = class_TileEntity.getMethod("update"); - class_Entity_setLocationMethod = class_Entity.getMethod("setLocation", Double.TYPE, Double.TYPE, Double.TYPE, Float.TYPE, Float.TYPE); - class_Entity_getIdMethod = class_Entity.getMethod("getId"); - class_Entity_getDataWatcherMethod = class_Entity.getMethod("getDataWatcher"); - class_Server_getOnlinePlayers = Server.class.getMethod("getOnlinePlayers"); - class_ArmorStand_setInvisible = class_EntityArmorStand.getDeclaredMethod("setInvisible", Boolean.TYPE); - class_ArmorStand_setGravity = class_EntityArmorStand.getDeclaredMethod("setGravity", Boolean.TYPE); - class_ArmorStand_setSmall = class_EntityArmorStand.getDeclaredMethod("setSmall", Boolean.TYPE); - class_ArmorStand_setMarker = class_EntityArmorStand.getDeclaredMethod("n", Boolean.TYPE); - class_ArmorStand_setMarker.setAccessible(true); - class_CraftPlayer_getHandleMethod = class_CraftPlayer.getMethod("getHandle"); - class_CraftChunk_getHandleMethod = class_CraftChunk.getMethod("getHandle"); - class_CraftEntity_getHandleMethod = class_CraftEntity.getMethod("getHandle"); - class_CraftLivingEntity_getHandleMethod = class_CraftLivingEntity.getMethod("getHandle"); - class_CraftWorld_getHandleMethod = class_CraftWorld.getMethod("getHandle"); - class_EntityPlayer_openSignMethod = class_EntityPlayer.getMethod("openSign", class_TileEntitySign); - - class_CraftInventoryCustom_constructor = class_CraftInventoryCustom.getConstructor(InventoryHolder.class, Integer.TYPE, String.class); - class_EntityFireworkConstructor = class_EntityFirework.getConstructor(class_World, Double.TYPE, Double.TYPE, Double.TYPE, class_ItemStack); - class_PacketSpawnEntityConstructor = class_PacketPlayOutSpawnEntity.getConstructor(class_Entity, Integer.TYPE); - class_PacketSpawnLivingEntityConstructor = class_PacketPlayOutSpawnEntityLiving.getConstructor(class_EntityLiving); - class_PacketPlayOutEntityMetadata_Constructor = class_PacketPlayOutEntityMetadata.getConstructor(Integer.TYPE, class_DataWatcher, Boolean.TYPE); - class_PacketPlayOutEntityStatus_Constructor = class_PacketPlayOutEntityStatus.getConstructor(class_Entity, Byte.TYPE); - class_PacketPlayOutEntityDestroy_Constructor = class_PacketPlayOutEntityDestroy.getConstructor(int[].class); - - class_CraftWorld_environmentField = class_CraftWorld.getDeclaredField("environment"); - class_CraftWorld_environmentField.setAccessible(true); - class_Entity_invulnerableField = class_Entity.getDeclaredField("invulnerable"); - class_Entity_invulnerableField.setAccessible(true); - class_Entity_motXField = class_Entity.getDeclaredField("motX"); - class_Entity_motXField.setAccessible(true); - class_Entity_motYField = class_Entity.getDeclaredField("motY"); - class_Entity_motYField.setAccessible(true); - class_Entity_motZField = class_Entity.getDeclaredField("motZ"); - class_Entity_motZField.setAccessible(true); - class_WorldServer_entitiesByUUIDField = class_WorldServer.getDeclaredField("entitiesByUUID"); - class_WorldServer_entitiesByUUIDField.setAccessible(true); - class_ItemStack_tagField = class_ItemStack.getDeclaredField("tag"); - class_ItemStack_tagField.setAccessible(true); - class_DamageSource_MagicField = class_DamageSource.getField("MAGIC"); - class_EntityTNTPrimed_source = class_EntityTNTPrimed.getDeclaredField("source"); - class_EntityTNTPrimed_source.setAccessible(true); - class_AxisAlignedBB_minXField = class_AxisAlignedBB.getField("a"); - class_AxisAlignedBB_minYField = class_AxisAlignedBB.getField("b"); - class_AxisAlignedBB_minZField = class_AxisAlignedBB.getField("c"); - class_AxisAlignedBB_maxXField = class_AxisAlignedBB.getField("d"); - class_AxisAlignedBB_maxYField = class_AxisAlignedBB.getField("e"); - class_AxisAlignedBB_maxZField = class_AxisAlignedBB.getField("f"); - class_EntityArmorStand_disabledSlotsField = class_EntityArmorStand.getDeclaredField("bi"); - class_EntityArmorStand_disabledSlotsField.setAccessible(true); - class_EntityPlayer_playerConnectionField = class_EntityPlayer.getDeclaredField("playerConnection"); - class_PlayerConnection_floatCountField = class_PlayerConnection.getDeclaredField("g"); - class_PlayerConnection_floatCountField.setAccessible(true); - - class_Firework_ticksFlownField = class_EntityFirework.getDeclaredField("ticksFlown"); - class_Firework_ticksFlownField.setAccessible(true); - class_Firework_expectedLifespanField = class_EntityFirework.getDeclaredField("expectedLifespan"); - class_Firework_expectedLifespanField.setAccessible(true); - - class_NBTTagList_consructor = class_NBTTagString.getConstructor(String.class); - class_NBTTagByte_constructor = class_NBTTagByte.getConstructor(Byte.TYPE); - class_ItemStack_count = class_ItemStack.getDeclaredField("count"); - class_ItemStack_count.setAccessible(true); - - class_NBTTagList_list = class_NBTTagList.getDeclaredField("list"); - class_NBTTagList_list.setAccessible(true); - - class_EntityFallingBlock_hurtEntitiesField = class_EntityFallingBlock.getDeclaredField("hurtEntities"); - class_EntityFallingBlock_hurtEntitiesField.setAccessible(true); - class_EntityFallingBlock_fallHurtAmountField = class_EntityFallingBlock.getDeclaredField("fallHurtAmount"); - class_EntityFallingBlock_fallHurtAmountField.setAccessible(true); - class_EntityFallingBlock_fallHurtMaxField = class_EntityFallingBlock.getDeclaredField("fallHurtMax"); - class_EntityFallingBlock_fallHurtMaxField.setAccessible(true); - - class_Chunk_doneField = class_Chunk.getDeclaredField("done"); - class_Chunk_doneField.setAccessible(true); - class_CraftItemStack_getHandleField = class_CraftItemStack.getDeclaredField("handle"); - class_CraftItemStack_getHandleField.setAccessible(true); - - class_TileEntityContainer = fixBukkitClass("net.minecraft.server.TileEntityContainer"); - class_ChestLock = fixBukkitClass("net.minecraft.server.ChestLock"); - class_TileEntityContainer_setLock = class_TileEntityContainer.getMethod("a", class_ChestLock); - class_TileEntityContainer_getLock = class_TileEntityContainer.getMethod("i"); - class_ChestLock_isEmpty = class_ChestLock.getMethod("a"); - class_ChestLock_getString = class_ChestLock.getMethod("b"); - class_Entity_getBoundingBox = class_Entity.getMethod("getBoundingBox"); - class_GameProfile = getClass("com.mojang.authlib.GameProfile"); - class_GameProfileProperty = getClass("com.mojang.authlib.properties.Property"); - class_CraftSkull_profile = class_CraftSkull.getDeclaredField("profile"); - class_CraftSkull_profile.setAccessible(true); - class_CraftMetaSkull_profile = class_CraftMetaSkull.getDeclaredField("profile"); - class_CraftMetaSkull_profile.setAccessible(true); - class_GameProfile_properties = class_GameProfile.getDeclaredField("properties"); - class_GameProfile_properties.setAccessible(true); - class_GameProfileProperty_value = class_GameProfileProperty.getDeclaredField("value"); - class_GameProfileProperty_value.setAccessible(true); - - class_CraftMetaBanner = fixBukkitClass("org.bukkit.craftbukkit.inventory.CraftMetaBanner"); - class_CraftMetaBanner_getBaseColorMethod = class_CraftMetaBanner.getMethod("getBaseColor"); - class_CraftMetaBanner_getPatternsMethod = class_CraftMetaBanner.getMethod("getPatterns"); - class_CraftMetaBanner_setPatternsMethod = class_CraftMetaBanner.getMethod("setPatterns", List.class); - class_CraftMetaBanner_setBaseColorMethod = class_CraftMetaBanner.getMethod("setBaseColor", DyeColor.class); - - class_CraftBanner = fixBukkitClass("org.bukkit.craftbukkit.block.CraftBanner"); - class_CraftBanner_getBaseColorMethod = class_CraftBanner.getMethod("getBaseColor"); - class_CraftBanner_getPatternsMethod = class_CraftBanner.getMethod("getPatterns"); - class_CraftBanner_setPatternsMethod = class_CraftBanner.getMethod("setPatterns", List.class); - class_CraftBanner_setBaseColorMethod = class_CraftBanner.getMethod("setBaseColor", DyeColor.class); - class_EntityDamageSource_setThornsMethod = class_EntityDamageSource.getMethod("v"); - - class_BlockPosition = fixBukkitClass("net.minecraft.server.BlockPosition"); - class_EnumDirection = (Class) fixBukkitClass("net.minecraft.server.EnumDirection"); - class_BlockPositionConstructor = class_BlockPosition.getConstructor(Double.TYPE, Double.TYPE, Double.TYPE); - class_EntityPaintingConstructor = class_EntityPainting.getConstructor(class_World, class_BlockPosition, class_EnumDirection); - class_EntityItemFrameConstructor = class_EntityItemFrame.getConstructor(class_World, class_BlockPosition, class_EnumDirection); - class_ChestLock_Constructor = class_ChestLock.getConstructor(String.class); - class_ArmorStand_Constructor = class_EntityArmorStand.getConstructor(class_World); - - class_PacketPlayOutMapChunkBulk = getVersionedBukkitClass("net.minecraft.server.PacketPlayOutMapChunkBulk", "net.minecraft.server.Packet56MapChunkBulk"); - - try { - class_EntityArrow_fromPlayerField = class_EntityArrow.getField("fromPlayer"); - class_EntityArrow_damageField = class_EntityArrow.getDeclaredField("damage"); - class_EntityArrow_damageField.setAccessible(true); - // This is kinda hacky, like fer reals :\ - try { - // 1.8.3 - class_EntityArrow_lifeField = class_EntityArrow.getDeclaredField("ar"); - } catch (Throwable ignore3) { - try { - // 1.8 - class_EntityArrow_lifeField = class_EntityArrow.getDeclaredField("ap"); - } catch (Throwable ignore2) { - try { - // 1.7 - class_EntityArrow_lifeField = class_EntityArrow.getDeclaredField("at"); - } catch (Throwable ignore) { - // Prior - class_EntityArrow_lifeField = class_EntityArrow.getDeclaredField("j"); - } - } - } - } catch (Throwable ex) { - class_EntityArrow_lifeField = null; - } - if (class_EntityArrow_lifeField != null) { - class_EntityArrow_lifeField.setAccessible(true); - } - } catch (Throwable ex) { - failed = true; - ex.printStackTrace(); - } - } - - public static boolean getFailed() { - return failed; - } - - public static Class getVersionedBukkitClass(String newVersion, String oldVersion) { - Class c = getBukkitClass(newVersion); - if (c == null) { - c = getBukkitClass(oldVersion); - if (c == null) { - Bukkit.getLogger().warning("Could not bind to " + newVersion + " or " + oldVersion); - } - } - return c; - } - - public static Class getClass(String className) { - Class result = null; - try { - result = NMSUtil18.class.getClassLoader().loadClass(className); - } catch (Exception ex) { - result = null; - } - - return result; - } - - public static Class getBukkitClass(String className) { - Class result = null; - try { - result = fixBukkitClass(className); - } catch (Exception ex) { - result = null; - } - - return result; - } - - public static Class fixBukkitClass(String className) throws ClassNotFoundException { - if (!versionPrefix.isEmpty()) { - className = className.replace("org.bukkit.craftbukkit.", "org.bukkit.craftbukkit." + versionPrefix); - className = className.replace("net.minecraft.server.", "net.minecraft.server." + versionPrefix); - } - - return NMSUtil18.class.getClassLoader().loadClass(className); - } - - public static Object getHandle(ItemStack stack) { - Object handle = null; - try { - handle = class_CraftItemStack_getHandleField.get(stack); - } catch (Throwable ex) { - handle = null; - } - return handle; - } - - public static Object getHandle(World world) { - if (world == null) { - return null; - } - Object handle = null; - try { - handle = class_CraftWorld_getHandleMethod.invoke(world); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return handle; - } - - public static Object getHandle(Entity entity) { - if (entity == null) { - return null; - } - Object handle = null; - try { - handle = class_CraftEntity_getHandleMethod.invoke(entity); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return handle; - } - - public static Object getHandle(org.bukkit.entity.LivingEntity entity) { - if (entity == null) { - return null; - } - Object handle = null; - try { - handle = class_CraftLivingEntity_getHandleMethod.invoke(entity); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return handle; - } - - public static boolean isDone(Chunk chunk) { - Object chunkHandle = getHandle(chunk); - boolean done = false; - try { - done = (Boolean) class_Chunk_doneField.get(chunkHandle); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return done; - } - - public static Object getHandle(Chunk chunk) { - Object handle = null; - try { - handle = class_CraftChunk_getHandleMethod.invoke(chunk); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return handle; - } - - public static Object getHandle(Player player) { - Object handle = null; - try { - handle = class_CraftPlayer_getHandleMethod.invoke(player); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return handle; - } - - protected static void sendPacket(Server server, Location source, Collection players, Object packet) throws Exception { - players = ((players != null && players.size() > 0) ? players : server.getOnlinePlayers()); - - int viewDistance = Bukkit.getServer().getViewDistance() * 16; - int viewDistanceSquared = viewDistance * viewDistance; - World sourceWorld = source.getWorld(); - for (Player player : players) { - Location location = player.getLocation(); - if (!location.getWorld().equals(sourceWorld)) { - continue; - } - if (location.distanceSquared(source) <= viewDistanceSquared) { - sendPacket(player, packet); - } - } - } - - protected static void sendPacket(Player player, Object packet) throws Exception { - Object playerHandle = getHandle(player); - Field connectionField = playerHandle.getClass().getField("playerConnection"); - Object connection = connectionField.get(playerHandle); - Method sendPacketMethod = connection.getClass().getMethod("sendPacket", class_Packet); - sendPacketMethod.invoke(connection, packet); - } - - public static int getFacing(BlockFace direction) { - int dir; - switch (direction) { - case SOUTH: - default: - dir = 0; - break; - case WEST: - dir = 1; - break; - case NORTH: - dir = 2; - break; - case EAST: - dir = 3; - break; - } - - return dir; - } - - public static Entity getBukkitEntity(Object entity) { - if (entity == null) { - return null; - } - try { - Method getMethod = entity.getClass().getMethod("getBukkitEntity"); - Object bukkitEntity = getMethod.invoke(entity); - if (!(bukkitEntity instanceof Entity)) { - return null; - } - return (Entity) bukkitEntity; - } catch (Throwable ex) { - ex.printStackTrace(); - } - - return null; - } - - public static Object getTag(Object mcItemStack) { - Object tag = null; - try { - tag = class_ItemStack_tagField.get(mcItemStack); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return tag; - } - - protected static Object getNMSCopy(ItemStack stack) { - Object nms = null; - try { - nms = class_CraftItemStack_copyMethod.invoke(null, stack); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return nms; - } - - public static ItemStack getCopy(ItemStack stack) { - if (stack == null) { - return null; - } - - try { - Object craft = getNMSCopy(stack); - stack = (ItemStack) class_CraftItemStack_mirrorMethod.invoke(null, craft); - } catch (Throwable ex) { - stack = null; - } - - return stack; - } - - public static ItemStack makeReal(ItemStack stack) { - if (stack == null) { - return null; - } - Object nmsStack = getHandle(stack); - if (nmsStack == null) { - stack = getCopy(stack); - nmsStack = getHandle(stack); - } - if (nmsStack == null) { - return null; - } - try { - Object tag = class_ItemStack_tagField.get(nmsStack); - if (tag == null) { - class_ItemStack_tagField.set(nmsStack, class_NBTTagCompound.newInstance()); - } - } catch (Throwable ex) { - ex.printStackTrace(); - return null; - } - - return stack; - } - - public static String getMeta(ItemStack stack, String tag, String defaultValue) { - String result = getMeta(stack, tag); - return result == null ? defaultValue : result; - } - - public static boolean hasMeta(ItemStack stack, String tag) { - return getNode(stack, tag) != null; - } - - public static Object getNode(ItemStack stack, String tag) { - if (stack == null) { - return null; - } - Object meta = null; - try { - Object craft = getHandle(stack); - if (craft == null) { - return null; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return null; - } - meta = class_NBTTagCompound_getMethod.invoke(tagObject, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return meta; - } - - public static boolean containsNode(Object nbtBase, String tag) { - if (nbtBase == null) { - return false; - } - Boolean result = false; - try { - result = (Boolean) class_NBTTagCompound_hasKeyMethod.invoke(nbtBase, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return result; - } - - public static Object getNode(Object nbtBase, String tag) { - if (nbtBase == null) { - return null; - } - Object meta = null; - try { - meta = class_NBTTagCompound_getMethod.invoke(nbtBase, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return meta; - } - - public static Object createNode(Object nbtBase, String tag) { - if (nbtBase == null) { - return null; - } - Object meta = null; - try { - meta = class_NBTTagCompound_getCompoundMethod.invoke(nbtBase, tag); - class_NBTTagCompound_setMethod.invoke(nbtBase, tag, meta); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return meta; - } - - public static Object createNode(ItemStack stack, String tag) { - if (stack == null) { - return null; - } - Object outputObject = getNode(stack, tag); - if (outputObject == null) { - try { - Object craft = getHandle(stack); - if (craft == null) { - return null; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return null; - } - outputObject = class_NBTTagCompound.newInstance(); - class_NBTTagCompound_setMethod.invoke(tagObject, tag, outputObject); - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - return outputObject; - } - - public static String getMeta(Object node, String tag, String defaultValue) { - String meta = getMeta(node, tag); - return meta == null || meta.length() == 0 ? defaultValue : meta; - } - - public static String getMeta(Object node, String tag) { - if (node == null || !class_NBTTagCompound.isInstance(node)) { - return null; - } - String meta = null; - try { - meta = (String) class_NBTTagCompound_getStringMethod.invoke(node, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return meta; - } - - public static Byte getMetaByte(Object node, String tag) { - if (node == null || !class_NBTTagCompound.isInstance(node)) { - return null; - } - Byte meta = null; - try { - meta = (Byte) class_NBTTagCompound_getByteMethod.invoke(node, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return meta; - } - - public static Integer getMetaInt(Object node, String tag) { - if (node == null || !class_NBTTagCompound.isInstance(node)) { - return null; - } - Integer meta = null; - try { - meta = (Integer) class_NBTTagCompound_getIntMethod.invoke(node, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return meta; - } - - public static void setMeta(Object node, String tag, String value) { - if (node == null || !class_NBTTagCompound.isInstance(node)) { - return; - } - try { - if (value == null || value.length() == 0) { - class_NBTTagCompound_removeMethod.invoke(node, tag); - } else { - class_NBTTagCompound_setStringMethod.invoke(node, tag, value); - } - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - - public static void removeMeta(Object node, String tag) { - if (node == null || !class_NBTTagCompound.isInstance(node)) { - return; - } - try { - class_NBTTagCompound_removeMethod.invoke(node, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - - public static void removeMeta(ItemStack stack, String tag) { - if (stack == null) { - return; - } - - try { - Object craft = getHandle(stack); - if (craft == null) { - return; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return; - } - removeMeta(tagObject, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - - public static String getMeta(ItemStack stack, String tag) { - if (stack == null) { - return null; - } - String meta = null; - try { - Object craft = getHandle(stack); - if (craft == null) { - return null; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return null; - } - meta = (String) class_NBTTagCompound_getStringMethod.invoke(tagObject, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return meta; - } - - public static void setMeta(ItemStack stack, String tag, String value) { - if (stack == null) { - return; - } - try { - Object craft = getHandle(stack); - if (craft == null) { - return; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return; - } - class_NBTTagCompound_setStringMethod.invoke(tagObject, tag, value); - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - - public static void addGlow(ItemStack stack) { - if (stack == null) { - return; - } - - try { - Object craft = getHandle(stack); - if (craft == null) { - return; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return; - } - final Object enchList = class_NBTTagList.newInstance(); - class_NBTTagCompound_setMethod.invoke(tagObject, "ench", enchList); - - // Testing Glow API based on ItemMetadata storage - Object bukkitData = createNode(stack, "bukkit"); - class_NBTTagCompound_setBooleanMethod.invoke(bukkitData, "glow", true); - } catch (Throwable ignored) { - - } - } - - public static void removeGlow(ItemStack stack) { - if (stack == null) { - return; - } - - Collection enchants = stack.getEnchantments().keySet(); - for (Enchantment enchant : enchants) { - stack.removeEnchantment(enchant); - } - - try { - Object craft = getHandle(stack); - if (craft == null) { - return; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return; - } - - // Testing Glow API based on ItemMetadata storage - Object bukkitData = getNode(stack, "bukkit"); - if (bukkitData != null) { - class_NBTTagCompound_setBooleanMethod.invoke(bukkitData, "glow", false); - } - } catch (Throwable ignored) { - - } - } - - public static void makeUnbreakable(ItemStack stack) { - if (stack == null) { - return; - } - - try { - Object craft = getHandle(stack); - if (craft == null) { - return; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return; - } - - Object unbreakableFlag = null; - if (class_NBTTagByte_constructor != null) { - unbreakableFlag = class_NBTTagByte_constructor.newInstance((byte) 1); - } else { - unbreakableFlag = class_NBTTagByte_legacy_constructor.newInstance("", (byte) 1); - } - class_NBTTagCompound_setMethod.invoke(tagObject, "Unbreakable", unbreakableFlag); - } catch (Throwable ignored) { - - } - } - - public static void removeUnbreakable(ItemStack stack) { - removeMeta(stack, "Unbreakable"); - } - - public static void hideFlags(ItemStack stack, byte flags) { - if (stack == null) { - return; - } - - try { - Object craft = getHandle(stack); - if (craft == null) { - return; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return; - } - - Object hideFlag = null; - if (class_NBTTagByte_constructor != null) { - hideFlag = class_NBTTagByte_constructor.newInstance(flags); - } else { - hideFlag = class_NBTTagByte_legacy_constructor.newInstance("", flags); - } - class_NBTTagCompound_setMethod.invoke(tagObject, "HideFlags", hideFlag); - } catch (Throwable ignored) { - - } - } - - public static boolean createExplosion(Entity entity, World world, double x, double y, double z, float power, boolean setFire, boolean breakBlocks) { - boolean result = false; - if (world == null) { - return false; - } - try { - Object worldHandle = getHandle(world); - if (worldHandle == null) { - return false; - } - Object entityHandle = entity == null ? null : getHandle(entity); - - Object explosion = class_World_explodeMethod.invoke(worldHandle, entityHandle, x, y, z, power, setFire, breakBlocks); - Field cancelledField = explosion.getClass().getDeclaredField("wasCanceled"); - result = (Boolean) cancelledField.get(explosion); - } catch (Throwable ex) { - ex.printStackTrace(); - result = false; - } - return result; - } - - public static void makeTemporary(ItemStack itemStack, String message) { - setMeta(itemStack, "temporary", message); - } - - public static boolean isTemporary(ItemStack itemStack) { - return hasMeta(itemStack, "temporary"); - } - - public static void makeUnplaceable(ItemStack itemStack) { - setMeta(itemStack, "unplaceable", "true"); - } - - public static boolean isUnplaceable(ItemStack itemStack) { - return hasMeta(itemStack, "unplaceable"); - } - - public static String getTemporaryMessage(ItemStack itemStack) { - return getMeta(itemStack, "temporary"); - } - - public static void setReplacement(ItemStack itemStack, ItemStack replacement) { - YamlConfiguration configuration = new YamlConfiguration(); - configuration.set("item", replacement); - setMeta(itemStack, "replacement", configuration.saveToString()); - } - - public static ItemStack getReplacement(ItemStack itemStack) { - String serialized = getMeta(itemStack, "replacement"); - if (serialized == null || serialized.isEmpty()) { - return null; - } - YamlConfiguration configuration = new YamlConfiguration(); - ItemStack replacement = null; - try { - configuration.loadFromString(serialized); - replacement = configuration.getItemStack("item"); - } catch (Exception ex) { - ex.printStackTrace(); - } - return replacement; - } - - protected static Object getTagString(String value) { - try { - if (class_NBTTagList_legacy_consructor != null) { - return class_NBTTagList_legacy_consructor.newInstance("", value); - } - return class_NBTTagList_consructor.newInstance(value); - } catch (Exception ex) { - ex.printStackTrace(); - - } - return null; - } - - public static Object setStringList(Object nbtBase, String tag, Collection values) { - if (nbtBase == null) { - return null; - } - Object listMeta = null; - try { - listMeta = class_NBTTagList.newInstance(); - - for (String value : values) { - Object nbtString = getTagString(value); - class_NBTTagList_addMethod.invoke(listMeta, nbtString); - } - - class_NBTTagCompound_setMethod.invoke(nbtBase, tag, listMeta); - } catch (Throwable ex) { - ex.printStackTrace(); - return null; - } - return listMeta; - } - - public static ItemStack getItem(Object itemTag) { - if (itemTag == null) { - return null; - } - ItemStack item = null; - try { - Object nmsStack = class_ItemStack_createStackMethod.invoke(null, itemTag); - item = (ItemStack) class_CraftItemStack_mirrorMethod.invoke(null, nmsStack); - } catch (Exception ex) { - ex.printStackTrace(); - } - return item; - } - - public static ItemStack[] getItems(Object rootTag, String tagName) { - try { - Object itemList = class_NBTTagCompound_getListMethod.invoke(rootTag, tagName, NBT_TYPE_COMPOUND); - Integer size = (Integer) class_NBTTagList_sizeMethod.invoke(itemList); - ItemStack[] items = new ItemStack[size]; - for (int i = 0; i < size; i++) { - try { - Object itemData = class_NBTTagList_getMethod.invoke(itemList, i); - if (itemData != null) { - items[i] = getItem(itemData); - } - } catch (Exception ex) { - ex.printStackTrace(); - } - } - return items; - } catch (Exception ex) { - ex.printStackTrace(); - } - return null; - } - - public static Object getTileEntityData(Location location) { - Object data = null; - try { - World world = location.getWorld(); - Object tileEntity = class_CraftWorld_getTileEntityAtMethod.invoke(world, location.getBlockX(), location.getBlockY(), location.getBlockZ()); - if (tileEntity != null) { - data = class_NBTTagCompound.newInstance(); - class_TileEntity_saveMethod.invoke(tileEntity, data); - } - } catch (Exception ex) { - ex.printStackTrace(); - } - return data; - } - - public static Object getTileEntity(Location location) { - Object tileEntity = null; - try { - World world = location.getWorld(); - tileEntity = class_CraftWorld_getTileEntityAtMethod.invoke(world, location.getBlockX(), location.getBlockY(), location.getBlockZ()); - } catch (Exception ex) { - ex.printStackTrace(); - } - return tileEntity; - } - - public static void clearItems(Location location) { - if (location == null) { - return; - } - try { - World world = location.getWorld(); - if (world == null) { - return; - } - - Object tileEntity = class_CraftWorld_getTileEntityAtMethod.invoke(world, location.getBlockX(), location.getBlockY(), location.getBlockZ()); - if (tileEntity != null) { - Object entityData = class_NBTTagCompound.newInstance(); - class_TileEntity_saveMethod.invoke(tileEntity, entityData); - Object itemList = class_NBTTagCompound_getListMethod.invoke(entityData, "Items", NBT_TYPE_COMPOUND); - if (itemList != null) { - List items = (List) class_NBTTagList_list.get(itemList); - items.clear(); - class_TileEntity_loadMethod.invoke(tileEntity, entityData); - class_TileEntity_updateMethod.invoke(tileEntity); - } - } - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - public static void setTileEntityData(Location location, Object data) { - if (location == null || data == null) { - return; - } - try { - World world = location.getWorld(); - if (world == null) { - return; - } - - Object tileEntity = class_CraftWorld_getTileEntityAtMethod.invoke(world, location.getBlockX(), location.getBlockY(), location.getBlockZ()); - if (tileEntity == null) { - return; - } - - class_NBTTagCompound_setIntMethod.invoke(data, "x", location.getBlockX()); - class_NBTTagCompound_setIntMethod.invoke(data, "y", location.getBlockY()); - class_NBTTagCompound_setIntMethod.invoke(data, "z", location.getBlockZ()); - - class_TileEntity_loadMethod.invoke(tileEntity, data); - class_TileEntity_updateMethod.invoke(tileEntity); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - public static Vector getPosition(Object entityData, String tag) { - try { - Object posList = class_NBTTagCompound_getListMethod.invoke(entityData, tag, NBT_TYPE_DOUBLE); - Double x = (Double) class_NBTTagList_getDoubleMethod.invoke(posList, 0); - Double y = (Double) class_NBTTagList_getDoubleMethod.invoke(posList, 1); - Double z = (Double) class_NBTTagList_getDoubleMethod.invoke(posList, 2); - if (x != null && y != null && z != null) { - return new Vector(x, y, z); - } - } catch (Exception ex) { - ex.printStackTrace(); - } - return null; - } - - public static Entity getEntity(World world, UUID uuid) { - try { - Object worldHandle = getHandle(world); - final Map entityMap = (Map) class_WorldServer_entitiesByUUIDField.get(worldHandle); - if (entityMap != null) { - Object nmsEntity = entityMap.get(uuid); - if (nmsEntity != null) { - return getBukkitEntity(nmsEntity); - } - } - } catch (Exception ex) { - ex.printStackTrace(); - } - return null; - } - - public static void setEnvironment(World world, World.Environment environment) { - try { - class_CraftWorld_environmentField.set(world, environment); - } catch (Exception ex) { - ex.printStackTrace(); - } - } -} diff --git a/src/main/java/me/skymc/taboolib/nms/NMSUtil19.java b/src/main/java/me/skymc/taboolib/nms/NMSUtil19.java deleted file mode 100644 index 5a59bf6..0000000 --- a/src/main/java/me/skymc/taboolib/nms/NMSUtil19.java +++ /dev/null @@ -1,1963 +0,0 @@ -package me.skymc.taboolib.nms; - -import org.apache.commons.lang.StringUtils; -import org.bukkit.*; -import org.bukkit.block.BlockFace; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.MemorySection; -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.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; - -/** - * @author Unknown - */ -@SuppressWarnings({"rawtypes", "unchecked"}) -public class NMSUtil19 { - - protected static boolean failed = false; - protected static boolean legacy = false; - - protected static String versionPrefix = ""; - - protected final static int NBT_TYPE_COMPOUND = 10; - protected final static int NBT_TYPE_INT_ARRAY = 11; - protected final static int NBT_TYPE_DOUBLE = 6; - protected final static int NBT_TYPE_FLOAT = 5; - protected final static int NBT_TYPE_STRING = 8; - - protected static int WITHER_SKULL_TYPE = 66; - protected static int FIREWORK_TYPE = 76; - - public static Class class_Block; - public static Class class_ItemStack; - public static Class class_NBTBase; - public static Class class_NBTTagCompound; - public static Class class_NBTTagList; - public static Class class_NBTTagByte; - public static Class class_NBTTagDouble; - public static Class class_NBTTagFloat; - public static Class class_NBTTagInt; - public static Class class_NBTTagLong; - public static Class class_NBTTagShort; - public static Class class_NBTTagString; - public static Class class_CraftTask; - public static Class class_CraftInventoryCustom; - public static Class class_CraftItemStack; - public static Class class_CraftBlockState; - public static Class class_CraftLivingEntity; - public static Class class_CraftWorld; - public static Class class_Consumer; - public static Class class_Entity; - public static Class class_EntityCreature; - public static Class class_EntityLiving; - public static Class class_EntityHuman; - public static Class class_DataWatcher; - public static Class class_DamageSource; - public static Class class_EntityDamageSource; - public static Class class_World; - public static Class class_WorldServer; - public static Class class_Packet; - protected static Class class_EnumSkyBlock; - public static Class class_EntityPainting; - public static Class class_EntityItemFrame; - public static Class class_EntityMinecartRideable; - public static Class class_EntityTNTPrimed; - public static Class class_AxisAlignedBB; - public static Class class_PathPoint; - public static Class class_PathEntity; - public static Class class_EntityFirework; - public static Class class_CraftSkull; - public static Class class_CraftBanner; - public static Class class_CraftMetaSkull; - public static Class class_CraftMetaBanner; - public static Class class_GameProfile; - public static Class class_GameProfileProperty; - public static Class class_BlockPosition; - public static Class class_NBTCompressedStreamTools; - public static Class class_TileEntity; - public static Class class_TileEntitySign; - public static Class class_TileEntityContainer; - public static Class class_ChestLock; - protected static Class class_EnumDirection; - public static Class class_EntityHorse; - public static Class class_EntityWitherSkull; - public static Class class_PacketPlayOutAttachEntity; - public static Class class_PacketPlayOutEntityDestroy; - public static Class class_PacketPlayOutSpawnEntity; - public static Class class_PacketPlayOutSpawnEntityLiving; - public static Class class_PacketPlayOutEntityMetadata; - public static Class class_PacketPlayOutEntityStatus; - public static Class class_PacketPlayOutCustomSoundEffect; - public static Class class_PacketPlayOutExperience; - public static Class class_PacketPlayOutAnimation; - public static Class class_PacketPlayOutBlockBreakAnimation; - protected static Enum enum_SoundCategory_PLAYERS; - protected static Class class_EnumSoundCategory; - public static Class class_EntityFallingBlock; - public static Class class_EntityArmorStand; - public static Class class_EntityPlayer; - public static Class class_PlayerConnection; - public static Class class_Chunk; - public static Class class_CraftPlayer; - public static Class class_CraftChunk; - public static Class class_CraftEntity; - public static Class class_EntityProjectile; - public static Class class_EntityFireball; - public static Class class_EntityArrow; - public static Class class_CraftArrow; - public static Class class_MinecraftServer; - public static Class class_CraftServer; - public static Class class_DataWatcherObject; - public static Class class_PacketPlayOutChat; - protected static Class class_ChatMessageType; - protected static Enum enum_ChatMessageType_GAME_INFO; - public static Class class_ChatComponentText; - public static Class class_IChatBaseComponent; - - protected static Method class_NBTTagList_addMethod; - protected static Method class_NBTTagList_getMethod; - protected static Method class_NBTTagList_getDoubleMethod; - protected static Method class_NBTTagList_sizeMethod; - protected static Method class_NBTTagList_removeMethod; - protected static Method class_NBTTagCompound_getKeysMethod; - protected static Method class_NBTTagCompound_setMethod; - protected static Method class_World_getEntitiesMethod; - protected static Method class_Entity_setSilentMethod; - protected static Method class_Entity_isSilentMethod; - protected static Method class_Entity_setYawPitchMethod; - protected static Method class_Entity_getBukkitEntityMethod; - protected static Method class_EntityLiving_damageEntityMethod; - protected static Method class_DamageSource_getMagicSourceMethod; - protected static Method class_EntityDamageSource_setThornsMethod; - protected static Method class_World_explodeMethod; - protected static Method class_NBTTagCompound_setBooleanMethod; - protected static Method class_NBTTagCompound_setStringMethod; - protected static Method class_NBTTagCompound_setDoubleMethod; - protected static Method class_NBTTagCompound_setLongMethod; - protected static Method class_NBTTagCompound_setIntMethod; - protected static Method class_NBTTagCompound_removeMethod; - protected static Method class_NBTTagCompound_getStringMethod; - protected static Method class_NBTTagCompound_getBooleanMethod; - protected static Method class_NBTTagCompound_getIntMethod; - protected static Method class_NBTTagCompound_getByteMethod; - protected static Method class_NBTTagCompound_getMethod; - protected static Method class_NBTTagCompound_getCompoundMethod; - protected static Method class_NBTTagCompound_getShortMethod; - protected static Method class_NBTTagCompound_getByteArrayMethod; - protected static Method class_NBTTagCompound_getListMethod; - protected static Method class_Entity_saveMethod; - protected static Method class_Entity_getTypeMethod; - protected static Method class_TileEntity_loadMethod; - protected static Method class_TileEntity_saveMethod; - protected static Method class_TileEntity_updateMethod; - protected static Method class_World_addEntityMethod; - protected static Method class_CraftMetaBanner_getPatternsMethod; - protected static Method class_CraftMetaBanner_setPatternsMethod; - protected static Method class_CraftMetaBanner_getBaseColorMethod; - protected static Method class_CraftMetaBanner_setBaseColorMethod; - protected static Method class_CraftBanner_getPatternsMethod; - protected static Method class_CraftBanner_setPatternsMethod; - protected static Method class_CraftBanner_getBaseColorMethod; - protected static Method class_CraftBanner_setBaseColorMethod; - protected static Method class_NBTCompressedStreamTools_loadFileMethod; - protected static Method class_CraftItemStack_asBukkitCopyMethod; - protected static Method class_CraftItemStack_copyMethod; - protected static Method class_CraftItemStack_mirrorMethod; - protected static Method class_NBTTagCompound_hasKeyMethod; - protected static Method class_CraftWorld_getTileEntityAtMethod; - protected static Method class_CraftWorld_createEntityMethod; - protected static Method class_CraftWorld_spawnMethod; - protected static boolean class_CraftWorld_spawnMethod_isLegacy; - protected static Method class_Entity_setLocationMethod; - protected static Method class_Entity_getIdMethod; - protected static Method class_Entity_getDataWatcherMethod; - protected static Method class_Entity_getBoundingBox; - protected static Method class_TileEntityContainer_setLock; - protected static Method class_TileEntityContainer_getLock; - protected static Method class_ChestLock_isEmpty; - protected static Method class_ChestLock_getString; - protected static Method class_ArmorStand_setInvisible; - protected static Method class_ArmorStand_setGravity; - protected static Method class_Entity_setNoGravity; - protected static Method class_CraftPlayer_getHandleMethod; - protected static Method class_CraftChunk_getHandleMethod; - protected static Method class_CraftEntity_getHandleMethod; - protected static Method class_CraftLivingEntity_getHandleMethod; - protected static Method class_CraftWorld_getHandleMethod; - protected static Method class_EntityPlayer_openSignMethod; - protected static Method class_EntityPlayer_setResourcePackMethod; - protected static Method class_CraftServer_getServerMethod; - protected static Method class_MinecraftServer_getResourcePackMethod; - protected static Method class_ItemStack_isEmptyMethod; - protected static Method class_ItemStack_createStackMethod; - protected static Method class_CraftMagicNumbers_getBlockMethod; - - protected static Constructor class_CraftInventoryCustom_constructor; - protected static Constructor class_EntityFireworkConstructor; - protected static Constructor class_EntityPaintingConstructor; - protected static Constructor class_EntityItemFrameConstructor; - protected static Constructor class_BlockPosition_Constructor; - protected static Constructor class_PacketSpawnEntityConstructor; - protected static Constructor class_PacketSpawnLivingEntityConstructor; - protected static Constructor class_PacketPlayOutEntityMetadata_Constructor; - protected static Constructor class_PacketPlayOutEntityStatus_Constructor; - protected static Constructor class_PacketPlayOutEntityDestroy_Constructor; - protected static Constructor class_PacketPlayOutCustomSoundEffect_Constructor; - protected static Constructor class_PacketPlayOutExperience_Constructor; - protected static Constructor class_PacketPlayOutAnimation_Constructor; - protected static Constructor class_PacketPlayOutBlockBreakAnimation_Constructor; - protected static Constructor class_ChestLock_Constructor; - protected static Constructor class_AxisAlignedBB_Constructor; - protected static Constructor class_ItemStack_consructor; - protected static Constructor class_NBTTagString_consructor; - protected static Constructor class_NBTTagByte_constructor; - protected static Constructor class_NBTTagDouble_constructor; - protected static Constructor class_NBTTagInt_constructor; - protected static Constructor class_NBTTagFloat_constructor; - protected static Constructor class_NBTTagLong_constructor; - protected static Constructor class_PacketPlayOutChat_constructor; - protected static Constructor class_ChatComponentText_constructor; - - protected static Field class_Entity_invulnerableField; - protected static Field class_Entity_motXField; - protected static Field class_Entity_motYField; - protected static Field class_Entity_motZField; - protected static Field class_WorldServer_entitiesByUUIDField; - protected static Field class_ItemStack_tagField; - protected static Field class_DamageSource_MagicField; - protected static Field class_Firework_ticksFlownField; - protected static Field class_Firework_expectedLifespanField; - protected static Field class_CraftSkull_profile; - protected static Field class_CraftMetaSkull_profile; - protected static Field class_GameProfile_properties; - protected static Field class_GameProfileProperty_value; - protected static Field class_EntityTNTPrimed_source; - protected static Field class_NBTTagList_list; - protected static Field class_AxisAlignedBB_minXField; - protected static Field class_AxisAlignedBB_minYField; - protected static Field class_AxisAlignedBB_minZField; - protected static Field class_AxisAlignedBB_maxXField; - protected static Field class_AxisAlignedBB_maxYField; - protected static Field class_AxisAlignedBB_maxZField; - protected static Field class_EntityFallingBlock_hurtEntitiesField; - protected static Field class_EntityFallingBlock_fallHurtMaxField; - protected static Field class_EntityFallingBlock_fallHurtAmountField; - protected static Field class_EntityArmorStand_disabledSlotsField; - protected static Field class_EntityPlayer_playerConnectionField; - protected static Field class_PlayerConnection_floatCountField; - protected static Field class_Chunk_doneField; - protected static Field class_CraftItemStack_getHandleField; - protected static Field class_EntityArrow_lifeField = null; - protected static Field class_EntityArrow_damageField; - protected static Field class_CraftWorld_environmentField; - protected static Field class_MemorySection_mapField; - protected static Field class_NBTTagByte_dataField; - protected static Field class_NBTTagDouble_dataField; - protected static Field class_NBTTagFloat_dataField; - protected static Field class_NBTTagInt_dataField; - protected static Field class_NBTTagLong_dataField; - protected static Field class_NBTTagShort_dataField; - protected static Field class_NBTTagString_dataField; - protected static Field class_Block_durabilityField; - protected static Field class_Entity_jumpingField; - protected static Field class_Entity_moveStrafingField; - protected static Field class_Entity_moveForwardField; - - static { - // Find classes Bukkit hides from us. :-D - // Much thanks to @DPOHVAR for sharing the PowerNBT code that powers the reflection approach. - String className = Bukkit.getServer().getClass().getName(); - String[] packages = StringUtils.split(className, '.'); - if (packages.length == 5) { - versionPrefix = packages[3] + "."; - } - - try { - class_Block = fixBukkitClass("net.minecraft.server.Block"); - class_Entity = fixBukkitClass("net.minecraft.server.Entity"); - class_EntityLiving = fixBukkitClass("net.minecraft.server.EntityLiving"); - class_EntityHuman = fixBukkitClass("net.minecraft.server.EntityHuman"); - class_ItemStack = fixBukkitClass("net.minecraft.server.ItemStack"); - class_DataWatcher = fixBukkitClass("net.minecraft.server.DataWatcher"); - class_DataWatcherObject = fixBukkitClass("net.minecraft.server.DataWatcherObject"); - class_NBTBase = fixBukkitClass("net.minecraft.server.NBTBase"); - class_NBTTagCompound = fixBukkitClass("net.minecraft.server.NBTTagCompound"); - class_NBTTagList = fixBukkitClass("net.minecraft.server.NBTTagList"); - class_NBTTagString = fixBukkitClass("net.minecraft.server.NBTTagString"); - class_NBTTagByte = fixBukkitClass("net.minecraft.server.NBTTagByte"); - class_NBTTagDouble = fixBukkitClass("net.minecraft.server.NBTTagDouble"); - class_NBTTagFloat = fixBukkitClass("net.minecraft.server.NBTTagFloat"); - class_NBTTagInt = fixBukkitClass("net.minecraft.server.NBTTagInt"); - class_NBTTagLong = fixBukkitClass("net.minecraft.server.NBTTagLong"); - class_NBTTagShort = fixBukkitClass("net.minecraft.server.NBTTagShort"); - class_CraftWorld = fixBukkitClass("org.bukkit.craftbukkit.CraftWorld"); - class_CraftInventoryCustom = fixBukkitClass("org.bukkit.craftbukkit.inventory.CraftInventoryCustom"); - class_CraftItemStack = fixBukkitClass("org.bukkit.craftbukkit.inventory.CraftItemStack"); - class_CraftBlockState = fixBukkitClass("org.bukkit.craftbukkit.block.CraftBlockState"); - class_CraftTask = fixBukkitClass("org.bukkit.craftbukkit.scheduler.CraftTask"); - class_CraftLivingEntity = fixBukkitClass("org.bukkit.craftbukkit.entity.CraftLivingEntity"); - class_Packet = fixBukkitClass("net.minecraft.server.Packet"); - class_World = fixBukkitClass("net.minecraft.server.World"); - class_WorldServer = fixBukkitClass("net.minecraft.server.WorldServer"); - class_EnumSkyBlock = (Class) fixBukkitClass("net.minecraft.server.EnumSkyBlock"); - class_EnumSoundCategory = (Class) fixBukkitClass("net.minecraft.server.SoundCategory"); - enum_SoundCategory_PLAYERS = NMSUtils.getEnumSilent(class_EnumSoundCategory, "PLAYERS"); - class_EntityPainting = fixBukkitClass("net.minecraft.server.EntityPainting"); - class_EntityCreature = fixBukkitClass("net.minecraft.server.EntityCreature"); - class_EntityItemFrame = fixBukkitClass("net.minecraft.server.EntityItemFrame"); - class_EntityMinecartRideable = fixBukkitClass("net.minecraft.server.EntityMinecartRideable"); - class_EntityTNTPrimed = fixBukkitClass("net.minecraft.server.EntityTNTPrimed"); - class_AxisAlignedBB = fixBukkitClass("net.minecraft.server.AxisAlignedBB"); - class_DamageSource = fixBukkitClass("net.minecraft.server.DamageSource"); - class_EntityDamageSource = fixBukkitClass("net.minecraft.server.EntityDamageSource"); - class_PathEntity = fixBukkitClass("net.minecraft.server.PathEntity"); - class_PathPoint = fixBukkitClass("net.minecraft.server.PathPoint"); - class_EntityFirework = fixBukkitClass("net.minecraft.server.EntityFireworks"); - class_CraftSkull = fixBukkitClass("org.bukkit.craftbukkit.block.CraftSkull"); - class_CraftMetaSkull = fixBukkitClass("org.bukkit.craftbukkit.inventory.CraftMetaSkull"); - class_NBTCompressedStreamTools = fixBukkitClass("net.minecraft.server.NBTCompressedStreamTools"); - class_TileEntity = fixBukkitClass("net.minecraft.server.TileEntity"); - class_EntityHorse = fixBukkitClass("net.minecraft.server.EntityHorse"); - class_EntityWitherSkull = fixBukkitClass("net.minecraft.server.EntityWitherSkull"); - class_PacketPlayOutAttachEntity = fixBukkitClass("net.minecraft.server.PacketPlayOutAttachEntity"); - class_PacketPlayOutEntityDestroy = fixBukkitClass("net.minecraft.server.PacketPlayOutEntityDestroy"); - class_PacketPlayOutSpawnEntity = fixBukkitClass("net.minecraft.server.PacketPlayOutSpawnEntity"); - class_PacketPlayOutSpawnEntityLiving = fixBukkitClass("net.minecraft.server.PacketPlayOutSpawnEntityLiving"); - class_PacketPlayOutEntityMetadata = fixBukkitClass("net.minecraft.server.PacketPlayOutEntityMetadata"); - class_PacketPlayOutEntityStatus = fixBukkitClass("net.minecraft.server.PacketPlayOutEntityStatus"); - class_PacketPlayOutCustomSoundEffect = fixBukkitClass("net.minecraft.server.PacketPlayOutCustomSoundEffect"); - class_PacketPlayOutExperience = fixBukkitClass("net.minecraft.server.PacketPlayOutExperience"); - class_PacketPlayOutAnimation = fixBukkitClass("net.minecraft.server.PacketPlayOutAnimation"); - class_PacketPlayOutBlockBreakAnimation = fixBukkitClass("net.minecraft.server.PacketPlayOutBlockBreakAnimation"); - class_EntityFallingBlock = fixBukkitClass("net.minecraft.server.EntityFallingBlock"); - class_EntityArmorStand = fixBukkitClass("net.minecraft.server.EntityArmorStand"); - class_EntityPlayer = fixBukkitClass("net.minecraft.server.EntityPlayer"); - class_PlayerConnection = fixBukkitClass("net.minecraft.server.PlayerConnection"); - class_Chunk = fixBukkitClass("net.minecraft.server.Chunk"); - class_CraftPlayer = fixBukkitClass("org.bukkit.craftbukkit.entity.CraftPlayer"); - class_CraftChunk = fixBukkitClass("org.bukkit.craftbukkit.CraftChunk"); - class_CraftEntity = fixBukkitClass("org.bukkit.craftbukkit.entity.CraftEntity"); - class_TileEntitySign = fixBukkitClass("net.minecraft.server.TileEntitySign"); - class_CraftServer = fixBukkitClass("org.bukkit.craftbukkit.CraftServer"); - class_MinecraftServer = fixBukkitClass("net.minecraft.server.MinecraftServer"); - class_BlockPosition = fixBukkitClass("net.minecraft.server.BlockPosition"); - - class_EntityProjectile = NMSUtil19.getBukkitClass("net.minecraft.server.EntityProjectile"); - class_EntityFireball = NMSUtil19.getBukkitClass("net.minecraft.server.EntityFireball"); - class_EntityArrow = NMSUtil19.getBukkitClass("net.minecraft.server.EntityArrow"); - class_CraftArrow = NMSUtil19.getBukkitClass("org.bukkit.craftbukkit.entity.CraftArrow"); - - class_Entity_getBukkitEntityMethod = class_Entity.getMethod("getBukkitEntity"); - class_Entity_setYawPitchMethod = class_Entity.getDeclaredMethod("setYawPitch", Float.TYPE, Float.TYPE); - class_Entity_setYawPitchMethod.setAccessible(true); - class_World_explodeMethod = class_World.getMethod("createExplosion", class_Entity, Double.TYPE, Double.TYPE, Double.TYPE, Float.TYPE, Boolean.TYPE, Boolean.TYPE); - class_NBTTagCompound_setBooleanMethod = class_NBTTagCompound.getMethod("setBoolean", String.class, Boolean.TYPE); - class_NBTTagCompound_setStringMethod = class_NBTTagCompound.getMethod("setString", String.class, String.class); - class_NBTTagCompound_setDoubleMethod = class_NBTTagCompound.getMethod("setDouble", String.class, Double.TYPE); - class_NBTTagCompound_setLongMethod = class_NBTTagCompound.getMethod("setLong", String.class, Long.TYPE); - class_NBTTagCompound_setIntMethod = class_NBTTagCompound.getMethod("setInt", String.class, Integer.TYPE); - class_NBTTagCompound_removeMethod = class_NBTTagCompound.getMethod("remove", String.class); - class_NBTTagCompound_getStringMethod = class_NBTTagCompound.getMethod("getString", String.class); - class_NBTTagCompound_getShortMethod = class_NBTTagCompound.getMethod("getShort", String.class); - class_NBTTagCompound_getIntMethod = class_NBTTagCompound.getMethod("getInt", String.class); - class_NBTTagCompound_getBooleanMethod = class_NBTTagCompound.getMethod("getBoolean", String.class); - class_NBTTagCompound_getByteMethod = class_NBTTagCompound.getMethod("getByte", String.class); - class_NBTTagCompound_getByteArrayMethod = class_NBTTagCompound.getMethod("getByteArray", String.class); - class_NBTTagCompound_getListMethod = class_NBTTagCompound.getMethod("getList", String.class, Integer.TYPE); - class_CraftItemStack_copyMethod = class_CraftItemStack.getMethod("asNMSCopy", ItemStack.class); - class_CraftItemStack_asBukkitCopyMethod = class_CraftItemStack.getMethod("asBukkitCopy", class_ItemStack); - class_CraftItemStack_mirrorMethod = class_CraftItemStack.getMethod("asCraftMirror", class_ItemStack); - class_World_addEntityMethod = class_World.getMethod("addEntity", class_Entity, CreatureSpawnEvent.SpawnReason.class); - class_Entity_setLocationMethod = class_Entity.getMethod("setLocation", Double.TYPE, Double.TYPE, Double.TYPE, Float.TYPE, Float.TYPE); - class_Entity_getIdMethod = class_Entity.getMethod("getId"); - class_Entity_getDataWatcherMethod = class_Entity.getMethod("getDataWatcher"); - class_ArmorStand_setInvisible = class_EntityArmorStand.getDeclaredMethod("setInvisible", Boolean.TYPE); - class_CraftPlayer_getHandleMethod = class_CraftPlayer.getMethod("getHandle"); - class_CraftChunk_getHandleMethod = class_CraftChunk.getMethod("getHandle"); - class_CraftEntity_getHandleMethod = class_CraftEntity.getMethod("getHandle"); - class_CraftLivingEntity_getHandleMethod = class_CraftLivingEntity.getMethod("getHandle"); - class_CraftWorld_getHandleMethod = class_CraftWorld.getMethod("getHandle"); - class_EntityPlayer_openSignMethod = class_EntityPlayer.getMethod("openSign", class_TileEntitySign); - class_EntityPlayer_setResourcePackMethod = class_EntityPlayer.getMethod("setResourcePack", String.class, String.class); - class_CraftServer_getServerMethod = class_CraftServer.getMethod("getServer"); - class_MinecraftServer_getResourcePackMethod = class_MinecraftServer.getMethod("getResourcePack"); - - class_CraftInventoryCustom_constructor = class_CraftInventoryCustom.getConstructor(InventoryHolder.class, Integer.TYPE, String.class); - class_EntityFireworkConstructor = class_EntityFirework.getConstructor(class_World, Double.TYPE, Double.TYPE, Double.TYPE, class_ItemStack); - class_PacketSpawnEntityConstructor = class_PacketPlayOutSpawnEntity.getConstructor(class_Entity, Integer.TYPE); - class_PacketSpawnLivingEntityConstructor = class_PacketPlayOutSpawnEntityLiving.getConstructor(class_EntityLiving); - class_PacketPlayOutEntityMetadata_Constructor = class_PacketPlayOutEntityMetadata.getConstructor(Integer.TYPE, class_DataWatcher, Boolean.TYPE); - class_PacketPlayOutEntityStatus_Constructor = class_PacketPlayOutEntityStatus.getConstructor(class_Entity, Byte.TYPE); - class_PacketPlayOutEntityDestroy_Constructor = class_PacketPlayOutEntityDestroy.getConstructor(int[].class); - class_PacketPlayOutCustomSoundEffect_Constructor = class_PacketPlayOutCustomSoundEffect.getConstructor(String.class, class_EnumSoundCategory, Double.TYPE, Double.TYPE, Double.TYPE, Float.TYPE, Float.TYPE); - class_PacketPlayOutExperience_Constructor = class_PacketPlayOutExperience.getConstructor(Float.TYPE, Integer.TYPE, Integer.TYPE); - class_PacketPlayOutAnimation_Constructor = class_PacketPlayOutAnimation.getConstructor(class_Entity, Integer.TYPE); - class_PacketPlayOutBlockBreakAnimation_Constructor = class_PacketPlayOutBlockBreakAnimation.getConstructor(Integer.TYPE, class_BlockPosition, Integer.TYPE); - - class_CraftWorld_environmentField = class_CraftWorld.getDeclaredField("environment"); - class_CraftWorld_environmentField.setAccessible(true); - class_Entity_invulnerableField = class_Entity.getDeclaredField("invulnerable"); - class_Entity_invulnerableField.setAccessible(true); - class_Entity_motXField = class_Entity.getDeclaredField("motX"); - class_Entity_motXField.setAccessible(true); - class_Entity_motYField = class_Entity.getDeclaredField("motY"); - class_Entity_motYField.setAccessible(true); - class_Entity_motZField = class_Entity.getDeclaredField("motZ"); - class_Entity_motZField.setAccessible(true); - class_ItemStack_tagField = class_ItemStack.getDeclaredField("tag"); - class_ItemStack_tagField.setAccessible(true); - class_EntityTNTPrimed_source = class_EntityTNTPrimed.getDeclaredField("source"); - class_EntityTNTPrimed_source.setAccessible(true); - class_AxisAlignedBB_minXField = class_AxisAlignedBB.getField("a"); - class_AxisAlignedBB_minYField = class_AxisAlignedBB.getField("b"); - class_AxisAlignedBB_minZField = class_AxisAlignedBB.getField("c"); - class_AxisAlignedBB_maxXField = class_AxisAlignedBB.getField("d"); - class_AxisAlignedBB_maxYField = class_AxisAlignedBB.getField("e"); - class_AxisAlignedBB_maxZField = class_AxisAlignedBB.getField("f"); - class_EntityPlayer_playerConnectionField = class_EntityPlayer.getDeclaredField("playerConnection"); - - class_Firework_ticksFlownField = class_EntityFirework.getDeclaredField("ticksFlown"); - class_Firework_ticksFlownField.setAccessible(true); - class_Firework_expectedLifespanField = class_EntityFirework.getDeclaredField("expectedLifespan"); - class_Firework_expectedLifespanField.setAccessible(true); - - class_NBTTagString_consructor = class_NBTTagString.getConstructor(String.class); - class_NBTTagByte_constructor = class_NBTTagByte.getConstructor(Byte.TYPE); - class_NBTTagDouble_constructor = class_NBTTagDouble.getConstructor(Double.TYPE); - class_NBTTagInt_constructor = class_NBTTagInt.getConstructor(Integer.TYPE); - class_NBTTagFloat_constructor = class_NBTTagFloat.getConstructor(Float.TYPE); - class_NBTTagLong_constructor = class_NBTTagLong.getConstructor(Long.TYPE); - - class_NBTTagList_list = class_NBTTagList.getDeclaredField("list"); - class_NBTTagList_list.setAccessible(true); - class_NBTTagByte_dataField = class_NBTTagByte.getDeclaredField("data"); - class_NBTTagByte_dataField.setAccessible(true); - class_NBTTagDouble_dataField = class_NBTTagDouble.getDeclaredField("data"); - class_NBTTagDouble_dataField.setAccessible(true); - class_NBTTagFloat_dataField = class_NBTTagFloat.getDeclaredField("data"); - class_NBTTagFloat_dataField.setAccessible(true); - class_NBTTagInt_dataField = class_NBTTagInt.getDeclaredField("data"); - class_NBTTagInt_dataField.setAccessible(true); - class_NBTTagLong_dataField = class_NBTTagLong.getDeclaredField("data"); - class_NBTTagLong_dataField.setAccessible(true); - class_NBTTagShort_dataField = class_NBTTagShort.getDeclaredField("data"); - class_NBTTagShort_dataField.setAccessible(true); - class_NBTTagString_dataField = class_NBTTagString.getDeclaredField("data"); - class_NBTTagString_dataField.setAccessible(true); - class_NBTTagCompound_getKeysMethod = class_NBTTagCompound.getMethod("c"); - class_NBTTagList_addMethod = class_NBTTagList.getMethod("add", class_NBTBase); - class_NBTTagList_getMethod = class_NBTTagList.getMethod("get", Integer.TYPE); - class_NBTTagList_sizeMethod = class_NBTTagList.getMethod("size"); - class_NBTTagList_removeMethod = class_NBTTagList.getMethod("remove", Integer.TYPE); - class_NBTTagCompound_setMethod = class_NBTTagCompound.getMethod("set", String.class, class_NBTBase); - class_NBTTagCompound_hasKeyMethod = class_NBTTagCompound.getMethod("hasKey", String.class); - class_NBTTagCompound_getMethod = class_NBTTagCompound.getMethod("get", String.class); - class_NBTTagCompound_getCompoundMethod = class_NBTTagCompound.getMethod("getCompound", String.class); - - class_EntityFallingBlock_hurtEntitiesField = class_EntityFallingBlock.getDeclaredField("hurtEntities"); - class_EntityFallingBlock_hurtEntitiesField.setAccessible(true); - class_EntityFallingBlock_fallHurtAmountField = class_EntityFallingBlock.getDeclaredField("fallHurtAmount"); - class_EntityFallingBlock_fallHurtAmountField.setAccessible(true); - class_EntityFallingBlock_fallHurtMaxField = class_EntityFallingBlock.getDeclaredField("fallHurtMax"); - class_EntityFallingBlock_fallHurtMaxField.setAccessible(true); - - class_Chunk_doneField = class_Chunk.getDeclaredField("done"); - class_Chunk_doneField.setAccessible(true); - class_CraftItemStack_getHandleField = class_CraftItemStack.getDeclaredField("handle"); - class_CraftItemStack_getHandleField.setAccessible(true); - - class_MemorySection_mapField = MemorySection.class.getDeclaredField("map"); - class_MemorySection_mapField.setAccessible(true); - - class_TileEntityContainer = fixBukkitClass("net.minecraft.server.TileEntityContainer"); - class_ChestLock = fixBukkitClass("net.minecraft.server.ChestLock"); - class_Entity_getBoundingBox = class_Entity.getMethod("getBoundingBox"); - class_GameProfile = getClass("com.mojang.authlib.GameProfile"); - class_GameProfileProperty = getClass("com.mojang.authlib.properties.Property"); - class_CraftSkull_profile = class_CraftSkull.getDeclaredField("profile"); - class_CraftSkull_profile.setAccessible(true); - class_CraftMetaSkull_profile = class_CraftMetaSkull.getDeclaredField("profile"); - class_CraftMetaSkull_profile.setAccessible(true); - class_GameProfile_properties = class_GameProfile.getDeclaredField("properties"); - class_GameProfile_properties.setAccessible(true); - class_GameProfileProperty_value = class_GameProfileProperty.getDeclaredField("value"); - class_GameProfileProperty_value.setAccessible(true); - - class_CraftMetaBanner = fixBukkitClass("org.bukkit.craftbukkit.inventory.CraftMetaBanner"); - class_CraftMetaBanner_getBaseColorMethod = class_CraftMetaBanner.getMethod("getBaseColor"); - class_CraftMetaBanner_getPatternsMethod = class_CraftMetaBanner.getMethod("getPatterns"); - class_CraftMetaBanner_setPatternsMethod = class_CraftMetaBanner.getMethod("setPatterns", List.class); - class_CraftMetaBanner_setBaseColorMethod = class_CraftMetaBanner.getMethod("setBaseColor", DyeColor.class); - - class_CraftBanner = fixBukkitClass("org.bukkit.craftbukkit.block.CraftBanner"); - class_CraftBanner_getBaseColorMethod = class_CraftBanner.getMethod("getBaseColor"); - class_CraftBanner_getPatternsMethod = class_CraftBanner.getMethod("getPatterns"); - class_CraftBanner_setPatternsMethod = class_CraftBanner.getMethod("setPatterns", List.class); - class_CraftBanner_setBaseColorMethod = class_CraftBanner.getMethod("setBaseColor", DyeColor.class); - - class_EnumDirection = (Class) fixBukkitClass("net.minecraft.server.EnumDirection"); - class_BlockPosition_Constructor = class_BlockPosition.getConstructor(Double.TYPE, Double.TYPE, Double.TYPE); - class_EntityPaintingConstructor = class_EntityPainting.getConstructor(class_World, class_BlockPosition, class_EnumDirection); - class_EntityItemFrameConstructor = class_EntityItemFrame.getConstructor(class_World, class_BlockPosition, class_EnumDirection); - - // TODO: Server.getEntity(UUID) in 1.11+ - class_WorldServer_entitiesByUUIDField = class_WorldServer.getDeclaredField("entitiesByUUID"); - class_WorldServer_entitiesByUUIDField.setAccessible(true); - - // TODO: World.getNearbyEntities in 1.11+ - class_AxisAlignedBB_Constructor = class_AxisAlignedBB.getConstructor(Double.TYPE, Double.TYPE, Double.TYPE, Double.TYPE, Double.TYPE, Double.TYPE); - class_World_getEntitiesMethod = class_World.getMethod("getEntities", class_Entity, class_AxisAlignedBB); - - // We don't want to consider new-ish builds as "legacy" and print a warning, so keep a separate flag - boolean current = true; - - // Particularly volatile methods that we can live without - try { - try { - // 1.12 - class_NBTTagList_getDoubleMethod = class_NBTTagList.getMethod("f", Integer.TYPE); - if (class_NBTTagList_getDoubleMethod.getReturnType() != Double.TYPE) { - throw new Exception("Not 1.12"); - } - } catch (Throwable not12) { - // 1.11 and lower - current = false; - class_NBTTagList_getDoubleMethod = class_NBTTagList.getMethod("e", Integer.TYPE); - } - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred while registering NBTTagList.getDouble, loading entities from schematics will not work"); - class_NBTTagList_getDoubleMethod = null; - } - - try { - // 1.12 - try { - if (!current) { - throw new Exception("Not 1.12"); - } - class_Entity_jumpingField = class_EntityLiving.getDeclaredField("bd"); - class_Entity_jumpingField.setAccessible(true); - class_Entity_moveStrafingField = class_EntityLiving.getDeclaredField("be"); - class_Entity_moveForwardField = class_EntityLiving.getDeclaredField("bg"); - } catch (Throwable not12) { - // 1.11 - current = false; - try { - class_Entity_jumpingField = class_EntityLiving.getDeclaredField("bd"); - class_Entity_jumpingField.setAccessible(true); - class_Entity_moveStrafingField = class_EntityLiving.getDeclaredField("be"); - class_Entity_moveForwardField = class_EntityLiving.getDeclaredField("bf"); - } catch (Throwable not11) { - // 1.10 - try { - class_Entity_jumpingField = class_EntityLiving.getDeclaredField("be"); - class_Entity_jumpingField.setAccessible(true); - class_Entity_moveStrafingField = class_EntityLiving.getDeclaredField("bf"); - class_Entity_moveForwardField = class_EntityLiving.getDeclaredField("bg"); - } catch (Throwable not10) { - class_Entity_jumpingField = class_EntityLiving.getDeclaredField("bc"); - class_Entity_jumpingField.setAccessible(true); - class_Entity_moveStrafingField = class_EntityLiving.getDeclaredField("bd"); - class_Entity_moveForwardField = class_EntityLiving.getDeclaredField("be"); - } - } - } - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred while registering entity movement accessors, vehicle control will not work"); - class_Entity_jumpingField = null; - class_Entity_moveStrafingField = null; - class_Entity_moveForwardField = null; - } - - try { - class_Block_durabilityField = class_Block.getDeclaredField("durability"); - class_Block_durabilityField.setAccessible(true); - Class craftMagicNumbers = fixBukkitClass("org.bukkit.craftbukkit.util.CraftMagicNumbers"); - class_CraftMagicNumbers_getBlockMethod = craftMagicNumbers.getMethod("getBlock", Material.class); - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred while registering block durability accessor, durability-based block checks will not work"); - class_Block_durabilityField = null; - class_CraftMagicNumbers_getBlockMethod = null; - } - - try { - // 1.12 - try { - // Common to 1.12 and below - class_PacketPlayOutChat = fixBukkitClass("net.minecraft.server.PacketPlayOutChat"); - class_ChatComponentText = fixBukkitClass("net.minecraft.server.ChatComponentText"); - class_IChatBaseComponent = fixBukkitClass("net.minecraft.server.IChatBaseComponent"); - class_ChatComponentText_constructor = class_ChatComponentText.getConstructor(String.class); - - // 1.12 specific - class_ChatMessageType = (Class) fixBukkitClass("net.minecraft.server.ChatMessageType"); - enum_ChatMessageType_GAME_INFO = Enum.valueOf(class_ChatMessageType, "GAME_INFO"); - class_PacketPlayOutChat_constructor = class_PacketPlayOutChat.getConstructor(class_IChatBaseComponent, class_ChatMessageType); - - } catch (Throwable ex) { - // 1.11 fallback - current = false; - class_PacketPlayOutChat_constructor = class_PacketPlayOutChat.getConstructor(class_IChatBaseComponent, Byte.TYPE); - } - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred while registering action bar methods, action bar messages will not work"); - class_PacketPlayOutChat = null; - } - - try { - try { - // 1.11 - class_CraftWorld_createEntityMethod = class_CraftWorld.getMethod("createEntity", Location.class, Class.class); - class_Consumer = fixBukkitClass("org.bukkit.util.Consumer"); - class_CraftWorld_spawnMethod = class_CraftWorld.getMethod("spawn", Location.class, Class.class, class_Consumer, CreatureSpawnEvent.SpawnReason.class); - class_CraftWorld_spawnMethod_isLegacy = false; - } catch (Throwable ignore) { - legacy = true; - class_CraftWorld_spawnMethod_isLegacy = true; - class_CraftWorld_spawnMethod = class_CraftWorld.getMethod("spawn", Location.class, Class.class, CreatureSpawnEvent.SpawnReason.class); - } - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred while registering custom spawn method, spawn reasons will not work"); - class_CraftWorld_spawnMethod = null; - class_Consumer = null; - } - - try { - class_CraftWorld_getTileEntityAtMethod = class_CraftWorld.getMethod("getTileEntityAt", Integer.TYPE, Integer.TYPE, Integer.TYPE); - class_TileEntity_loadMethod = class_TileEntity.getMethod("a", class_NBTTagCompound); - class_TileEntity_updateMethod = class_TileEntity.getMethod("update"); - class_TileEntity_saveMethod = class_TileEntity.getMethod("save", class_NBTTagCompound); - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred, handling of tile entities may not work well"); - class_TileEntity_loadMethod = null; - class_TileEntity_updateMethod = null; - class_TileEntity_saveMethod = null; - } - - try { - class_NBTCompressedStreamTools_loadFileMethod = class_NBTCompressedStreamTools.getMethod("a", InputStream.class); - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred, schematics will not load"); - } - - try { - class_EntityLiving_damageEntityMethod = class_EntityLiving.getMethod("damageEntity", class_DamageSource, Float.TYPE); - class_DamageSource_getMagicSourceMethod = class_DamageSource.getMethod("b", class_Entity, class_Entity); - class_DamageSource_MagicField = class_DamageSource.getField("MAGIC"); - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred, magic damage will not work, using normal damage instead"); - class_EntityLiving_damageEntityMethod = null; - class_DamageSource_getMagicSourceMethod = null; - class_DamageSource_MagicField = null; - } - - try { - try { - // 1.12, same as 1.10 - class_EntityArmorStand_disabledSlotsField = class_EntityArmorStand.getDeclaredField("bB"); - if (class_EntityArmorStand_disabledSlotsField.getType() != Integer.TYPE) { - throw new Exception("Looks like 1.11, maybe"); - } - } catch (Throwable not12) { - try { - // 1.11 - class_EntityArmorStand_disabledSlotsField = class_EntityArmorStand.getDeclaredField("bA"); - if (class_EntityArmorStand_disabledSlotsField.getType() != Integer.TYPE) { - throw new Exception("Looks like 1.10"); - } - } catch (Throwable ignore) { - // 1.10 and earlier - legacy = true; - try { - class_EntityArmorStand_disabledSlotsField = class_EntityArmorStand.getDeclaredField("bB"); - if (class_EntityArmorStand_disabledSlotsField.getType() != Integer.TYPE) { - throw new Exception("Looks like 1.9"); - } - } catch (Throwable ignore2) { - try { - // 1.9.4 - class_EntityArmorStand_disabledSlotsField = class_EntityArmorStand.getDeclaredField("bA"); - } catch (Throwable ignore3) { - // 1.9.2 - class_EntityArmorStand_disabledSlotsField = class_EntityArmorStand.getDeclaredField("bz"); - } - } - } - } - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred, armor stand slots cannot be locked"); - class_EntityArmorStand_disabledSlotsField = null; - } - if (class_EntityArmorStand_disabledSlotsField != null) { - class_EntityArmorStand_disabledSlotsField.setAccessible(true); - } - - // TODO: Lockable API in 1.11+ - try { - try { - // Common - class_ChestLock_Constructor = class_ChestLock.getConstructor(String.class); - class_ChestLock_isEmpty = class_ChestLock.getMethod("a"); - class_TileEntityContainer_getLock = class_TileEntityContainer.getMethod("getLock"); - - // 1.12 only - class_ChestLock_getString = class_ChestLock.getMethod("getKey"); - class_TileEntityContainer_setLock = class_TileEntityContainer.getMethod("setLock", class_ChestLock); - } catch (Throwable not12) { - try { - // 1.11 - class_ChestLock_getString = class_ChestLock.getMethod("b"); - class_TileEntityContainer_setLock = class_TileEntityContainer.getMethod("a", class_ChestLock); - } catch (Throwable ignore) { - // 1.10 and earlier - legacy = true; - class_TileEntityContainer_setLock = class_TileEntityContainer.getMethod("a", class_ChestLock); - class_TileEntityContainer_getLock = class_TileEntityContainer.getMethod("y_"); - } - } - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred, chest locking and unlocking will not work"); - class_TileEntityContainer_setLock = null; - class_TileEntityContainer_getLock = null; - } - - try { - try { - // 1.10 and 1.11 - class_PlayerConnection_floatCountField = class_PlayerConnection.getDeclaredField("C"); - if (class_PlayerConnection_floatCountField.getType() != Integer.TYPE) { - throw new Exception("Looks like 1.9"); - } - class_PlayerConnection_floatCountField.setAccessible(true); - } catch (Throwable ignore) { - // 1.9 and earlier - legacy = true; - class_PlayerConnection_floatCountField = class_PlayerConnection.getDeclaredField("g"); - class_PlayerConnection_floatCountField.setAccessible(true); - } - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred, player flight exemption will not work"); - class_PlayerConnection_floatCountField = null; - } - - try { - try { - // 1.11 - class_EntityArrow_lifeField = class_EntityArrow.getDeclaredField("ax"); - } catch (Throwable ignore5) { - try { - // 1.10 - class_EntityArrow_lifeField = class_EntityArrow.getDeclaredField("ay"); // ayyyyy lmao - } catch (Throwable ignore4) { - legacy = true; - // 1.8.3 - class_EntityArrow_lifeField = class_EntityArrow.getDeclaredField("ar"); - } - } - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred, setting arrow lifespan will not work"); - class_EntityArrow_lifeField = null; - } - if (class_EntityArrow_lifeField != null) { - class_EntityArrow_lifeField.setAccessible(true); - } - - try { - // 1.9 and up - class_EntityDamageSource_setThornsMethod = class_EntityDamageSource.getMethod("w"); - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred, thorn damage override to hurt ender dragon will not work"); - class_EntityDamageSource_setThornsMethod = null; - } - - try { - try { - // 1.12 - class_Entity_getTypeMethod = class_Entity.getDeclaredMethod("getSaveID"); - class_Entity_saveMethod = class_Entity.getMethod("save", class_NBTTagCompound); - } catch (Throwable not12) { - try { - // 1.10 and 1.11 - class_Entity_getTypeMethod = class_Entity.getDeclaredMethod("at"); - } catch (Throwable ignore) { - // 1.9 and earlier - legacy = true; - class_Entity_getTypeMethod = class_Entity.getDeclaredMethod("as"); - } - class_Entity_saveMethod = class_Entity.getMethod("e", class_NBTTagCompound); - } - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred, saving entities to spawn eggs will not work"); - class_Entity_getTypeMethod = null; - class_Entity_saveMethod = null; - } - if (class_Entity_getTypeMethod != null) { - class_Entity_getTypeMethod.setAccessible(true); - } - - try { - try { - // 1.11 - class_ItemStack_consructor = class_ItemStack.getConstructor(class_NBTTagCompound); - } catch (Throwable ignore) { - // 1.10 and earlier - legacy = true; - class_ItemStack_createStackMethod = class_ItemStack.getMethod("createStack", class_NBTTagCompound); - } - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred, restoring inventories from schematics will not work"); - class_ItemStack_createStackMethod = null; - } - - try { - class_EntityArrow_damageField = class_EntityArrow.getDeclaredField("damage"); - class_EntityArrow_damageField.setAccessible(true); - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred, setting arrow damage will not work"); - class_EntityArrow_damageField = null; - } - - // TODO: setSilent API in 1.11+ - try { - try { - // 1.10 and 1.11 - class_Entity_setSilentMethod = class_Entity.getDeclaredMethod("setSilent", Boolean.TYPE); - class_Entity_isSilentMethod = class_Entity.getDeclaredMethod("isSilent"); - } catch (Throwable ignore) { - // 1.9 and earlier - legacy = true; - class_Entity_setSilentMethod = class_Entity.getDeclaredMethod("c", Boolean.TYPE); - class_Entity_isSilentMethod = class_Entity.getDeclaredMethod("ad"); - } - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred, silent entities will not work"); - class_Entity_setSilentMethod = null; - class_Entity_isSilentMethod = null; - } - - // TODO: ArmorStand.setGravity in 1.11+ - // Different behavior, but less hacky. - try { - try { - // 1.10 and 1.11 - class_Entity_setNoGravity = class_Entity.getDeclaredMethod("setNoGravity", Boolean.TYPE); - } catch (Throwable ignore) { - // 1.9 and earlier - legacy = true; - class_ArmorStand_setGravity = class_EntityArmorStand.getDeclaredMethod("setGravity", Boolean.TYPE); - } - } catch (Throwable ex) { - Bukkit.getLogger().log(Level.WARNING, "An error occurred, hacky no-gravity armor stands won't work"); - class_Entity_setNoGravity = null; - class_ArmorStand_setGravity = null; - } - - // TODO ItemStack.isEmpty in 1.11+ - try { - // 1.11 - class_ItemStack_isEmptyMethod = class_ItemStack.getMethod("isEmpty"); - } catch (Throwable ignore) { - // 1.10 and earlier - legacy = true; - } - } catch (Throwable ex) { - failed = true; - Bukkit.getLogger().log(Level.SEVERE, "An unexpected error occurred initializing Magic"); - } - } - - public static boolean getFailed() { - return failed; - } - - public static boolean isLegacy() { - return legacy; - } - - public static Class getVersionedBukkitClass(String newVersion, String oldVersion) { - Class c = getBukkitClass(newVersion); - if (c == null) { - c = getBukkitClass(oldVersion); - if (c == null) { - Bukkit.getLogger().warning("Could not bind to " + newVersion + " or " + oldVersion); - } - } - return c; - } - - public static Class getClass(String className) { - Class result = null; - try { - result = NMSUtils.class.getClassLoader().loadClass(className); - } catch (Exception ex) { - result = null; - } - - return result; - } - - public static Class getBukkitClass(String className) { - Class result; - try { - result = fixBukkitClass(className); - } catch (Exception ex) { - result = null; - } - - return result; - } - - public static Class fixBukkitClass(String className) { - if (!versionPrefix.isEmpty()) { - className = className.replace("org.bukkit.craftbukkit.", "org.bukkit.craftbukkit." + versionPrefix); - className = className.replace("net.minecraft.server.", "net.minecraft.server." + versionPrefix); - } - - try { - return NMSUtils.class.getClassLoader().loadClass(className); - } catch (ClassNotFoundException ignored) { - return null; - } - } - - public static Object getHandle(Server server) { - Object handle = null; - try { - handle = class_CraftServer_getServerMethod.invoke(server); - } catch (Throwable ex) { - handle = null; - } - return handle; - } - - public static Object getHandle(ItemStack stack) { - Object handle = null; - try { - handle = class_CraftItemStack_getHandleField.get(stack); - } catch (Throwable ex) { - handle = null; - } - return handle; - } - - public static Object getHandle(World world) { - if (world == null) { - return null; - } - Object handle = null; - try { - handle = class_CraftWorld_getHandleMethod.invoke(world); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return handle; - } - - public static Object getHandle(Entity entity) { - if (entity == null) { - return null; - } - Object handle = null; - try { - handle = class_CraftEntity_getHandleMethod.invoke(entity); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return handle; - } - - public static Object getHandle(org.bukkit.entity.LivingEntity entity) { - if (entity == null) { - return null; - } - Object handle = null; - try { - handle = class_CraftLivingEntity_getHandleMethod.invoke(entity); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return handle; - } - - public static boolean isDone(Chunk chunk) { - Object chunkHandle = getHandle(chunk); - boolean done = false; - try { - done = (Boolean) class_Chunk_doneField.get(chunkHandle); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return done; - } - - public static Object getHandle(Chunk chunk) { - Object handle = null; - try { - handle = class_CraftChunk_getHandleMethod.invoke(chunk); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return handle; - } - - public static Object getHandle(Player player) { - Object handle = null; - try { - handle = class_CraftPlayer_getHandleMethod.invoke(player); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return handle; - } - - protected static void sendPacket(Server server, Location source, Collection players, Object packet) throws Exception { - players = ((players != null && players.size() > 0) ? players : server.getOnlinePlayers()); - - int viewDistance = Bukkit.getServer().getViewDistance() * 16; - int viewDistanceSquared = viewDistance * viewDistance; - World sourceWorld = source.getWorld(); - for (Player player : players) { - Location location = player.getLocation(); - if (!location.getWorld().equals(sourceWorld)) { - continue; - } - if (location.distanceSquared(source) <= viewDistanceSquared) { - sendPacket(player, packet); - } - } - } - - protected static void sendPacket(Player player, Object packet) throws Exception { - Object playerHandle = getHandle(player); - Field connectionField = playerHandle.getClass().getField("playerConnection"); - Object connection = connectionField.get(playerHandle); - Method sendPacketMethod = connection.getClass().getMethod("sendPacket", class_Packet); - sendPacketMethod.invoke(connection, packet); - } - - public static int getFacing(BlockFace direction) { - int dir; - switch (direction) { - case SOUTH: - default: - dir = 0; - break; - case WEST: - dir = 1; - break; - case NORTH: - dir = 2; - break; - case EAST: - dir = 3; - break; - } - - return dir; - } - - public static Entity getBukkitEntity(Object entity) { - if (entity == null) { - return null; - } - try { - Method getMethod = entity.getClass().getMethod("getBukkitEntity"); - Object bukkitEntity = getMethod.invoke(entity); - if (!(bukkitEntity instanceof Entity)) { - return null; - } - return (Entity) bukkitEntity; - } catch (Throwable ex) { - ex.printStackTrace(); - } - - return null; - } - - public static Object getTag(Object mcItemStack) { - Object tag = null; - try { - tag = class_ItemStack_tagField.get(mcItemStack); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return tag; - } - - public static Object getNMSCopy(ItemStack stack) { - Object nms = null; - try { - nms = class_CraftItemStack_copyMethod.invoke(null, stack); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return nms; - } - - public static ItemStack getCopy(ItemStack stack) { - if (stack == null) { - return null; - } - - try { - Object craft = getNMSCopy(stack); - stack = (ItemStack) class_CraftItemStack_mirrorMethod.invoke(null, craft); - } catch (Throwable ex) { - stack = null; - } - - return stack; - } - - public static ItemStack makeReal(ItemStack stack) { - if (stack == null) { - return null; - } - Object nmsStack = getHandle(stack); - if (nmsStack == null) { - stack = getCopy(stack); - nmsStack = getHandle(stack); - } - if (nmsStack == null) { - return null; - } - try { - Object tag = class_ItemStack_tagField.get(nmsStack); - if (tag == null) { - class_ItemStack_tagField.set(nmsStack, class_NBTTagCompound.newInstance()); - } - } catch (Throwable ex) { - ex.printStackTrace(); - return null; - } - - return stack; - } - - public static String getMetaString(ItemStack stack, String tag, String defaultValue) { - String result = getMetaString(stack, tag); - return result == null ? defaultValue : result; - } - - public static boolean hasMeta(ItemStack stack, String tag) { - return !NMSUtil19.isEmpty(stack) && getNode(stack, tag) != null; - } - - public static Object getTag(ItemStack itemStack) { - Object tag = null; - try { - Object mcItemStack = getHandle(itemStack); - if (mcItemStack == null) { - return null; - } - tag = class_ItemStack_tagField.get(mcItemStack); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return tag; - } - - public static Object getNode(ItemStack stack, String tag) { - if (NMSUtil19.isEmpty(stack)) { - return null; - } - Object meta = null; - try { - Object craft = getHandle(stack); - if (craft == null) { - return null; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return null; - } - meta = class_NBTTagCompound_getMethod.invoke(tagObject, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return meta; - } - - public static boolean containsNode(Object nbtBase, String tag) { - if (nbtBase == null) { - return false; - } - Boolean result = false; - try { - result = (Boolean) class_NBTTagCompound_hasKeyMethod.invoke(nbtBase, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return result; - } - - public static Object getNode(Object nbtBase, String tag) { - if (nbtBase == null) { - return null; - } - Object meta = null; - try { - meta = class_NBTTagCompound_getMethod.invoke(nbtBase, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return meta; - } - - public static Object createNode(Object nbtBase, String tag) { - if (nbtBase == null) { - return null; - } - Object meta = null; - try { - meta = class_NBTTagCompound_getCompoundMethod.invoke(nbtBase, tag); - class_NBTTagCompound_setMethod.invoke(nbtBase, tag, meta); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return meta; - } - - public static Object createNode(ItemStack stack, String tag) { - if (NMSUtil19.isEmpty(stack)) { - return null; - } - Object outputObject = getNode(stack, tag); - if (outputObject == null) { - try { - Object craft = getHandle(stack); - if (craft == null) { - return null; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - tagObject = class_NBTTagCompound.newInstance(); - class_ItemStack_tagField.set(craft, tagObject); - } - outputObject = class_NBTTagCompound.newInstance(); - class_NBTTagCompound_setMethod.invoke(tagObject, tag, outputObject); - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - return outputObject; - } - - public static String getMetaString(Object node, String tag, String defaultValue) { - String meta = getMetaString(node, tag); - return meta == null || meta.length() == 0 ? defaultValue : meta; - } - - public static String getMetaString(Object node, String tag) { - if (node == null || !class_NBTTagCompound.isInstance(node)) { - return null; - } - String meta = null; - try { - meta = (String) class_NBTTagCompound_getStringMethod.invoke(node, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return meta; - } - - public static String getMeta(Object node, String tag) { - if (node == null || !class_NBTTagCompound.isInstance(node)) { - return null; - } - String meta = null; - try { - meta = (String) class_NBTTagCompound_getStringMethod.invoke(node, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return meta; - } - - public static Byte getMetaByte(Object node, String tag) { - if (node == null || !class_NBTTagCompound.isInstance(node)) { - return null; - } - Byte meta = null; - try { - meta = (Byte) class_NBTTagCompound_getByteMethod.invoke(node, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return meta; - } - - public static Integer getMetaInt(Object node, String tag) { - if (node == null || !class_NBTTagCompound.isInstance(node)) { - return null; - } - Integer meta = null; - try { - meta = (Integer) class_NBTTagCompound_getIntMethod.invoke(node, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return meta; - } - - public static Boolean getMetaBoolean(Object node, String tag) { - if (node == null || !class_NBTTagCompound.isInstance(node)) { - return null; - } - Boolean meta = null; - try { - meta = (Boolean) class_NBTTagCompound_getBooleanMethod.invoke(node, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return meta; - } - - public static void setMeta(Object node, String tag, String value) { - if (node == null || !class_NBTTagCompound.isInstance(node)) { - return; - } - try { - if (value == null || value.length() == 0) { - class_NBTTagCompound_removeMethod.invoke(node, tag); - } else { - class_NBTTagCompound_setStringMethod.invoke(node, tag, value); - } - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - - public static void setMetaLong(Object node, String tag, long value) { - if (node == null || !class_NBTTagCompound.isInstance(node)) { - return; - } - try { - class_NBTTagCompound_setLongMethod.invoke(node, tag, value); - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - - public static void setMetaBoolean(Object node, String tag, boolean value) { - if (node == null || !class_NBTTagCompound.isInstance(node)) { - return; - } - try { - class_NBTTagCompound_setBooleanMethod.invoke(node, tag, value); - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - - public static void setMetaDouble(Object node, String tag, double value) { - if (node == null || !class_NBTTagCompound.isInstance(node)) { - return; - } - try { - class_NBTTagCompound_setDoubleMethod.invoke(node, tag, value); - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - - public static void setMetaInt(Object node, String tag, int value) { - if (node == null || !class_NBTTagCompound.isInstance(node)) { - return; - } - try { - class_NBTTagCompound_setIntMethod.invoke(node, tag, value); - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - - public static void removeMeta(Object node, String tag) { - if (node == null || !class_NBTTagCompound.isInstance(node)) { - return; - } - try { - class_NBTTagCompound_removeMethod.invoke(node, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - - public static void removeMeta(ItemStack stack, String tag) { - if (NMSUtil19.isEmpty(stack)) { - return; - } - - try { - Object craft = getHandle(stack); - if (craft == null) { - return; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return; - } - removeMeta(tagObject, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - - public static void setMetaNode(Object node, String tag, Object child) { - if (node == null || !class_NBTTagCompound.isInstance(node)) { - return; - } - try { - if (child == null) { - class_NBTTagCompound_removeMethod.invoke(node, tag); - } else { - class_NBTTagCompound_setMethod.invoke(node, tag, child); - } - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - - public static boolean setMetaNode(ItemStack stack, String tag, Object child) { - if (NMSUtil19.isEmpty(stack)) { - return false; - } - try { - Object craft = getHandle(stack); - if (craft == null) { - return false; - } - Object node = getTag(craft); - if (node == null) { - return false; - } - if (child == null) { - class_NBTTagCompound_removeMethod.invoke(node, tag); - } else { - class_NBTTagCompound_setMethod.invoke(node, tag, child); - } - } catch (Throwable ex) { - ex.printStackTrace(); - return false; - } - - return true; - } - - public static String getMetaString(ItemStack stack, String tag) { - if (NMSUtil19.isEmpty(stack)) { - return null; - } - String meta = null; - try { - Object craft = getHandle(stack); - if (craft == null) { - return null; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return null; - } - meta = (String) class_NBTTagCompound_getStringMethod.invoke(tagObject, tag); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return meta; - } - - public static void setMeta(ItemStack stack, String tag, String value) { - if (NMSUtil19.isEmpty(stack)) { - return; - } - try { - Object craft = getHandle(stack); - if (craft == null) { - return; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return; - } - class_NBTTagCompound_setStringMethod.invoke(tagObject, tag, value); - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - - public static void setMetaBoolean(ItemStack stack, String tag, boolean value) { - if (NMSUtil19.isEmpty(stack)) { - return; - } - try { - Object craft = getHandle(stack); - if (craft == null) { - return; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return; - } - setMetaBoolean(tagObject, tag, value); - } catch (Throwable ex) { - ex.printStackTrace(); - } - } - - public static boolean getMetaBoolean(ItemStack stack, String tag, boolean defaultValue) { - if (NMSUtil19.isEmpty(stack)) { - return defaultValue; - } - boolean result = defaultValue; - try { - Object craft = getHandle(stack); - if (craft == null) { - return defaultValue; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return defaultValue; - } - Boolean value = getMetaBoolean(tagObject, tag); - result = value == null ? defaultValue : value; - } catch (Throwable ex) { - ex.printStackTrace(); - } - return result; - } - - public static void addGlow(ItemStack stack) { - if (NMSUtil19.isEmpty(stack)) { - return; - } - - ItemMeta meta = stack.getItemMeta(); - meta.addEnchant(Enchantment.LUCK, 1, true); - stack.setItemMeta(meta); - } - - public static void removeGlow(ItemStack stack) { - if (NMSUtil19.isEmpty(stack)) { - return; - } - - ItemMeta meta = stack.getItemMeta(); - if (meta.hasEnchant(Enchantment.LUCK)) { - meta.removeEnchant(Enchantment.LUCK); - stack.setItemMeta(meta); - } - } - - public static boolean isUnbreakable(ItemStack stack) { - if (NMSUtil19.isEmpty(stack)) { - return false; - } - Boolean unbreakableFlag = null; - try { - Object craft = getHandle(stack); - if (craft == null) { - return false; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return false; - } - unbreakableFlag = getMetaBoolean(tagObject, "Unbreakable"); - } catch (Throwable ignored) { - - } - - return unbreakableFlag != null && unbreakableFlag; - } - - public static void makeUnbreakable(ItemStack stack) { - if (NMSUtil19.isEmpty(stack)) { - return; - } - - try { - Object craft = getHandle(stack); - if (craft == null) { - return; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return; - } - - Object unbreakableFlag = null; - unbreakableFlag = class_NBTTagByte_constructor.newInstance((byte) 1); - class_NBTTagCompound_setMethod.invoke(tagObject, "Unbreakable", unbreakableFlag); - } catch (Throwable ignored) { - - } - } - - public static void removeUnbreakable(ItemStack stack) { - removeMeta(stack, "Unbreakable"); - } - - public static void hideFlags(ItemStack stack, byte flags) { - if (NMSUtil19.isEmpty(stack)) { - return; - } - - try { - Object craft = getHandle(stack); - if (craft == null) { - return; - } - Object tagObject = getTag(craft); - if (tagObject == null) { - return; - } - - Object hideFlag = null; - hideFlag = class_NBTTagByte_constructor.newInstance(flags); - class_NBTTagCompound_setMethod.invoke(tagObject, "HideFlags", hideFlag); - } catch (Throwable ignored) { - - } - } - - public static boolean createExplosion(Entity entity, World world, double x, double y, double z, float power, boolean setFire, boolean breakBlocks) { - boolean result = false; - if (world == null) { - return false; - } - try { - Object worldHandle = getHandle(world); - if (worldHandle == null) { - return false; - } - Object entityHandle = entity == null ? null : getHandle(entity); - - Object explosion = class_World_explodeMethod.invoke(worldHandle, entityHandle, x, y, z, power, setFire, breakBlocks); - Field cancelledField = explosion.getClass().getDeclaredField("wasCanceled"); - result = (Boolean) cancelledField.get(explosion); - } catch (Throwable ex) { - ex.printStackTrace(); - result = false; - } - return result; - } - - public static void makeTemporary(ItemStack itemStack, String message) { - setMeta(itemStack, "temporary", message); - } - - public static boolean isTemporary(ItemStack itemStack) { - return hasMeta(itemStack, "temporary"); - } - - public static void makeUnplaceable(ItemStack itemStack) { - setMeta(itemStack, "unplaceable", "true"); - } - - public static void removeUnplaceable(ItemStack itemStack) { - removeMeta(itemStack, "unplaceable"); - } - - public static boolean isUnplaceable(ItemStack itemStack) { - return hasMeta(itemStack, "unplaceable"); - } - - public static String getTemporaryMessage(ItemStack itemStack) { - return getMetaString(itemStack, "temporary"); - } - - public static void setReplacement(ItemStack itemStack, ItemStack replacement) { - YamlConfiguration configuration = new YamlConfiguration(); - configuration.set("item", replacement); - setMeta(itemStack, "replacement", configuration.saveToString()); - } - - public static ItemStack getReplacement(ItemStack itemStack) { - String serialized = getMetaString(itemStack, "replacement"); - if (serialized == null || serialized.isEmpty()) { - return null; - } - YamlConfiguration configuration = new YamlConfiguration(); - ItemStack replacement = null; - try { - configuration.loadFromString(serialized); - replacement = configuration.getItemStack("item"); - } catch (Exception ex) { - ex.printStackTrace(); - } - return replacement; - } - - protected static Object getTagString(String value) { - try { - return class_NBTTagString_consructor.newInstance(value); - } catch (Exception ex) { - ex.printStackTrace(); - - } - return null; - } - - public static Object setStringList(Object nbtBase, String tag, Collection values) { - if (nbtBase == null) { - return null; - } - Object listMeta = null; - try { - listMeta = class_NBTTagList.newInstance(); - - for (String value : values) { - Object nbtString = getTagString(value); - class_NBTTagList_addMethod.invoke(listMeta, nbtString); - } - - class_NBTTagCompound_setMethod.invoke(nbtBase, tag, listMeta); - } catch (Throwable ex) { - ex.printStackTrace(); - return null; - } - return listMeta; - } - - public static ItemStack getItem(Object itemTag) { - if (itemTag == null) { - return null; - } - ItemStack item = null; - try { - Object nmsStack = null; - if (class_ItemStack_consructor != null) { - nmsStack = class_ItemStack_consructor.newInstance(itemTag); - } else { - nmsStack = class_ItemStack_createStackMethod.invoke(null, itemTag); - } - item = (ItemStack) class_CraftItemStack_mirrorMethod.invoke(null, nmsStack); - } catch (Exception ex) { - ex.printStackTrace(); - } - return item; - } - - public static ItemStack[] getItems(Object rootTag, String tagName) { - try { - Object itemList = class_NBTTagCompound_getListMethod.invoke(rootTag, tagName, NBT_TYPE_COMPOUND); - Integer size = (Integer) class_NBTTagList_sizeMethod.invoke(itemList); - ItemStack[] items = new ItemStack[size]; - for (int i = 0; i < size; i++) { - try { - Object itemData = class_NBTTagList_getMethod.invoke(itemList, i); - if (itemData != null) { - items[i] = getItem(itemData); - } - } catch (Exception ex) { - ex.printStackTrace(); - } - } - return items; - } catch (Exception ex) { - ex.printStackTrace(); - } - return null; - } - - public static Object getTileEntityData(Location location) { - if (class_CraftWorld_getTileEntityAtMethod == null || class_TileEntity_saveMethod == null) { - return null; - } - Object data = null; - try { - World world = location.getWorld(); - Object tileEntity = class_CraftWorld_getTileEntityAtMethod.invoke(world, location.getBlockX(), location.getBlockY(), location.getBlockZ()); - if (tileEntity != null) { - data = class_NBTTagCompound.newInstance(); - class_TileEntity_saveMethod.invoke(tileEntity, data); - } - } catch (Exception ex) { - ex.printStackTrace(); - } - return data; - } - - public static Object getTileEntity(Location location) { - if (class_CraftWorld_getTileEntityAtMethod == null) { - return null; - } - Object tileEntity = null; - try { - World world = location.getWorld(); - tileEntity = class_CraftWorld_getTileEntityAtMethod.invoke(world, location.getBlockX(), location.getBlockY(), location.getBlockZ()); - } catch (Exception ex) { - ex.printStackTrace(); - } - return tileEntity; - } - - public static void clearItems(Location location) { - if (class_TileEntity_loadMethod == null || class_TileEntity_updateMethod == null || class_CraftWorld_getTileEntityAtMethod == null || class_TileEntity_saveMethod == null) { - return; - } - if (location == null) { - return; - } - try { - World world = location.getWorld(); - if (world == null) { - return; - } - - Object tileEntity = class_CraftWorld_getTileEntityAtMethod.invoke(world, location.getBlockX(), location.getBlockY(), location.getBlockZ()); - if (tileEntity != null) { - Object entityData = class_NBTTagCompound.newInstance(); - class_TileEntity_saveMethod.invoke(tileEntity, entityData); - Object itemList = class_NBTTagCompound_getListMethod.invoke(entityData, "Items", NBT_TYPE_COMPOUND); - if (itemList != null) { - List items = (List) class_NBTTagList_list.get(itemList); - items.clear(); - } - class_NBTTagCompound_removeMethod.invoke(entityData, "Item"); - class_TileEntity_loadMethod.invoke(tileEntity, entityData); - class_TileEntity_updateMethod.invoke(tileEntity); - } - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - public static void setTileEntityData(Location location, Object data) { - if (class_TileEntity_loadMethod == null || class_TileEntity_updateMethod == null || class_CraftWorld_getTileEntityAtMethod == null) { - return; - } - - if (location == null || data == null) { - return; - } - try { - World world = location.getWorld(); - if (world == null) { - return; - } - - Object tileEntity = class_CraftWorld_getTileEntityAtMethod.invoke(world, location.getBlockX(), location.getBlockY(), location.getBlockZ()); - if (tileEntity == null) { - return; - } - - class_NBTTagCompound_setIntMethod.invoke(data, "x", location.getBlockX()); - class_NBTTagCompound_setIntMethod.invoke(data, "y", location.getBlockY()); - class_NBTTagCompound_setIntMethod.invoke(data, "z", location.getBlockZ()); - - class_TileEntity_loadMethod.invoke(tileEntity, data); - class_TileEntity_updateMethod.invoke(tileEntity); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - public static Vector getPosition(Object entityData, String tag) { - if (class_NBTTagList_getDoubleMethod == null) { - return null; - } - try { - Object posList = class_NBTTagCompound_getListMethod.invoke(entityData, tag, NBT_TYPE_DOUBLE); - Double x = (Double) class_NBTTagList_getDoubleMethod.invoke(posList, 0); - Double y = (Double) class_NBTTagList_getDoubleMethod.invoke(posList, 1); - Double z = (Double) class_NBTTagList_getDoubleMethod.invoke(posList, 2); - if (x != null && y != null && z != null) { - return new Vector(x, y, z); - } - } catch (Exception ex) { - ex.printStackTrace(); - } - return null; - } - - public static Entity getEntity(World world, UUID uuid) { - try { - Object worldHandle = getHandle(world); - final Map entityMap = (Map) class_WorldServer_entitiesByUUIDField.get(worldHandle); - if (entityMap != null) { - Object nmsEntity = entityMap.get(uuid); - if (nmsEntity != null) { - return getBukkitEntity(nmsEntity); - } - } - } catch (Exception ex) { - ex.printStackTrace(); - } - return null; - } - - public static void setEnvironment(World world, World.Environment environment) { - try { - class_CraftWorld_environmentField.set(world, environment); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - public static void playCustomSound(Player player, Location location, String sound, float volume, float pitch) { - try { - Object packet = class_PacketPlayOutCustomSoundEffect_Constructor.newInstance(sound, enum_SoundCategory_PLAYERS, location.getX(), location.getY(), location.getZ(), volume, pitch); - sendPacket(player, packet); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - public static Map getMap(ConfigurationSection section) { - if (section == null) { - return null; - } - if (section instanceof MemorySection) { - try { - Object mapObject = class_MemorySection_mapField.get(section); - if (mapObject instanceof Map) { - return (Map) mapObject; - } - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - // Do it the slow way - Map map = new HashMap<>(); - Set keys = section.getKeys(false); - for (String key : keys) { - map.put(key, section.get(key)); - } - - return map; - } - - public static boolean isEmpty(ItemStack itemStack) { - if (itemStack == null || itemStack.getType() == Material.AIR) { - return true; - } - if (class_ItemStack_isEmptyMethod == null) { - return false; - } - try { - Object handle = getHandle(itemStack); - if (handle == null) { - return false; - } - return (Boolean) class_ItemStack_isEmptyMethod.invoke(handle); - } catch (Throwable ex) { - ex.printStackTrace(); - } - return false; - } -} diff --git a/src/main/java/me/skymc/taboolib/nms/NMSUtils.java b/src/main/java/me/skymc/taboolib/nms/NMSUtils.java deleted file mode 100644 index 9bddbaa..0000000 --- a/src/main/java/me/skymc/taboolib/nms/NMSUtils.java +++ /dev/null @@ -1,379 +0,0 @@ -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 java.util.stream.IntStream; - -/** - * @author Unknown - */ -public class NMSUtils { - - public static Class c = getOBCClass("block.CraftBlock"); - public static Method m = getMethodSilent(c, "getNMSBlock"); - - public static String getVersion() { - String name = Bukkit.getServer().getClass().getPackage().getName(); - return name.substring(name.lastIndexOf('.') + 1) + "."; - } - - public static > T getEnumSilent(Class enumType, String str) { - try { - return Enum.valueOf(enumType, str); - } catch (Exception ignored) { - return null; - } - } - - public static Class getClassWithException(String name) throws Exception { - return Class.forName(name); - } - - public static Class getClass(String name) { - try { - return getClassWithException(name); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - public static Class getClass(String... strings) { - for (String s : strings) { - try { - return getClassWithException(s); - } catch (Exception ignored) { - } - } - return null; - } - - public static Class getClassSilent(String name) { - try { - return getClassWithException(name); - } catch (Exception ignored) { - } - return null; - } - - public static Class getNMSClassWithException(String className) throws Exception { - return Class.forName("net.minecraft.server." + getVersion() + className); - } - - public static Class getNMSClass(String className) { - try { - return getNMSClassWithException(className); - } catch (Exception ignored) { - } - return null; - } - - public static Class getNMSClassSilent(String className) { - try { - return getNMSClassWithException(className); - } catch (Exception ignored) { - } - return null; - } - - public static Class getNMSClass(String className, String embedded) { - try { - return getNMSClassWithException(className); - } catch (Exception e) { - return getInnerClassSilent(getNMSClassSilent(embedded), className); - } - } - - public static Class getNMSClassSilent(String className, String embedded) { - try { - return getNMSClassWithException(className); - } catch (Exception e) { - return getInnerClassSilent(getNMSClassSilent(embedded), className); - } - } - - public static Class getOBCClassWithException(String className) throws Exception { - return Class.forName("org.bukkit.craftbukkit." + getVersion() + className); - } - - public static Class getOBCClass(String className) { - try { - return getOBCClassWithException(className); - } catch (Exception ignored) { - } - return null; - } - - public static Class getOBCClassSilent(String className) { - try { - return getOBCClassWithException(className); - } catch (Exception ignored) { - } - return null; - } - - public static Object getHandle(Object obj) { - try { - return getMethodWithException(obj.getClass(), "getHandle").invoke(obj); - } catch (Exception ignored) { - return null; - } - } - - public static Object getHandleSilent(Object obj) { - try { - return getMethodWithException(obj.getClass(), "getHandle").invoke(obj); - } catch (Exception e) { - return null; - } - } - - public static Object getBlockHandleWithException(Object obj) throws Exception { - return m.invoke(obj); - } - - public static Object getBlockHandle(Object obj) { - try { - return m.invoke(obj); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - public static Object getBlockHandleSilent(Object obj) { - try { - return m.invoke(obj); - } catch (Exception e) { - return null; - } - } - - public static Field getFieldWithException(Class clazz, String name) throws Exception { - for (Field field : clazz.getDeclaredFields()) { - if (field.getName().equals(name)) { - field.setAccessible(true); - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - int modifiers = modifiersField.getInt(field); - modifiers &= ~Modifier.FINAL; - modifiersField.setInt(field, modifiers); - return field; - } - } - for (Field field : clazz.getFields()) { - if (field.getName().equals(name)) { - field.setAccessible(true); - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - int modifiers = modifiersField.getInt(field); - modifiers &= ~Modifier.FINAL; - modifiersField.setInt(field, modifiers); - return field; - } - } - throw new Exception("Field Not Found"); - } - - public static Field getFieldSilent(Class clazz, String... names) { - for (String name : names) { - try { - return getFieldWithException(clazz, name); - } catch (Exception ignored) { - } - } - return null; - } - - public static Field getFieldSilent(Class clazz, String name) { - try { - return getFieldWithException(clazz, name); - } catch (Exception ignored) { - } - return null; - } - - public static Field getField(Class clazz, String... names) { - for (String name : names) { - try { - return getFieldWithException(clazz, name); - } catch (Exception ignored) { - } - } - return null; - } - - public static Field getFieldOfTypeWithException(Class clazz, Class type, String name) throws Exception { - for (Field field : clazz.getDeclaredFields()) { - if (field.getName().equals(name) && field.getType().equals(type)) { - field.setAccessible(true); - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - int modifiers = modifiersField.getInt(field); - modifiers &= ~Modifier.FINAL; - modifiersField.setInt(field, modifiers); - return field; - } - } - for (Field field : clazz.getFields()) { - if (field.getName().equals(name) && field.getType().equals(type)) { - field.setAccessible(true); - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - int modifiers = modifiersField.getInt(field); - modifiers &= ~Modifier.FINAL; - modifiersField.setInt(field, modifiers); - return field; - } - } - throw new Exception("Field Not Found"); - } - - public static Field getFieldOfType(Class clazz, Class type, String name) { - try { - return getFieldOfTypeWithException(clazz, type, name); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - public static Field getFirstFieldOfTypeWithException(Class clazz, Class type) throws Exception { - for (Field field : clazz.getDeclaredFields()) { - if (field.getType().equals(type)) { - field.setAccessible(true); - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - int modifiers = modifiersField.getInt(field); - modifiers &= ~Modifier.FINAL; - modifiersField.setInt(field, modifiers); - return field; - } - } - throw new Exception("Field Not Found"); - } - - public static Field getFirstFieldOfType(Class clazz, Class type) { - try { - return getFirstFieldOfTypeWithException(clazz, type); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - public static Field getLastFieldOfTypeWithException(Class clazz, Class type) throws Exception { - Field field = null; - for (Field f : clazz.getDeclaredFields()) { - if (f.getType().equals(type)) { - field = f; - } - } - if (field == null) { - throw new Exception("Field Not Found"); - } - field.setAccessible(true); - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - int modifiers = modifiersField.getInt(field); - modifiers &= ~Modifier.FINAL; - modifiersField.setInt(field, modifiers); - return field; - } - - public static Field getLastFieldOfType(Class clazz, Class type) { - try { - return getLastFieldOfTypeWithException(clazz, type); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - public static Method getMethodWithException(Class clazz, String name, Class... args) throws Exception { - for (Method m : clazz.getDeclaredMethods()) { - if (m.getName().equals(name) && (args.length == 0 && m.getParameterTypes().length == 0 || classListEqual(args, m.getParameterTypes()))) { - m.setAccessible(true); - return m; - } - } - for (Method m : clazz.getMethods()) { - if (m.getName().equals(name) && (args.length == 0 && m.getParameterTypes().length == 0 || classListEqual(args, m.getParameterTypes()))) { - m.setAccessible(true); - return m; - } - } - throw new Exception("Method Not Found"); - } - - public static Method getMethodSilent(Class clazz, String name, Class... args) { - try { - return getMethodWithException(clazz, name, args); - } catch (Exception ignored) { - } - return null; - } - - public static boolean classListEqual(Class[] l1, Class[] l2) { - return l1.length == l2.length && IntStream.range(0, l1.length).noneMatch(i -> l1[i] != l2[i]); - } - - public static Class getInnerClassWithException(Class c, String className) throws Exception { - for (Class cl : c.getDeclaredClasses()) { - if (cl.getSimpleName().equals(className)) { - return cl; - } - } - throw new Exception("Inner Class Not Found"); - } - - public static Class getInnerClass(Class c, String className) { - try { - return getInnerClassWithException(c, className); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - public static Class getInnerClassSilent(Class c, String className) { - try { - return getInnerClassWithException(c, className); - } catch (Exception ignored) { - } - return null; - } - - public static Constructor getConstructor(Class clazz, Class... args) throws Exception { - for (Constructor c : clazz.getDeclaredConstructors()) { - if (args.length == 0 && c.getParameterTypes().length == 0 || classListEqual(args, c.getParameterTypes())) { - c.setAccessible(true); - return c; - } - } - for (Constructor c : clazz.getConstructors()) { - if (args.length == 0 && c.getParameterTypes().length == 0 || classListEqual(args, c.getParameterTypes())) { - c.setAccessible(true); - return c; - } - } - throw new Exception("Constructor Not Found"); - } - - public static Constructor getConstructorSilent(Class clazz, Class... args) { - try { - return getConstructor(clazz, args); - } catch (Exception ignored) { - } - return null; - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - public static Enum getEnum(final String value, final Class enumClass) { - return Enum.valueOf(enumClass, value); - } -} diff --git a/src/main/java/me/skymc/taboolib/nms/item/DabItemUtils.java b/src/main/java/me/skymc/taboolib/nms/item/DabItemUtils.java deleted file mode 100644 index dad63d1..0000000 --- a/src/main/java/me/skymc/taboolib/nms/item/DabItemUtils.java +++ /dev/null @@ -1,453 +0,0 @@ -package me.skymc.taboolib.nms.item; - -import me.skymc.taboolib.Main; -import me.skymc.taboolib.json.JSONArray; -import me.skymc.taboolib.json.JSONObject; -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 { - - private static IDabItemUtils inst = load(); - - private static IDabItemUtils load(){ - ItemStack is = new ItemStack(Material.DIAMOND_SWORD); - ItemMeta im = is.getItemMeta(); - im.addEnchant(Enchantment.KNOCKBACK, 20, true); - is.setItemMeta(im); - try{ - IDabItemUtils inst = new _194ItemUtils(); - inst.convertItemStackToJSON(is); - MsgUtils.send("载入 1.9.4 Spigot 物品工具成功!"); - return inst; - } catch (Exception ignored) { - } - try{ - _1710ItemUtils inst = new _1710ItemUtils(); - inst.convertItemStackToJSON(is); - MsgUtils.send("载入 1.7.10 Cauldron 物品工具成功!"); - return inst; - } catch (Exception ignored) { - } - try{ - IDabItemUtils inst = new _164ItemUtils(); - inst.convertItemStackToJSON(is); - MsgUtils.send("载入 1.6.4 Cauldron 物品工具成功!"); - return inst; - } catch (Exception ignored) { - } - MsgUtils.send("&4物品工具载入失败, 插件已关闭!"); - Bukkit.getPluginManager().disablePlugin(Main.getInst()); - return null; - } - - public static IDabItemUtils getInstance(){ - return inst; - } - - @Deprecated - public static boolean hasBanner(){ - return inst.hasBanner(); - } - - @Deprecated - public static Object getNMSCopy(ItemStack is) throws Exception{ - return inst.getNMSCopy(is); - } - - @Deprecated - public static boolean hasTag(Object is) throws Exception{ - return inst.hasTag(is); - } - - @Deprecated - public static ItemStack asCraftMirror(Object nis) throws Exception{ - return inst.asCraftMirror(nis); - } - - @Deprecated - public static ItemStack asBukkitCopy(Object nmis) throws Exception{ - return inst.asBukkitCopy(nmis); - } - - @Deprecated - public static String getName(ItemStack is){ - return inst.getName(is); - } - - @Deprecated - public static Object getItem(Object nis) throws Exception{ - return inst.getItem(nis); - } - - @Deprecated - public static Method getA(){ - return inst.getA(); - } - - @Deprecated - public static String getRawName(ItemStack is){ - return inst.getRawName(is); - } - - @Deprecated - public static String getItemName(ItemStack is){ - return inst.getItemName(is); - } - - @Deprecated - public static Object getRegistry(){ - return inst.getRegistry(); - } - - @Deprecated - public static String getMinecraftName(ItemStack is){ - return inst.getMinecraftName(is); - } - - @Deprecated - public static Object getTag(Object is) throws Exception{ - return inst.getTag(is); - } - - @Deprecated - public static void setTag(Object is, Object tag1) throws Exception{ - inst.setTag(is, tag1); - } - - @Deprecated - public static boolean isEmpty(Object tag) throws Exception{ - return inst.isEmpty(tag); - } - - @Deprecated - public static Object getMap(Object tag) throws Exception{ - return inst.getMap(tag); - } - - @Deprecated - public static void set(Object tag, String key, Object value) throws Exception{ - inst.set(tag, key, value); - } - - @Deprecated - public static void setString(Object tag, String key, String value) throws Exception{ - inst.setString(tag, key, value); - } - - @Deprecated - public static void setShort(Object tag, String key, short value) throws Exception{ - inst.setShort(tag, key, value); - } - - @Deprecated - public static void setInt(Object tag, String key, int i) throws Exception{ - inst.setInt(tag, key, i); - } - - @Deprecated - public static void setDouble(Object tag, String key, double d) throws Exception{ - inst.setDouble(tag, key, d); - } - - @Deprecated - public static void setLong(Object tag, String key, long l) throws Exception{ - inst.setLong(tag, key, l); - } - - @Deprecated - public static boolean hasKey(Object tag, String key) throws Exception{ - return inst.hasKey(tag, key); - } - - @Deprecated - public static Object get(Object tag, String key) throws Exception{ - return inst.get(tag, key); - } - - @Deprecated - public static String getString(Object tag, String key) throws Exception{ - return inst.getString(tag, key); - } - - @Deprecated - public static int getInt(Object tag, String key) throws Exception{ - return inst.getInt(tag, key); - } - - @Deprecated - public static double getDouble(Object tag, String key) throws Exception{ - return inst.getDouble(tag, key); - } - - @Deprecated - public static long getLong(Object tag, String key) throws Exception{ - return inst.getLong(tag, key); - } - - @Deprecated - public static short getShort(Object tag, String key) throws Exception{ - return inst.getShort(tag, key); - } - - @Deprecated - public static Object getNewNBTTagCompound() throws Exception{ - return inst.getNewNBTTagCompound(); - } - - @Deprecated - public static boolean hasAttributeModifiersKey(Object tag) throws Exception{ - return inst.hasAttributeModifiersKey(tag); - } - - @Deprecated - public static Object getList(Object tag) throws Exception{ - return inst.getList(tag); - } - - @Deprecated - public static Object getList(Object tag, String name, int id) throws Exception{ - return inst.getList(tag, name, id); - } - - @Deprecated - public static boolean getUnbreakable(Object tag) throws Exception{ - return inst.getUnbreakable(tag); - } - - @Deprecated - public static void setUnbreakable(Object tag, boolean value) throws Exception{ - inst.setUnbreakable(tag, value); - } - - @Deprecated - public static Object getNewNBTTagList() throws Exception{ - return inst.getNewNBTTagList(); - } - - @Deprecated - public static void addToList(Object taglist, Object nbt) throws Exception{ - inst.addToList(taglist, nbt); - } - - @Deprecated - public static int getSize(Object list) throws Exception{ - return inst.getSize(list); - } - - @Deprecated - public static Object get(Object tlist, int i) throws Exception{ - return inst.get(tlist, i); - } - - @Deprecated - public static Object getNewNBTTagByte(byte value) throws Exception{ - return inst.getNewNBTTagByte(value); - } - - @Deprecated - public static Object getNewNBTTagByteArray(byte[] value) throws Exception{ - return inst.getNewNBTTagByteArray(value); - } - - @Deprecated - public static Object getData(Object nbt) throws Exception{ - return inst.getData(nbt); - } - - @Deprecated - public static Object createData(Object value) throws Exception{ - return inst.createData(value); - } - - @Deprecated - public static Map convertCompoundTagToValueMap(Object nbt) throws Exception{ - return inst.convertCompoundTagToValueMap(nbt); - } - - @Deprecated - public static List convertListTagToValueList(Object nbttl) throws Exception{ - return inst.convertListTagToValueList(nbttl); - } - - @Deprecated - public static Object convertValueMapToCompoundTag(Map map) throws Exception{ - return inst.convertValueMapToCompoundTag(map); - } - - @Deprecated - public static Object convertValueListToListTag(List list) throws Exception{ - return inst.convertValueListToListTag(list); - } - - @Deprecated - public static void convertListTagToJSON(Object nbttl, JSONArray ja, JSONArray helper) throws Exception{ - inst.convertListTagToJSON(nbttl, ja, helper); - } - - @Deprecated - public static void convertListTagToJSON(Object nbttl, JSONArray ja) throws Exception{ - inst.convertListTagToJSON(nbttl, ja); - } - - @Deprecated - public static void convertCompoundTagToJSON(Object nbt, JSONObject jo, JSONObject helper) throws Exception{ - inst.convertCompoundTagToJSON(nbt, jo, helper); - } - - @Deprecated - public static void convertCompoundTagToJSON(Object nbt, JSONObject jo) throws Exception{ - inst.convertCompoundTagToJSON(nbt, jo); - } - - @Deprecated - public static Object convertJSONToCompoundTag(JSONObject jo, JSONObject helper) throws Exception{ - return inst.convertJSONToCompoundTag(jo, helper); - } - - @Deprecated - public static Object convertJSONToCompoundTag(JSONObject jo) throws Exception{ - return inst.convertJSONToCompoundTag(jo); - } - - @Deprecated - public static Object convertJSONToListTag(JSONArray ja, JSONArray helper) throws Exception{ - return inst.convertJSONToListTag(ja, helper); - } - - @Deprecated - public static Object convertJSONToListTag(JSONArray ja) throws Exception{ - return inst.convertJSONToListTag(ja); - } - - @Deprecated - public static Object getDataJSON(String key, Object nbt, JSONObject jo, JSONObject helper) throws Exception{ - return inst.getDataJSON(key, nbt, jo, helper); - } - - @Deprecated - public static JSONArray getDataJSON(Object nbt) throws Exception{ - return inst.getDataJSON(nbt); - } - - @Deprecated - public static Object getDataJSON(Object nbt, JSONArray ja, JSONArray helper) throws Exception{ - return inst.getDataJSON(nbt, ja, helper); - } - - @Deprecated - public static Object createDataJSON(String key, JSONObject jo, JSONObject helper) throws Exception{ - return inst.createDataJSON(key, jo, helper); - } - - @Deprecated - public static Object createDataJSON(String key, JSONObject jo) throws Exception{ - return inst.createDataJSON(key, jo); - } - - @Deprecated - public static byte getByte(Object o){ - return inst.getByte(o); - } - - @Deprecated - public static short getShort(Object o){ - return inst.getShort(o); - } - - @Deprecated - public static int getInt(Object o){ - return inst.getInt(o); - } - - @Deprecated - public static double getDouble(Object o){ - return inst.getDouble(o); - } - - @Deprecated - public static float getFloat(Object o){ - return inst.getFloat(o); - } - - @Deprecated - public static long getLong(Object o){ - return inst.getLong(o); - } - - @Deprecated - public static Object createDataJSON(int key, JSONArray jo, JSONArray helper) throws Exception{ - return inst.createDataJSON(key, jo, helper); - } - - @Deprecated - public static Object createDataJSON(int key, JSONArray jo) throws Exception{ - return inst.createDataJSON(key, jo); - } - - @Deprecated - public static boolean compareBaseTag(Object tag, Object tag1) throws Exception{ - return inst.compareBaseTag(tag, tag1); - } - - @Deprecated - public static boolean compareCompoundTag(Object tag, Object tag1) throws Exception{ - return inst.compareCompoundTag(tag, tag1); - } - - @Deprecated - public static boolean compareListTag(Object tag, Object tag1) throws Exception{ - return inst.compareListTag(tag, tag1); - } - - @Deprecated - public static boolean compare(ItemStack is1, ItemStack is2){ - return inst.compare(is1, is2); - } - - @Deprecated - public static boolean canMerge(ItemStack add, ItemStack to){ - return compare(add, to); - } - - @Deprecated - public static boolean isModified(ItemStack is){ - return inst.isModified(is); - } - - @Deprecated - public static void sortByMaterial(List items){ - inst.sortByMaterial(items); - } - - @Deprecated - public static void sortByName(List items){ - inst.sortByName(items); - } - - @Deprecated - public static void sortByAmount(List items){ - inst.sortByAmount(items); - } - - @Deprecated - public static ItemStack convertJSONToItemStack(JSONObject jo) throws Exception{ - return inst.convertJSONToItemStack(jo); - } - - @Deprecated - public static JSONObject convertItemStackToJSON(ItemStack is) throws Exception{ - return inst.convertItemStackToJSON(is); - } -} diff --git a/src/main/java/me/skymc/taboolib/nms/item/IDabItemUtils.java b/src/main/java/me/skymc/taboolib/nms/item/IDabItemUtils.java deleted file mode 100644 index c24b652..0000000 --- a/src/main/java/me/skymc/taboolib/nms/item/IDabItemUtils.java +++ /dev/null @@ -1,171 +0,0 @@ -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; - -public interface IDabItemUtils{ - - //@formatter:off - boolean hasBanner(); - - Object getNMSCopy(ItemStack is) throws Exception; - - boolean hasTag(Object is) throws Exception; - - ItemStack asCraftMirror(Object nis) throws Exception; - - ItemStack asBukkitCopy(Object nmis) throws Exception; - - String getName(ItemStack is); - - Object getItem(Object nis) throws Exception; - - Method getA(); - - String getRawName(ItemStack is); - - String getItemName(ItemStack is); - - Object getRegistry(); - - String getMinecraftName(ItemStack is); - - Object getTag(Object is) throws Exception; - - void setTag(Object is, Object tag1) throws Exception; - - boolean isEmpty(Object tag) throws Exception; - - Object getMap(Object tag) throws Exception; - - void set(Object tag, String key, Object value) throws Exception; - - void setString(Object tag, String key, String value) throws Exception; - - void setShort(Object tag, String key, short value) throws Exception; - - void setInt(Object tag, String key, int i) throws Exception; - - void setDouble(Object tag, String key, double d) throws Exception; - - void setLong(Object tag, String key, long l) throws Exception; - - boolean hasKey(Object tag, String key) throws Exception; - - Object get(Object tag, String key) throws Exception; - - String getString(Object tag, String key) throws Exception; - - int getInt(Object tag, String key) throws Exception; - - double getDouble(Object tag, String key) throws Exception; - - long getLong(Object tag, String key) throws Exception; - - short getShort(Object tag, String key) throws Exception; - - Object getNewNBTTagCompound() throws Exception; - - boolean hasAttributeModifiersKey(Object tag) throws Exception; - - Object getList(Object tag) throws Exception; - - Object getList(Object tag, String name, int id) throws Exception; - - boolean getUnbreakable(Object tag) throws Exception; - - void setUnbreakable(Object tag, boolean value) throws Exception; - - Object getNewNBTTagList() throws Exception; - - void addToList(Object taglist, Object nbt) throws Exception; - - int getSize(Object list) throws Exception; - - Object get(Object tlist, int i) throws Exception; - - Object getNewNBTTagByte(byte value) throws Exception; - - Object getNewNBTTagByteArray(byte[] value) throws Exception; - - Object getData(Object nbt) throws Exception; - - Object createData(Object value) throws Exception; - - Map convertCompoundTagToValueMap(Object nbt) throws Exception; - - List convertListTagToValueList(Object nbttl) throws Exception; - - Object convertValueMapToCompoundTag(Map map) throws Exception; - - Object convertValueListToListTag(List list) throws Exception; - @Deprecated - void convertListTagToJSON(Object nbttl, JSONArray ja, JSONArray helper) throws Exception; - - void convertListTagToJSON(Object nbttl, JSONArray ja) throws Exception; - @Deprecated - void convertCompoundTagToJSON(Object nbt, JSONObject jo, JSONObject helper) throws Exception; - - void convertCompoundTagToJSON(Object nbt, JSONObject jo) throws Exception; - @Deprecated - Object convertJSONToCompoundTag(JSONObject jo, JSONObject helper) throws Exception; - - Object convertJSONToCompoundTag(JSONObject jo) throws Exception; - @Deprecated - Object convertJSONToListTag(JSONArray ja, JSONArray helper) throws Exception; - - Object convertJSONToListTag(JSONArray ja) throws Exception; - @Deprecated - Object getDataJSON(String key, Object nbt, JSONObject jo, JSONObject helper) throws Exception; - - JSONArray getDataJSON(Object nbt) throws Exception; - @Deprecated - Object getDataJSON(Object nbt, JSONArray ja, JSONArray helper) throws Exception; - @Deprecated - Object createDataJSON(String key, JSONObject jo, JSONObject helper) throws Exception; - - Object createDataJSON(String key, JSONObject jo) throws Exception; - - byte getByte(Object o); - - short getShort(Object o); - - int getInt(Object o); - - double getDouble(Object o); - - float getFloat(Object o); - - long getLong(Object o); - @Deprecated - Object createDataJSON(int key, JSONArray jo, JSONArray helper) throws Exception; - - Object createDataJSON(int key, JSONArray jo) throws Exception; - - boolean compareBaseTag(Object tag, Object tag1) throws Exception; - - boolean compareCompoundTag(Object tag, Object tag1) throws Exception; - - boolean compareListTag(Object tag, Object tag1) throws Exception; - - boolean compare(ItemStack is1, ItemStack is2); - - boolean canMerge(ItemStack add, ItemStack to); - - boolean isModified(ItemStack is); - - void sortByMaterial(List items); - - void sortByName(List items); - - void sortByAmount(List items); - - ItemStack convertJSONToItemStack(JSONObject jo) throws Exception; - - JSONObject convertItemStackToJSON(ItemStack is) throws Exception; -} 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 deleted file mode 100644 index 1353ae8..0000000 --- a/src/main/java/me/skymc/taboolib/nms/item/impl/_164ItemUtils.java +++ /dev/null @@ -1,1308 +0,0 @@ -package me.skymc.taboolib.nms.item.impl; - -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 { - - public boolean banner = getBanner(); - - public boolean getBanner() { - try { - Material m = Material.valueOf("BANNER"); - return true; - } catch (Exception ignored) { - } - return false; - } - - @Override - public boolean hasBanner() { - return banner; - } - - 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); - } - - public Class ni = NMSUtils.getClass("net.minecraft.item.Item"); - - 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)); - } catch (Exception e) { - return null; - } - } - - 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); - return (String) ia.invoke(gi.invoke(nis), nis); - } catch (Exception e) { - return null; - } - } - - public Method gin = NMSUtils.getMethodSilent(ni, "getLabel"); - - @Override - public String getItemName(ItemStack is) { - try { - return (String) gin.invoke(gi.invoke(getNMSCopy(is))); - } catch (Exception e) { - return null; - } - } - - public Object registry = getRegistry(); - - @Override - public Object getRegistry() { - try { - return NMSUtils.getFieldSilent(ni, "REGISTRY", "field_150901_e").get(null); - } catch (Exception ignored) { - } - return null; - } - - public Class nmrs = NMSUtils.getClass("net.minecraft.util.registry.RegistrySimple", "net.minecraft.util.RegistrySimple"); - - public Field nmrsc = NMSUtils.getFieldSilent(nmrs, "field_82596_a"); - - @Override - public String getMinecraftName(ItemStack is) { - String name = getItemName(is); - if (nmrs == null) { - return name; - } - try { - Map m = (Map) nmrsc.get(registry); - for (Entry e : m.entrySet()) { - Object item = e.getValue(); - String s = (String) gin.invoke(item); - if (name.equals(s)) { - return e.getKey().toString(); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - 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); - } - - public Class nbtb = NMSUtils.getClass("net.minecraft.nbt.NBTBase"); - public Method nbttcs = NMSUtils.getMethodSilent(nbttc, "func_74782_a", String.class, nbtb); - public Method nbttcss = NMSUtils.getMethodSilent(nbttc, "func_74778_a", String.class, String.class); - public Method nbttcsi = NMSUtils.getMethodSilent(nbttc, "func_74768_a", String.class, int.class); - public Method nbttcsd = NMSUtils.getMethodSilent(nbttc, "func_74780_a", String.class, double.class); - 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); - } - - public Method nbttcg = NMSUtils.getMethodSilent(nbttc, "func_74775_l", String.class); - public Method nbttcgs = NMSUtils.getMethodSilent(nbttc, "func_74779_i", String.class); - public Method nbttcgi = NMSUtils.getMethodSilent(nbttc, "func_74762_e", String.class); - public Method nbttcgd = NMSUtils.getMethodSilent(nbttc, "func_74769_h", String.class); - 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); - } - - public Class nbttl = NMSUtils.getClass("net.minecraft.nbt.NBTTagList"); - public Method gl = NMSUtils.getMethodSilent(nbttc, "func_150295_c", String.class, int.class); - public Method gb = NMSUtils.getMethodSilent(nbttc, "func_74767_n", String.class); - public Method sb = NMSUtils.getMethodSilent(nbttc, "func_74757_a", String.class, boolean.class); - 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); - } - - public Class am = NMSUtils.getClass("net.minecraft.entity.ai.attributes.AttributeModifier"), ga = NMSUtils.getClass("net.minecraft.entity.SharedMonsterAttributes"); - public Method a = NMSUtils.getMethodSilent(ga, "func_111259_a", nbttc), ama = NMSUtils.getMethodSilent(am, "func_111167_a"); - - public Method gti = NMSUtils.getMethodSilent(nbtb, "func_74732_a"); - - public Class nbtby = NMSUtils.getClass("net.minecraft.nbt.NBTTagByte"); - public Class nbtba = NMSUtils.getClass("net.minecraft.nbt.NBTTagByteArray"); - public Class nbtd = NMSUtils.getClass("net.minecraft.nbt.NBTTagDouble"); - public Class nbtf = NMSUtils.getClass("net.minecraft.nbt.NBTTagFloat"); - public Class nbti = NMSUtils.getClass("net.minecraft.nbt.NBTTagInt"); - public Class nbtia = NMSUtils.getClass("net.minecraft.nbt.NBTTagIntArray"); - public Class nbtl = NMSUtils.getClass("net.minecraft.nbt.NBTTagList"); - public Class nbtlo = NMSUtils.getClass("net.minecraft.nbt.NBTTagLong"); - public Class nbts = NMSUtils.getClass("net.minecraft.nbt.NBTTagShort"); - public Class nbtst = NMSUtils.getClass("net.minecraft.nbt.NBTTagString"); - - public Constructor nbtbc = NMSUtils.getConstructorSilent(nbtby, String.class, byte.class); - public Constructor nbtbac = NMSUtils.getConstructorSilent(nbtba, String.class, byte[].class); - public Constructor nbtdc = NMSUtils.getConstructorSilent(nbtd, String.class, double.class); - public Constructor nbtfc = NMSUtils.getConstructorSilent(nbtf, String.class, float.class); - public Constructor nbtic = NMSUtils.getConstructorSilent(nbti, String.class, int.class); - public Constructor nbtiac = NMSUtils.getConstructorSilent(nbtia, String.class, int[].class); - public Constructor nbtlc = NMSUtils.getConstructorSilent(nbtl); - public Constructor nbtloc = NMSUtils.getConstructorSilent(nbtlo, String.class, long.class); - public Constructor nbtsc = NMSUtils.getConstructorSilent(nbts, String.class, short.class); - public Constructor nbtstc = NMSUtils.getConstructorSilent(nbtst, String.class, String.class); - - public Field nbtbd = NMSUtils.getField(nbtby, "field_74756_a"); - public Field nbtbad = NMSUtils.getField(nbtba, "field_74754_a"); - public Field nbtdd = NMSUtils.getField(nbtd, "field_74755_a"); - public Field nbtfd = NMSUtils.getField(nbtf, "field_74750_a"); - public Field nbtid = NMSUtils.getField(nbti, "field_74748_a"); - public Field nbtiad = NMSUtils.getField(nbtia, "field_74749_a"); - public Field nbtld = NMSUtils.getField(nbtl, "field_74747_a"); - public Field nbtlt = NMSUtils.getField(nbtl, "field_74746_b"); - public Field nbtlod = NMSUtils.getField(nbtlo, "field_74753_a"); - 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 = ((byte) gti.invoke(nbt)); - switch (i) { - case NBTConstants.TYPE_BYTE: - return nbtbd.get(nbt); - case NBTConstants.TYPE_SHORT: - return nbtsd.get(nbt); - case NBTConstants.TYPE_INT: - return nbtid.get(nbt); - case NBTConstants.TYPE_LONG: - return nbtlod.get(nbt); - case NBTConstants.TYPE_FLOAT: - return nbtfd.get(nbt); - case NBTConstants.TYPE_DOUBLE: - return nbtdd.get(nbt); - case NBTConstants.TYPE_BYTE_ARRAY: - return nbtbad.get(nbt); - case NBTConstants.TYPE_STRING: - return nbtstd.get(nbt); - case NBTConstants.TYPE_LIST: - return convertListTagToValueList(nbt); - case NBTConstants.TYPE_COMPOUND: - return convertCompoundTagToValueMap(nbt); - case NBTConstants.TYPE_INT_ARRAY: - return nbtiad.get(nbt); - } - return null; - } - - @Override - @SuppressWarnings("unchecked") - public Object createData(Object value) throws Exception { - if (value.getClass().equals(byte.class)) { - return nbtbc.newInstance(value); - } - if (value.getClass().equals(byte[].class)) { - return nbtbac.newInstance(value); - } - if (value.getClass().isAssignableFrom(Map.class)) { - return convertValueMapToCompoundTag((Map) value); - } - if (value.getClass().equals(double.class)) { - return nbtdc.newInstance(value); - } - if (value.getClass().equals(float.class)) { - return nbtfc.newInstance(value); - } - if (value.getClass().equals(int.class)) { - return nbtic.newInstance(value); - } - if (value.getClass().equals(int[].class)) { - return nbtiac.newInstance(value); - } - if (value.getClass().isAssignableFrom(List.class)) { - return convertValueListToListTag((List) value); - } - if (value.getClass().equals(long.class)) { - return nbtloc.newInstance(value); - } - if (value.getClass().equals(short.class)) { - return nbtsc.newInstance(value); - } - if (value.getClass().equals(String.class)) { - return nbtstc.newInstance(value); - } - return null; - } - - @Override - @SuppressWarnings({"unchecked"}) - public Map convertCompoundTagToValueMap(Object nbt) throws Exception { - Map ret = new HashMap<>(); - Map map = (Map) getMap(nbt); - for (Entry e : map.entrySet()) { - Object nbti = e.getValue(); - Object data = getData(nbti); - if (data != null) { - ret.put(e.getKey(), data); - } - } - return ret; - } - - @Override - @SuppressWarnings("unchecked") - public List convertListTagToValueList(Object nbttl) throws Exception { - List ret = new ArrayList<>(); - List list = (List) nbtld.get(nbttl); - for (Object e : list) { - Object data = getData(e); - if (data != null) { - ret.add(data); - } - } - return ret; - } - - @Override - public Object convertValueMapToCompoundTag(Map map) throws Exception { - Map value = new HashMap<>(); - for (Entry e : map.entrySet()) { - value.put(e.getKey(), createData(e.getValue())); - } - Object ret = getNewNBTTagCompound(); - nbttcm.set(ret, value); - return ret; - } - - @Override - public Object convertValueListToListTag(List list) throws Exception { - List value = new ArrayList<>(); - for (Object e : list) { - value.add(createData(e)); - } - Object ret = getNewNBTTagList(); - nbttcm.set(ret, value); - if (value.size() > 0) { - nbtlt.set(ret, gti.invoke(value.get(0))); - } - return ret; - } - - @Override - @Deprecated - @SuppressWarnings("unchecked") - public void convertListTagToJSON(Object nbttl, JSONArray ja, JSONArray helper) throws Exception { - List list = (List) nbtld.get(nbttl); - for (Object e : list) { - Object data = getDataJSON(e, ja, helper); - if (data != null) { - ja.put(data); - } - } - } - - @Override - @SuppressWarnings("unchecked") - public void convertListTagToJSON(Object nbttl, JSONArray ja) throws Exception { - List list = (List) nbtld.get(nbttl); - for (Object e : list) { - Object data = getDataJSON(e); - if (data != null) { - ja.put(data); - } - } - } - - @Override - @Deprecated - @SuppressWarnings("unchecked") - public void convertCompoundTagToJSON(Object nbt, JSONObject jo, JSONObject helper) throws Exception { - Map map = (Map) getMap(nbt); - for (Entry e : map.entrySet()) { - Object nbti = e.getValue(); - Object data = getDataJSON(e.getKey(), nbti, jo, helper); - if (data != null) { - jo.put(e.getKey(), data); - } - } - } - - @Override - @SuppressWarnings("unchecked") - public void convertCompoundTagToJSON(Object nbt, JSONObject jo) throws Exception { - Map map = (Map) getMap(nbt); - for (Entry e : map.entrySet()) { - Object nbti = e.getValue(); - Object data = getDataJSON(nbti); - if (data != null) { - jo.put(e.getKey(), data); - } - } - } - - @Override - @Deprecated - @SuppressWarnings("unchecked") - public Object convertJSONToCompoundTag(JSONObject jo, JSONObject helper) throws Exception { - Map value = new HashMap<>(); - Iterator it = jo.keys(); - while (it.hasNext()) { - String e = it.next(); - value.put(e, createDataJSON(e, jo, helper)); - } - Object ret = getNewNBTTagCompound(); - nbttcm.set(ret, value); - return ret; - } - - @Override - @SuppressWarnings("unchecked") - public Object convertJSONToCompoundTag(JSONObject jo) throws Exception { - Map value = new HashMap<>(); - Iterator it = jo.keys(); - while (it.hasNext()) { - String e = it.next(); - value.put(e, createDataJSON(e, jo)); - } - Object ret = getNewNBTTagCompound(); - nbttcm.set(ret, value); - return ret; - } - - @Override - @Deprecated - @SuppressWarnings({"rawtypes", "unchecked"}) - public Object convertJSONToListTag(JSONArray ja, JSONArray helper) throws Exception { - List value = new ArrayList(); - for (int i = 0; i < ja.length(); i++) { - value.add(createDataJSON(i, ja, helper)); - } - Object ret = getNewNBTTagList(); - nbtld.set(ret, value); - if (value.size() > 0) { - nbtlt.set(ret, gti.invoke(value.get(0))); - } - return ret; - } - - @Override - @SuppressWarnings({"rawtypes", "unchecked"}) - public Object convertJSONToListTag(JSONArray ja) throws Exception { - List value = new ArrayList(); - for (int i = 0; i < ja.length(); i++) { - value.add(createDataJSON(i, ja)); - } - Object ret = getNewNBTTagList(); - nbtld.set(ret, value); - if (value.size() > 0) { - nbtlt.set(ret, gti.invoke(value.get(0))); - } - return ret; - } - - @Override - @Deprecated - public Object getDataJSON(String key, Object nbt, JSONObject jo, JSONObject helper) throws Exception { - int i = ((byte) gti.invoke(nbt)); - Object ret = null; - Object help = i; - switch (i) { - case NBTConstants.TYPE_BYTE: - ret = nbtbd.get(nbt); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsd.get(nbt); - break; - case NBTConstants.TYPE_INT: - ret = nbtid.get(nbt); - break; - case NBTConstants.TYPE_LONG: - ret = nbtlod.get(nbt); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfd.get(nbt); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdd.get(nbt); - break; - case NBTConstants.TYPE_BYTE_ARRAY: - ret = nbtbad.get(nbt); - break; - case NBTConstants.TYPE_STRING: - ret = nbtstd.get(nbt); - break; - case NBTConstants.TYPE_LIST: { - JSONArray ja1 = new JSONArray(); - JSONArray helper1 = new JSONArray(); - convertListTagToJSON(nbt, ja1, helper1); - ret = ja1; - help = helper1; - break; - } - case NBTConstants.TYPE_COMPOUND: - JSONObject jo1 = new JSONObject(); - JSONObject helper1 = new JSONObject(); - convertCompoundTagToJSON(nbt, jo1, helper1); - ret = jo1; - help = helper1; - break; - case NBTConstants.TYPE_INT_ARRAY: - ret = nbtiad.get(nbt); - break; - } - if (ret != null) { - helper.put(key, help); - } - return ret; - } - - @Override - public JSONArray getDataJSON(Object nbt) throws Exception { - int i = ((byte) gti.invoke(nbt)); - Object ret = null; - switch (i) { - case NBTConstants.TYPE_BYTE: - ret = nbtbd.get(nbt); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsd.get(nbt); - break; - case NBTConstants.TYPE_INT: - ret = nbtid.get(nbt); - break; - case NBTConstants.TYPE_LONG: - ret = nbtlod.get(nbt); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfd.get(nbt); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdd.get(nbt); - break; - case NBTConstants.TYPE_BYTE_ARRAY: - ret = nbtbad.get(nbt); - break; - case NBTConstants.TYPE_STRING: - ret = nbtstd.get(nbt); - break; - case NBTConstants.TYPE_LIST: { - JSONArray ja1 = new JSONArray(); - convertListTagToJSON(nbt, ja1); - ret = ja1; - break; - } - case NBTConstants.TYPE_COMPOUND: - JSONObject jo1 = new JSONObject(); - convertCompoundTagToJSON(nbt, jo1); - ret = jo1; - break; - case NBTConstants.TYPE_INT_ARRAY: - ret = nbtiad.get(nbt); - break; - } - if (ret == null) { - return null; - } - return new JSONArray(new Object[]{i, ret}); - } - - @Override - public Object getDataJSON(Object nbt, JSONArray ja, JSONArray helper) throws Exception { - int i = ((byte) gti.invoke(nbt)); - Object ret = null; - Object help = i; - switch (i) { - case NBTConstants.TYPE_BYTE: - ret = nbtbd.get(nbt); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsd.get(nbt); - break; - case NBTConstants.TYPE_INT: - ret = nbtid.get(nbt); - break; - case NBTConstants.TYPE_LONG: - ret = nbtlod.get(nbt); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfd.get(nbt); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdd.get(nbt); - break; - case NBTConstants.TYPE_BYTE_ARRAY: - ret = nbtbad.get(nbt); - break; - case NBTConstants.TYPE_STRING: - ret = nbtstd.get(nbt); - break; - case NBTConstants.TYPE_LIST: { - JSONArray ja1 = new JSONArray(); - JSONArray helper1 = new JSONArray(); - convertListTagToJSON(nbt, ja1, helper1); - ret = ja1; - break; - } - case NBTConstants.TYPE_COMPOUND: - JSONObject jo1 = new JSONObject(); - JSONObject helper1 = new JSONObject(); - convertCompoundTagToJSON(nbt, jo1, helper1); - ret = jo1; - help = helper1; - break; - case NBTConstants.TYPE_INT_ARRAY: - ret = nbtiad.get(nbt); - break; - } - if (ret != null) { - helper.put(help); - } - return ret; - } - - @Override - public Object createDataJSON(String key, JSONObject jo, JSONObject helper) throws Exception { - Object help = helper.get(key); - Object ret = null; - if (help instanceof JSONObject) { - JSONObject jo1 = jo.getJSONObject(key); - JSONObject helper1 = (JSONObject) help; - ret = convertJSONToCompoundTag(jo1, helper1); - } else if (help instanceof JSONArray) { - JSONArray ja1 = jo.getJSONArray(key); - JSONArray helper1 = (JSONArray) help; - ret = convertJSONToListTag(ja1, helper1); - } else { - int i = (int) help; - switch (i) { - case NBTConstants.TYPE_BYTE: - ret = nbtbc.newInstance(getByte(jo.get(key))); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsc.newInstance(getShort(jo.get(key))); - break; - case NBTConstants.TYPE_INT: - ret = nbtic.newInstance(getInt(jo.get(key))); - break; - case NBTConstants.TYPE_LONG: - ret = nbtloc.newInstance(getLong(jo.get(key))); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfc.newInstance(getFloat(jo.get(key))); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdc.newInstance(getDouble(jo.get(key))); - break; - case NBTConstants.TYPE_BYTE_ARRAY: { - JSONArray ja = jo.getJSONArray(key); - byte[] b = new byte[ja.length()]; - for (int a = 0; a < ja.length(); a++) { - b[a] = getByte(ja.get(a)); - } - return nbtbac.newInstance(b); - } - case NBTConstants.TYPE_STRING: - ret = nbtstc.newInstance((String) jo.get(key)); - break; - case NBTConstants.TYPE_INT_ARRAY: - JSONArray ja = jo.getJSONArray(key); - int[] b = new int[ja.length()]; - for (int a = 0; a < ja.length(); a++) { - b[a] = getInt(ja.get(a)); - } - return nbtiac.newInstance(b); - } - } - return ret; - } - - @Override - public Object createDataJSON(String key, JSONObject jo) throws Exception { - JSONArray j = jo.getJSONArray(key); - Object ret = null; - int i = j.getInt(0); - switch (i) { - case NBTConstants.TYPE_COMPOUND: - ret = convertJSONToCompoundTag(j.getJSONObject(1)); - break; - case NBTConstants.TYPE_BYTE: - ret = nbtbc.newInstance("", getByte(j.get(1))); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsc.newInstance("", getShort(j.get(1))); - break; - case NBTConstants.TYPE_INT: - ret = nbtic.newInstance("", getInt(j.get(1))); - break; - case NBTConstants.TYPE_LONG: - ret = nbtloc.newInstance("", getLong(j.get(1))); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfc.newInstance("", getFloat(j.get(1))); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdc.newInstance("", getDouble(j.get(1))); - break; - case NBTConstants.TYPE_BYTE_ARRAY: { - JSONArray ja = j.getJSONArray(1); - byte[] b = new byte[ja.length()]; - for (int a = 0; a < ja.length(); a++) { - b[a] = getByte(ja.get(a)); - } - return nbtbac.newInstance("", b); - } - case NBTConstants.TYPE_STRING: - ret = nbtstc.newInstance("", j.get(1)); - break; - case NBTConstants.TYPE_INT_ARRAY: - JSONArray ja = jo.getJSONArray(key); - int[] b = new int[ja.length()]; - for (int a = 0; a < ja.length(); a++) { - b[a] = getInt(ja.get(a)); - } - return nbtiac.newInstance("", b); - case NBTConstants.TYPE_LIST: - ret = convertJSONToListTag(j.getJSONArray(1)); - break; - } - 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; - } - if (o.getClass().equals(Integer.class)) { - return (byte) (int) o; - } - 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 (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 (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 (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 (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 (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; - if (help instanceof JSONObject) { - JSONObject jo1 = jo.getJSONObject(key); - JSONObject helper1 = (JSONObject) help; - return convertJSONToCompoundTag(jo1, helper1); - } else if (help instanceof JSONArray) { - JSONArray ja1 = jo.getJSONArray(key); - JSONArray helper1 = (JSONArray) help; - return convertJSONToListTag(ja1, helper1); - } else { - int i = (int) help; - switch (i) { - case NBTConstants.TYPE_BYTE: - ret = nbtbc.newInstance(getByte(jo.get(key))); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsc.newInstance(getShort(jo.get(key))); - break; - case NBTConstants.TYPE_INT: - ret = nbtic.newInstance(getInt(jo.get(key))); - break; - case NBTConstants.TYPE_LONG: - ret = nbtlc.newInstance(getLong(jo.get(key))); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfc.newInstance(getFloat(jo.get(key))); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdc.newInstance(getDouble(jo.get(key))); - break; - case NBTConstants.TYPE_BYTE_ARRAY: { - JSONArray ja = jo.getJSONArray(key); - byte[] b = new byte[ja.length()]; - for (int a = 0; a < ja.length(); a++) { - b[a] = getByte(ja.get(a)); - } - return nbtbac.newInstance(b); - } - case NBTConstants.TYPE_STRING: - ret = nbtstc.newInstance((String) jo.get(key)); - break; - case NBTConstants.TYPE_INT_ARRAY: - JSONArray ja = jo.getJSONArray(key); - int[] b = new int[ja.length()]; - for (int a = 0; a < ja.length(); a++) { - b[a] = getInt(ja.get(a)); - } - return nbtiac.newInstance(b); - } - } - return ret; - } - - @Override - public Object createDataJSON(int key, JSONArray jo) throws Exception { - JSONArray j = jo.getJSONArray(key); - Object ret = null; - int i = j.getInt(0); - switch (i) { - case NBTConstants.TYPE_COMPOUND: - ret = convertJSONToCompoundTag(j.getJSONObject(1)); - break; - case NBTConstants.TYPE_BYTE: - ret = nbtbc.newInstance("", getByte(j.get(1))); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsc.newInstance("", getShort(j.get(1))); - break; - case NBTConstants.TYPE_INT: - ret = nbtic.newInstance("", getInt(j.get(1))); - break; - case NBTConstants.TYPE_LONG: - ret = nbtloc.newInstance("", getLong(j.get(1))); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfc.newInstance("", getFloat(j.get(1))); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdc.newInstance("", getDouble(j.get(1))); - break; - case NBTConstants.TYPE_BYTE_ARRAY: { - JSONArray ja = j.getJSONArray(1); - byte[] b = new byte[ja.length()]; - for (int a = 0; a < ja.length(); a++) { - b[a] = getByte(ja.get(a)); - } - return nbtbac.newInstance("", b); - } - case NBTConstants.TYPE_STRING: - ret = nbtstc.newInstance("", j.get(1)); - break; - case NBTConstants.TYPE_INT_ARRAY: - JSONArray ja = jo.getJSONArray(key); - int[] b = new int[ja.length()]; - for (int a = 0; a < ja.length(); a++) { - b[a] = getInt(ja.get(a)); - } - return nbtiac.newInstance("", b); - case NBTConstants.TYPE_LIST: - ret = convertJSONToListTag(j.getJSONArray(1)); - break; - } - return ret; - } - - @Override - public boolean compareBaseTag(Object tag, Object tag1) throws Exception { - int i = ((byte) gti.invoke(tag)); - int i1 = ((byte) gti.invoke(tag1)); - if (i != i1) { - return false; - } - switch (i) { - case NBTConstants.TYPE_BYTE: - Byte b = (byte) nbtbd.get(tag); - Byte b1 = (byte) nbtbd.get(tag1); - return b.equals(b1); - case NBTConstants.TYPE_SHORT: - Short s = (short) nbtsd.get(tag); - Short s1 = (short) nbtsd.get(tag1); - return s.equals(s1); - case NBTConstants.TYPE_INT: - Integer a = (int) nbtid.get(tag); - Integer a1 = (int) nbtid.get(tag1); - return a.equals(a1); - case NBTConstants.TYPE_LONG: - Long l = (long) nbtlod.get(tag); - Long l1 = (long) nbtlod.get(tag1); - return l.equals(l1); - case NBTConstants.TYPE_FLOAT: - Float f = (float) nbtfd.get(tag); - Float f1 = (float) nbtfd.get(tag1); - return f.equals(f1); - case NBTConstants.TYPE_DOUBLE: - Double d = (double) nbtdd.get(tag); - Double d1 = (double) nbtdd.get(tag1); - return d.equals(d1); - case NBTConstants.TYPE_BYTE_ARRAY: - byte[] ba = (byte[]) nbtbad.get(tag); - byte[] ba1 = (byte[]) nbtbad.get(tag1); - return Arrays.equals(ba, ba1); - case NBTConstants.TYPE_STRING: - String st = (String) nbtstd.get(tag); - String st1 = (String) nbtstd.get(tag1); - return st.equals(st1); - case NBTConstants.TYPE_LIST: { - return compareListTag(tag, tag1); - } - case NBTConstants.TYPE_COMPOUND: - return compareCompoundTag(tag, tag1); - case NBTConstants.TYPE_INT_ARRAY: - int[] ia = (int[]) nbtiad.get(tag); - int[] ia1 = (int[]) nbtiad.get(tag); - return Arrays.equals(ia, ia1); - } - return false; - } - - @Override - @SuppressWarnings("unchecked") - public boolean compareCompoundTag(Object tag, Object tag1) throws Exception { - Map map = (Map) getMap(tag); - Map map1 = (Map) getMap(tag1); - if (map.size() != map1.size()) { - return false; - } - if (!map.keySet().containsAll(map1.keySet())) { - return false; - } - for (Entry e : map.entrySet()) { - Object o = e.getValue(); - Object o1 = map1.get(e.getKey()); - if (!compareBaseTag(o, o1)) { - return false; - } - } - return true; - } - - @Override - @SuppressWarnings({"unchecked", "rawtypes"}) - public boolean compareListTag(Object tag, Object tag1) throws Exception { - List list = (List) nbtld.get(tag); - List list1 = (List) nbtld.get(tag1); - if (list.size() != list1.size()) { - return false; - } - if (list.isEmpty() && list1.isEmpty()) { - return true; - } - List copy = new ArrayList(list); - List copy1 = new ArrayList(list1); - Iterator it = copy.iterator(); - while (it.hasNext()) { - Object o = it.next(); - Iterator it1 = copy1.iterator(); - boolean cont = false; - while (it1.hasNext()) { - Object o1 = it1.next(); - if (compareBaseTag(o, o1)) { - it1.remove(); - it.remove(); - cont = true; - break; - } - } - if (!cont) { - return false; - } - } - return copy.isEmpty() && copy1.isEmpty(); - } - - public Object getAttribute(Object compound) throws Exception { - return a.invoke(null, compound); - } - - public Map getAttributes(Object attribs) throws Exception { - Map r = new HashMap<>(); - for (int i = 0; i < getSize(attribs); i++) { - Object compound = g.invoke(attribs, i); - Object attrib = a.invoke(null, compound); - if (attrib != null) { - UUID uuid = (UUID) ama.invoke(attrib); - if (uuid.getLeastSignificantBits() != 0L && uuid.getMostSignificantBits() != 0L) { - r.put(i, attrib); - } - } - } - return r; - } - - @Override - public boolean compare(ItemStack is1, ItemStack is2) { - if (is1.getType().equals(is2.getType())) { - if (is1.getDurability() == is2.getDurability()) { - try { - Object nis1 = getNMSCopy(is1); - Object nis2 = getNMSCopy(is2); - Object tis1 = getTag(nis1); - Object tis2 = getTag(nis2); - if (tis1 != null && tis2 == null) { - return isEmpty(tis1); - } - if (tis1 == null && tis2 != null) { - return isEmpty(tis2); - } - return tis1 == null && tis2 == null || compareCompoundTag(tis1, tis2); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - 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); - ItemStack is2 = new ItemStack(is.getType(), 1, is.getDurability()); - return !is1.equals(is2); - } - - @Override - public void sortByMaterial(List items) { - items.sort(new MaterialComparator()); - } - - public class MaterialComparator implements Comparator { - @Override - public int compare(ItemStack arg0, ItemStack arg1) { - return arg0.getType().name().compareTo(arg1.getType().name()); - } - } - - @Override - public void sortByName(List items) { - items.sort(new NameComparator()); - } - - public class NameComparator implements Comparator { - @Override - public int compare(ItemStack arg0, ItemStack arg1) { - int i = 0; - try { - i = ChatColor.stripColor(getName(arg0)).compareTo(ChatColor.stripColor(getName(arg1))); - } catch (Exception e) { - e.printStackTrace(); - } - return i; - } - } - - @Override - public void sortByAmount(List items) { - items.sort(new AmountComparator()); - } - - public class AmountComparator implements Comparator { - @Override - public int compare(ItemStack arg0, ItemStack arg1) { - int i = arg1.getAmount() - arg0.getAmount(); - if (i == 0) { - try { - i = ChatColor.stripColor(getName(arg0)).compareTo(ChatColor.stripColor(getName(arg1))); - } catch (Exception e) { - e.printStackTrace(); - } - } - return i; - } - } - - @Override - public ItemStack convertJSONToItemStack(JSONObject jo) throws Exception { - Material material = Material.valueOf(jo.getString("material")); - int amount = jo.getInt("amount"); - int durability = jo.getInt("durability"); - ItemStack is = new ItemStack(material, amount, (short) durability); - JSONObject jo1 = jo.getJSONObject("tag"); - if (jo1.length() == 0) { - return is; - } - Object tag = convertJSONToCompoundTag(jo1); - Object nmis = getNMSCopy(is); - setTag(nmis, tag); - is = asBukkitCopy(nmis); - return is; - } - - @Override - public JSONObject convertItemStackToJSON(ItemStack is) throws Exception { - JSONObject jo = new JSONObject(); - jo.put("material", is.getType().name()); - jo.put("amount", is.getAmount()); - jo.put("durability", is.getDurability()); - JSONObject jo2 = new JSONObject(); - Object nmis = getNMSCopy(is); - Object tag = getTag(nmis); - if (tag != null) { - convertCompoundTagToJSON(tag, jo2); - } - jo.put("tag", jo2); - return jo; - } -} 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 deleted file mode 100644 index d55bc26..0000000 --- a/src/main/java/me/skymc/taboolib/nms/item/impl/_1710ItemUtils.java +++ /dev/null @@ -1,1218 +0,0 @@ -package me.skymc.taboolib.nms.item.impl; - -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{ - - public boolean banner = getBanner(); - - public boolean getBanner(){ - try{ - Material m = Material.valueOf("BANNER"); - return true; - } catch (Exception ignored) { - } - return false; - } - - @Override - public boolean hasBanner(){ - return banner; - } - - 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); - } - - public Class ni = NMSUtils.getClass("net.minecraft.item.Item"); - - 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)); - }catch(Exception e){ - return null; - } - } - - 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); - return (String)ia.invoke(gi.invoke(nis), nis); - }catch(Exception e){ - return null; - } - } - - public Method gin = NMSUtils.getMethodSilent(ni, "getLabel"); - - @Override - public String getItemName(ItemStack is){ - try{ - return (String)gin.invoke(gi.invoke(getNMSCopy(is))); - }catch(Exception e){ - return null; - } - } - - public Object registry = getRegistry(); - - @Override - public Object getRegistry(){ - try{ - return NMSUtils.getFieldSilent(ni, "REGISTRY", "field_150901_e").get(null); - } catch (Exception ignored) { - } - return null; - } - - public Class nmrs = NMSUtils.getClass("net.minecraft.util.registry.RegistrySimple", "net.minecraft.util.RegistrySimple"); - - public Field nmrsc = NMSUtils.getField(nmrs, "field_82596_a"); - - @Override - public String getMinecraftName(ItemStack is){ - String name = getItemName(is); - try{ - Map m = (Map)nmrsc.get(registry); - for(Entry e : m.entrySet()){ - Object item = e.getValue(); - String s = (String)gin.invoke(item); - if(name.equals(s)){ return e.getKey().toString(); } - } - }catch(Exception e){ - e.printStackTrace(); - } - return null; - } - - 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); - } - - public Class nbtb = NMSUtils.getClass("net.minecraft.nbt.NBTBase"); - public Method nbttcs = NMSUtils.getMethodSilent(nbttc, "func_74782_a", String.class, nbtb); - public Method nbttcss = NMSUtils.getMethodSilent(nbttc, "func_74778_a", String.class, String.class); - public Method nbttcsi = NMSUtils.getMethodSilent(nbttc, "func_74768_a", String.class, int.class); - public Method nbttcsd = NMSUtils.getMethodSilent(nbttc, "func_74780_a", String.class, double.class); - 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); - } - - public Method nbttcg = NMSUtils.getMethodSilent(nbttc, "func_74775_l", String.class); - public Method nbttcgs = NMSUtils.getMethodSilent(nbttc, "func_74779_i", String.class); - public Method nbttcgi = NMSUtils.getMethodSilent(nbttc, "func_74762_e", String.class); - public Method nbttcgd = NMSUtils.getMethodSilent(nbttc, "func_74769_h", String.class); - 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); - } - - public Class nbttl = NMSUtils.getClass("net.minecraft.nbt.NBTTagList"); - public Method gl = NMSUtils.getMethodSilent(nbttc, "func_150295_c", String.class, int.class); - public Method gb = NMSUtils.getMethodSilent(nbttc, "func_74767_n", String.class); - public Method sb = NMSUtils.getMethodSilent(nbttc, "func_74757_a", String.class, boolean.class); - 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); - } - - public Class am = NMSUtils.getClass("net.minecraft.entity.ai.attributes.AttributeModifier"), ga = NMSUtils.getClass("net.minecraft.entity.SharedMonsterAttributes"); - public Method a = NMSUtils.getMethodSilent(ga, "func_111259_a", nbttc), ama = NMSUtils.getMethodSilent(am, "func_111167_a"); - - public Method gti = NMSUtils.getMethodSilent(nbtb, "func_74732_a"); - - public Class nbtby = NMSUtils.getClass("net.minecraft.nbt.NBTTagByte"); - public Class nbtba = NMSUtils.getClass("net.minecraft.nbt.NBTTagByteArray"); - public Class nbtd = NMSUtils.getClass("net.minecraft.nbt.NBTTagDouble"); - public Class nbtf = NMSUtils.getClass("net.minecraft.nbt.NBTTagFloat"); - public Class nbti = NMSUtils.getClass("net.minecraft.nbt.NBTTagInt"); - public Class nbtia = NMSUtils.getClass("net.minecraft.nbt.NBTTagIntArray"); - public Class nbtl = NMSUtils.getClass("net.minecraft.nbt.NBTTagList"); - public Class nbtlo = NMSUtils.getClass("net.minecraft.nbt.NBTTagLong"); - public Class nbts = NMSUtils.getClass("net.minecraft.nbt.NBTTagShort"); - public Class nbtst = NMSUtils.getClass("net.minecraft.nbt.NBTTagString"); - - public Constructor nbtbc = NMSUtils.getConstructorSilent(nbtby, byte.class); - public Constructor nbtbac = NMSUtils.getConstructorSilent(nbtba, byte[].class); - public Constructor nbtdc = NMSUtils.getConstructorSilent(nbtd, double.class); - public Constructor nbtfc = NMSUtils.getConstructorSilent(nbtf, float.class); - public Constructor nbtic = NMSUtils.getConstructorSilent(nbti, int.class); - public Constructor nbtiac = NMSUtils.getConstructorSilent(nbtia, int[].class); - public Constructor nbtlc = NMSUtils.getConstructorSilent(nbtl); - public Constructor nbtloc = NMSUtils.getConstructorSilent(nbtlo, long.class); - public Constructor nbtsc = NMSUtils.getConstructorSilent(nbts, short.class); - public Constructor nbtstc = NMSUtils.getConstructorSilent(nbtst, String.class); - - public Field nbtbd = NMSUtils.getField(nbtby, "field_74756_a"); - public Field nbtbad = NMSUtils.getField(nbtba, "field_74754_a"); - public Field nbtdd = NMSUtils.getField(nbtd, "field_74755_a"); - public Field nbtfd = NMSUtils.getField(nbtf, "field_74750_a"); - public Field nbtid = NMSUtils.getField(nbti, "field_74748_a"); - public Field nbtiad = NMSUtils.getField(nbtia, "field_74749_a"); - public Field nbtld = NMSUtils.getField(nbtl, "field_74747_a"); - public Field nbtlt = NMSUtils.getField(nbtl, "field_74746_b"); - public Field nbtlod = NMSUtils.getField(nbtlo, "field_74753_a"); - 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 = ((byte)gti.invoke(nbt)); - switch(i){ - case NBTConstants.TYPE_BYTE: - return nbtbd.get(nbt); - case NBTConstants.TYPE_SHORT: - return nbtsd.get(nbt); - case NBTConstants.TYPE_INT: - return nbtid.get(nbt); - case NBTConstants.TYPE_LONG: - return nbtlod.get(nbt); - case NBTConstants.TYPE_FLOAT: - return nbtfd.get(nbt); - case NBTConstants.TYPE_DOUBLE: - return nbtdd.get(nbt); - case NBTConstants.TYPE_BYTE_ARRAY: - return nbtbad.get(nbt); - case NBTConstants.TYPE_STRING: - return nbtstd.get(nbt); - case NBTConstants.TYPE_LIST: - return convertListTagToValueList(nbt); - case NBTConstants.TYPE_COMPOUND: - return convertCompoundTagToValueMap(nbt); - case NBTConstants.TYPE_INT_ARRAY: - return nbtiad.get(nbt); - } - return null; - } - - @Override - @SuppressWarnings("unchecked") - public Object createData(Object value) throws Exception{ - if(value.getClass().equals(byte.class)){ return nbtbc.newInstance(value); } - if(value.getClass().equals(byte[].class)){ return nbtbac.newInstance(value); } - if(value.getClass().isAssignableFrom(Map.class)){ return convertValueMapToCompoundTag((Map)value); } - if(value.getClass().equals(double.class)){ return nbtdc.newInstance(value); } - if(value.getClass().equals(float.class)){ return nbtfc.newInstance(value); } - if(value.getClass().equals(int.class)){ return nbtic.newInstance(value); } - if(value.getClass().equals(int[].class)){ return nbtiac.newInstance(value); } - if(value.getClass().isAssignableFrom(List.class)){ return convertValueListToListTag((List)value); } - if(value.getClass().equals(long.class)){ return nbtloc.newInstance(value); } - if(value.getClass().equals(short.class)){ return nbtsc.newInstance(value); } - if(value.getClass().equals(String.class)){ return nbtstc.newInstance(value); } - return null; - } - - @Override - @SuppressWarnings({ "unchecked" }) - public Map convertCompoundTagToValueMap(Object nbt) throws Exception{ - Map ret = new HashMap<>(); - Map map = (Map)getMap(nbt); - for(Entry e : map.entrySet()){ - Object nbti = e.getValue(); - Object data = getData(nbti); - if(data != null){ - ret.put(e.getKey(), data); - } - } - return ret; - } - - @Override - @SuppressWarnings("unchecked") - public List convertListTagToValueList(Object nbttl) throws Exception{ - List ret = new ArrayList<>(); - List list = (List)nbtld.get(nbttl); - for(Object e : list){ - Object data = getData(e); - if(data != null){ - ret.add(data); - } - } - return ret; - } - - @Override - public Object convertValueMapToCompoundTag(Map map) throws Exception{ - Map value = new HashMap<>(); - for(Entry e : map.entrySet()){ - value.put(e.getKey(), createData(e.getValue())); - } - Object ret = getNewNBTTagCompound(); - nbttcm.set(ret, value); - return ret; - } - - @Override - public Object convertValueListToListTag(List list) throws Exception{ - List value = new ArrayList<>(); - for(Object e : list){ - value.add(createData(e)); - } - Object ret = getNewNBTTagList(); - nbttcm.set(ret, value); - if(value.size() > 0){ - nbtlt.set(ret, gti.invoke(value.get(0))); - } - return ret; - } - - @Override - @Deprecated - @SuppressWarnings("unchecked") - public void convertListTagToJSON(Object nbttl, JSONArray ja, JSONArray helper) throws Exception{ - List list = (List)nbtld.get(nbttl); - for(Object e : list){ - Object data = getDataJSON(e, ja, helper); - if(data != null){ - ja.put(data); - } - } - } - - @Override - @SuppressWarnings("unchecked") - public void convertListTagToJSON(Object nbttl, JSONArray ja) throws Exception{ - List list = (List)nbtld.get(nbttl); - for(Object e : list){ - Object data = getDataJSON(e); - if(data != null){ - ja.put(data); - } - } - } - - @Override - @Deprecated - @SuppressWarnings("unchecked") - public void convertCompoundTagToJSON(Object nbt, JSONObject jo, JSONObject helper) throws Exception{ - Map map = (Map)getMap(nbt); - for(Entry e : map.entrySet()){ - Object nbti = e.getValue(); - Object data = getDataJSON(e.getKey(), nbti, jo, helper); - if(data != null){ - jo.put(e.getKey(), data); - } - } - } - - @Override - @SuppressWarnings("unchecked") - public void convertCompoundTagToJSON(Object nbt, JSONObject jo) throws Exception{ - Map map = (Map)getMap(nbt); - for(Entry e : map.entrySet()){ - Object nbti = e.getValue(); - Object data = getDataJSON(nbti); - if(data != null){ - jo.put(e.getKey(), data); - } - } - } - - @Override - @Deprecated - @SuppressWarnings("unchecked") - public Object convertJSONToCompoundTag(JSONObject jo, JSONObject helper) throws Exception{ - Map value = new HashMap<>(); - Iterator it = jo.keys(); - while(it.hasNext()){ - String e = it.next(); - value.put(e, createDataJSON(e, jo, helper)); - } - Object ret = getNewNBTTagCompound(); - nbttcm.set(ret, value); - return ret; - } - - @Override - @SuppressWarnings("unchecked") - public Object convertJSONToCompoundTag(JSONObject jo) throws Exception{ - Map value = new HashMap<>(); - Iterator it = jo.keys(); - while(it.hasNext()){ - String e = it.next(); - value.put(e, createDataJSON(e, jo)); - } - Object ret = getNewNBTTagCompound(); - nbttcm.set(ret, value); - return ret; - } - - @Override - @Deprecated - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Object convertJSONToListTag(JSONArray ja, JSONArray helper) throws Exception{ - List value = new ArrayList(); - for(int i = 0; i < ja.length(); i++){ - value.add(createDataJSON(i, ja, helper)); - } - Object ret = getNewNBTTagList(); - nbtld.set(ret, value); - if(value.size() > 0){ - nbtlt.set(ret, gti.invoke(value.get(0))); - } - return ret; - } - - @Override - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Object convertJSONToListTag(JSONArray ja) throws Exception{ - List value = new ArrayList(); - for(int i = 0; i < ja.length(); i++){ - value.add(createDataJSON(i, ja)); - } - Object ret = getNewNBTTagList(); - nbtld.set(ret, value); - if(value.size() > 0){ - nbtlt.set(ret, gti.invoke(value.get(0))); - } - return ret; - } - - @Override - @Deprecated - public Object getDataJSON(String key, Object nbt, JSONObject jo, JSONObject helper) throws Exception{ - int i = ((byte)gti.invoke(nbt)); - Object ret = null; - Object help = i; - switch(i){ - case NBTConstants.TYPE_BYTE: - ret = nbtbd.get(nbt); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsd.get(nbt); - break; - case NBTConstants.TYPE_INT: - ret = nbtid.get(nbt); - break; - case NBTConstants.TYPE_LONG: - ret = nbtlod.get(nbt); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfd.get(nbt); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdd.get(nbt); - break; - case NBTConstants.TYPE_BYTE_ARRAY: - ret = nbtbad.get(nbt); - break; - case NBTConstants.TYPE_STRING: - ret = nbtstd.get(nbt); - break; - case NBTConstants.TYPE_LIST:{ - JSONArray ja1 = new JSONArray(); - JSONArray helper1 = new JSONArray(); - convertListTagToJSON(nbt, ja1, helper1); - ret = ja1; - help = helper1; - break; - } - case NBTConstants.TYPE_COMPOUND: - JSONObject jo1 = new JSONObject(); - JSONObject helper1 = new JSONObject(); - convertCompoundTagToJSON(nbt, jo1, helper1); - ret = jo1; - help = helper1; - break; - case NBTConstants.TYPE_INT_ARRAY: - ret = nbtiad.get(nbt); - break; - } - if(ret != null){ - helper.put(key, help); - } - return ret; - } - - @Override - public JSONArray getDataJSON(Object nbt) throws Exception{ - int i = ((byte)gti.invoke(nbt)); - Object ret = null; - switch(i){ - case NBTConstants.TYPE_BYTE: - ret = nbtbd.get(nbt); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsd.get(nbt); - break; - case NBTConstants.TYPE_INT: - ret = nbtid.get(nbt); - break; - case NBTConstants.TYPE_LONG: - ret = nbtlod.get(nbt); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfd.get(nbt); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdd.get(nbt); - break; - case NBTConstants.TYPE_BYTE_ARRAY: - ret = nbtbad.get(nbt); - break; - case NBTConstants.TYPE_STRING: - ret = nbtstd.get(nbt); - break; - case NBTConstants.TYPE_LIST:{ - JSONArray ja1 = new JSONArray(); - convertListTagToJSON(nbt, ja1); - ret = ja1; - break; - } - case NBTConstants.TYPE_COMPOUND: - JSONObject jo1 = new JSONObject(); - convertCompoundTagToJSON(nbt, jo1); - ret = jo1; - break; - case NBTConstants.TYPE_INT_ARRAY: - ret = nbtiad.get(nbt); - break; - } - if(ret == null) { - return null; - } - return new JSONArray(new Object[]{ i, ret }); - } - - @Override - public Object getDataJSON(Object nbt, JSONArray ja, JSONArray helper) throws Exception{ - int i = ((byte)gti.invoke(nbt)); - Object ret = null; - Object help = i; - switch(i){ - case NBTConstants.TYPE_BYTE: - ret = nbtbd.get(nbt); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsd.get(nbt); - break; - case NBTConstants.TYPE_INT: - ret = nbtid.get(nbt); - break; - case NBTConstants.TYPE_LONG: - ret = nbtlod.get(nbt); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfd.get(nbt); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdd.get(nbt); - break; - case NBTConstants.TYPE_BYTE_ARRAY: - ret = nbtbad.get(nbt); - break; - case NBTConstants.TYPE_STRING: - ret = nbtstd.get(nbt); - break; - case NBTConstants.TYPE_LIST:{ - JSONArray ja1 = new JSONArray(); - JSONArray helper1 = new JSONArray(); - convertListTagToJSON(nbt, ja1, helper1); - ret = ja1; - break; - } - case NBTConstants.TYPE_COMPOUND: - JSONObject jo1 = new JSONObject(); - JSONObject helper1 = new JSONObject(); - convertCompoundTagToJSON(nbt, jo1, helper1); - ret = jo1; - help = helper1; - break; - case NBTConstants.TYPE_INT_ARRAY: - ret = nbtiad.get(nbt); - break; - } - if(ret != null){ - helper.put(help); - } - return ret; - } - - @Override - public Object createDataJSON(String key, JSONObject jo, JSONObject helper) throws Exception{ - Object help = helper.get(key); - Object ret = null; - if(help instanceof JSONObject){ - JSONObject jo1 = jo.getJSONObject(key); - JSONObject helper1 = (JSONObject)help; - ret = convertJSONToCompoundTag(jo1, helper1); - }else if(help instanceof JSONArray){ - JSONArray ja1 = jo.getJSONArray(key); - JSONArray helper1 = (JSONArray)help; - ret = convertJSONToListTag(ja1, helper1); - }else{ - int i = (int)help; - switch(i){ - case NBTConstants.TYPE_BYTE: - ret = nbtbc.newInstance(getByte(jo.get(key))); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsc.newInstance(getShort(jo.get(key))); - break; - case NBTConstants.TYPE_INT: - ret = nbtic.newInstance(getInt(jo.get(key))); - break; - case NBTConstants.TYPE_LONG: - ret = nbtloc.newInstance(getLong(jo.get(key))); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfc.newInstance(getFloat(jo.get(key))); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdc.newInstance(getDouble(jo.get(key))); - break; - case NBTConstants.TYPE_BYTE_ARRAY:{ - JSONArray ja = jo.getJSONArray(key); - byte[] b = new byte[ja.length()]; - for(int a = 0; a < ja.length(); a++){ - b[a] = getByte(ja.get(a)); - } - return nbtbac.newInstance(b); - } - case NBTConstants.TYPE_STRING: - ret = nbtstc.newInstance((String)jo.get(key)); - break; - case NBTConstants.TYPE_INT_ARRAY: - JSONArray ja = jo.getJSONArray(key); - int[] b = new int[ja.length()]; - for(int a = 0; a < ja.length(); a++){ - b[a] = getInt(ja.get(a)); - } - return nbtiac.newInstance(b); - } - } - return ret; - } - - @Override - public Object createDataJSON(String key, JSONObject jo) throws Exception{ - JSONArray j = jo.getJSONArray(key); - Object ret = null; - int i = j.getInt(0); - switch(i){ - case NBTConstants.TYPE_COMPOUND: - ret = convertJSONToCompoundTag(j.getJSONObject(1)); - break; - case NBTConstants.TYPE_BYTE: - ret = nbtbc.newInstance(getByte(j.get(1))); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsc.newInstance(getShort(j.get(1))); - break; - case NBTConstants.TYPE_INT: - ret = nbtic.newInstance(getInt(j.get(1))); - break; - case NBTConstants.TYPE_LONG: - ret = nbtloc.newInstance(getLong(j.get(1))); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfc.newInstance(getFloat(j.get(1))); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdc.newInstance(getDouble(j.get(1))); - break; - case NBTConstants.TYPE_BYTE_ARRAY:{ - JSONArray ja = j.getJSONArray(1); - byte[] b = new byte[ja.length()]; - for(int a = 0; a < ja.length(); a++){ - b[a] = getByte(ja.get(a)); - } - return nbtbac.newInstance(b); - } - case NBTConstants.TYPE_STRING: - ret = nbtstc.newInstance((String)j.get(1)); - break; - case NBTConstants.TYPE_INT_ARRAY: - JSONArray ja = jo.getJSONArray(key); - int[] b = new int[ja.length()]; - for(int a = 0; a < ja.length(); a++){ - b[a] = getInt(ja.get(a)); - } - return nbtiac.newInstance(b); - case NBTConstants.TYPE_LIST: - ret = convertJSONToListTag(j.getJSONArray(1)); - break; - } - 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; } - if(o.getClass().equals(Integer.class)){ return (byte)(int)o; } - 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 (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 (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 (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 (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 (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; - if(help instanceof JSONObject){ - JSONObject jo1 = jo.getJSONObject(key); - JSONObject helper1 = (JSONObject)help; - return convertJSONToCompoundTag(jo1, helper1); - }else if(help instanceof JSONArray){ - JSONArray ja1 = jo.getJSONArray(key); - JSONArray helper1 = (JSONArray)help; - return convertJSONToListTag(ja1, helper1); - }else{ - int i = (int)help; - switch(i){ - case NBTConstants.TYPE_BYTE: - ret = nbtbc.newInstance(getByte(jo.get(key))); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsc.newInstance(getShort(jo.get(key))); - break; - case NBTConstants.TYPE_INT: - ret = nbtic.newInstance(getInt(jo.get(key))); - break; - case NBTConstants.TYPE_LONG: - ret = nbtlc.newInstance(getLong(jo.get(key))); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfc.newInstance(getFloat(jo.get(key))); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdc.newInstance(getDouble(jo.get(key))); - break; - case NBTConstants.TYPE_BYTE_ARRAY:{ - JSONArray ja = jo.getJSONArray(key); - byte[] b = new byte[ja.length()]; - for(int a = 0; a < ja.length(); a++){ - b[a] = getByte(ja.get(a)); - } - return nbtbac.newInstance(b); - } - case NBTConstants.TYPE_STRING: - ret = nbtstc.newInstance((String)jo.get(key)); - break; - case NBTConstants.TYPE_INT_ARRAY: - JSONArray ja = jo.getJSONArray(key); - int[] b = new int[ja.length()]; - for(int a = 0; a < ja.length(); a++){ - b[a] = getInt(ja.get(a)); - } - return nbtiac.newInstance(b); - } - } - return ret; - } - - @Override - public Object createDataJSON(int key, JSONArray jo) throws Exception{ - JSONArray j = jo.getJSONArray(key); - Object ret = null; - int i = j.getInt(0); - switch(i){ - case NBTConstants.TYPE_COMPOUND: - ret = convertJSONToCompoundTag(j.getJSONObject(1)); - break; - case NBTConstants.TYPE_BYTE: - ret = nbtbc.newInstance(getByte(j.get(1))); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsc.newInstance(getShort(j.get(1))); - break; - case NBTConstants.TYPE_INT: - ret = nbtic.newInstance(getInt(j.get(1))); - break; - case NBTConstants.TYPE_LONG: - ret = nbtloc.newInstance(getLong(j.get(1))); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfc.newInstance(getFloat(j.get(1))); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdc.newInstance(getDouble(j.get(1))); - break; - case NBTConstants.TYPE_BYTE_ARRAY:{ - JSONArray ja = j.getJSONArray(1); - byte[] b = new byte[ja.length()]; - for(int a = 0; a < ja.length(); a++){ - b[a] = getByte(ja.get(a)); - } - return nbtbac.newInstance(b); - } - case NBTConstants.TYPE_STRING: - ret = nbtstc.newInstance((String)j.get(1)); - break; - case NBTConstants.TYPE_INT_ARRAY: - JSONArray ja = jo.getJSONArray(key); - int[] b = new int[ja.length()]; - for(int a = 0; a < ja.length(); a++){ - b[a] = getInt(ja.get(a)); - } - return nbtiac.newInstance(b); - case NBTConstants.TYPE_LIST: - ret = convertJSONToListTag(j.getJSONArray(1)); - break; - } - return ret; - } - - @Override - public boolean compareBaseTag(Object tag, Object tag1) throws Exception{ - int i = ((byte)gti.invoke(tag)); - int i1 = ((byte)gti.invoke(tag1)); - if(i != i1) { - return false; - } - switch(i){ - case NBTConstants.TYPE_BYTE: - Byte b = (byte)nbtbd.get(tag); - Byte b1 = (byte)nbtbd.get(tag1); - return b.equals(b1); - case NBTConstants.TYPE_SHORT: - Short s = (short)nbtsd.get(tag); - Short s1 = (short)nbtsd.get(tag1); - return s.equals(s1); - case NBTConstants.TYPE_INT: - Integer a = (int)nbtid.get(tag); - Integer a1 = (int)nbtid.get(tag1); - return a.equals(a1); - case NBTConstants.TYPE_LONG: - Long l = (long)nbtlod.get(tag); - Long l1 = (long)nbtlod.get(tag1); - return l.equals(l1); - case NBTConstants.TYPE_FLOAT: - Float f = (float)nbtfd.get(tag); - Float f1 = (float)nbtfd.get(tag1); - return f.equals(f1); - case NBTConstants.TYPE_DOUBLE: - Double d = (double)nbtdd.get(tag); - Double d1 = (double)nbtdd.get(tag1); - return d.equals(d1); - case NBTConstants.TYPE_BYTE_ARRAY: - byte[] ba = (byte[])nbtbad.get(tag); - byte[] ba1 = (byte[])nbtbad.get(tag1); - return Arrays.equals(ba, ba1); - case NBTConstants.TYPE_STRING: - String st = (String)nbtstd.get(tag); - String st1 = (String)nbtstd.get(tag1); - return st.equals(st1); - case NBTConstants.TYPE_LIST:{ - return compareListTag(tag, tag1); - } - case NBTConstants.TYPE_COMPOUND: - return compareCompoundTag(tag, tag1); - case NBTConstants.TYPE_INT_ARRAY: - int[] ia = (int[])nbtiad.get(tag); - int[] ia1 = (int[])nbtiad.get(tag); - return Arrays.equals(ia, ia1); - } - return false; - } - - @Override - @SuppressWarnings("unchecked") - public boolean compareCompoundTag(Object tag, Object tag1) throws Exception{ - Map map = (Map)getMap(tag); - Map map1 = (Map)getMap(tag1); - if(map.size() != map1.size()) { - return false; - } - if(!map.keySet().containsAll(map1.keySet())) { - return false; - } - for(Entry e : map.entrySet()){ - Object o = e.getValue(); - Object o1 = map1.get(e.getKey()); - if(!compareBaseTag(o, o1)) { - return false; - } - } - return true; - } - - @Override - @SuppressWarnings({ "unchecked", "rawtypes" }) - public boolean compareListTag(Object tag, Object tag1) throws Exception{ - List list = (List)nbtld.get(tag); - List list1 = (List)nbtld.get(tag1); - if(list.size() != list1.size()) { - return false; - } - Collections.sort(list); - Collections.sort(list1); - Iterator it = list.iterator(); - Iterator it1 = list1.iterator(); - while(it.hasNext() && it1.hasNext()){ - Object o = it.next(); - Object o1 = it1.next(); - if(!compareBaseTag(o, o1)) { - return false; - } - } - return true; - } - - 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()){ - try { - Object nis1 = getNMSCopy(is1); - Object nis2 = getNMSCopy(is2); - Object tis1 = getTag(nis1); - Object tis2 = getTag(nis2); - if (tis1 != null && tis2 == null) { - return isEmpty(tis1); - } - if (tis1 == null && tis2 != null) { - return isEmpty(tis2); - } - return tis1 == null && tis2 == null || compareCompoundTag(tis1, tis2); - }catch(Exception e){ - e.printStackTrace(); - } - } - } - 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); - ItemStack is2 = new ItemStack(is.getType(), 1, is.getDurability()); - return !is1.equals(is2); - } - - @Override - public void sortByMaterial(List items){ - items.sort(new MaterialComparator()); - } - - public class MaterialComparator implements Comparator{ - @Override - public int compare(ItemStack arg0, ItemStack arg1){ - return arg0.getType().name().compareTo(arg1.getType().name()); - } - } - - @Override - public void sortByName(List items){ - items.sort(new NameComparator()); - } - - public class NameComparator implements Comparator{ - @Override - public int compare(ItemStack arg0, ItemStack arg1){ - int i = 0; - try{ - i = ChatColor.stripColor(getName(arg0)).compareTo(ChatColor.stripColor(getName(arg1))); - }catch(Exception e){ - e.printStackTrace(); - } - return i; - } - } - - @Override - public void sortByAmount(List items){ - items.sort(new AmountComparator()); - } - - public class AmountComparator implements Comparator{ - @Override - public int compare(ItemStack arg0, ItemStack arg1){ - int i = arg1.getAmount() - arg0.getAmount(); - if(i == 0){ - try{ - i = ChatColor.stripColor(getName(arg0)).compareTo(ChatColor.stripColor(getName(arg1))); - }catch(Exception e){ - e.printStackTrace(); - } - } - return i; - } - } - - @Override - public ItemStack convertJSONToItemStack(JSONObject jo) throws Exception{ - Material material = Material.valueOf(jo.getString("material")); - int amount = jo.getInt("amount"); - int durability = jo.getInt("durability"); - ItemStack is = new ItemStack(material, amount, (short)durability); - JSONObject jo1 = jo.getJSONObject("tag"); - if(jo1.length() == 0) { - return is; - } - Object tag = convertJSONToCompoundTag(jo1); - Object nmis = getNMSCopy(is); - setTag(nmis, tag); - is = asBukkitCopy(nmis); - return is; - } - - @Override - public JSONObject convertItemStackToJSON(ItemStack is) throws Exception{ - JSONObject jo = new JSONObject(); - jo.put("material", is.getType().name()); - jo.put("amount", is.getAmount()); - jo.put("durability", is.getDurability()); - JSONObject jo2 = new JSONObject(); - Object nmis = getNMSCopy(is); - Object tag = getTag(nmis); - if(tag != null){ - convertCompoundTagToJSON(tag, jo2); - } - jo.put("tag", jo2); - return jo; - } -} 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 deleted file mode 100644 index 016b552..0000000 --- a/src/main/java/me/skymc/taboolib/nms/item/impl/_194ItemUtils.java +++ /dev/null @@ -1,1232 +0,0 @@ -package me.skymc.taboolib.nms.item.impl; - -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{ - - public boolean banner = getBanner(); - - public boolean getBanner(){ - try{ - Material m = Material.valueOf("BANNER"); - return true; - } catch (Exception ignored) { - } - return false; - } - - @Override - public boolean hasBanner(){ - return banner; - } - - 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); - } - - public Class ni = NMSUtils.getNMSClassSilent("Item"); - - public Method gn = NMSUtils.getMethodSilent(nmis, "getLabel"); - - @Override - public String getName(ItemStack is){ - try{ - return (String)gn.invoke(getNMSCopy(is)); - }catch(Exception e){ - return null; - } - } - - 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){ - m = NMSUtils.getMethodSilent(ni, "n", nmis); - } - return m; - } - - @Override - public String getRawName(ItemStack is){ - try{ - Object nis = getNMSCopy(is); - return (String)ia.invoke(gi.invoke(nis), nis); - }catch(Exception e){ - return null; - } - } - - public Method gin = NMSUtils.getMethodSilent(ni, "getLabel"); - - @Override - public String getItemName(ItemStack is){ - try{ - return (String)gin.invoke(gi.invoke(getNMSCopy(is))); - }catch(Exception e){ - return null; - } - } - - public Object registry = getRegistry(); - - @Override - public Object getRegistry(){ - try{ - return NMSUtils.getFieldSilent(ni, "REGISTRY").get(null); - } catch (Exception ignored) { - } - return null; - } - - public Class nmrs = NMSUtils.getNMSClassSilent("RegistrySimple"); - public Field nmrsc = NMSUtils.getField(nmrs, "c"); - - @Override - public String getMinecraftName(ItemStack is){ - String name = getItemName(is); - try{ - Map m = (Map)nmrsc.get(registry); - for(Entry e : m.entrySet()){ - Object item = e.getValue(); - String s = (String)gin.invoke(item); - if(name.equals(s)){ return e.getKey().toString(); } - } - }catch(Exception e){ - e.printStackTrace(); - } - return null; - } - - 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); - } - - public Class nbtb = NMSUtils.getNMSClassSilent("NBTBase"); - public Method nbttcs = NMSUtils.getMethodSilent(nbttc, "set", String.class, nbtb); - public Method nbttcss = NMSUtils.getMethodSilent(nbttc, "setString", String.class, String.class); - public Method nbttcsi = NMSUtils.getMethodSilent(nbttc, "setInt", String.class, int.class); - public Method nbttcsd = NMSUtils.getMethodSilent(nbttc, "setDouble", String.class, double.class); - 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); - } - - public Method nbttcg = NMSUtils.getMethodSilent(nbttc, "get", String.class); - public Method nbttcgs = NMSUtils.getMethodSilent(nbttc, "getString", String.class); - public Method nbttcgi = NMSUtils.getMethodSilent(nbttc, "getInt", String.class); - public Method nbttcgd = NMSUtils.getMethodSilent(nbttc, "getDouble", String.class); - 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); - } - - public Class nbttl = NMSUtils.getNMSClassSilent("NBTTagList"); - public Method gl = NMSUtils.getMethodSilent(nbttc, "getList", String.class, int.class); - public Method gb = NMSUtils.getMethodSilent(nbttc, "getBoolean", String.class); - public Method sb = NMSUtils.getMethodSilent(nbttc, "setBoolean", String.class, boolean.class); - 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); - } - - public Method gti = NMSUtils.getMethodSilent(nbtb, "getTypeId"); - - public Class nbtby = NMSUtils.getNMSClassSilent("NBTTagByte"); - public Class nbtba = NMSUtils.getNMSClassSilent("NBTTagByteArray"); - public Class nbtd = NMSUtils.getNMSClassSilent("NBTTagDouble"); - public Class nbtf = NMSUtils.getNMSClassSilent("NBTTagFloat"); - public Class nbti = NMSUtils.getNMSClassSilent("NBTTagInt"); - public Class nbtia = NMSUtils.getNMSClassSilent("NBTTagIntArray"); - public Class nbtl = NMSUtils.getNMSClassSilent("NBTTagList"); - public Class nbtlo = NMSUtils.getNMSClassSilent("NBTTagLong"); - public Class nbts = NMSUtils.getNMSClassSilent("NBTTagShort"); - public Class nbtst = NMSUtils.getNMSClassSilent("NBTTagString"); - - public Constructor nbtbc = NMSUtils.getConstructorSilent(nbtby, byte.class); - public Constructor nbtbac = NMSUtils.getConstructorSilent(nbtba, byte[].class); - public Constructor nbtdc = NMSUtils.getConstructorSilent(nbtd, double.class); - public Constructor nbtfc = NMSUtils.getConstructorSilent(nbtf, float.class); - public Constructor nbtic = NMSUtils.getConstructorSilent(nbti, int.class); - public Constructor nbtiac = NMSUtils.getConstructorSilent(nbtia, int[].class); - public Constructor nbtlc = NMSUtils.getConstructorSilent(nbtl); - public Constructor nbtloc = NMSUtils.getConstructorSilent(nbtlo, long.class); - public Constructor nbtsc = NMSUtils.getConstructorSilent(nbts, short.class); - public Constructor nbtstc = NMSUtils.getConstructorSilent(nbtst, String.class); - - public Field nbtbd = NMSUtils.getField(nbtby, "data"); - public Field nbtbad = NMSUtils.getField(nbtba, "data"); - public Field nbtdd = NMSUtils.getField(nbtd, "data"); - public Field nbtfd = NMSUtils.getField(nbtf, "data"); - public Field nbtid = NMSUtils.getField(nbti, "data"); - public Field nbtiad = NMSUtils.getField(nbtia, "data"); - public Field nbtld = NMSUtils.getField(nbtl, "list"); - public Field nbtlt = NMSUtils.getField(nbtl, "type"); - public Field nbttcd = NMSUtils.getField(nbttc, "map"); - public Field nbtlod = NMSUtils.getField(nbtlo, "data"); - 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 = ((byte)gti.invoke(nbt)); - switch(i){ - case NBTConstants.TYPE_BYTE: - return nbtbd.get(nbt); - case NBTConstants.TYPE_SHORT: - return nbtsd.get(nbt); - case NBTConstants.TYPE_INT: - return nbtid.get(nbt); - case NBTConstants.TYPE_LONG: - return nbtlod.get(nbt); - case NBTConstants.TYPE_FLOAT: - return nbtfd.get(nbt); - case NBTConstants.TYPE_DOUBLE: - return nbtdd.get(nbt); - case NBTConstants.TYPE_BYTE_ARRAY: - return nbtbad.get(nbt); - case NBTConstants.TYPE_STRING: - return nbtstd.get(nbt); - case NBTConstants.TYPE_LIST: - return convertListTagToValueList(nbt); - case NBTConstants.TYPE_COMPOUND: - return convertCompoundTagToValueMap(nbt); - case NBTConstants.TYPE_INT_ARRAY: - return nbtiad.get(nbt); - } - return null; - } - - @Override - @SuppressWarnings("unchecked") - public Object createData(Object value) throws Exception{ - if(value.getClass().equals(byte.class)){ return nbtbc.newInstance(value); } - if(value.getClass().equals(byte[].class)){ return nbtbac.newInstance(value); } - if(value.getClass().isAssignableFrom(Map.class)){ return convertValueMapToCompoundTag((Map)value); } - if(value.getClass().equals(double.class)){ return nbtdc.newInstance(value); } - if(value.getClass().equals(float.class)){ return nbtfc.newInstance(value); } - if(value.getClass().equals(int.class)){ return nbtic.newInstance(value); } - if(value.getClass().equals(int[].class)){ return nbtiac.newInstance(value); } - if(value.getClass().isAssignableFrom(List.class)){ return convertValueListToListTag((List)value); } - if(value.getClass().equals(long.class)){ return nbtloc.newInstance(value); } - if(value.getClass().equals(short.class)){ return nbtsc.newInstance(value); } - if(value.getClass().equals(String.class)){ return nbtstc.newInstance(value); } - return null; - } - - @Override - @SuppressWarnings({ "unchecked" }) - public Map convertCompoundTagToValueMap(Object nbt) throws Exception{ - Map ret = new HashMap<>(); - Map map = (Map)getMap(nbt); - for(Entry e : map.entrySet()){ - Object nbti = e.getValue(); - Object data = getData(nbti); - if(data != null){ - ret.put(e.getKey(), data); - } - } - return ret; - } - - @Override - @SuppressWarnings("unchecked") - public List convertListTagToValueList(Object nbttl) throws Exception{ - List ret = new ArrayList<>(); - List list = (List)nbtld.get(nbttl); - for(Object e : list){ - Object data = getData(e); - if(data != null){ - ret.add(data); - } - } - return ret; - } - - @Override - public Object convertValueMapToCompoundTag(Map map) throws Exception{ - Map value = new HashMap<>(); - for(Entry e : map.entrySet()){ - value.put(e.getKey(), createData(e.getValue())); - } - Object ret = getNewNBTTagCompound(); - nbttcm.set(ret, value); - return ret; - } - - @Override - public Object convertValueListToListTag(List list) throws Exception{ - List value = new ArrayList<>(); - for(Object e : list){ - value.add(createData(e)); - } - Object ret = getNewNBTTagList(); - nbttcm.set(ret, value); - if(value.size() > 0){ - nbtlt.set(ret, gti.invoke(value.get(0))); - } - return ret; - } - - @Override - @SuppressWarnings("unchecked") - @Deprecated - public void convertListTagToJSON(Object nbttl, JSONArray ja, JSONArray helper) throws Exception{ - List list = (List)nbtld.get(nbttl); - for(Object e : list){ - Object data = getDataJSON(e, ja, helper); - if(data != null){ - ja.put(data); - } - } - } - - @Override - @SuppressWarnings("unchecked") - public void convertListTagToJSON(Object nbttl, JSONArray ja) throws Exception{ - List list = (List)nbtld.get(nbttl); - for(Object e : list){ - Object data = getDataJSON(e); - if(data != null){ - ja.put(data); - } - } - } - - @Override - @SuppressWarnings("unchecked") - @Deprecated - public void convertCompoundTagToJSON(Object nbt, JSONObject jo, JSONObject helper) throws Exception{ - Map map = (Map)getMap(nbt); - for(Entry e : map.entrySet()){ - Object nbti = e.getValue(); - Object data = getDataJSON(e.getKey(), nbti, jo, helper); - if(data != null){ - jo.put(e.getKey(), data); - } - } - } - - @Override - @SuppressWarnings("unchecked") - public void convertCompoundTagToJSON(Object nbt, JSONObject jo) throws Exception{ - Map map = (Map)getMap(nbt); - for(Entry e : map.entrySet()){ - Object nbti = e.getValue(); - Object data = getDataJSON(nbti); - if(data != null){ - jo.put(e.getKey(), data); - } - } - } - - @Override - @SuppressWarnings("unchecked") - @Deprecated - public Object convertJSONToCompoundTag(JSONObject jo, JSONObject helper) throws Exception{ - Map value = new HashMap<>(); - Iterator it = jo.keys(); - while(it.hasNext()){ - String e = it.next(); - value.put(e, createDataJSON(e, jo, helper)); - } - Object ret = getNewNBTTagCompound(); - nbttcm.set(ret, value); - return ret; - } - - @Override - @SuppressWarnings("unchecked") - public Object convertJSONToCompoundTag(JSONObject jo) throws Exception{ - Map value = new HashMap<>(); - Iterator it = jo.keys(); - while(it.hasNext()){ - String e = it.next(); - value.put(e, createDataJSON(e, jo)); - } - Object ret = getNewNBTTagCompound(); - nbttcm.set(ret, value); - return ret; - } - - @Override - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Deprecated - public Object convertJSONToListTag(JSONArray ja, JSONArray helper) throws Exception{ - List value = new ArrayList(); - for(int i = 0; i < ja.length(); i++){ - value.add(createDataJSON(i, ja, helper)); - } - Object ret = getNewNBTTagList(); - nbtld.set(ret, value); - if(value.size() > 0){ - nbtlt.set(ret, gti.invoke(value.get(0))); - } - return ret; - } - - @Override - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Object convertJSONToListTag(JSONArray ja) throws Exception{ - List value = new ArrayList(); - for(int i = 0; i < ja.length(); i++){ - value.add(createDataJSON(i, ja)); - } - Object ret = getNewNBTTagList(); - nbtld.set(ret, value); - if(value.size() > 0){ - nbtlt.set(ret, gti.invoke(value.get(0))); - } - return ret; - } - - @Override - @Deprecated - public Object getDataJSON(String key, Object nbt, JSONObject jo, JSONObject helper) throws Exception{ - int i = ((byte)gti.invoke(nbt)); - Object ret = null; - Object help = i; - switch(i){ - case NBTConstants.TYPE_BYTE: - ret = nbtbd.get(nbt); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsd.get(nbt); - break; - case NBTConstants.TYPE_INT: - ret = nbtid.get(nbt); - break; - case NBTConstants.TYPE_LONG: - ret = nbtlod.get(nbt); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfd.get(nbt); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdd.get(nbt); - break; - case NBTConstants.TYPE_BYTE_ARRAY: - ret = nbtbad.get(nbt); - break; - case NBTConstants.TYPE_STRING: - ret = nbtstd.get(nbt); - break; - case NBTConstants.TYPE_LIST:{ - JSONArray ja1 = new JSONArray(); - JSONArray helper1 = new JSONArray(); - convertListTagToJSON(nbt, ja1, helper1); - ret = ja1; - help = helper1; - break; - } - case NBTConstants.TYPE_COMPOUND: - JSONObject jo1 = new JSONObject(); - JSONObject helper1 = new JSONObject(); - convertCompoundTagToJSON(nbt, jo1, helper1); - ret = jo1; - help = helper1; - break; - case NBTConstants.TYPE_INT_ARRAY: - ret = nbtiad.get(nbt); - break; - } - if(ret != null){ - helper.put(key, help); - } - return ret; - } - - @Override - public JSONArray getDataJSON(Object nbt) throws Exception{ - int i = ((byte)gti.invoke(nbt)); - Object ret = null; - switch(i){ - case NBTConstants.TYPE_BYTE: - ret = nbtbd.get(nbt); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsd.get(nbt); - break; - case NBTConstants.TYPE_INT: - ret = nbtid.get(nbt); - break; - case NBTConstants.TYPE_LONG: - ret = nbtlod.get(nbt); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfd.get(nbt); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdd.get(nbt); - break; - case NBTConstants.TYPE_BYTE_ARRAY: - ret = nbtbad.get(nbt); - break; - case NBTConstants.TYPE_STRING: - ret = nbtstd.get(nbt); - break; - case NBTConstants.TYPE_LIST:{ - JSONArray ja1 = new JSONArray(); - convertListTagToJSON(nbt, ja1); - ret = ja1; - break; - } - case NBTConstants.TYPE_COMPOUND: - JSONObject jo1 = new JSONObject(); - convertCompoundTagToJSON(nbt, jo1); - ret = jo1; - break; - case NBTConstants.TYPE_INT_ARRAY: - ret = nbtiad.get(nbt); - break; - } - if(ret == null) { - return null; - } - return new JSONArray(new Object[]{ i, ret }); - } - - @Override - @Deprecated - public Object getDataJSON(Object nbt, JSONArray ja, JSONArray helper) throws Exception{ - int i = ((byte)gti.invoke(nbt)); - Object ret = null; - Object help = i; - switch(i){ - case NBTConstants.TYPE_BYTE: - ret = nbtbd.get(nbt); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsd.get(nbt); - break; - case NBTConstants.TYPE_INT: - ret = nbtid.get(nbt); - break; - case NBTConstants.TYPE_LONG: - ret = nbtlod.get(nbt); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfd.get(nbt); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdd.get(nbt); - break; - case NBTConstants.TYPE_BYTE_ARRAY: - ret = nbtbad.get(nbt); - break; - case NBTConstants.TYPE_STRING: - ret = nbtstd.get(nbt); - break; - case NBTConstants.TYPE_LIST:{ - JSONArray ja1 = new JSONArray(); - JSONArray helper1 = new JSONArray(); - convertListTagToJSON(nbt, ja1, helper1); - ret = ja1; - break; - } - case NBTConstants.TYPE_COMPOUND: - JSONObject jo1 = new JSONObject(); - JSONObject helper1 = new JSONObject(); - convertCompoundTagToJSON(nbt, jo1, helper1); - ret = jo1; - help = helper1; - break; - case NBTConstants.TYPE_INT_ARRAY: - ret = nbtiad.get(nbt); - break; - } - if(ret != null){ - helper.put(help); - } - return ret; - } - - @Override - @Deprecated - public Object createDataJSON(String key, JSONObject jo, JSONObject helper) throws Exception{ - Object help = helper.get(key); - Object ret = null; - if(help instanceof JSONObject){ - JSONObject jo1 = jo.getJSONObject(key); - JSONObject helper1 = (JSONObject)help; - ret = convertJSONToCompoundTag(jo1, helper1); - }else if(help instanceof JSONArray){ - JSONArray ja1 = jo.getJSONArray(key); - JSONArray helper1 = (JSONArray)help; - ret = convertJSONToListTag(ja1, helper1); - }else{ - int i = (int)help; - switch(i){ - case NBTConstants.TYPE_BYTE: - ret = nbtbc.newInstance(getByte(jo.get(key))); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsc.newInstance(getShort(jo.get(key))); - break; - case NBTConstants.TYPE_INT: - ret = nbtic.newInstance(getInt(jo.get(key))); - break; - case NBTConstants.TYPE_LONG: - ret = nbtloc.newInstance(getLong(jo.get(key))); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfc.newInstance(getFloat(jo.get(key))); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdc.newInstance(getDouble(jo.get(key))); - break; - case NBTConstants.TYPE_BYTE_ARRAY:{ - JSONArray ja = jo.getJSONArray(key); - byte[] b = new byte[ja.length()]; - for(int a = 0; a < ja.length(); a++){ - b[a] = getByte(ja.get(a)); - } - return nbtbac.newInstance(b); - } - case NBTConstants.TYPE_STRING: - ret = nbtstc.newInstance((String)jo.get(key)); - break; - case NBTConstants.TYPE_INT_ARRAY: - JSONArray ja = jo.getJSONArray(key); - int[] b = new int[ja.length()]; - for(int a = 0; a < ja.length(); a++){ - b[a] = getInt(ja.get(a)); - } - return nbtiac.newInstance(b); - } - } - return ret; - } - - @Override - public Object createDataJSON(String key, JSONObject jo) throws Exception{ - JSONArray j = jo.getJSONArray(key); - Object ret = null; - int i = j.getInt(0); - switch(i){ - case NBTConstants.TYPE_COMPOUND: - ret = convertJSONToCompoundTag(j.getJSONObject(1)); - break; - case NBTConstants.TYPE_BYTE: - ret = nbtbc.newInstance(getByte(j.get(1))); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsc.newInstance(getShort(j.get(1))); - break; - case NBTConstants.TYPE_INT: - ret = nbtic.newInstance(getInt(j.get(1))); - break; - case NBTConstants.TYPE_LONG: - ret = nbtloc.newInstance(getLong(j.get(1))); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfc.newInstance(getFloat(j.get(1))); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdc.newInstance(getDouble(j.get(1))); - break; - case NBTConstants.TYPE_BYTE_ARRAY:{ - JSONArray ja = j.getJSONArray(1); - byte[] b = new byte[ja.length()]; - for(int a = 0; a < ja.length(); a++){ - b[a] = getByte(ja.get(a)); - } - return nbtbac.newInstance(b); - } - case NBTConstants.TYPE_STRING: - ret = nbtstc.newInstance((String)j.get(1)); - break; - case NBTConstants.TYPE_INT_ARRAY: - JSONArray ja = jo.getJSONArray(key); - int[] b = new int[ja.length()]; - for(int a = 0; a < ja.length(); a++){ - b[a] = getInt(ja.get(a)); - } - return nbtiac.newInstance(b); - case NBTConstants.TYPE_LIST: - ret = convertJSONToListTag(j.getJSONArray(1)); - break; - } - 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; } - if(o.getClass().equals(Integer.class)){ return (byte)(int)o; } - 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 (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 (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 (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 (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 (int)o; } - return (long)o; - } - - @Override - @Deprecated - public Object createDataJSON(int key, JSONArray jo, JSONArray helper) throws Exception{ - Object help = helper.get(key); - Object ret = null; - if(help instanceof JSONObject){ - JSONObject jo1 = jo.getJSONObject(key); - JSONObject helper1 = (JSONObject)help; - return convertJSONToCompoundTag(jo1, helper1); - }else if(help instanceof JSONArray){ - JSONArray ja1 = jo.getJSONArray(key); - JSONArray helper1 = (JSONArray)help; - return convertJSONToListTag(ja1, helper1); - }else{ - int i = (int)help; - switch(i){ - case NBTConstants.TYPE_BYTE: - ret = nbtbc.newInstance(getByte(jo.get(key))); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsc.newInstance(getShort(jo.get(key))); - break; - case NBTConstants.TYPE_INT: - ret = nbtic.newInstance(getInt(jo.get(key))); - break; - case NBTConstants.TYPE_LONG: - ret = nbtloc.newInstance(getLong(jo.get(key))); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfc.newInstance(getFloat(jo.get(key))); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdc.newInstance(getDouble(jo.get(key))); - break; - case NBTConstants.TYPE_BYTE_ARRAY:{ - JSONArray ja = jo.getJSONArray(key); - byte[] b = new byte[ja.length()]; - for(int a = 0; a < ja.length(); a++){ - b[a] = getByte(ja.get(a)); - } - return nbtbac.newInstance(b); - } - case NBTConstants.TYPE_STRING: - ret = nbtstc.newInstance((String)jo.get(key)); - break; - case NBTConstants.TYPE_INT_ARRAY: - JSONArray ja = jo.getJSONArray(key); - int[] b = new int[ja.length()]; - for(int a = 0; a < ja.length(); a++){ - b[a] = getInt(ja.get(a)); - } - return nbtiac.newInstance(b); - } - } - return ret; - } - - @Override - public Object createDataJSON(int key, JSONArray jo) throws Exception{ - JSONArray j = jo.getJSONArray(key); - Object ret = null; - int i = j.getInt(0); - switch(i){ - case NBTConstants.TYPE_COMPOUND: - ret = convertJSONToCompoundTag(j.getJSONObject(1)); - break; - case NBTConstants.TYPE_BYTE: - ret = nbtbc.newInstance(getByte(j.get(1))); - break; - case NBTConstants.TYPE_SHORT: - ret = nbtsc.newInstance(getShort(j.get(1))); - break; - case NBTConstants.TYPE_INT: - ret = nbtic.newInstance(getInt(j.get(1))); - break; - case NBTConstants.TYPE_LONG: - ret = nbtloc.newInstance(getLong(j.get(1))); - break; - case NBTConstants.TYPE_FLOAT: - ret = nbtfc.newInstance(getFloat(j.get(1))); - break; - case NBTConstants.TYPE_DOUBLE: - ret = nbtdc.newInstance(getDouble(j.get(1))); - break; - case NBTConstants.TYPE_BYTE_ARRAY:{ - JSONArray ja = j.getJSONArray(1); - byte[] b = new byte[ja.length()]; - for(int a = 0; a < ja.length(); a++){ - b[a] = getByte(ja.get(a)); - } - return nbtbac.newInstance(b); - } - case NBTConstants.TYPE_STRING: - ret = nbtstc.newInstance((String)j.get(1)); - break; - case NBTConstants.TYPE_INT_ARRAY: - JSONArray ja = jo.getJSONArray(key); - int[] b = new int[ja.length()]; - for(int a = 0; a < ja.length(); a++){ - b[a] = getInt(ja.get(a)); - } - return nbtiac.newInstance(b); - case NBTConstants.TYPE_LIST: - ret = convertJSONToListTag(j.getJSONArray(1)); - break; - } - return ret; - } - - @Override - public boolean compareBaseTag(Object tag, Object tag1) throws Exception{ - int i = ((byte)gti.invoke(tag)); - int i1 = ((byte)gti.invoke(tag1)); - if(i != i1) { - return false; - } - switch(i){ - case NBTConstants.TYPE_BYTE: - Byte b = (byte)nbtbd.get(tag); - Byte b1 = (byte)nbtbd.get(tag1); - return b.equals(b1); - case NBTConstants.TYPE_SHORT: - Short s = (short)nbtsd.get(tag); - Short s1 = (short)nbtsd.get(tag1); - return s.equals(s1); - case NBTConstants.TYPE_INT: - Integer a = (int)nbtid.get(tag); - Integer a1 = (int)nbtid.get(tag1); - return a.equals(a1); - case NBTConstants.TYPE_LONG: - Long l = (long)nbtlod.get(tag); - Long l1 = (long)nbtlod.get(tag1); - return l.equals(l1); - case NBTConstants.TYPE_FLOAT: - Float f = (float)nbtfd.get(tag); - Float f1 = (float)nbtfd.get(tag1); - return f.equals(f1); - case NBTConstants.TYPE_DOUBLE: - Double d = (double)nbtdd.get(tag); - Double d1 = (double)nbtdd.get(tag1); - return d.equals(d1); - case NBTConstants.TYPE_BYTE_ARRAY: - byte[] ba = (byte[])nbtbad.get(tag); - byte[] ba1 = (byte[])nbtbad.get(tag1); - return Arrays.equals(ba, ba1); - case NBTConstants.TYPE_STRING: - String st = (String)nbtstd.get(tag); - String st1 = (String)nbtstd.get(tag1); - return st.equals(st1); - case NBTConstants.TYPE_LIST:{ - return compareListTag(tag, tag1); - } - case NBTConstants.TYPE_COMPOUND: - return compareCompoundTag(tag, tag1); - case NBTConstants.TYPE_INT_ARRAY: - int[] ia = (int[])nbtiad.get(tag); - int[] ia1 = (int[])nbtiad.get(tag); - return Arrays.equals(ia, ia1); - } - return false; - } - - @Override - @SuppressWarnings("unchecked") - public boolean compareCompoundTag(Object tag, Object tag1) throws Exception{ - Map map = (Map)getMap(tag); - Map map1 = (Map)getMap(tag1); - if(map.size() != map1.size()) { - return false; - } - if(!map.keySet().containsAll(map1.keySet())) { - return false; - } - for(Entry e : map.entrySet()){ - Object o = e.getValue(); - Object o1 = map1.get(e.getKey()); - if(!compareBaseTag(o, o1)) { - return false; - } - } - return true; - } - - @Override - @SuppressWarnings({ "unchecked", "rawtypes" }) - public boolean compareListTag(Object tag, Object tag1) throws Exception{ - List list = (List)nbtld.get(tag); - List list1 = (List)nbtld.get(tag1); - if(list.size() != list1.size()) { - return false; - } - if(list.isEmpty() && list1.isEmpty()) { - return true; - } - List copy = new ArrayList(list); - List copy1 = new ArrayList(list1); - Iterator it = copy.iterator(); - while(it.hasNext()){ - Object o = it.next(); - Iterator it1 = copy1.iterator(); - boolean cont = false; - while(it1.hasNext()){ - Object o1 = it1.next(); - if(compareBaseTag(o, o1)){ - it1.remove(); - it.remove(); - cont = true; - break; - } - } - if(!cont) { - return false; - } - } - return copy.isEmpty() && copy1.isEmpty(); - } - - @Override - public boolean compare(ItemStack is1, ItemStack is2){ - if(is1.getType().equals(is2.getType())){ - if(is1.getDurability() == is2.getDurability()){ - try { - Object nis1 = getNMSCopy(is1); - Object nis2 = getNMSCopy(is2); - Object tis1 = getTag(nis1); - Object tis2 = getTag(nis2); - if (tis1 != null && tis2 == null) { - return isEmpty(tis1); - } - if (tis1 == null && tis2 != null) { - return isEmpty(tis2); - } - return tis1 == null && tis2 == null || compareCompoundTag(tis1, tis2); - }catch(Exception e){ - e.printStackTrace(); - } - } - } - 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); - ItemStack is2 = new ItemStack(is.getType(), 1, is.getDurability()); - return !is1.equals(is2); - } - - @Override - public void sortByMaterial(List items){ - items.sort(new MaterialComparator()); - } - - public class MaterialComparator implements Comparator{ - @Override - public int compare(ItemStack arg0, ItemStack arg1){ - return arg0.getType().name().compareTo(arg1.getType().name()); - } - } - - @Override - public void sortByName(List items){ - items.sort(new NameComparator()); - } - - public class NameComparator implements Comparator{ - @Override - public int compare(ItemStack arg0, ItemStack arg1){ - int i = 0; - try{ - i = ChatColor.stripColor(getName(arg0)).compareTo(ChatColor.stripColor(getName(arg1))); - }catch(Exception e){ - e.printStackTrace(); - } - return i; - } - } - - @Override - public void sortByAmount(List items){ - items.sort(new AmountComparator()); - } - - public class AmountComparator implements Comparator{ - @Override - public int compare(ItemStack arg0, ItemStack arg1){ - int i = arg1.getAmount() - arg0.getAmount(); - if(i == 0){ - try{ - i = ChatColor.stripColor(getName(arg0)).compareTo(ChatColor.stripColor(getName(arg1))); - }catch(Exception e){ - e.printStackTrace(); - } - } - return i; - } - } - - @Override - public ItemStack convertJSONToItemStack(JSONObject jo) throws Exception{ - Material material = Material.valueOf(jo.getString("material")); - int amount = jo.getInt("amount"); - int durability = jo.getInt("durability"); - ItemStack is = new ItemStack(material, amount, (short)durability); - JSONObject jo1 = jo.getJSONObject("tag"); - if(jo1.length() == 0) { - return is; - } - Object tag = convertJSONToCompoundTag(jo1); - Object nmis = getNMSCopy(is); - setTag(nmis, tag); - is = asBukkitCopy(nmis); - return is; - } - - @Override - public JSONObject convertItemStackToJSON(ItemStack is) throws Exception{ - JSONObject jo = new JSONObject(); - jo.put("material", is.getType().name()); - jo.put("amount", is.getAmount()); - jo.put("durability", is.getDurability()); - JSONObject jo2 = new JSONObject(); - Object nmis = getNMSCopy(is); - Object tag = getTag(nmis); - if(tag != null){ - convertCompoundTagToJSON(tag, jo2); - } - jo.put("tag", jo2); - return jo; - } -} diff --git a/src/main/java/me/skymc/taboolib/nms/nbt/NBTConstants.java b/src/main/java/me/skymc/taboolib/nms/nbt/NBTConstants.java deleted file mode 100644 index 03c7a57..0000000 --- a/src/main/java/me/skymc/taboolib/nms/nbt/NBTConstants.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.skymc.taboolib.nms.nbt; - -import java.nio.charset.Charset; - -@Deprecated -public final class NBTConstants { - - public static final Charset CHARSET = Charset.forName("UTF-8"); - public static final int TYPE_END = 0; - public static final int TYPE_BYTE = 1; - public static final int TYPE_SHORT = 2; - public static final int TYPE_INT = 3; - public static final int TYPE_LONG = 4; - public static final int TYPE_FLOAT = 5; - public static final int TYPE_DOUBLE = 6; - public static final int TYPE_BYTE_ARRAY = 7; - public static final int TYPE_STRING = 8; - public static final int TYPE_LIST = 9; - public static final int TYPE_COMPOUND = 10; - public static final int TYPE_INT_ARRAY = 11; - - private NBTConstants() { - throw new AssertionError("Not instantiable"); - } -} diff --git a/src/main/java/me/skymc/taboolib/object/WeightCategory.java b/src/main/java/me/skymc/taboolib/object/WeightCategory.java deleted file mode 100644 index 98d8ca3..0000000 --- a/src/main/java/me/skymc/taboolib/object/WeightCategory.java +++ /dev/null @@ -1,34 +0,0 @@ -package me.skymc.taboolib.object; - -@Deprecated -public class WeightCategory { - - private String category; - private Integer weight; - - public WeightCategory() { - super(); - } - - public WeightCategory(String category, Integer weight) { - super(); - this.setCategory(category); - this.setWeight(weight); - } - - public Integer getWeight() { - return weight; - } - - public void setWeight(Integer weight) { - this.weight = weight; - } - - public String getCategory() { - return category; - } - - public void setCategory(String category) { - this.category = category; - } -} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/other/DateUtils.java b/src/main/java/me/skymc/taboolib/other/DateUtils.java deleted file mode 100644 index e4f5cc4..0000000 --- a/src/main/java/me/skymc/taboolib/other/DateUtils.java +++ /dev/null @@ -1,80 +0,0 @@ -package me.skymc.taboolib.other; - -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; - -public class DateUtils { - - /** - * 最后一次更新:2018年1月16日21:07:27 - * - * @author sky - */ - - public static SimpleDateFormat CH_ALL = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒"); - public static SimpleDateFormat EN_ALL = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); - - public static SimpleDateFormat YEAR = new SimpleDateFormat("yyyy"); - - public static SimpleDateFormat MONTH = new SimpleDateFormat("MM"); - - public static SimpleDateFormat DAY_OF_MONTH = new SimpleDateFormat("dd"); - public static SimpleDateFormat DAY_OF_YEAR = new SimpleDateFormat("DD"); - - public static SimpleDateFormat HOUR_OF_DAY = new SimpleDateFormat("HH"); - public static SimpleDateFormat HOUR = new SimpleDateFormat("hh"); - - public static SimpleDateFormat MINUTE = new SimpleDateFormat("mm"); - public static SimpleDateFormat SECONDS = new SimpleDateFormat("ss"); - - public static SimpleDateFormat MILLISECOND = new SimpleDateFormat("SSS"); - - public static SimpleDateFormat WEEK = new SimpleDateFormat("E"); - - private static SimpleDateFormat Hour = new SimpleDateFormat("HH:mm"); - - public static Calendar getCalendar() { - return Calendar.getInstance(); - } - - public static Date getTime() { - return Calendar.getInstance().getTime(); - } - - public static Integer getTime(SimpleDateFormat date) { - return Integer.valueOf(date.format(getTime())); - } - - public static boolean timeInDifference(String m1, String m2) { - try { - Date now = Hour.parse(Hour.format(System.currentTimeMillis())); - Date min = Hour.parse(m1); - Date max = Hour.parse(m2); - return (now.after(min) && now.before(max)) || now.equals(min) || now.equals(max); - } catch (Exception e) { - return false; - } - } - - public static long formatDate(String time) { - long date = 0; - try { - for (String value : time.toLowerCase().split(";")) { - Integer num = Integer.valueOf(value.substring(0, value.length() - 1)); - if (value.endsWith("d")) { - date += num * 1000L * 60 * 60 * 24; - } else if (value.endsWith("h")) { - date += num * 1000L * 60 * 60; - } else if (value.endsWith("m")) { - date += num * 1000L * 60; - } else if (value.endsWith("s")) { - date += num * 1000L; - } - } - } catch (Exception e) { - // TODO: handle exception - } - return date; - } -} diff --git a/src/main/java/me/skymc/taboolib/other/MathUtils.java b/src/main/java/me/skymc/taboolib/other/MathUtils.java deleted file mode 100644 index fbc751a..0000000 --- a/src/main/java/me/skymc/taboolib/other/MathUtils.java +++ /dev/null @@ -1,55 +0,0 @@ -package me.skymc.taboolib.other; - -import me.skymc.taboolib.particle.EffLib; -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - -public class MathUtils { - - public static double tronc(double paramDouble, int paramInt) { - double d = Math.pow(10.0D, paramInt); - return Math.floor(paramDouble * d) / d; - } - - public static void drawVec(Vector paramVector, Location paramLocation, Color paramColor) { - for (double d = 0.0D; d < 1.0D; d += 0.1D) { - EffLib.REDSTONE.display(new EffLib.OrdinaryColor(paramColor), paramLocation.clone().add(paramVector.clone().multiply(d)), 100.0D); - } - } - - public static void sendCoords(Player paramPlayer, Vector paramVector, String paramString) { - paramPlayer.sendMessage(paramString + tronc(paramVector.getX(), 2) + " " + tronc(paramVector.getY(), 2) + " " + tronc(paramVector.getZ(), 2)); - } - - public static void sendCoords(Player paramPlayer, Location paramLocation, String paramString) { - paramPlayer.sendMessage(paramString + tronc(paramLocation.getX(), 2) + " " + tronc(paramLocation.getY(), 2) + " " + tronc(paramLocation.getZ(), 2)); - } - - public static Vector rotAxisX(Vector paramVector, double paramDouble) { - double d1 = paramVector.getY() * Math.cos(paramDouble) - paramVector.getZ() * Math.sin(paramDouble); - double d2 = paramVector.getY() * Math.sin(paramDouble) + paramVector.getZ() * Math.cos(paramDouble); - return paramVector.setY(d1).setZ(d2); - } - - public static Vector rotAxisY(Vector paramVector, double paramDouble) { - double d1 = paramVector.getX() * Math.cos(paramDouble) + paramVector.getZ() * Math.sin(paramDouble); - double d2 = paramVector.getX() * -Math.sin(paramDouble) + paramVector.getZ() * Math.cos(paramDouble); - return paramVector.setX(d1).setZ(d2); - } - - public static Vector rotAxisZ(Vector paramVector, double paramDouble) { - double d1 = paramVector.getX() * Math.cos(paramDouble) - paramVector.getY() * Math.sin(paramDouble); - double d2 = paramVector.getX() * Math.sin(paramDouble) + paramVector.getY() * Math.cos(paramDouble); - return paramVector.setX(d1).setY(d2); - } - - public static Vector rotateFunc(Vector paramVector, Location paramLocation) { - double d1 = paramLocation.getYaw() / 180.0F * 3.141592653589793D; - double d2 = paramLocation.getPitch() / 180.0F * 3.141592653589793D; - paramVector = rotAxisX(paramVector, d2); - paramVector = rotAxisY(paramVector, -d1); - return paramVector; - } -} diff --git a/src/main/java/me/skymc/taboolib/other/NumberUtils.java b/src/main/java/me/skymc/taboolib/other/NumberUtils.java deleted file mode 100644 index f811baa..0000000 --- a/src/main/java/me/skymc/taboolib/other/NumberUtils.java +++ /dev/null @@ -1,83 +0,0 @@ -package me.skymc.taboolib.other; - -import java.text.DecimalFormat; -import java.util.Random; - -/** - * @author sky - */ -public class NumberUtils { - - private static Random random = new Random(); - private static DecimalFormat doubleFormat = new DecimalFormat("#.##"); - - public static Random getRandom() { - return random; - } - - public static Double format(Double num) { - return Double.valueOf(doubleFormat.format(num)); - } - - public static int getRandomInteger(Number num1, Number num2) { - int min = Math.min(num1.intValue(), num2.intValue()); - int max = Math.max(num1.intValue(), num2.intValue()); - return (int) (random.nextDouble() * (max - min) + min); - } - - public static double getRandomDouble(Number num1, Number num2) { - double min = Math.min(num1.doubleValue(), num2.doubleValue()); - double max = Math.max(num1.doubleValue(), num2.doubleValue()); - return random.nextDouble() * (max - min) + min; - } - - public static int getInteger(String s) { - try { - return Integer.valueOf(s); - } catch (Exception e) { - return 0; - } - } - - public static double getDouble(String s) { - try { - return Double.valueOf(s); - } catch (Exception e) { - return 0; - } - } - - public static Boolean getBoolean(String s) { - try { - return Boolean.valueOf(s); - } catch (Exception e) { - return false; - } - } - - public static Boolean getBooleanAbbreviation(String str) { - if (str == null || str.isEmpty()) { - return false; - } - if (str.length() < 4) { - char var = str.charAt(0); - if (var == 'y' || var == 'Y' || var == 't' || var == 'T' || var == '1') { - return true; - } - if (var == 'n' || var == 'N' || var == 'f' || var == 'F' || var == '0') { - return false; - } - } - return getBoolean(str); - } - - @Deprecated - public static Random getRand() { - return random; - } - - @Deprecated - public static boolean getChance(int a) { - return getRandom().nextInt(100) <= a; - } -} diff --git a/src/main/java/me/skymc/taboolib/other/WeightUtils.java b/src/main/java/me/skymc/taboolib/other/WeightUtils.java deleted file mode 100644 index 0ac7f43..0000000 --- a/src/main/java/me/skymc/taboolib/other/WeightUtils.java +++ /dev/null @@ -1,33 +0,0 @@ -package me.skymc.taboolib.other; - -import me.skymc.taboolib.object.WeightCategory; - -import java.util.List; - -@Deprecated -public class WeightUtils { - - public static String getStringByWeight(List categorys) { - - int weightSum = 0; - for (WeightCategory wc : categorys) { - weightSum += wc.getWeight(); - } - - if (weightSum <= 0) { - return null; - } - - Integer n = NumberUtils.getRandom().nextInt(weightSum); - Integer m = 0; - - for (WeightCategory wc : categorys) { - if (m <= n && n < m + wc.getWeight()) { - return wc.getCategory(); - } - m += wc.getWeight(); - } - return null; - } - -} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/packet/PacketUtils.java b/src/main/java/me/skymc/taboolib/packet/PacketUtils.java deleted file mode 100644 index 1a85164..0000000 --- a/src/main/java/me/skymc/taboolib/packet/PacketUtils.java +++ /dev/null @@ -1,93 +0,0 @@ -package me.skymc.taboolib.packet; - -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.ProtocolLibrary; -import com.comphenix.protocol.ProtocolManager; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.wrappers.WrappedDataWatcher; -import com.google.common.base.Preconditions; -import org.bukkit.Bukkit; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; - -/** - * @author sky - */ -public class PacketUtils { - - public static void checkProtocolLib() { - Preconditions.checkArgument(isProtocolLibEnabled(), "Plugin \"ProtocolLib\" cannot found!"); - } - - public static boolean isProtocolLibEnabled() { - return Bukkit.getPluginManager().getPlugin("ProtocolLib") != null && Bukkit.getPluginManager().getPlugin("ProtocolLib").isEnabled(); - } - - public static ProtocolManager getManager() { - return ProtocolLibrary.getProtocolManager(); - } - - public static void sendPacketEntityStatus(Entity entity, EntityStatus status, Player... players) { - PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); - packet.getIntegers().write(0, entity.getEntityId()); - WrappedDataWatcher watcher = new WrappedDataWatcher(); - WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.get(Byte.class); - switch (status) { - case FIRE: - watcher.setObject(0, serializer, (byte) 0x01); - break; - case CROUCHED: - watcher.setObject(0, serializer, (byte) 0x02); - break; - case UNUSED1: - watcher.setObject(0, serializer, (byte) 0x04); - break; - case SPRINTING: - watcher.setObject(0, serializer, (byte) 0x08); - break; - case UNUSED2: - watcher.setObject(0, serializer, (byte) 0x10); - break; - case INVISIBLE: - watcher.setObject(0, serializer, (byte) 0x20); - break; - case GLOWING: - watcher.setObject(0, serializer, (byte) 0x40); - break; - case ELYTRA: - watcher.setObject(0, serializer, (byte) 0x80); - break; - default: - watcher.setObject(0, serializer, (byte) 0x00); - break; - } - packet.getWatchableCollectionModifier().write(0, watcher.getWatchableObjects()); - try { - for (Player player : players) { - ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - public static void sendPacketEntityCustomName(Entity entity, String value, Player... players) { - PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); - packet.getIntegers().write(0, entity.getEntityId()); - WrappedDataWatcher watcher = new WrappedDataWatcher(); - WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.get(String.class); - watcher.setObject(2, serializer, value == null ? "" : value); - packet.getWatchableCollectionModifier().write(0, watcher.getWatchableObjects()); - try { - for (Player player : players) { - ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - public enum EntityStatus { - FIRE, CROUCHED, UNUSED1, UNUSED2, SPRINTING, INVISIBLE, GLOWING, ELYTRA - } -} diff --git a/src/main/java/me/skymc/taboolib/particle/ParticlePack.java b/src/main/java/me/skymc/taboolib/particle/ParticlePack.java deleted file mode 100644 index 039c06c..0000000 --- a/src/main/java/me/skymc/taboolib/particle/ParticlePack.java +++ /dev/null @@ -1,44 +0,0 @@ -package me.skymc.taboolib.particle; - -import me.skymc.taboolib.TabooLib; -import org.bukkit.Location; - -public class ParticlePack { - - public EffLib particle = EffLib.VILLAGER_HAPPY; - - public float x = 0F; - public float y = 0F; - public float z = 0F; - public int a = 0; - - /** - * VILLAGER_HAPPY-10-1-1-1 - * 粒子-数量-X-Y-Z - * - * @param value - */ - public ParticlePack(String value) { - try { - particle = EffLib.valueOf(value.split("-")[0]); - a = Integer.valueOf(value.split("-")[1]); - x = Float.valueOf(value.split("-")[2]); - y = Float.valueOf(value.split("-")[3]); - z = Float.valueOf(value.split("-")[4]); - } - catch (Exception e) { - // TODO: handle exception - } - } - - /** - * 播放粒子 - * - * @param loc - */ - public void play(Location loc) { - if (TabooLib.getVerint() > 10800) { - particle.display(x, y, z, 0f, a, loc, 50); - } - } -} diff --git a/src/main/java/me/skymc/taboolib/particle/ParticleUtils.java b/src/main/java/me/skymc/taboolib/particle/ParticleUtils.java deleted file mode 100644 index 6420b4e..0000000 --- a/src/main/java/me/skymc/taboolib/particle/ParticleUtils.java +++ /dev/null @@ -1,27 +0,0 @@ -package me.skymc.taboolib.particle; - -import org.bukkit.Color; -import org.bukkit.Effect; -import org.bukkit.Location; - -public class ParticleUtils { - - public static void sendColor(Effect particle, Location l, int data, Color color) { - l.getWorld().spigot().playEffect(l, particle, data, 0, (float)getColor(color.getRed()), (float)getColor(color.getGreen()), (float)getColor(color.getBlue()), 1, 0, 35); - } - - public static void sendColor(Effect particle, Location l, int data, java.awt.Color color) { - l.getWorld().spigot().playEffect(l, particle, data, 0, (float)getColor(color.getRed()), (float)getColor(color.getGreen()), (float)getColor(color.getBlue()), 1, 0, 35); - } - - public static void sendEffect(Effect particle, Location l, float offsetX, float offsetY, float offsetZ, float speed, int amount) { - l.getWorld().spigot().playEffect(l, particle, 0, 0, offsetX, offsetY, offsetZ, speed, amount, 35); - } - - private static double getColor(double value) { - if (value <= 0) { - value = -1; - } - return value / 255; - } -} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/permission/PermissionUtils.java b/src/main/java/me/skymc/taboolib/permission/PermissionUtils.java deleted file mode 100644 index 3d5ba16..0000000 --- a/src/main/java/me/skymc/taboolib/permission/PermissionUtils.java +++ /dev/null @@ -1,34 +0,0 @@ -package me.skymc.taboolib.permission; - -import me.skymc.taboolib.Main; -import net.milkbowl.vault.permission.Permission; -import org.bukkit.entity.Player; -import org.bukkit.plugin.RegisteredServiceProvider; - -import java.util.Arrays; - -public class PermissionUtils { - - private static Permission perms; - - public static void loadRegisteredServiceProvider() { - RegisteredServiceProvider rsp = Main.getInst().getServer().getServicesManager().getRegistration(Permission.class); - perms = rsp.getProvider(); - } - - public static Permission getPermission() { - return perms; - } - - public static void addPermission(Player player, String perm) { - perms.playerAdd(player, perm); - } - - public static void removePermission(Player player, String perm) { - perms.playerRemove(player, perm); - } - - public static boolean hasPermission(Player player, String perm) { - return perms.playerHas(player, perm) || Arrays.stream(perms.getPlayerGroups(player)).anyMatch(group -> perms.groupHas(player.getWorld(), group, perm)); - } -} diff --git a/src/main/java/me/skymc/taboolib/player/PlayerUtils.java b/src/main/java/me/skymc/taboolib/player/PlayerUtils.java deleted file mode 100644 index cb2ed91..0000000 --- a/src/main/java/me/skymc/taboolib/player/PlayerUtils.java +++ /dev/null @@ -1,139 +0,0 @@ -package me.skymc.taboolib.player; - -import com.google.common.collect.ImmutableList; -import org.bukkit.Bukkit; -import org.bukkit.GameMode; -import org.bukkit.block.Block; -import org.bukkit.entity.HumanEntity; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; - -/** - * @author sky - */ -public class PlayerUtils { - - private static boolean setup; - private static boolean useReflection; - private static Method oldGetOnlinePlayersMethod; - - public static Collection getOnlinePlayers() { - try { - if (!setup) { - oldGetOnlinePlayersMethod = Bukkit.class.getDeclaredMethod("getOnlinePlayers"); - if (oldGetOnlinePlayersMethod.getReturnType() == Player[].class) { - useReflection = true; - } - setup = true; - } - if (!useReflection) { - return Bukkit.getOnlinePlayers(); - } else { - Player[] playersArray = (Player[]) oldGetOnlinePlayersMethod.invoke(null); - return ImmutableList.copyOf(playersArray); - } - } catch (Exception e) { - return Collections.emptyList(); - } - } - - /** - * 获取目标方块 - * - * @param player 玩家 - * @param max 最大视野 - * @return - */ - public static Block getTargetBlock(Player player, int max) { - HashSet bytes = new HashSet<>(); - bytes.add((byte) 0); - return player.getTargetBlock(bytes, max); - } - - /** - * 重写数据 - * - * @param player 玩家 - * @param scoreboard 是否清理计分板 - */ - public static void resetData(Player player, boolean scoreboard) { - if (player.isDead()) { - player.spigot().respawn(); - } - player.closeInventory(); - player.setGameMode(GameMode.SURVIVAL); - player.getInventory().setArmorContents(new ItemStack[4]); - player.getInventory().setContents(new ItemStack[0]); - player.setAllowFlight(false); - player.setFlying(false); - player.setExp(0.0F); - player.setLevel(0); - player.setSneaking(false); - player.setSprinting(false); - player.setFoodLevel(20); - player.setSaturation(10.0F); - player.setExhaustion(0.0F); - player.setMaxHealth(20.0D); - player.setHealth(20.0D); - player.setFireTicks(0); - player.setItemOnCursor(null); - player.getActivePotionEffects().clear(); - player.getEnderChest().clear(); - player.updateInventory(); - if (scoreboard) { - player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard()); - } - } - - /** - * 获取玩家的鱼钩 - * - * @param player 玩家 - * @return net.minecraft.server.{version}.EntityFishingHook - */ - public static Object getPlayerHookedFish(HumanEntity player) { - try { - Object entityHuman = player.getClass().getMethod("getHandle").invoke(player); - return entityHuman.getClass().getField("hookedFish").get(entityHuman); - } catch (Exception ignored) { - } - return null; - } - - /** - * 获取鱼钩的钓鱼时间 - * - * @param fishHook 鱼钩 - * @return int - */ - public static int getFishingTicks(Object fishHook) { - try { - Field fishingTicks = fishHook.getClass().getDeclaredField("h"); - fishingTicks.setAccessible(true); - return (int) fishingTicks.get(fishHook); - } catch (Exception ignored) { - } - return -1; - } - - /** - * 设置鱼钩的钓鱼时间 - * - * @param fishHook 鱼钩 - * @param ticks 时间 - */ - public static void setFishingTicks(Object fishHook, int ticks) { - try { - Field fishingTicks = fishHook.getClass().getDeclaredField("h"); - fishingTicks.setAccessible(true); - fishingTicks.set(fishHook, ticks); - } catch (Exception ignored) { - } - } -} diff --git a/src/main/java/me/skymc/taboolib/player/TargetUtils.java b/src/main/java/me/skymc/taboolib/player/TargetUtils.java deleted file mode 100644 index fa993a9..0000000 --- a/src/main/java/me/skymc/taboolib/player/TargetUtils.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.skymc.taboolib.player; - -import org.bukkit.block.Block; -import org.bukkit.entity.LivingEntity; -import org.bukkit.util.BlockIterator; - -import java.util.LinkedList; - - -@Deprecated -public class TargetUtils { - - public static LinkedList getTarget(LivingEntity p, int max) { - BlockIterator itor = new BlockIterator(p); - LinkedList block = new LinkedList<>(); - while (itor.hasNext()) { - max++; - block.add(itor.next()); - if (max >= 100) { - break; - } - } - return block; - } -} diff --git a/src/main/java/me/skymc/taboolib/regen/WorldGuardUtils.java b/src/main/java/me/skymc/taboolib/regen/WorldGuardUtils.java deleted file mode 100644 index d0ad421..0000000 --- a/src/main/java/me/skymc/taboolib/regen/WorldGuardUtils.java +++ /dev/null @@ -1,26 +0,0 @@ -package me.skymc.taboolib.regen; - -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 { - - public static String getRegen(Location loc) { - int x = (int) loc.getX(); - int y = (int) loc.getY() + 1; - int z = (int) loc.getZ(); - - Map regens = WorldGuardPlugin.inst().getRegionManager(loc.getWorld()).getRegions(); - for (String s : regens.keySet()) { - ProtectedRegion regen = regens.get(s); - if (regen.contains(x, y, z)) { - return regen.getId(); - } - } - return null; - } -} diff --git a/src/main/java/me/skymc/taboolib/sign/SignUtils.java b/src/main/java/me/skymc/taboolib/sign/SignUtils.java deleted file mode 100644 index dbdc8a9..0000000 --- a/src/main/java/me/skymc/taboolib/sign/SignUtils.java +++ /dev/null @@ -1,152 +0,0 @@ -package me.skymc.taboolib.sign; - -import com.google.common.annotations.Beta; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.TabooLib; -import me.skymc.taboolib.listener.TListener; -import me.skymc.taboolib.location.LocationUtils; -import me.skymc.taboolib.message.MsgUtils; -import me.skymc.taboolib.methods.MethodsUtils; -import me.skymc.taboolib.nms.NMSUtils; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockPhysicsEvent; -import org.bukkit.event.block.SignChangeEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.metadata.FixedMetadataValue; - -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; - -@Deprecated -@Beta -@TListener(condition = "check") -public class SignUtils implements Listener { - - public static HashMap signs = new HashMap<>(); - - public static boolean check() { - return TabooLib.getVerint() > 10700; - } - - public static void openSign(Player p, Block b) { - - if (!(b.getType().equals(Material.WALL_SIGN) || b.getType().equals(Material.SIGN_POST))) { - return; - } - - b.setMetadata("TabooLib-Sign-Editing", new FixedMetadataValue(Main.getInst(), true)); - - try { - Object world = b.getWorld().getClass().getMethod("getHandle").invoke(b.getWorld()); - Object blockPos = NMSUtils.getNMSClass("BlockPosition").getConstructor(int.class, int.class, int.class).newInstance(b.getX(), b.getY(), b.getZ()); - Object sign = world.getClass().getMethod("getTileEntity", NMSUtils.getNMSClass("BlockPosition")).invoke(world, blockPos); - - Object player = p.getClass().getMethod("getHandle").invoke(p); - - player.getClass().getMethod("openSign", NMSUtils.getNMSClass("TileEntitySign")).invoke(player, sign); - } catch (Exception e) { - MsgUtils.send(p, "&4操作失败 &8(SIGN OPENED ERROR.1)"); - e.printStackTrace(); - } - } - - public static void openSign(Player p, String[] lines, String signid) { - if (!MethodsUtils.checkUser(new String(new byte[]{'m', 'e', '.', 's', 'k', 'y', 'm', 'c'}), new Exception().getStackTrace()[1].getClassName())) { - throw new Error("未经允许的方法调用"); - } - - Block b = LocationUtils.findBlockByLocation(p.getLocation()); - if (b == null) { - MsgUtils.send(p, "&4所在位置无法进行该操作 &8(NOT FOUND AIR BY SIGN)"); - return; - } - - b.setData((byte) 0); - b.setType(Material.WALL_SIGN); - - b.setMetadata("TabooLib-Sign", new FixedMetadataValue(Main.getInst(), true)); - b.setMetadata("TabooLib-Sign-UUID", new FixedMetadataValue(Main.getInst(), signid)); - - try { - Object world = b.getWorld().getClass().getMethod("getHandle").invoke(b.getWorld()); - Object blockPos = NMSUtils.getNMSClass("BlockPosition").getConstructor(int.class, int.class, int.class).newInstance(b.getX(), b.getY(), b.getZ()); - Object sign = world.getClass().getMethod("getTileEntity", NMSUtils.getNMSClass("BlockPosition")).invoke(world, blockPos); - - Object[] _lines = (Object[]) sign.getClass().getField("lines").get(sign); - - for (int i = 0; i < lines.length; i++) { - Object object = NMSUtils.getNMSClass("ChatComponentText").getConstructor(String.class).newInstance(lines[i]); - _lines[i] = object; - } - - Object player = p.getClass().getMethod("getHandle").invoke(p); - - Bukkit.getScheduler().runTaskLater(Main.getInst(), () -> { - if (p.isOnline()) { - try { - player.getClass().getMethod("openSign", NMSUtils.getNMSClass("TileEntitySign")).invoke(player, sign); - signs.put(p.getName(), b); - } catch (IllegalAccessException | SecurityException | NoSuchMethodException | InvocationTargetException | IllegalArgumentException e) { - MsgUtils.send(p, "&4操作失败 &8(SIGN OPENED ERROR.2)"); - e.printStackTrace(); - } - } - }, 3); - } catch (Exception e) { - MsgUtils.send(p, "&4操作失败 &8(SIGN OPENED ERROR.1)"); - e.printStackTrace(); - } - } - - @EventHandler(priority = EventPriority.LOWEST) - public void signChange(SignChangeEvent e) { - Block block = e.getBlock(); - if (block.hasMetadata("TabooLib-Sign")) { - signs.remove(e.getPlayer().getName()); - - String signid = String.valueOf(block.getMetadata("TabooLib-Sign-UUID").get(0).value()); - Bukkit.getPluginManager().callEvent(new TabooSignChangeEvent(e.getPlayer(), block, e.getLines(), signid)); - - block.removeMetadata("TabooLib-Sign", Main.getInst()); - block.removeMetadata("TabooLib-Sign-UUID", Main.getInst()); - block.setType(Material.AIR); - block.setData((byte) 0); - } - } - - @EventHandler - public void quit(PlayerQuitEvent e) { - if (signs.containsKey(e.getPlayer().getName())) { - Block block = signs.get(e.getPlayer().getName()); - if (block.hasMetadata("TabooLib-Sign")) { - block.removeMetadata("TabooLib-Sign", Main.getInst()); - block.removeMetadata("TabooLib-Sign-UUID", Main.getInst()); - block.setType(Material.AIR); - block.setData((byte) 0); - } - } - } - - @EventHandler - public void block(BlockPhysicsEvent e) { - Block block = e.getBlock(); - if (block.hasMetadata("TabooLib-Sign")) { - e.setCancelled(true); - } - } - - @EventHandler - public void blocku(BlockBreakEvent e) { - Block block = e.getBlock(); - if (block.hasMetadata("TabooLib-Sign") && !e.getPlayer().isOp()) { - e.setCancelled(true); - } - } -} diff --git a/src/main/java/me/skymc/taboolib/sign/TabooSignChangeEvent.java b/src/main/java/me/skymc/taboolib/sign/TabooSignChangeEvent.java deleted file mode 100644 index f198ba7..0000000 --- a/src/main/java/me/skymc/taboolib/sign/TabooSignChangeEvent.java +++ /dev/null @@ -1,48 +0,0 @@ -package me.skymc.taboolib.sign; - -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -@Deprecated -public class TabooSignChangeEvent extends Event { - - private static final HandlerList handlers = new HandlerList(); - private Player player; - private Block block; - private String[] lines; - private String uuid; - - public TabooSignChangeEvent(Player player, Block block, String[] lines, String uuid) { - this.player = player; - this.block = block; - this.lines = lines; - this.uuid = uuid; - } - - public Player getPlayer() { - return this.player; - } - - public Block getBlock() { - return this.block; - } - - public String[] getLines() { - return this.lines; - } - - public String getUUID() { - return this.uuid; - } - - @Override - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } -} diff --git a/src/main/java/me/skymc/taboolib/skript/SkriptHandler.java b/src/main/java/me/skymc/taboolib/skript/SkriptHandler.java deleted file mode 100644 index 909e87d..0000000 --- a/src/main/java/me/skymc/taboolib/skript/SkriptHandler.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.skymc.taboolib.skript; - -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 - * @since 2018-02-28 15:40:55 - */ -public class SkriptHandler { - - public static void register() { - if (Bukkit.getPluginManager().getPlugin("Skript") != null) { - try { - Skript.registerExpression(ExpressionItemCache.class, ItemStack.class, ExpressionType.SIMPLE, "taboolib itemcache %string%"); - Skript.registerExpression(ExpressionTabooCodeItem.class, ItemStack.class, ExpressionType.SIMPLE, "taboocode itemcache %string%"); - } catch (Exception ignored) { - } - } - } -} diff --git a/src/main/java/me/skymc/taboolib/skript/expression/ExpressionItemCache.java b/src/main/java/me/skymc/taboolib/skript/expression/ExpressionItemCache.java deleted file mode 100644 index 761f8c2..0000000 --- a/src/main/java/me/skymc/taboolib/skript/expression/ExpressionItemCache.java +++ /dev/null @@ -1,46 +0,0 @@ -package me.skymc.taboolib.skript.expression; - -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.taboolib.inventory.ItemUtils; -import org.bukkit.event.Event; -import org.bukkit.inventory.ItemStack; - -/** - * @author sky - * @since 2018-02-28 15:45:49 - */ -public class ExpressionItemCache extends SimpleExpression { - - private Expression name; - - @Override - public Class getReturnType() { - return ItemStack.class; - } - - @Override - public boolean isSingle() { - return true; - } - - @SuppressWarnings("unchecked") - @Override - public boolean init(Expression[] args, int arg1, Kleenean arg2, ParseResult arg3) { - name = (Expression) args[0]; - return true; - } - - @Override - public String toString(Event e, boolean arg1) { - return this.getClass().getName(); - } - - @Override - protected ItemStack[] get(Event e) { - ItemStack item = ItemUtils.getCacheItem(name.getSingle(e)); - return new ItemStack[] { item == null ? null : item.clone() }; - } -} diff --git a/src/main/java/me/skymc/taboolib/skript/expression/ExpressionTabooCodeItem.java b/src/main/java/me/skymc/taboolib/skript/expression/ExpressionTabooCodeItem.java deleted file mode 100644 index 566305a..0000000 --- a/src/main/java/me/skymc/taboolib/skript/expression/ExpressionTabooCodeItem.java +++ /dev/null @@ -1,51 +0,0 @@ -package me.skymc.taboolib.skript.expression; - -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 - * @since 2018-02-28 15:45:49 - */ -public class ExpressionTabooCodeItem extends SimpleExpression { - - private Expression name; - - @Override - public Class getReturnType() { - return ItemStack.class; - } - - @Override - public boolean isSingle() { - return true; - } - - @SuppressWarnings("unchecked") - @Override - public boolean init(Expression[] args, int arg1, Kleenean arg2, ParseResult arg3) { - name = (Expression) args[0]; - return true; - } - - @Override - public String toString(Event e, boolean arg1) { - return this.getClass().getName(); - } - - @Override - protected ItemStack[] get(Event e) { - try { - ItemStack item = TabooCodeItem.getItem(name.getSingle(e), false); - return new ItemStack[] { item == null ? null : item.clone() }; - } - catch (Exception err) { - return null; - } - } -} diff --git a/src/main/java/me/skymc/taboolib/skull/SkullUtils.java b/src/main/java/me/skymc/taboolib/skull/SkullUtils.java deleted file mode 100644 index c30b668..0000000 --- a/src/main/java/me/skymc/taboolib/skull/SkullUtils.java +++ /dev/null @@ -1,21 +0,0 @@ -package me.skymc.taboolib.skull; - -import com.google.common.annotations.Beta; -import me.skymc.taboolib.inventory.builder.ItemBuilder; -import org.bukkit.Material; -import org.bukkit.OfflinePlayer; -import org.bukkit.inventory.ItemStack; - -@Beta -@Deprecated -public class SkullUtils { - - public static ItemStack getItem(OfflinePlayer p) { - return new ItemBuilder(p).build(); - } - - public static ItemStack getOnlineItem(OfflinePlayer p) { - return p.isOnline() ? new ItemBuilder(p).build() : new ItemStack(Material.SKULL_ITEM); - } - -} diff --git a/src/main/java/me/skymc/taboolib/string/obfuscated/CT.java b/src/main/java/me/skymc/taboolib/string/obfuscated/CT.java deleted file mode 100644 index 37c3537..0000000 --- a/src/main/java/me/skymc/taboolib/string/obfuscated/CT.java +++ /dev/null @@ -1,52 +0,0 @@ -package me.skymc.taboolib.string.obfuscated; - -import javax.xml.bind.DatatypeConverter; - -@Deprecated -public class CT { - - public static String decode(CodeType type, String string) { - switch (type) { - case BASE64: { - return new String(DatatypeConverter.parseBase64Binary(string)); - } - case BINARY: { - StringBuilder text = new StringBuilder(); - for (String segment : string.split(" ")) { - text.append(Character.toString((char) Integer.parseInt(segment, 2))); - } - return text.toString(); - } - default: - } - return ""; - } - - public static String encode(CodeType type, String string) { - switch (type) { - case BASE64: { - return DatatypeConverter.printBase64Binary(string.getBytes()); - } - case BINARY: { - StringBuilder binary = new StringBuilder(); - for (byte b : string.getBytes()) { - int value = b; - for (int i = 0; i < 8; i++) { - binary.append((value & 128) == 0 ? 0 : 1); - value <<= 1; - } - binary.append(" "); - } - return binary.toString(); - } - default: - } - return ""; - } - - public enum CodeType { - BASE64, - BINARY - } - -} diff --git a/src/main/java/me/skymc/taboolib/string/obfuscated/FZ.java b/src/main/java/me/skymc/taboolib/string/obfuscated/FZ.java deleted file mode 100644 index 1d02cbe..0000000 --- a/src/main/java/me/skymc/taboolib/string/obfuscated/FZ.java +++ /dev/null @@ -1,59 +0,0 @@ -package me.skymc.taboolib.string.obfuscated; - -@Deprecated -public class FZ { - - public static String toByte(final String string) { - final StringBuilder sb = new StringBuilder(); - final byte[] bs = string.getBytes(); - byte[] array; - for (int length = (array = bs).length, i = 0; i < length; ++i) { - final byte b = array[i]; - sb.append(String.valueOf(b)).append("#"); - } - return sb.toString(); - } - - public static byte[] getByte(final String string) { - final String[] value = string.split("#"); - final byte[] bs = new byte[value.length]; - for (int i = 0; i < value.length; ++i) { - bs[i] = Byte.valueOf(value[i]); - } - return bs; - } - - public static String unByte(final String string) { - final String[] value = string.split("#"); - final byte[] bs = new byte[value.length]; - for (int i = 0; i < value.length; ++i) { - bs[i] = Byte.valueOf(value[i]); - } - return new String(bs); - } - - public static String load(final String string, final int power) { - final StringBuilder sb = new StringBuilder(); - char[] charArray; - for (int length = (charArray = string.toCharArray()).length, j = 0; j < length; ++j) { - int i; - final char c = (char)(i = charArray[j]); - i *= power; - sb.append(String.valueOf(i)).append("#"); - } - return sb.toString(); - } - - public static String load2(final String string, final int power) { - final String[] value = string.split("#"); - final StringBuilder sb = new StringBuilder(); - String[] array; - for (int length = (array = value).length, j = 0; j < length; ++j) { - final String c = array[j]; - int i = Integer.valueOf(c); - i /= power; - sb.append((char)i); - } - return sb.toString(); - } -} diff --git a/src/main/java/me/skymc/taboolib/string/obfuscated/RS.java b/src/main/java/me/skymc/taboolib/string/obfuscated/RS.java deleted file mode 100644 index e407a3e..0000000 --- a/src/main/java/me/skymc/taboolib/string/obfuscated/RS.java +++ /dev/null @@ -1,48 +0,0 @@ -package me.skymc.taboolib.string.obfuscated; - -import me.skymc.taboolib.Main; - -@Deprecated -public class RS { - - private static final char[] charsDown = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray(); - private static final char[] charsUp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray(); - - public static char getRandomCharacter() { - return charsDown[Main.getRandom().nextInt(charsDown.length)]; - } - - public static char getRandomCharacter(Boolean isUp) { - if (isUp) { - return charsUp[Main.getRandom().nextInt(charsUp.length)]; - } - return charsDown[Main.getRandom().nextInt(charsDown.length)]; - } - - public static String getRandomString(int length) { - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < length; i++) { - builder.append(getRandomCharacter()); - } - return builder.toString(); - } - - public static String getRandomString(String prefix, String rule, Boolean isUp) { - StringBuilder builder = new StringBuilder(prefix + "-"); - String[] value = rule.split("-"); - - int size = 0; - for (String subrule : value) { - size++; - - for (int i = 0; i < Integer.valueOf(subrule); i++) { - builder.append(getRandomCharacter(isUp)); - } - if (!(size == value.length)) { - builder.append("-"); - } - } - - return builder.toString(); - } -} diff --git a/src/main/java/me/skymc/taboolib/team/TagAPI.java b/src/main/java/me/skymc/taboolib/team/TagAPI.java deleted file mode 100644 index 5afb4da..0000000 --- a/src/main/java/me/skymc/taboolib/team/TagAPI.java +++ /dev/null @@ -1,66 +0,0 @@ -package me.skymc.taboolib.team; - -import com.google.common.base.Preconditions; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.itagapi.TagDataHandler; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -import java.util.Set; - -/** - * @Author sky - * @Since 2018-05-09 21:03 - */ -@Deprecated -public class TagAPI { - - /** - * 该工具于 2018年5月23日02:31:14 失效 - * 新工具类: {@link TagDataHandler} - */ - - TagAPI() { - } - - public static void inst() { - } - - public static String getPlayerDisplayName(Player player) { - return TagDataHandler.getHandler().getDisplay(player); - } - - public static void setPlayerDisplayName(Player player, String name) { - TagDataHandler.getHandler().setDisplay(player, name); - } - - public static void removePlayerDisplayName(Player player) { - TagDataHandler.getHandler().setDisplay(player, player.getName()); - } - - public static void refreshPlayer(Player player) { - Preconditions.checkState(Main.getInst().isEnabled(), "Not Enabled!"); - Preconditions.checkNotNull(player, "player"); - - player.getWorld().getPlayers().forEach(playerFor -> refreshPlayer(player, playerFor)); - } - - public static void refreshPlayer(final Player player, final Player forWhom) { - Preconditions.checkState(Main.getInst().isEnabled(), "Not Enabled!"); - Preconditions.checkNotNull(player, "player"); - Preconditions.checkNotNull(forWhom, "forWhom"); - - if (player != forWhom && player.getWorld() == forWhom.getWorld() && forWhom.canSee(player)) { - forWhom.hidePlayer(player); - Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(Main.getInst(), () -> forWhom.showPlayer(player), 2); - } - } - - public static void refreshPlayer(Player player, Set forWhom) { - Preconditions.checkState(Main.getInst().isEnabled(), "Not Enabled!"); - Preconditions.checkNotNull(player, "player"); - Preconditions.checkNotNull(forWhom, "forWhom"); - - forWhom.forEach(playerFor -> refreshPlayer(player, playerFor)); - } -} diff --git a/src/main/java/me/skymc/taboolib/team/TagManager.java b/src/main/java/me/skymc/taboolib/team/TagManager.java deleted file mode 100644 index 7c78340..0000000 --- a/src/main/java/me/skymc/taboolib/team/TagManager.java +++ /dev/null @@ -1,126 +0,0 @@ -package me.skymc.taboolib.team; - -import com.ilummc.tlib.util.Strings; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.itagapi.TagDataHandler; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.scoreboard.Scoreboard; -import org.bukkit.scoreboard.Team; - -import java.util.HashMap; -import java.util.UUID; - -/** - * @author sky - * @since 2018-03-17 21:43:49 - */ -@Deprecated -public class TagManager { - - /** - * 该工具于 2018年5月23日02:31:14 失效 - * 新工具类: {@link TagDataHandler} - */ - - private static TagManager inst; - - public static TagManager getInst() { - synchronized (TagManager.class) { - if (inst == null) { - inst = new TagManager(); - } - } - return inst; - } - - public HashMap getPlayerData() { - return new HashMap<>(0); - } - - public void setPrefix(Player player, String prefix) { - TagDataHandler.getHandler().setPrefix(player, prefix); - } - - public void setSuffix(Player player, String suffix) { - TagDataHandler.getHandler().setSuffix(player, suffix); - } - - public String getPrefix(Player player) { - return TagDataHandler.getHandler().getPrefix(player); - } - - public String getSuffix(Player player) { - return TagDataHandler.getHandler().getSuffix(player); - } - - public PlayerData getPlayerData(Player player) { - return new PlayerData(player); - } - - public void unloadData(Player targetPlayer) { - TagDataHandler.getHandler().resetVariable(targetPlayer); - } - - public void uploadData(Player targetPlayer) { - } - - public void downloadData(Player targetPlayer) { - } - - static class PlayerData { - - private UUID uuid; - private String name; - private String prefix; - private String suffix; - - public PlayerData(Player player) { - this.uuid = player.getUniqueId(); - this.name = player.getName(); - this.prefix = ""; - this.suffix = ""; - } - - public UUID getUuid() { - return uuid; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getPrefix() { - return prefix; - } - - public void setPrefix(String prefix) { - this.prefix = prefix; - } - - public String getSuffix() { - return suffix; - } - - public void setSuffix(String suffix) { - this.suffix = suffix; - } - - public boolean isEmpty() { - return Strings.isEmpty(suffix) && Strings.isEmpty(prefix); - } - - public void reset() { - prefix = ""; - suffix = ""; - } - } -} diff --git a/src/main/java/me/skymc/taboolib/thread/ThreadUtils.java b/src/main/java/me/skymc/taboolib/thread/ThreadUtils.java deleted file mode 100644 index 750e218..0000000 --- a/src/main/java/me/skymc/taboolib/thread/ThreadUtils.java +++ /dev/null @@ -1,86 +0,0 @@ -package me.skymc.taboolib.thread; - -import java.util.LinkedList; - -/** - * @author sky - */ -@Deprecated -public class ThreadUtils { - - private static final LinkedList queue = new LinkedList<>(); - private static PoolWorker[] threads; - - /** - * 构造方法 - * - * @param number 线程数量 - */ - public ThreadUtils(int number) { - threads = new PoolWorker[number]; - - for (int i = 0; i < number; i++) { - threads[i] = new PoolWorker(); - threads[i].setName("TabooLib WorkThread - " + i); - threads[i].start(); - } - } - - /** - * 停止工作 - */ - public void stop() { - for (PoolWorker p : threads) { - p.stop(); - } - } - - /** - * 添加任务 - * - * @param r - */ - public void execute(Runnable r) { - // 线程锁 - synchronized (queue) { - // 添加任务 - queue.addLast(r); - // 开始任务 - queue.notify(); - } - } - - private class PoolWorker extends Thread { - - @Override - public void run() { - Runnable runnable; - - while (true) { - - // 线程锁 - synchronized (queue) { - - // 如果任务为空 - while (queue.isEmpty()) { - // 等待任务 - try { - queue.wait(); - } catch (InterruptedException ignored) { - - } - } - // 获取任务 - runnable = queue.removeFirst(); - } - - // 运行任务 - try { - runnable.run(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } -} \ No newline at end of file diff --git a/src/main/java/me/skymc/taboolib/timecycle/TimeCycle.java b/src/main/java/me/skymc/taboolib/timecycle/TimeCycle.java deleted file mode 100644 index c8609bb..0000000 --- a/src/main/java/me/skymc/taboolib/timecycle/TimeCycle.java +++ /dev/null @@ -1,35 +0,0 @@ -package me.skymc.taboolib.timecycle; - -import me.skymc.taboolib.other.DateUtils; -import org.bukkit.plugin.Plugin; - -public class TimeCycle { - - private String name; - private Plugin plugin; - - private long cycle; - - public TimeCycle(String name, long cycle, Plugin plugin) { - this.name = name; - this.cycle = cycle; - this.plugin = plugin; - - long millisHour = DateUtils.getTime(DateUtils.HOUR_OF_DAY) * 60L * 60L * 1000L; - long millisMinute = DateUtils.getTime(DateUtils.MINUTE) * 60L * 1000L; - - long time = System.currentTimeMillis() - millisHour - millisMinute; - } - - public Plugin getPlugin() { - return plugin; - } - - public String getName() { - return name; - } - - public long getCycle() { - return cycle; - } -} diff --git a/src/main/java/me/skymc/taboolib/timecycle/TimeCycleEvent.java b/src/main/java/me/skymc/taboolib/timecycle/TimeCycleEvent.java deleted file mode 100644 index 2797f25..0000000 --- a/src/main/java/me/skymc/taboolib/timecycle/TimeCycleEvent.java +++ /dev/null @@ -1,28 +0,0 @@ -package me.skymc.taboolib.timecycle; - -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -public class TimeCycleEvent extends Event { - - private static final HandlerList handlers = new HandlerList(); - private TimeCycle cycle; - - public TimeCycleEvent(TimeCycle cycle) { - super(true); - this.cycle = cycle; - } - - public TimeCycle getCycle() { - return this.cycle; - } - - @Override - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } -} diff --git a/src/main/java/me/skymc/taboolib/timecycle/TimeCycleInitializeEvent.java b/src/main/java/me/skymc/taboolib/timecycle/TimeCycleInitializeEvent.java deleted file mode 100644 index e8fa476..0000000 --- a/src/main/java/me/skymc/taboolib/timecycle/TimeCycleInitializeEvent.java +++ /dev/null @@ -1,46 +0,0 @@ -package me.skymc.taboolib.timecycle; - -import org.bukkit.Bukkit; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -public class TimeCycleInitializeEvent extends Event { - - private static final HandlerList handlers = new HandlerList(); - private TimeCycle cycle; - private Long time; - - public TimeCycleInitializeEvent(TimeCycle cycle, Long time) { - super(true); - this.cycle = cycle; - this.time = time; - } - - public TimeCycleInitializeEvent call() { - Bukkit.getPluginManager().callEvent(this); - return this; - } - - public Long getTimeline() { - return time; - } - - public void setTimeLine(Long time) { - this.time = time; - } - - public TimeCycle getCycle() { - return this.cycle; - } - - @Override - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - - -} diff --git a/src/main/java/me/skymc/taboolib/timecycle/TimeCycleManager.java b/src/main/java/me/skymc/taboolib/timecycle/TimeCycleManager.java deleted file mode 100644 index 6357156..0000000 --- a/src/main/java/me/skymc/taboolib/timecycle/TimeCycleManager.java +++ /dev/null @@ -1,159 +0,0 @@ -package me.skymc.taboolib.timecycle; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.database.GlobalDataManager; -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; - -public class TimeCycleManager { - - /** - * 最后一次更新: 2018年1月16日21:07:49 - * - * @author sky - */ - - private static ConcurrentHashMap cycles = new ConcurrentHashMap<>(); - - /** - * 获取周期管理器 - * - * @param name - * @return - */ - public static TimeCycle getTimeCycle(String name) { - return cycles.get(name); - } - - /** - * 获取所有周期管理器 - * - * @return - */ - public static Collection getTimeCycles() { - return cycles.values(); - } - - /** - * 彻底删除周期数据 - * - * @param name - */ - public static void deleteCycleData(String name) { - HashMap map = GlobalDataManager.getVariables(); - map.keySet().stream().filter(_name -> _name.startsWith("timecycle")).forEach(_name -> GlobalDataManager.setVariable(name, null)); - } - - /** - * 注册周期管理器 - * - * @param cycle - */ - public static void register(TimeCycle cycle) { - if (!cycles.containsKey(cycle.getName())) { - cycles.put(cycle.getName(), cycle); - } else { - TLocale.Logger.error("TIMECYCLE.FAIL-CYCLE-EXISTS", cycle.getName()); - } - } - - /** - * 注销周期管理器 - * - * @param name - * @return - */ - public static TimeCycle cancel(String name) { - return cycles.remove(name); - } - - /** - * 注销插件所有周期管理器 - * - * @param plugin - */ - public static void cancel(Plugin plugin) { - cycles.values().stream().filter(x -> x.getPlugin().equals(plugin)).forEach(x -> cycles.remove(x.getName())); - } - - /** - * 设置上一次更新事件 - * - * @param name - * @param time - */ - public static boolean setTimeline(String name, Long time) { - if (cycles.containsKey(name)) { - GlobalDataManager.setVariable("timecycle:" + name, time.toString()); - return true; - } - return false; - } - - /** - * 获取下一次刷新时间 - * - * @param name - * @return - */ - public static long getAfterTimeline(String name) { - if (cycles.containsKey(name)) { - Long value = Long.valueOf(GlobalDataManager.getVariable("timecycle:" + name, "0")); - return value + cycles.get(name).getCycle(); - } - return 0L; - } - - /** - * 获取上一次刷新时间 - * - * @param name - * @return - */ - public static long getBeforeTimeline(String name) { - if (cycles.containsKey(name)) { - return Long.valueOf(GlobalDataManager.getVariable("timecycle:" + name, "0")); - } - return 0L; - } - - - public static void load() { - // 注册调度器 - new BukkitRunnable() { - - @Override - public void run() { - for (TimeCycle cycle : cycles.values()) { - // 调度器没有被执行过 - if (!GlobalDataManager.contains("timecycle:" + cycle.getName())) { - long time = new TimeCycleInitializeEvent(cycle, System.currentTimeMillis()).call().getTimeline(); - // 初始化 - GlobalDataManager.setVariable("timecycle:" + cycle.getName(), String.valueOf(time)); - // 触发器 - Bukkit.getPluginManager().callEvent(new TimeCycleEvent(cycle)); - } - // 如果超出刷新时间 - else if (System.currentTimeMillis() >= getAfterTimeline(cycle.getName())) { - long time = System.currentTimeMillis(); - // 如果时间差大于 30 秒 - if (time - getAfterTimeline(cycle.getName()) > 30000) { - // 初始化 - time = new TimeCycleInitializeEvent(cycle, time).call().getTimeline(); - } - // 重置 - GlobalDataManager.setVariable("timecycle:" + cycle.getName(), String.valueOf(time)); - // 触发器 - Bukkit.getPluginManager().callEvent(new TimeCycleEvent(cycle)); - } - } - } - }.runTaskTimerAsynchronously(Main.getInst(), 0, 20); - } -} diff --git a/src/main/java/me/skymc/taboolib/translateuuid/TranslateUUID.java b/src/main/java/me/skymc/taboolib/translateuuid/TranslateUUID.java deleted file mode 100644 index 25a8732..0000000 --- a/src/main/java/me/skymc/taboolib/translateuuid/TranslateUUID.java +++ /dev/null @@ -1,205 +0,0 @@ -package me.skymc.taboolib.translateuuid; - -import com.ilummc.tlib.logger.TLogger; -import com.ilummc.tlib.util.Strings; -import com.zaxxer.hikari.HikariDataSource; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.fileutils.ConfigUtils; -import me.skymc.taboolib.json.JSONObject; -import me.skymc.taboolib.mysql.builder.*; -import me.skymc.taboolib.mysql.hikari.HikariHandler; -import me.skymc.taboolib.nms.NMSUtils; -import org.bukkit.configuration.file.FileConfiguration; - -import java.io.*; -import java.lang.reflect.Method; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Properties; -import java.util.UUID; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * @Author sky - * @Since 2018-06-21 22:16 - */ -public class TranslateUUID { - - private static FileConfiguration settings; - private static HikariDataSource dataSource; - - private static SQLHost sqlHost; - private static SQLTable sqlTable; - - private static final String INSERT_PLAYER_DATA = "insert into {0} values(null, ?, ?)"; - private static final String SELECT_WITH_UUID = "select * from {0} where uuid = ?"; - private static final String SELECT_WITH_USERNAME = "select * from {0} where username = ?"; - private static final String UPDATE_PLAYER_USERNAME = "update {0} set username = ? where uuid = ?"; - - private static boolean enabled = false; - - public static void init() { - settings = ConfigUtils.saveDefaultConfig(Main.getInst(), "translateuuid.yml"); - if (!settings.getBoolean("Enable")) { - enabled = false; - return; - } - sqlHost = new SQLHost(settings.getConfigurationSection("Database"), Main.getInst()); - sqlTable = new SQLTable(settings.getString("Database.table"), SQLColumn.PRIMARY_KEY_ID, new SQLColumn(SQLColumnType.TEXT, "uuid"), new SQLColumn(SQLColumnType.TEXT, "username")); - try { - dataSource = HikariHandler.createDataSource(sqlHost, null); - createTable(); - } catch (Exception e) { - TLogger.getGlobalLogger().error("Database connected fail: " + e.toString()); - } - enabled = true; - } - - public static void cancel() { - HikariHandler.closeDataSource(sqlHost); - } - - public static String translateUUID(String username) { - try (Connection connection = dataSource.getConnection()) { - return translateInternal(connection, username, "uuid", SELECT_WITH_USERNAME); - } catch (SQLException e) { - TLogger.getGlobalLogger().error("Database error: " + e.toString()); - return null; - } - } - - public static String translateUsername(UUID uuid) { - try (Connection connection = dataSource.getConnection()) { - return translateInternal(connection, uuid.toString(), "username", SELECT_WITH_UUID); - } catch (SQLException e) { - TLogger.getGlobalLogger().error("Database error: " + e.toString()); - return null; - } - } - - public static void updateUsername(UUID uuid, String username) { - PreparedStatement preparedStatement = null; - try (Connection connection = dataSource.getConnection()) { - String usernameExists = translateInternal(connection, uuid.toString(), "username", SELECT_WITH_UUID); - if (usernameExists == null) { - preparedStatement = connection.prepareStatement(Strings.replaceWithOrder(INSERT_PLAYER_DATA, sqlTable.getTableName())); - preparedStatement.setString(1, uuid.toString()); - preparedStatement.setString(2, username); - } else { - preparedStatement = connection.prepareStatement(Strings.replaceWithOrder(UPDATE_PLAYER_USERNAME, sqlTable.getTableName())); - preparedStatement.setString(1, username); - preparedStatement.setString(2, uuid.toString()); - } - preparedStatement.executeUpdate(); - } catch (SQLException e) { - TLogger.getGlobalLogger().error("Database error: " + e.toString()); - } finally { - SQLExecutor.freeStatement(preparedStatement, null); - } - } - - public static void importLocal() { - File worldFolder = new File(getDefaultWorldName()); - if (!worldFolder.exists()) { - TLogger.getGlobalLogger().error("Invalid \"world\" folder"); - return; - } - - File playerDataFolder = new File(worldFolder, "playerdata"); - if (!playerDataFolder.exists() || !playerDataFolder.isDirectory()) { - TLogger.getGlobalLogger().error("Invalid \"playerdata\" folder"); - return; - } - - ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(32); - - AtomicInteger i = new AtomicInteger(); - AtomicInteger fail = new AtomicInteger(); - int size = playerDataFolder.listFiles().length; - - TLogger.getGlobalLogger().info("Start importing the local data..."); - for (File file : playerDataFolder.listFiles()) { - if (fail.get() > 10) { - TLogger.getGlobalLogger().info("The number of failures exceeds the threshold! import stopped.."); - break; - } - threadPool.submit(() -> { - try { - String username = getUsernameInDatFile(file); - updateUsername(UUID.fromString(file.getName().split("\\.")[0]), username); - TLogger.getGlobalLogger().info("importing... " + username + "(" + i.getAndIncrement() + "/" + size + ")"); - } catch (Exception ignored) { - fail.getAndIncrement(); - } - }); - } - - threadPool.shutdown(); - } - - public static JSONObject getPlayerDataInDatFile(File datFile) { - Class clazz = NMSUtils.getNMSClassSilent("NBTCompressedStreamTools"); - try (FileInputStream fileInputStream = new FileInputStream(datFile)) { - Method a = clazz.getMethod("a", InputStream.class); - Object nbtTagCompound = a.invoke(null, fileInputStream); - return new JSONObject(nbtTagCompound.getClass().getMethod("toString").invoke(nbtTagCompound)); - } catch (Exception ignored) { - } - return new JSONObject(); - } - - // ********************************* - // - // Private Methods - // - // ********************************* - - private static void createTable() { - sqlTable.executeUpdate(sqlTable.createQuery()).dataSource(dataSource).run(); - } - - private static String getDefaultWorldName() { - Properties properties = new Properties(); - try { - properties.load(new FileReader(new File("server.properties"))); - } catch (IOException ignored) { - } - return properties.getProperty("level-name", "world"); - } - - private static String getUsernameInDatFile(File datFile) { - Class clazz = NMSUtils.getNMSClassSilent("NBTCompressedStreamTools"); - try (FileInputStream fileInputStream = new FileInputStream(datFile)) { - Method a = clazz.getMethod("a", InputStream.class); - Object nbtTagCompound = a.invoke(null, fileInputStream); - Method getCompound = nbtTagCompound.getClass().getMethod("getCompound", String.class); - Object bukkit = getCompound.invoke(nbtTagCompound, "bukkit"); - Method getString = bukkit.getClass().getMethod("getString", String.class); - return String.valueOf(getString.invoke(bukkit, "lastKnownName")); - } catch (Exception ignored) { - } - return "null"; - } - - private static String translateInternal(Connection connection, String input, String output, String command) { - return sqlTable.executeQuery(Strings.replaceWithOrder(command, sqlTable.getTableName())) - .connection(connection) - .statement(statement -> statement.setString(1, input)) - .resultNext(result -> result.getString(output)) - .run(null, ""); - } - - // ********************************* - // - // Getter and Setter - // - // ********************************* - - public static boolean isEnabled() { - return enabled; - } -} diff --git a/src/main/java/me/skymc/taboolib/translateuuid/TranslateUUIDCommand.java b/src/main/java/me/skymc/taboolib/translateuuid/TranslateUUIDCommand.java deleted file mode 100644 index 86e3c31..0000000 --- a/src/main/java/me/skymc/taboolib/translateuuid/TranslateUUIDCommand.java +++ /dev/null @@ -1,81 +0,0 @@ -package me.skymc.taboolib.translateuuid; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.commands.internal.BaseMainCommand; -import me.skymc.taboolib.commands.internal.BaseSubCommand; -import me.skymc.taboolib.commands.internal.TCommand; -import me.skymc.taboolib.commands.internal.type.CommandArgument; -import me.skymc.taboolib.commands.internal.type.CommandRegister; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; - -/** - * @Author sky - * @Since 2018-06-22 17:09 - */ -@TCommand( - name = "translateuuid", - aliases = "tuuid", - permission = "taboolib.admin" -) -public class TranslateUUIDCommand extends BaseMainCommand { - - @Override - public String getCommandTitle() { - return TLocale.asString("COMMANDS.TRANSLATE-UUID.COMMAND-TITLE"); - } - - @CommandRegister - BaseSubCommand importLocal = new BaseSubCommand() { - @Override - public String getLabel() { - return "importLocal"; - } - - @Override - public String getDescription() { - return TLocale.asString("COMMANDS.TRANSLATE-UUID.IMPORTLOCAL.DESCRIPTION"); - } - - @Override - public CommandArgument[] getArguments() { - return new CommandArgument[0]; - } - - @Override - public void onCommand(CommandSender sender, Command command, String label, String[] args) { - if (!TranslateUUID.isEnabled()) { - TLocale.sendTo(sender, "COMMANDS.TRANSLATE-UUID.IMPORTLOCAL.DISABLED"); - return; - } - - TLocale.sendTo(sender, "COMMANDS.TRANSLATE-UUID.IMPORTLOCAL.SUCCESS"); - TranslateUUID.importLocal(); - } - }; - - @CommandRegister - BaseSubCommand reload = new BaseSubCommand() { - @Override - public String getLabel() { - return "reload"; - } - - @Override - public String getDescription() { - return TLocale.asString("COMMANDS.TRANSLATE-UUID.RELOAD.DESCRIPTION"); - } - - @Override - public CommandArgument[] getArguments() { - return new CommandArgument[0]; - } - - @Override - public void onCommand(CommandSender sender, Command command, String label, String[] args) { - TLocale.sendTo(sender, "COMMANDS.TRANSLATE-UUID.RELOAD.SUCCESS"); - TranslateUUID.cancel(); - TranslateUUID.init(); - } - }; -} diff --git a/src/main/java/me/skymc/tlm/TLM.java b/src/main/java/me/skymc/tlm/TLM.java deleted file mode 100644 index 1578e34..0000000 --- a/src/main/java/me/skymc/tlm/TLM.java +++ /dev/null @@ -1,102 +0,0 @@ -package me.skymc.tlm; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.fileutils.ConfigUtils; -import me.skymc.taboolib.string.language2.Language2; -import me.skymc.tlm.module.TabooLibraryModule; -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 - * @since 2018年2月17日 下午10:28:05 - */ -public class TLM { - - private static TLM inst = null; - - private FileConfiguration config; - - private Language2 language; - - /** - * 构造方法 - */ - private TLM() { - // 重载配置文件 - reloadConfig(); - - // 载入模块 - if (isEnableModule("TimeCycle")) { - TabooLibraryModule.getInst().register(new ModuleTimeCycle()); - } - if (isEnableModule("Kits")) { - TabooLibraryModule.getInst().register(new ModuleKits()); - } - if (isEnableModule("CommandChanger")) { - TabooLibraryModule.getInst().register(new ModuleCommandChanger()); - } - if (isEnableModule("InventorySave")) { - TabooLibraryModule.getInst().register(new ModuleInventorySave()); - } - - // 载入模块 - TabooLibraryModule.getInst().loadModules(); - // 提示 - TLocale.Logger.info("TABOOLIB-MODULE.SUCCESS-LOADED", String.valueOf(TabooLibraryModule.getInst().getSize())); - } - - /** - * 获取 TLM 对象 - * - * @return TLM - */ - public static TLM getInst() { - if (inst == null) { - synchronized (TLM.class) { - if (inst == null) { - inst = new TLM(); - } - } - } - return inst; - } - - public FileConfiguration getConfig() { - return config; - } - - public Language2 getLanguage() { - return language; - } - - /** - * 载入配置文件 - */ - public void reloadConfig() { - config = ConfigUtils.saveDefaultConfig(Main.getInst(), "module.yml"); - language = new Language2(config.getString("Language"), Main.getInst()); - } - - /** - * 模块是否启用 - * - * @param name 名称 - * @return boolean - */ - public boolean isEnableModule(String name) { - return config.getStringList("EnableModule").contains(name); - } - - public void loadedFall(String moduleName, String result, String location) { - TLocale.Logger.error("TABOOLIB-MODULE.FAIL-LOADED", moduleName, result, location); - } - - public void runtimeFall(String moduleName, String result, String location) { - TLocale.Logger.error("TABOOLIB-MODULE.FAIL-RUNTIME", moduleName, result, location); - } -} diff --git a/src/main/java/me/skymc/tlm/annotation/DisableConfig.java b/src/main/java/me/skymc/tlm/annotation/DisableConfig.java deleted file mode 100644 index 90a3b18..0000000 --- a/src/main/java/me/skymc/tlm/annotation/DisableConfig.java +++ /dev/null @@ -1,13 +0,0 @@ -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; - -@Retention(RUNTIME) -@Target(TYPE) -public @interface DisableConfig { - -} diff --git a/src/main/java/me/skymc/tlm/command/TLMCommands.java b/src/main/java/me/skymc/tlm/command/TLMCommands.java deleted file mode 100644 index 99b6393..0000000 --- a/src/main/java/me/skymc/tlm/command/TLMCommands.java +++ /dev/null @@ -1,68 +0,0 @@ -package me.skymc.tlm.command; - -import me.skymc.taboolib.TabooLib; -import me.skymc.taboolib.commands.builder.SimpleCommandBuilder; -import me.skymc.taboolib.object.Instantiable; -import me.skymc.tlm.TLM; -import me.skymc.tlm.command.sub.TLMInvCommand; -import me.skymc.tlm.command.sub.TLMKitCommand; -import me.skymc.tlm.command.sub.TLMListCommand; -import me.skymc.tlm.command.sub.TLMReloadCommand; - -/** - * @author sky - * @since 2018年2月18日 上午12:02:08 - */ -@Instantiable("TLMCommands") -public class TLMCommands { - - public TLMCommands() { - SimpleCommandBuilder.create("taboolibrarymodule", TabooLib.instance()) - .aliases("tlm") - .permission("tlm.use") - .execute((sender, args) -> { - if (args.length == 0 || "help".equalsIgnoreCase(args[0])) { - if (sender.hasPermission("taboolib.admin")) { - TLM.getInst().getLanguage().get("COMMAND-HELP").send(sender); - } else { - TLM.getInst().getLanguage().get("NOPERMISSION-HELP").send(sender); - } - } - - // 重载 - else if ("reload".equalsIgnoreCase(args[0])) { - if (sender.hasPermission("taboolib.admin")) { - new TLMReloadCommand(sender, args); - } else { - TLM.getInst().getLanguage().get("NOPERMISSION-RELOAD").send(sender); - } - } - - // 列出 - else if ("list".equalsIgnoreCase(args[0])) { - if (sender.hasPermission("taboolib.admin")) { - new TLMListCommand(sender, args); - } else { - TLM.getInst().getLanguage().get("NOPERMISSION-LIST").send(sender); - } - } - - // InventorySave 模块 - else if ("inv".equalsIgnoreCase(args[0])) { - if (sender.hasPermission("taboolib.admin")) { - new TLMInvCommand(sender, args); - } else { - TLM.getInst().getLanguage().get("NOPERMISSION-INV").send(sender); - } - } - - // Kit 模块 - else if ("kit".equalsIgnoreCase(args[0])) { - new TLMKitCommand(sender, args); - } else { - TLM.getInst().getLanguage().get("COMMAND-ERROR").send(sender); - } - return true; - }).build(); - } -} diff --git a/src/main/java/me/skymc/tlm/command/sub/TLMInvCommand.java b/src/main/java/me/skymc/tlm/command/sub/TLMInvCommand.java deleted file mode 100644 index 2c130e1..0000000 --- a/src/main/java/me/skymc/tlm/command/sub/TLMInvCommand.java +++ /dev/null @@ -1,201 +0,0 @@ -package me.skymc.tlm.command.sub; - - -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.inventory.ItemUtils; -import me.skymc.tlm.TLM; -import me.skymc.tlm.inventory.TLMInventoryHolder; -import me.skymc.tlm.module.TabooLibraryModule; -import me.skymc.tlm.module.sub.ModuleInventorySave; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; - -import java.util.List; - -/** - * @author sky - * @since 2018年2月18日 下午2:53:58 - */ -public class TLMInvCommand extends SubCommand { - - /** - * @param sender - * @param args - */ - public TLMInvCommand(CommandSender sender, String[] args) { - super(sender, args); - if (TabooLibraryModule.getInst().valueOf("InventorySave") == null) { - TLM.getInst().getLanguage().get("INV-DISABLE").send(sender); - return; - } - - // 获取模块 - ModuleInventorySave moduleInventorySave = (ModuleInventorySave) TabooLibraryModule.getInst().valueOf("InventorySave"); - - // 判断命令 - if (args.length == 1) { - TLM.getInst().getLanguage().get("INV-EMPTY").send(sender); - } - - // 列出背包 - else if ("list".equalsIgnoreCase(args[1])) { - TLM.getInst().getLanguage().get("INV-LIST").addPlaceholder("$name", moduleInventorySave.getInventorys().toString()).send(sender); - } - - // 查看背包 - else if ("info".equalsIgnoreCase(args[1])) { - // 如果是后台 - if (!(sender instanceof Player)) { - TLM.getInst().getLanguage().get("INV-CONSOLE").send(sender); - return; - } - - // 判断长度 - if (args.length < 3) { - TLM.getInst().getLanguage().get("INV-NAME").send(sender); - return; - } - - // 判断背包 - if (!moduleInventorySave.getInventorys().contains(args[2])) { - TLM.getInst().getLanguage().get("INV-NOTFOUND").addPlaceholder("$name", args[2]).send(sender); - return; - } - - // 获取玩家 - Player player = (Player) sender; - - // 获取物品 - List items = moduleInventorySave.getItems(args[2]); - - // 打开界面 - Inventory inv = Bukkit.createInventory(new TLMInventoryHolder("InventorySave"), 54, TLM.getInst().getLanguage().get("INV-INFO-TITLE") - .addPlaceholder("$name", args[2]) - .asString()); - - // 设置物品 - ItemStack barrier = ItemUtils.setName(new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 15), "§f"); - - for (int i = 9 ; i < 18 ; i++) { - inv.setItem(i, barrier); - } - - for (int i = 9 ; i < 35 ; i++) { - inv.setItem(i + 9, items.get(i)); - } - - for (int i = 0 ; i < 9 ; i++) { - inv.setItem(i + 45, items.get(i)); - } - - inv.setItem(1, items.get(39)); - inv.setItem(2, items.get(38)); - inv.setItem(3, items.get(37)); - inv.setItem(4, items.get(36)); - - // 判断版本 - if (items.size() == 41) { - inv.setItem(6, items.get(40)); - } - - // 打开背包 - player.openInventory(inv); - } - - // 保存背包 - else if ("save".equalsIgnoreCase(args[1])) { - // 如果是后台 - if (!(sender instanceof Player)) { - TLM.getInst().getLanguage().get("INV-CONSOLE").send(sender); - return; - } - - // 判断长度 - if (args.length < 3) { - TLM.getInst().getLanguage().get("INV-NAME").send(sender); - return; - } - - // 获取玩家 - Player player = (Player) sender; - - // 保存背包 - moduleInventorySave.saveInventory(player, args[2]); - - // 提示信息 - TLM.getInst().getLanguage().get("INV-SAVE").addPlaceholder("$name", args[2]).send(player); - } - - // 覆盖背包 - else if ("paste".equalsIgnoreCase(args[1])) { - // 判断长度 - if (args.length < 3) { - TLM.getInst().getLanguage().get("INV-NAME").send(sender); - return; - } - - // 判断背包 - if (!moduleInventorySave.getInventorys().contains(args[2])) { - TLM.getInst().getLanguage().get("INV-NOTFOUND").addPlaceholder("$name", args[2]).send(sender); - return; - } - - // 获取玩家 - Player player; - if (args.length > 3) { - player = Bukkit.getPlayerExact(args[3]); - // 玩家不存在 - if (player == null) { - TLM.getInst().getLanguage().get("INV-OFFLINE").addPlaceholder("$name", args[3]).send(sender); - return; - } - } else if (sender instanceof Player) { - player = (Player) sender; - } else { - TLM.getInst().getLanguage().get("INV-CONSOLE").send(sender); - return; - } - - // 覆盖背包 - moduleInventorySave.pasteInventory(player, args[2], args.length > 4 ? args[4] : "null"); - - // 如果是玩家 - if (sender instanceof Player) { - // 提示信息 - TLM.getInst().getLanguage().get("INV-PASTE") - .addPlaceholder("$name", args[2]) - .addPlaceholder("$player", player.getName()) - .send(player); - } - } - - // 删除背包 - else if ("delete".equalsIgnoreCase(args[1])) { - // 判断长度 - if (args.length < 3) { - TLM.getInst().getLanguage().get("INV-NAME").send(sender); - return; - } - - // 判断背包 - if (!moduleInventorySave.getInventorys().contains(args[2])) { - TLM.getInst().getLanguage().get("INV-NOTFOUND").addPlaceholder("$name", args[2]).send(sender); - return; - } - - // 删除 - moduleInventorySave.deleteInventory(args[2]); - - // 提示信息 - TLM.getInst().getLanguage().get("KIT-DELETE").addPlaceholder("$name", args[2]).send(sender); - } - - else { - TLM.getInst().getLanguage().get("INV-EMPTY").send(sender); - } - } -} diff --git a/src/main/java/me/skymc/tlm/command/sub/TLMKitCommand.java b/src/main/java/me/skymc/tlm/command/sub/TLMKitCommand.java deleted file mode 100644 index fa22444..0000000 --- a/src/main/java/me/skymc/tlm/command/sub/TLMKitCommand.java +++ /dev/null @@ -1,173 +0,0 @@ -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 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; - -/** - * @author sky - * @since 2018年2月18日 下午2:53:58 - */ -public class TLMKitCommand extends SubCommand { - - /** - * @param sender - * @param args - */ - public TLMKitCommand(CommandSender sender, String[] args) { - super(sender, args); - if (TabooLibraryModule.getInst().valueOf("Kits") == null) { - TLM.getInst().getLanguage().get("KIT-DISABLE").send(sender); - return; - } - - // 获取模块 - ModuleKits moduleKits = (ModuleKits) TabooLibraryModule.getInst().valueOf("Kits"); - - // 判断命令 - if (args.length == 1) { - TLM.getInst().getLanguage().get("KIT-EMPTY").send(sender); - } - - else if ("list".equalsIgnoreCase(args[1])) { - // 判断权限 - if (!sender.hasPermission("taboolib.kit.list")) { - TLM.getInst().getLanguage().get("NOPERMISSION-KIT-LIST").send(sender); - } - else { - TLM.getInst().getLanguage().get("KIT-LIST") - .addPlaceholder("$kits", moduleKits.getConfig().getConfigurationSection("Kits").getKeys(false).toString()) - .send(sender); - } - } - - else if ("reward".equalsIgnoreCase(args[1])) { - // 判断权限 - if (!sender.hasPermission("taboolib.kit.reward")) { - TLM.getInst().getLanguage().get("NOPERMISSION-KIT-REWARD").send(sender); - return; - } - - // 检查礼包 - if (args.length < 3) { - TLM.getInst().getLanguage().get("KIT-NAME").send(sender); - return; - } - - // 礼包不存在 - if (!moduleKits.contains(args[2])) { - TLM.getInst().getLanguage().get("KIT-NOTFOUND").addPlaceholder("$kit", args[2]).send(sender); - return; - } - - // 获取玩家 - Player player; - if (args.length > 3) { - player = Bukkit.getPlayerExact(args[3]); - // 玩家不存在 - if (player == null) { - TLM.getInst().getLanguage().get("KIT-OFFLINE").addPlaceholder("$name", args[3]).send(sender); - return; - } - } else if (sender instanceof Player) { - player = (Player) sender; - } else { - TLM.getInst().getLanguage().get("KIT-CONSOLE").send(sender); - return; - } - - // 是否领取 - if (moduleKits.isPlayerRewared(player, args[2])) { - // 是否只能领取一次 - if (moduleKits.isDisposable(args[2])) { - TLM.getInst().getLanguage().get("KIT-DISPOSABLE").addPlaceholder("$kit", args[2]).send(sender); - return; - } - // 是否冷却中 - if (moduleKits.isPlayerCooldown(player, args[2])) { - TLM.getInst().getLanguage().get("KIT-COOLDOWN").addPlaceholder("$kit", args[2]).send(sender); - return; - } - } - - // 是否有权限领取 - String permission = moduleKits.getPermission(args[2]); - if (permission != null && !player.hasPermission(permission)) { - // 提示信息 - player.sendMessage(moduleKits.getPermissionMessage(args[2])); - return; - } - - // 发送礼包 - List items = moduleKits.getItems(args[2]); - for (ItemStack item : items) { - // 给予物品 - HashMap result = player.getInventory().addItem(item); - // 如果背包空间不足 - if (result.size() > 0 && moduleKits.isFullDrop(args[2])) { - // 掉落物品 - player.getWorld().dropItem(player.getLocation(), item); - } - } - - // 执行命令 - for (String command : moduleKits.getCommands(args[2])) { - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command.replace("$player", player.getName())); - } - - // 已领取 - moduleKits.setPlayerReward(player, args[2], true); - - // 提示信息 - TLM.getInst().getLanguage().get("KIT-SUCCESS").addPlaceholder("$kit", args[2]).send(sender); - } - else if ("reset".equalsIgnoreCase(args[1])) { - // 判断权限 - if (!sender.hasPermission("taboolib.kit.reset")) { - TLM.getInst().getLanguage().get("NOPERMISSION-KIT-RESET").send(sender); - return; - } - - // 检查礼包 - if (args.length < 3) { - TLM.getInst().getLanguage().get("KIT-NAME").send(sender); - return; - } - - // 礼包不存在 - if (!moduleKits.contains(args[2])) { - TLM.getInst().getLanguage().get("KIT-NOTFOUND").addPlaceholder("$kit", args[2]).send(sender); - return; - } - - // 获取玩家 - Player player; - if (args.length > 3) { - player = Bukkit.getPlayerExact(args[3]); - // 玩家不存在 - if (player == null) { - TLM.getInst().getLanguage().get("KIT-OFFLINE").addPlaceholder("$name", args[3]).send(sender); - } - else { - moduleKits.setPlayerReward(player, args[2], false); - TLM.getInst().getLanguage().get("KIT-RESET-PLAYER").addPlaceholder("$kit", args[2]).addPlaceholder("$player", player.getName()).send(sender); - } - } else { - moduleKits.resetKit(args[2]); - TLM.getInst().getLanguage().get("KIT-RESET-ALL").addPlaceholder("$kit", args[2]).send(sender); - } - } - else { - TLM.getInst().getLanguage().get("COMMAND-ERROR").send(sender); - } - } - -} diff --git a/src/main/java/me/skymc/tlm/command/sub/TLMListCommand.java b/src/main/java/me/skymc/tlm/command/sub/TLMListCommand.java deleted file mode 100644 index 42a0906..0000000 --- a/src/main/java/me/skymc/tlm/command/sub/TLMListCommand.java +++ /dev/null @@ -1,31 +0,0 @@ -package me.skymc.tlm.command.sub; - -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.tlm.module.ITabooLibraryModule; -import me.skymc.tlm.module.TabooLibraryModule; -import org.bukkit.command.CommandSender; - -/** - * @author sky - * @since 2018年2月18日 下午2:10:12 - */ -public class TLMListCommand extends SubCommand { - - /** - * @param sender - * @param args - */ - public TLMListCommand(CommandSender sender, String[] args) { - super(sender, args); - sender.sendMessage("§f"); - sender.sendMessage("§b§l----- §3§lTaooLibraryModule Modules §b§l-----"); - sender.sendMessage("§f"); - - for (ITabooLibraryModule module : TabooLibraryModule.getInst().keySet()) { - sender.sendMessage("§f - §8" + module.getName()); - } - - sender.sendMessage("§f"); - } - -} diff --git a/src/main/java/me/skymc/tlm/command/sub/TLMReloadCommand.java b/src/main/java/me/skymc/tlm/command/sub/TLMReloadCommand.java deleted file mode 100644 index 05fdbd8..0000000 --- a/src/main/java/me/skymc/tlm/command/sub/TLMReloadCommand.java +++ /dev/null @@ -1,48 +0,0 @@ -package me.skymc.tlm.command.sub; - -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.message.MsgUtils; -import me.skymc.tlm.TLM; -import me.skymc.tlm.module.ITabooLibraryModule; -import me.skymc.tlm.module.TabooLibraryModule; -import org.bukkit.command.CommandSender; - -/** - * @author sky - * @since 2018年2月18日 下午2:09:34 - */ -public class TLMReloadCommand extends SubCommand { - - /** - * @param sender - * @param args - */ - public TLMReloadCommand(CommandSender sender, String[] args) { - super(sender, args); - if (args.length != 2) { - MsgUtils.send(sender, "&4参数错误。"); - } - - else if ("tlm".equalsIgnoreCase(args[1])) { - TLM.getInst().reloadConfig(); - MsgUtils.send(sender, "&fTLM &7配置文件已重载。"); - } - - else if ("all".equalsIgnoreCase(args[1])) { - TabooLibraryModule.getInst().reloadConfig(); - MsgUtils.send(sender, "所有模块配置文件已重载。"); - } - - else { - ITabooLibraryModule module = TabooLibraryModule.getInst().valueOf(args[1]); - if (module == null) { - MsgUtils.send(sender, "&4模块 &c" + args[1] + " &4不存在。"); - } - else { - TabooLibraryModule.getInst().reloadConfig(module, true); - MsgUtils.send(sender, "模块 &f" + args[1] + " &7的配置文件已重载。"); - } - } - } - -} diff --git a/src/main/java/me/skymc/tlm/inventory/TLMInventoryHolder.java b/src/main/java/me/skymc/tlm/inventory/TLMInventoryHolder.java deleted file mode 100644 index 526396c..0000000 --- a/src/main/java/me/skymc/tlm/inventory/TLMInventoryHolder.java +++ /dev/null @@ -1,39 +0,0 @@ -package me.skymc.tlm.inventory; - -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; - -import java.util.HashMap; - -/** - * @author sky - * @since 2018年2月22日 下午3:34:59 - */ -public class TLMInventoryHolder implements InventoryHolder { - - private String module; - - private HashMap holderData = new HashMap<>(); - - /** - * 构造方法 - * - * @param module 模块名 - */ - public TLMInventoryHolder(String module) { - this.module = module; - } - - public String getModule() { - return module; - } - - public HashMap getHolderData() { - return holderData; - } - - @Override - public Inventory getInventory() { - return null; - } -} diff --git a/src/main/java/me/skymc/tlm/module/ITabooLibraryModule.java b/src/main/java/me/skymc/tlm/module/ITabooLibraryModule.java deleted file mode 100644 index 1526b90..0000000 --- a/src/main/java/me/skymc/tlm/module/ITabooLibraryModule.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.skymc.tlm.module; - -import org.bukkit.configuration.file.FileConfiguration; - -/** - * @author sky - * @since 2018年2月17日 下午11:22:42 - */ -public interface ITabooLibraryModule { - - default void onEnable() { - } - - default void onDisable() { - } - - default void onReload() { - } - - String getName(); - - default FileConfiguration getConfig() { - return TabooLibraryModule.getInst().getConfig(this); - } -} diff --git a/src/main/java/me/skymc/tlm/module/TabooLibraryModule.java b/src/main/java/me/skymc/tlm/module/TabooLibraryModule.java deleted file mode 100644 index 9da328c..0000000 --- a/src/main/java/me/skymc/tlm/module/TabooLibraryModule.java +++ /dev/null @@ -1,100 +0,0 @@ -package me.skymc.tlm.module; - -import me.skymc.taboolib.Main; -import me.skymc.tlm.annotation.DisableConfig; -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; - -/** - * @author sky - * @since 2018年2月17日 下午11:22:48 - */ -public class TabooLibraryModule { - - private static TabooLibraryModule inst = null; - private final HashMap TLM_MODULE = new HashMap<>(); - - private TabooLibraryModule() { - - } - - public static TabooLibraryModule getInst() { - if (inst == null) { - synchronized (TabooLibraryModule.class) { - if (inst == null) { - inst = new TabooLibraryModule(); - } - } - } - return inst; - } - - public void register(ITabooLibraryModule module) { - if (!TLM_MODULE.containsKey(module)) { - TLM_MODULE.put(module, new YamlConfiguration()); - reloadConfig(module, false); - } - } - - public void loadModules() { - for (ITabooLibraryModule module : TLM_MODULE.keySet()) { - module.onEnable(); - if (module instanceof Listener) { - Bukkit.getPluginManager().registerEvents((Listener) module, Main.getInst()); - } - } - } - - public void unloadModules() { - TLM_MODULE.keySet().forEach(ITabooLibraryModule::onDisable); - } - - public void reloadConfig() { - TLM_MODULE.keySet().forEach(x -> reloadConfig(x, true)); - } - - public void reloadConfig(ITabooLibraryModule module, boolean isReload) { - if (module.getName() == null || module.getClass().getAnnotation(DisableConfig.class) != null) { - return; - } - File file = new File(Main.getInst().getDataFolder(), "TLM/" + module.getName() + ".yml"); - if (!file.exists()) { - Main.getInst().saveResource("TLM/" + module.getName() + ".yml", true); - } - try { - TLM_MODULE.get(module).load(file); - } catch (Exception e) { - // TODO Auto-generated catch block - } - if (isReload) { - module.onReload(); - } - } - - public FileConfiguration getConfig(ITabooLibraryModule module) { - return TLM_MODULE.get(module); - } - - public int getSize() { - return TLM_MODULE.size(); - } - - public Set keySet() { - return TLM_MODULE.keySet(); - } - - public ITabooLibraryModule valueOf(String name) { - for (ITabooLibraryModule module : TLM_MODULE.keySet()) { - if (module.getName().equals(name)) { - return module; - } - } - return null; - } -} diff --git a/src/main/java/me/skymc/tlm/module/sub/ModuleCommandChanger.java b/src/main/java/me/skymc/tlm/module/sub/ModuleCommandChanger.java deleted file mode 100644 index 186c72c..0000000 --- a/src/main/java/me/skymc/tlm/module/sub/ModuleCommandChanger.java +++ /dev/null @@ -1,55 +0,0 @@ -package me.skymc.tlm.module.sub; - -import me.skymc.tlm.module.ITabooLibraryModule; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import org.bukkit.event.server.ServerCommandEvent; - -/** - * @author sky - * @since 2018年2月22日 下午1:32:29 - */ -public class ModuleCommandChanger implements ITabooLibraryModule, Listener { - - @Override - public String getName() { - return "CommandChanger"; - } - - @EventHandler - public void command(PlayerCommandPreprocessEvent e) { - // 循环命令 - for (String id : getConfig().getConfigurationSection("Commands").getKeys(false)) { - // 获取命令 - String key = getConfig().getString("Commands." + id + ".Input"); - // 判断命令 - if (e.getMessage().startsWith(key)) { - // 判断执行方式 - if (!getConfig().contains("Commands." + id + ".ReplaceMode") || "PLAYER".equals(getConfig().getString("Commands." + id + ".ReplaceMode"))) { - // 替换命令 - e.setMessage(e.getMessage().replace(key, getConfig().getString("Commands." + id + ".Replace"))); - return; - } - } - } - } - - @EventHandler - public void command(ServerCommandEvent e) { - // 循环命令 - for (String id : getConfig().getConfigurationSection("Commands").getKeys(false)) { - // 获取命令 - String key = getConfig().getString("Commands." + id + ".Input"); - // 判断命令 - if (e.getCommand().startsWith(key)) { - // 判断执行方式 - if (!getConfig().contains("Commands." + id + ".ReplaceMode") || "CONSOLE".equals(getConfig().getString("Commands." + id + ".ReplaceMode"))) { - // 替换命令 - e.setCommand(e.getCommand().replace(key, getConfig().getString("Commands." + id + ".Replace"))); - return; - } - } - } - } -} diff --git a/src/main/java/me/skymc/tlm/module/sub/ModuleInventorySave.java b/src/main/java/me/skymc/tlm/module/sub/ModuleInventorySave.java deleted file mode 100644 index b6f71a0..0000000 --- a/src/main/java/me/skymc/tlm/module/sub/ModuleInventorySave.java +++ /dev/null @@ -1,174 +0,0 @@ -package me.skymc.tlm.module.sub; - -import me.skymc.taboolib.Main; -import me.skymc.taboolib.TabooLib; -import me.skymc.taboolib.inventory.ItemUtils; -import me.skymc.taboolib.playerdata.DataUtils; -import me.skymc.tlm.TLM; -import me.skymc.tlm.annotation.DisableConfig; -import me.skymc.tlm.inventory.TLMInventoryHolder; -import me.skymc.tlm.module.ITabooLibraryModule; -import org.bukkit.Material; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.ItemStack; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -/** - * @author sky - * @since 2018年2月22日 下午2:48:27 - */ -@DisableConfig -public class ModuleInventorySave implements ITabooLibraryModule, Listener { - - private FileConfiguration conf; - - @Override - public String getName() { - return "InventorySave"; - } - - @Override - public void onEnable() { - reloadConfig(); - } - - @Override - public void onReload() { - reloadConfig(); - } - - public void reloadConfig() { - conf = DataUtils.addPluginData("InventorySave", Main.getInst()); - } - - /** - * 保存玩家背包 - * - * @param player 玩家 - * @param name 名称 - */ - public void saveInventory(Player player, String name) { - // 设置物品 - for (int i = 0; i < (TabooLib.getVerint() > 10800 ? 41 : 40); i++) { - ItemStack item = player.getInventory().getItem(i); - conf.set(name + "." + i, item == null ? new ItemStack(Material.AIR) : item.clone()); - } - } - - /** - * 覆盖玩家背包 - * - * @param player 玩家 - * @param name 名称 - */ - public void pasteInventory(Player player, String name) { - pasteInventory(player, name, "null"); - } - - /** - * 覆盖玩家背包 - * - * @param player 玩家 - * @param name 名称 - * @param module 模式 - */ - public void pasteInventory(Player player, String name, String module) { - // 如果背包不存在 - if (!conf.contains(name)) { - TLM.getInst().runtimeFall("InventorySave", "InventoryNotFound", name); - return; - } - // 异常物品 - List otherItem = new ArrayList<>(); - // 设置物品 - for (int i = 0; i < (TabooLib.getVerint() > 10800 ? 41 : 40); i++) { - try { - ItemStack item = (ItemStack) conf.get(name + "." + i); - // 如果原本有物品 - if (!ItemUtils.isNull(player.getInventory().getItem(i))) { - // 跳过 - if ("-b".equalsIgnoreCase(module)) { - continue; - } - // 给予 - else if ("-a".equalsIgnoreCase(module)) { - otherItem.add(item); - continue; - } - } - // 覆盖 - player.getInventory().setItem(i, item); - } catch (Exception e) { - TLM.getInst().runtimeFall("InventorySave", "InventoryCoverFall", name); - } - } - // 循环异常物品 - for (ItemStack item : otherItem) { - player.getInventory().addItem(item); - } - } - - /** - * 获取背包内所有物品 - * - * @param name 背包名称 - * @return {@link List} - */ - public List getItems(String name) { - // 如果背包不存在 - if (!conf.contains(name)) { - TLM.getInst().runtimeFall("InventorySave", "InventoryNotFound", name); - return new LinkedList<>(); - } - - List items = new LinkedList<>(); - // 设置物品 - for (int i = 0; i < (TabooLib.getVerint() > 10800 ? 41 : 40); i++) { - try { - ItemStack item = (ItemStack) conf.get(name + "." + i); - items.add(item); - } catch (Exception e) { - TLM.getInst().runtimeFall("InventorySave", "ItemStackLoadFall", name); - } - } - return items; - } - - /** - * 获取所有背包 - * - * @return {@link Set} - */ - public Set getInventorys() { - return conf.getConfigurationSection("").getKeys(false); - } - - /** - * 删除背包 - * - * @param name 名称 - */ - public void deleteInventory(String name) { - conf.set(name, null); - } - - @EventHandler - public void onClick(InventoryClickEvent e) { - if (!(e.getInventory().getHolder() instanceof TLMInventoryHolder)) { - return; - } - - TLMInventoryHolder holder = (TLMInventoryHolder) e.getInventory().getHolder(); - if (holder.getModule().equals(getName())) { - e.setCancelled(true); - } - } -} diff --git a/src/main/java/me/skymc/tlm/module/sub/ModuleKits.java b/src/main/java/me/skymc/tlm/module/sub/ModuleKits.java deleted file mode 100644 index 15f7d3d..0000000 --- a/src/main/java/me/skymc/tlm/module/sub/ModuleKits.java +++ /dev/null @@ -1,166 +0,0 @@ -package me.skymc.tlm.module.sub; - -import me.skymc.taboolib.inventory.ItemUtils; -import me.skymc.taboolib.other.DateUtils; -import me.skymc.taboolib.other.NumberUtils; -import me.skymc.taboolib.playerdata.DataUtils; -import me.skymc.tlm.TLM; -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 - * @since 2018年2月18日 下午12:13:55 - */ -public class ModuleKits implements ITabooLibraryModule { - - private FileConfiguration data; - - @Override - public String getName() { - return "Kits"; - } - - @Override - public void onEnable() { - data = DataUtils.addPluginData("ModuleKits", null); - } - - /** - * 设置玩家是否领取礼包 - * - * @param player 玩家 - */ - public void setPlayerReward(Player player, String kit, boolean reward) { - data.set(kit + "." + player.getName(), reward ? System.currentTimeMillis() : null); - } - - /** - * 清空礼包数据 - * - * @param kit 礼包 - */ - public void resetKit(String kit) { - data.set(kit, null); - } - - /** - * 玩家是否领取礼包 - * - * @param player 玩家 - * @param kit 礼包 - * @return boolean - */ - public boolean isPlayerRewared(Player player, String kit) { - return data.contains(kit + "." + player.getName()); - } - - /** - * 礼包是否在冷却中 - * - * @param player - * @param kit - * @return - */ - public boolean isPlayerCooldown(Player player, String kit) { - return System.currentTimeMillis() - data.getLong(kit + "." + player.getName()) < getCooldown(kit); - } - - /** - * 礼包是否存在 - * - * @param kit 礼包名 - * @return boolean - */ - public boolean contains(String kit) { - return getConfig().contains("Kits." + kit); - } - - /** - * 获取礼包冷却时间 - * - * @param kit 礼包名 - * @return long - */ - public long getCooldown(String kit) { - return DateUtils.formatDate(getConfig().getString("Kits." + kit + ".Cooldown")); - } - - /** - * 获取礼包空间不足时的处理方式 - * - * @param kit 礼包名 - * @return boolean - */ - public Boolean isFullDrop(String kit) { - return getConfig().getBoolean("Kits." + kit + ".FullDrop"); - } - - /** - * 礼包是否只能领取一次 - * - * @param kit 礼包名 - * @return boolean - */ - public boolean isDisposable(String kit) { - return getConfig().getBoolean("Kits." + kit + ".Disposable"); - } - - /** - * 获取礼包权限 - * - * @param kit 礼包名 - * @return String - */ - public String getPermission(String kit) { - return getConfig().getString("Kits." + kit + ".Permission"); - } - - /** - * 获取礼包权限提示 - * - * @param kit 礼包名 - * @return String - */ - public String getPermissionMessage(String kit) { - return getConfig().getString("Kits." + kit + ".Permission-message").replace("&", "§"); - } - - /** - * 获取礼包物品 - * - * @param kit 礼包名 - * @return {@link List} - */ - public List getItems(String kit) { - List items = new ArrayList<>(); - for (String itemStr : getConfig().getStringList("Kits." + kit + ".Items")) { - ItemStack item = ItemUtils.getCacheItem(itemStr.split(" ")[0]); - if (item != null) { - item = item.clone(); - try { - item.setAmount(NumberUtils.getInteger(itemStr.split(" ")[1])); - items.add(item); - } catch (Exception e) { - TLM.getInst().runtimeFall("Kits", "InvalidAmount", itemStr); - } - } - } - return items; - } - - /** - * 获取礼包命令 - * - * @param kit 礼包名 - * @return {@link List} - */ - public List getCommands(String kit) { - return getConfig().contains("Kits." + kit + ".Commands") ? getConfig().getStringList("Kits." + kit + ".Commands") : new ArrayList<>(); - } -} diff --git a/src/main/java/me/skymc/tlm/module/sub/ModuleTimeCycle.java b/src/main/java/me/skymc/tlm/module/sub/ModuleTimeCycle.java deleted file mode 100644 index 772dd84..0000000 --- a/src/main/java/me/skymc/tlm/module/sub/ModuleTimeCycle.java +++ /dev/null @@ -1,109 +0,0 @@ -package me.skymc.tlm.module.sub; - -import me.skymc.taboolib.Main; -import me.skymc.taboolib.other.DateUtils; -import me.skymc.taboolib.other.NumberUtils; -import me.skymc.taboolib.timecycle.TimeCycle; -import me.skymc.taboolib.timecycle.TimeCycleEvent; -import me.skymc.taboolib.timecycle.TimeCycleInitializeEvent; -import me.skymc.taboolib.timecycle.TimeCycleManager; -import me.skymc.tlm.TLM; -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 - * @since 2018年2月17日 下午11:23:38 - */ -public class ModuleTimeCycle implements ITabooLibraryModule, Listener { - - @Override - public String getName() { - return "TimeCycle"; - } - - @Override - public void onEnable() { - // 载入检查器 - loadCycles(); - } - - @Override - public void onDisable() { - // 注销检查器 - unloadCycles(); - } - - @Override - public void onReload() { - // 注销检查器 - unloadCycles(); - // 载入检查器 - loadCycles(); - } - - @EventHandler - public void onTimeCycleInitialize(TimeCycleInitializeEvent e) { - if (e.getCycle().getName().contains("tlm|")) { - // 获取名称 - String name = e.getCycle().getName().replace("tlm|", ""); - // 如果有初始化时间配置 - if (getConfig().contains("TimeCycle." + name + ".Initialise.InitialiseDate")) { - // 获取时间 - Calendar date = Calendar.getInstance(); - // 遍历初始化规则 - for (String typeStr : getConfig().getStringList("TimeCycle." + name + ".Initialise.InitialiseDate")) { - try { - int type = (int) Calendar.class.getField(typeStr.split("=")[0]).get(Calendar.class); - date.set(type, NumberUtils.getInteger(typeStr.split("=")[1])); - } catch (Exception ignored) { - TLM.getInst().runtimeFall("TimeCycle", "DateFormatFall", typeStr); - } - } - e.setTimeLine(date.getTimeInMillis()); - } - // 如果有初始化命令 - if (getConfig().contains("TimeCycle." + name + ".Initialise.InitialiseCommand")) { - // 遍历初始化命令 - for (String command : getConfig().getStringList("TimeCycle." + name + ".Initialise.InitialiseCommand")) { - // 执行命令 - Bukkit.getScheduler().runTask(Main.getInst(), () -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command)); - } - } - } - } - - @EventHandler - public void onTimeCycle(TimeCycleEvent e) { - if (e.getCycle().getName().contains("tlm|")) { - // 获取名称 - String name = e.getCycle().getName().replace("tlm|", ""); - // 如果有更新命令 - if (getConfig().contains("TimeCycle." + name + ".UpdateCommand")) { - // 遍历更新命令 - for (String command : getConfig().getStringList("TimeCycle." + name + ".UpdateCommand")) { - // 执行命令 - Bukkit.getScheduler().runTask(Main.getInst(), () -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command)); - } - } - } - } - - private void loadCycles() { - for (String name : getConfig().getConfigurationSection("TimeCycle").getKeys(false)) { - TimeCycleManager.register(new TimeCycle("tlm|" + name, DateUtils.formatDate(getConfig().getString("TimeCycle." + name + ".Cycle")), Main.getInst())); - } - } - - private void unloadCycles() { - for (TimeCycle cycle : TimeCycleManager.getTimeCycles()) { - if (cycle.getName().startsWith("tlm|")) { - TimeCycleManager.cancel(cycle.getName()); - } - } - } -} diff --git a/src/main/resources/Addons/TabooLibDeprecated.jar b/src/main/resources/Addons/TabooLibDeprecated.jar new file mode 100644 index 0000000000000000000000000000000000000000..3565ece79aaa9d541f322e22490585f5f1052b43 GIT binary patch literal 354031 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%0DJtgjY99B?`$v;= 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≪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