├── jitpack.yml ├── src ├── test │ ├── resources │ │ ├── material_error.yml │ │ └── input.json │ └── java │ │ └── github │ │ └── saukiya │ │ ├── expression │ │ ├── operator │ │ │ ├── Operator.java │ │ │ ├── number │ │ │ │ ├── ValueOperator.java │ │ │ │ ├── NumberParseOperator.java │ │ │ │ ├── AdditionOperator.java │ │ │ │ ├── SubtractionOperator.java │ │ │ │ ├── MultiplicationOperator.java │ │ │ │ ├── DivisionOperator.java │ │ │ │ ├── ModulusOperator.java │ │ │ │ └── DynamicOperator.java │ │ │ ├── StringOperator.java │ │ │ ├── ConditionOperator.java │ │ │ ├── NumberOperator.java │ │ │ └── condition │ │ │ │ ├── LessThanOrEqualOperator.java │ │ │ │ └── EqualOperator.java │ │ └── ConditionExpressionParser.java │ │ ├── retention │ │ └── DeluxeMenusHelper.java │ │ ├── tools │ │ └── TestBenchmark.java │ │ └── deprecated │ │ ├── MaterialManager.java │ │ └── CmdUtil.java └── main │ ├── resources │ ├── Localization │ │ ├── zh │ │ │ ├── RandomString │ │ │ │ ├── NoLoad │ │ │ │ │ └── Test.yml │ │ │ │ └── DefaultRandom.yml │ │ │ ├── Item │ │ │ │ └── NoLoad │ │ │ │ │ └── Test.yml │ │ │ ├── Scripts │ │ │ │ ├── Global │ │ │ │ │ ├── Global.js │ │ │ │ │ └── Event.js │ │ │ │ └── Default.js │ │ │ ├── Config.yml │ │ │ └── Message.yml │ │ ├── en │ │ │ ├── RandomString │ │ │ │ ├── NoLoad │ │ │ │ │ └── Test.yml │ │ │ │ └── DefaultRandom.yml │ │ │ ├── Item │ │ │ │ └── NoLoad │ │ │ │ │ └── Test.yml │ │ │ ├── Scripts │ │ │ │ ├── Global │ │ │ │ │ ├── Global.js │ │ │ │ │ └── Event.js │ │ │ │ └── Default.js │ │ │ ├── Config.yml │ │ │ └── Message.yml │ │ └── de │ │ │ ├── RandomString │ │ │ └── NoLoad │ │ │ │ └── Test.yml │ │ │ ├── Item │ │ │ └── NoLoad │ │ │ │ └── Test.yml │ │ │ ├── Scripts │ │ │ ├── Global │ │ │ │ ├── Global.js │ │ │ │ └── Event.js │ │ │ └── Default.js │ │ │ ├── Config.yml │ │ │ └── Message.yml │ └── plugin.yml │ └── java │ └── github │ └── saukiya │ └── sxitem │ ├── data │ ├── random │ │ ├── INode.java │ │ └── nodes │ │ │ ├── SingletonNode.java │ │ │ └── MultipleNode.java │ ├── expression │ │ ├── IExpression.java │ │ ├── impl │ │ │ ├── UUIDExpression.java │ │ │ ├── MaxExpression.java │ │ │ ├── MinExpression.java │ │ │ ├── DecimalExpression.java │ │ │ ├── IntExpression.java │ │ │ ├── StringRandomExpression.java │ │ │ ├── CalculatorExpression.java │ │ │ ├── LockStringExpression.java │ │ │ ├── BooleanExpression.java │ │ │ ├── ScriptExpression.java │ │ │ └── TimeExpression.java │ │ └── ExpressionManager.java │ └── item │ │ ├── impl │ │ ├── GeneratorReMaterial.java │ │ └── GeneratorImport.java │ │ ├── IUpdate.java │ │ └── IGenerator.java │ ├── event │ ├── SXItemReloadEvent.java │ ├── SXItemSpawnEvent.java │ ├── SXItemMythicMobsGiveToInventoryEvent.java │ └── SXItemUpdateEvent.java │ ├── util │ ├── Util.java │ ├── Config.java │ └── Message.java │ └── command │ ├── ReloadCommand.java │ ├── SaveCommand.java │ ├── InfoCommand.java │ └── ScriptCommand.java ├── Module-Deprecated-v3 ├── README.md ├── build.gradle └── src │ └── main │ └── java │ └── github │ └── saukiya │ └── sxitem │ ├── data │ └── random │ │ ├── IRandom.java │ │ └── RandomDocker.java │ ├── command │ ├── SenderType.java │ ├── MainCommand.java │ └── SubCommand.java │ ├── util │ ├── Tuple.java │ ├── LogUtil.java │ ├── LocalizationUtil.java │ ├── MessageUtil.java │ ├── NbtUtil.java │ ├── NMS.java │ ├── ComponentBuilder.java │ ├── ItemUtil.java │ └── CommandUtil.java │ ├── nbt │ ├── NBTTagWrapper.java │ └── NBTItemWrapper.java │ └── helper │ └── PlaceholderHelper.java ├── Module-NMS ├── V1_8_R3 │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── github │ │ └── saukiya │ │ └── tools │ │ └── nms │ │ ├── ComponentUtil_v1_8_R3.java │ │ └── MessageUtil_v1_8_R3.java ├── V1_11_R1 │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── github │ │ └── saukiya │ │ └── tools │ │ └── nms │ │ ├── MessageUtil_v1_11_R1.java │ │ └── ItemUtil_v1_11_R1.java ├── V1_14_R1 │ └── build.gradle ├── V1_15_R1 │ └── build.gradle ├── V1_17_R1 │ └── build.gradle ├── V1_16_R3 │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── github │ │ └── saukiya │ │ └── tools │ │ └── nms │ │ └── MessageUtil_v1_16_R3.java ├── V1_12_R1 │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── github │ │ └── saukiya │ │ └── tools │ │ └── nms │ │ └── MessageUtil_v1_12_R1.java ├── V1_13_R2 │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── github │ │ └── saukiya │ │ └── tools │ │ └── nms │ │ └── MessageUtil_v1_13_R2.java ├── V1_18_R2 │ └── build.gradle ├── V1_19_R1 │ └── build.gradle ├── V1_19_R3 │ └── build.gradle ├── V1_20_R1 │ └── build.gradle ├── V1_20_R2 │ └── build.gradle ├── V1_20_R3 │ └── build.gradle ├── V1_21_R2 │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── github │ │ └── saukiya │ │ └── tools │ │ └── nms │ │ └── ComponentUtil_v1_21_R2.java ├── V1_21_R3 │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── github │ │ └── saukiya │ │ └── tools │ │ └── nms │ │ └── ComponentUtil_v1_21_R3.java ├── V1_21_R4 │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── github │ │ └── saukiya │ │ └── tools │ │ └── nms │ │ └── ComponentUtil_v1_21_R4.java ├── V1_21_R5 │ └── build.gradle ├── v1_21_R6 │ └── build.gradle ├── v1_21_R7 │ └── build.gradle ├── V1_20_R4 │ ├── build.gradle │ └── src │ │ └── main │ │ └── java │ │ └── github │ │ └── saukiya │ │ └── tools │ │ └── nms │ │ ├── MessageUtil_v1_20_R4.java │ │ └── ComponentUtil_v1_20_R4.java └── V1_21_R1 │ ├── build.gradle │ └── src │ └── main │ └── java │ └── github │ └── saukiya │ └── tools │ └── nms │ └── ComponentUtil_v1_21_R1.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── Module-Base ├── src │ └── main │ │ └── java │ │ └── github │ │ └── saukiya │ │ └── tools │ │ ├── base │ │ ├── package-info.java │ │ ├── Tuple.java │ │ ├── EmptyMap.java │ │ ├── CharStack.java │ │ └── DoubleStack.java │ │ ├── util │ │ ├── package-info.java │ │ ├── TimingsUtil.java │ │ └── LogUtil.java │ │ ├── command │ │ ├── package-info.java │ │ ├── SenderType.java │ │ └── SubCommand.java │ │ ├── helper │ │ └── package-info.java │ │ ├── manager │ │ └── package-info.java │ │ ├── nms │ │ └── package-info.java │ │ └── nbt │ │ ├── package-info.java │ │ ├── TagNumber.java │ │ ├── TagBase.java │ │ ├── TagListBase.java │ │ ├── TagEnd.java │ │ ├── TagLong.java │ │ ├── TagInt.java │ │ ├── TagFloat.java │ │ ├── TagShort.java │ │ ├── TagDouble.java │ │ ├── TagString.java │ │ ├── TagByte.java │ │ ├── TagByteArray.java │ │ ├── TagIntArray.java │ │ ├── TagLongArray.java │ │ ├── TagType.java │ │ └── TagList.java └── build.gradle ├── .gitignore ├── gradle.properties ├── settings.gradle ├── README.md ├── .github └── workflows │ └── gradle-publish.yml └── gradlew.bat /jitpack.yml: -------------------------------------------------------------------------------- 1 | jdk: 2 | - openjdk21 -------------------------------------------------------------------------------- /src/test/resources/material_error.yml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Module-Deprecated-v3/README.md: -------------------------------------------------------------------------------- 1 | ### 向后兼容 V3 版本 -------------------------------------------------------------------------------- /Module-NMS/V1_8_R3/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | compileOnly 'org.spigotmc:spigot:1.8.8-R0.1-SNAPSHOT' 3 | } -------------------------------------------------------------------------------- /Module-NMS/V1_11_R1/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | compileOnly 'org.spigotmc:spigot:1.11.2-R0.1-SNAPSHOT' 3 | } -------------------------------------------------------------------------------- /Module-NMS/V1_14_R1/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | compileOnly 'org.bukkit:craftbukkit:1.14.4-R0.1-SNAPSHOT' 3 | } -------------------------------------------------------------------------------- /Module-NMS/V1_15_R1/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | compileOnly 'org.bukkit:craftbukkit:1.15.2-R0.1-SNAPSHOT' 3 | } -------------------------------------------------------------------------------- /Module-NMS/V1_17_R1/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | compileOnly 'org.bukkit:craftbukkit:1.17.1-R0.1-SNAPSHOT' 3 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Saukiya/SX-Item/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/base/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 一些基本单元 3 | */ 4 | package github.saukiya.tools.base; -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/util/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 通用工具集 3 | */ 4 | package github.saukiya.tools.util; -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/command/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 指令集 3 | */ 4 | package github.saukiya.tools.command; -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/helper/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 其他插件辅助 3 | */ 4 | package github.saukiya.tools.helper; -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/manager/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 通用管理集 3 | */ 4 | package github.saukiya.tools.manager; -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nms/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 版本兼容工具类 [1.8.8+] 3 | */ 4 | package github.saukiya.tools.nms; -------------------------------------------------------------------------------- /src/main/resources/Localization/zh/RandomString/NoLoad/Test.yml: -------------------------------------------------------------------------------- 1 | Test: 2 | - "支持加载子文件夹, NoLoad前缀的文件/文件夹不会被加载" 3 | - "默认配置文件将会被保留, 不需要的可以将文件内容删除" -------------------------------------------------------------------------------- /Module-Deprecated-v3/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | compileOnly rootProject 3 | compileOnly "$spigot" 4 | compileOnly "$commons_lang" 5 | } -------------------------------------------------------------------------------- /src/test/java/github/saukiya/expression/operator/Operator.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.expression.operator; 2 | 3 | public interface Operator { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/resources/Localization/zh/Item/NoLoad/Test.yml: -------------------------------------------------------------------------------- 1 | NoLoad_Test: 2 | Lore: 3 | - "支持加载子文件夹, NoLoad前缀的文件/文件夹不会被加载" 4 | - "默认配置文件将会被保留, 不需要的可以将文件内容删除" -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/random/INode.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.random; 2 | 3 | public interface INode { 4 | String get(); 5 | } 6 | -------------------------------------------------------------------------------- /Module-Base/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | compileOnly 'com.github.PlaceholderAPI:PlaceholderAPI:2.10.9' 3 | compileOnly 'org.openjdk.nashorn:nashorn-core:15.4' 4 | } -------------------------------------------------------------------------------- /Module-NMS/V1_16_R3/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | compileOnly 'org.bukkit:craftbukkit:1.16.5-R0.1-SNAPSHOT' 3 | compileOnly 'net.md-5:bungeecord-chat:1.16-R0.4' 4 | } -------------------------------------------------------------------------------- /Module-NMS/V1_12_R1/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | compileOnly 'org.bukkit:craftbukkit:1.12.2-R0.1-SNAPSHOT' 3 | compileOnly 'net.md-5:bungeecord-chat:1.12-SNAPSHOT' 4 | } -------------------------------------------------------------------------------- /Module-NMS/V1_13_R2/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | compileOnly 'org.bukkit:craftbukkit:1.13.2-R0.1-SNAPSHOT' 3 | compileOnly 'net.md-5:bungeecord-chat:1.13-SNAPSHOT' 4 | } -------------------------------------------------------------------------------- /Module-NMS/V1_18_R2/build.gradle: -------------------------------------------------------------------------------- 1 | sourceCompatibility = JavaVersion.VERSION_17 2 | targetCompatibility = JavaVersion.VERSION_17 3 | dependencies { 4 | compileOnly 'org.bukkit:craftbukkit:1.18.2-R0.1-SNAPSHOT' 5 | } -------------------------------------------------------------------------------- /Module-NMS/V1_19_R1/build.gradle: -------------------------------------------------------------------------------- 1 | sourceCompatibility = JavaVersion.VERSION_17 2 | targetCompatibility = JavaVersion.VERSION_17 3 | dependencies { 4 | compileOnly 'org.bukkit:craftbukkit:1.19.2-R0.1-SNAPSHOT' 5 | } -------------------------------------------------------------------------------- /Module-NMS/V1_19_R3/build.gradle: -------------------------------------------------------------------------------- 1 | sourceCompatibility = JavaVersion.VERSION_17 2 | targetCompatibility = JavaVersion.VERSION_17 3 | dependencies { 4 | compileOnly 'org.bukkit:craftbukkit:1.19.4-R0.1-SNAPSHOT' 5 | } -------------------------------------------------------------------------------- /Module-NMS/V1_20_R1/build.gradle: -------------------------------------------------------------------------------- 1 | sourceCompatibility = JavaVersion.VERSION_17 2 | targetCompatibility = JavaVersion.VERSION_17 3 | dependencies { 4 | compileOnly 'org.bukkit:craftbukkit:1.20.1-R0.1-SNAPSHOT' 5 | } -------------------------------------------------------------------------------- /Module-NMS/V1_20_R2/build.gradle: -------------------------------------------------------------------------------- 1 | sourceCompatibility = JavaVersion.VERSION_17 2 | targetCompatibility = JavaVersion.VERSION_17 3 | dependencies { 4 | compileOnly 'org.bukkit:craftbukkit:1.20.2-R0.1-SNAPSHOT' 5 | } -------------------------------------------------------------------------------- /Module-NMS/V1_20_R3/build.gradle: -------------------------------------------------------------------------------- 1 | sourceCompatibility = JavaVersion.VERSION_17 2 | targetCompatibility = JavaVersion.VERSION_17 3 | dependencies { 4 | compileOnly 'org.bukkit:craftbukkit:1.20.3-R0.1-SNAPSHOT' 5 | } -------------------------------------------------------------------------------- /Module-NMS/V1_21_R2/build.gradle: -------------------------------------------------------------------------------- 1 | sourceCompatibility = JavaVersion.VERSION_21 2 | targetCompatibility = JavaVersion.VERSION_21 3 | dependencies { 4 | compileOnly 'org.bukkit:craftbukkit:1.21.2-R0.1-SNAPSHOT' 5 | } -------------------------------------------------------------------------------- /Module-NMS/V1_21_R3/build.gradle: -------------------------------------------------------------------------------- 1 | sourceCompatibility = JavaVersion.VERSION_21 2 | targetCompatibility = JavaVersion.VERSION_21 3 | dependencies { 4 | compileOnly 'org.bukkit:craftbukkit:1.21.4-R0.1-SNAPSHOT' 5 | } -------------------------------------------------------------------------------- /Module-NMS/V1_21_R4/build.gradle: -------------------------------------------------------------------------------- 1 | sourceCompatibility = JavaVersion.VERSION_21 2 | targetCompatibility = JavaVersion.VERSION_21 3 | dependencies { 4 | compileOnly 'org.bukkit:craftbukkit:1.21.5-R0.1-SNAPSHOT' 5 | } -------------------------------------------------------------------------------- /Module-NMS/V1_21_R5/build.gradle: -------------------------------------------------------------------------------- 1 | sourceCompatibility = JavaVersion.VERSION_21 2 | targetCompatibility = JavaVersion.VERSION_21 3 | dependencies { 4 | compileOnly 'org.bukkit:craftbukkit:1.21.7-R0.1-SNAPSHOT' 5 | } -------------------------------------------------------------------------------- /Module-NMS/v1_21_R6/build.gradle: -------------------------------------------------------------------------------- 1 | sourceCompatibility = JavaVersion.VERSION_21 2 | targetCompatibility = JavaVersion.VERSION_21 3 | dependencies { 4 | compileOnly 'org.bukkit:craftbukkit:1.21.10-R0.1-SNAPSHOT' 5 | } -------------------------------------------------------------------------------- /Module-NMS/v1_21_R7/build.gradle: -------------------------------------------------------------------------------- 1 | sourceCompatibility = JavaVersion.VERSION_21 2 | targetCompatibility = JavaVersion.VERSION_21 3 | dependencies { 4 | compileOnly 'org.bukkit:craftbukkit:1.21.11-R0.1-SNAPSHOT' 5 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Project exclude paths 2 | /.gradle/ 3 | /.idea 4 | /build/ 5 | /out/ 6 | /run/ 7 | /versions/ 8 | 9 | **/out/ 10 | **/build/ 11 | **/generated/ 12 | **/generated_tests/ 13 | 14 | local.properties 15 | -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nbt/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * NBT转换类 (如需操作NBT, 请使用 {@link github.saukiya.tools.nms.NbtUtil#getItemTagWrapper(org.bukkit.inventory.ItemStack)}) 3 | */ 4 | package github.saukiya.tools.nbt; -------------------------------------------------------------------------------- /Module-NMS/V1_20_R4/build.gradle: -------------------------------------------------------------------------------- 1 | sourceCompatibility = JavaVersion.VERSION_17 2 | targetCompatibility = JavaVersion.VERSION_17 3 | dependencies { 4 | compileOnly 'org.bukkit:craftbukkit:1.20.6-R0.1-SNAPSHOT' 5 | compileOnly 'net.md-5:bungeecord-chat:1.20-R0.2' 6 | } -------------------------------------------------------------------------------- /Module-NMS/V1_21_R1/build.gradle: -------------------------------------------------------------------------------- 1 | sourceCompatibility = JavaVersion.VERSION_17 2 | targetCompatibility = JavaVersion.VERSION_17 3 | dependencies { 4 | compileOnly 'org.bukkit:craftbukkit:1.21.1-R0.1-SNAPSHOT' 5 | compileOnly 'net.md-5:bungeecord-chat:1.20-R0.2' 6 | } -------------------------------------------------------------------------------- /src/main/resources/Localization/en/RandomString/NoLoad/Test.yml: -------------------------------------------------------------------------------- 1 | Test: 2 | - "Support for loading subfolders" 3 | - "files/folders prefixed by NoLoad will not be loaded" 4 | - "" 5 | - "The default profile will be preserved" 6 | - "You can delete the contents of the file if you don't need it." -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /src/main/resources/Localization/en/Item/NoLoad/Test.yml: -------------------------------------------------------------------------------- 1 | NoLoad_Test: 2 | Lore: 3 | - "Support for loading subfolders" 4 | - "files/folders prefixed by NoLoad will not be loaded" 5 | - "" 6 | - "The default profile will be preserved" 7 | - "You can delete the contents of the file if you don't need it." -------------------------------------------------------------------------------- /Module-Deprecated-v3/src/main/java/github/saukiya/sxitem/data/random/IRandom.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.random; 2 | 3 | import github.saukiya.sxitem.data.expression.IExpression; 4 | 5 | /** 6 | * @see IExpression 7 | * @deprecated 8 | */ 9 | public interface IRandom extends IExpression { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/resources/Localization/de/RandomString/NoLoad/Test.yml: -------------------------------------------------------------------------------- 1 | Test: 2 | - 'Unterstützt das Laden von Unterordnern' 3 | - 'Dateien/Ordner mit dem Präfix "NoLoad" werden nicht geladen' 4 | - '' 5 | - 'Die Standardkonfigurationsdateien werden beibehalten' 6 | - 'unnötige Dateien können durch Löschen des Inhalts entfernt werden' -------------------------------------------------------------------------------- /Module-Deprecated-v3/src/main/java/github/saukiya/sxitem/data/random/RandomDocker.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.random; 2 | 3 | import github.saukiya.sxitem.data.expression.ExpressionHandler; 4 | 5 | /** 6 | * @see ExpressionHandler 7 | * @deprecated 8 | */ 9 | public class RandomDocker extends ExpressionHandler { 10 | } 11 | -------------------------------------------------------------------------------- /src/main/resources/Localization/de/Item/NoLoad/Test.yml: -------------------------------------------------------------------------------- 1 | NoLoad_Test: 2 | Lore: 3 | - 'Unterstützt das Laden von Unterordnern' 4 | - 'Dateien/Ordner mit dem Präfix "NoLoad" werden nicht geladen' 5 | - '' 6 | - 'Die Standardkonfigurationsdateien werden beibehalten' 7 | - 'unnötige Dateien können durch Löschen des Inhalts entfernt werden' -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/command/SenderType.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.command; 2 | 3 | /** 4 | * 发送者类型 5 | */ 6 | public enum SenderType { 7 | /** 8 | * 玩家 9 | */ 10 | PLAYER, 11 | /** 12 | * 控制台 13 | */ 14 | CONSOLE, 15 | /** 16 | * 所有 17 | */ 18 | ALL 19 | } 20 | -------------------------------------------------------------------------------- /Module-Deprecated-v3/src/main/java/github/saukiya/sxitem/command/SenderType.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.command; 2 | 3 | /** 4 | * @see github.saukiya.tools.command.SenderType 5 | * @deprecated 6 | */ 7 | public enum SenderType { 8 | 9 | @Deprecated 10 | PLAYER, 11 | 12 | @Deprecated 13 | CONSOLE, 14 | 15 | @Deprecated 16 | ALL 17 | } 18 | -------------------------------------------------------------------------------- /Module-Deprecated-v3/src/main/java/github/saukiya/sxitem/util/Tuple.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.util; 2 | 3 | /** 4 | * @see github.saukiya.tools.base.Tuple 5 | * @deprecated 6 | */ 7 | public class Tuple extends github.saukiya.tools.base.Tuple { 8 | 9 | @Deprecated 10 | public Tuple(A var0, B var1) { 11 | super(var0, var1); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs="-Dfile.encoding=UTF-8" "-Dsun.stdout.encoding=UTF-8" "-Dsun.stderr.encoding=UTF-8" 2 | org.gradle.console.encoding=UTF-8 3 | org.gradle.logging.level=quiet 4 | #Information 5 | group=io.github.saukiya 6 | version=4.4.9 7 | shapshot=false 8 | languages=zh,en,de 9 | 10 | #Dependency 11 | spigot=org.spigotmc:spigot-api:1.21.7-R0.1-SNAPSHOT 12 | commons_lang=commons-lang:commons-lang:2.6 -------------------------------------------------------------------------------- /src/main/resources/Localization/zh/Scripts/Global/Global.js: -------------------------------------------------------------------------------- 1 | /*global Bukkit, Arrays, SXItem, listener*/ 2 | /** 3 | * 常用的开发文档 4 | * Bukkit - https://bukkit.windit.net/javadoc/ 5 | * Java8 - https://www.matools.com/api/java8 6 | */ 7 | // 可以在此设置你的全局变量 提供给除了Global文件夹的脚本类使用 8 | /** 9 | * @see [ArrayList](https://www.matools.com/doc/java8/java/util/ArrayList.html) 10 | */ 11 | ArrayList = Java.type("java.util.ArrayList") -------------------------------------------------------------------------------- /Module-Deprecated-v3/src/main/java/github/saukiya/sxitem/command/MainCommand.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.command; 2 | 3 | /** 4 | * @see github.saukiya.tools.command.MainCommand 5 | * @deprecated 6 | */ 7 | public class MainCommand extends github.saukiya.tools.command.MainCommand { 8 | 9 | @Deprecated 10 | public MainCommand(org.bukkit.plugin.java.JavaPlugin plugin) { 11 | super(plugin); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/test/java/github/saukiya/expression/operator/number/ValueOperator.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.expression.operator.number; 2 | 3 | import github.saukiya.expression.operator.NumberOperator; 4 | import lombok.AllArgsConstructor; 5 | 6 | @AllArgsConstructor 7 | public class ValueOperator implements NumberOperator { 8 | 9 | private double value; 10 | 11 | @Override 12 | public double evaluate() { 13 | return value; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/random/nodes/SingletonNode.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.random.nodes; 2 | 3 | import github.saukiya.sxitem.data.random.INode; 4 | import lombok.AllArgsConstructor; 5 | import lombok.ToString; 6 | 7 | @ToString 8 | @AllArgsConstructor 9 | public class SingletonNode implements INode { 10 | 11 | final String value; 12 | 13 | @Override 14 | public String get() { 15 | return value; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: SX-Item 2 | main: github.saukiya.sxitem.SXItem 3 | version: $version 4 | authors: [ Saukiya, Ray_Hughes, Lounode ] 5 | language: $language 6 | api-version: 1.13 7 | folia-supported: true # SNAPSHOT 8 | website: https://github.com/Saukiya/SX-Item/releases 9 | softdepend: 10 | - PlaceholderAPI 11 | - MythicMobs 12 | 13 | libraries: 14 | - org.openjdk.nashorn:nashorn-core:15.4 15 | 16 | commands: 17 | SxItem: 18 | aliases: [ sxi, si ] -------------------------------------------------------------------------------- /src/test/java/github/saukiya/expression/operator/StringOperator.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.expression.operator; 2 | 3 | import lombok.AllArgsConstructor; 4 | 5 | @AllArgsConstructor 6 | public class StringOperator implements Operator { 7 | 8 | String value; 9 | 10 | public String evaluate() { 11 | return value; 12 | } 13 | 14 | public static StringOperator Convert(Operator operator) { 15 | // TODO 16 | return null; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/github/saukiya/expression/operator/number/NumberParseOperator.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.expression.operator.number; 2 | 3 | import github.saukiya.expression.operator.NumberOperator; 4 | import lombok.AllArgsConstructor; 5 | 6 | @AllArgsConstructor 7 | public class NumberParseOperator implements NumberOperator { 8 | 9 | String value; 10 | 11 | @Override 12 | public double evaluate() { 13 | return Integer.parseInt(value); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module-Deprecated-v3/src/main/java/github/saukiya/sxitem/util/LogUtil.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.util; 2 | 3 | import org.bukkit.plugin.java.JavaPlugin; 4 | 5 | /** 6 | * @see github.saukiya.tools.util.LogUtil 7 | * @deprecated 8 | */ 9 | public class LogUtil extends github.saukiya.tools.util.LogUtil { 10 | 11 | @Deprecated 12 | public LogUtil(JavaPlugin plugin) { 13 | setup(plugin); 14 | } 15 | 16 | public void onDisable() { 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/resources/Localization/en/Scripts/Global/Global.js: -------------------------------------------------------------------------------- 1 | /*global Bukkit, Arrays, SXItem, listener*/ 2 | /** 3 | * Common development documents 4 | * Bukkit - https://hub.spigotmc.org/javadocs/bukkit/ 5 | * Java8 - https://docs.oracle.com/javase/8/docs/api/ 6 | */ 7 | // You can set your global variables here to use in addition to the global folder in 8 | /** 9 | * @see [ArrayList](https://docs.oracle.com/javase/8/docs/api/) 10 | */ 11 | ArrayList = Java.type("java.util.ArrayList") -------------------------------------------------------------------------------- /src/test/java/github/saukiya/expression/operator/number/AdditionOperator.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.expression.operator.number; 2 | 3 | import github.saukiya.expression.operator.NumberOperator; 4 | import lombok.AllArgsConstructor; 5 | 6 | @AllArgsConstructor 7 | public class AdditionOperator implements NumberOperator { 8 | 9 | private NumberOperator left; 10 | private NumberOperator right; 11 | 12 | @Override 13 | public double evaluate() { 14 | return left.evaluate() + right.evaluate(); 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/resources/Localization/de/Scripts/Global/Global.js: -------------------------------------------------------------------------------- 1 | /*global Bukkit, Arrays, SXItem, listener*/ 2 | /** 3 | * Häufig verwendete Entwicklungsdokumentation 4 | * Bukkit - https://bukkit.windit.net/javadoc/ 5 | * Java8 - https://www.matools.com/api/java8 6 | */ 7 | // Hier kannst du deine globalen Variablen festlegen, die für Skriptklassen außerhalb des Global-Ordners verfügbar sind. 8 | /** 9 | * @see [ArrayList](https://www.matools.com/doc/java8/java/util/ArrayList.html) 10 | */ 11 | ArrayList = Java.type("java.util.ArrayList") -------------------------------------------------------------------------------- /src/test/java/github/saukiya/expression/operator/number/SubtractionOperator.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.expression.operator.number; 2 | 3 | import github.saukiya.expression.operator.NumberOperator; 4 | import lombok.AllArgsConstructor; 5 | 6 | @AllArgsConstructor 7 | public class SubtractionOperator implements NumberOperator { 8 | 9 | private NumberOperator left; 10 | private NumberOperator right; 11 | 12 | @Override 13 | public double evaluate() { 14 | return left.evaluate() - right.evaluate(); 15 | } 16 | } -------------------------------------------------------------------------------- /src/test/java/github/saukiya/expression/operator/number/MultiplicationOperator.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.expression.operator.number; 2 | 3 | import github.saukiya.expression.operator.NumberOperator; 4 | import lombok.AllArgsConstructor; 5 | 6 | @AllArgsConstructor 7 | public class MultiplicationOperator implements NumberOperator { 8 | 9 | private NumberOperator left; 10 | private NumberOperator right; 11 | 12 | @Override 13 | public double evaluate() { 14 | return left.evaluate() * right.evaluate(); 15 | } 16 | } -------------------------------------------------------------------------------- /src/test/java/github/saukiya/expression/operator/ConditionOperator.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.expression.operator; 2 | 3 | /** 4 | * 条件操作符 5 | * LessThanOrEqualOperator: A <= B 6 | * EqualOperator: A == B 7 | * GreaterThanOrEqualOperator: A >= B 8 | * NotEqualOperator: A != B 9 | * LessThanOperator: A < B 10 | * GreaterThanOperator: A > B 11 | * LogicalAndOperator: A && B 12 | * LogicalOrOperator: A || B 13 | * LogicalNotOperator: !A 14 | */ 15 | public interface ConditionOperator extends Operator { 16 | boolean evaluate(); 17 | } 18 | -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/base/Tuple.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.base; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.ToString; 5 | 6 | @ToString 7 | @AllArgsConstructor 8 | public class Tuple { 9 | private final A a; 10 | private final B b; 11 | 12 | public A a() { 13 | return this.a; 14 | } 15 | 16 | public B b() { 17 | return this.b; 18 | } 19 | 20 | public static Tuple of(A var0, B var1) { 21 | return new Tuple<>(var0, var1); 22 | } 23 | } -------------------------------------------------------------------------------- /Module-Deprecated-v3/src/main/java/github/saukiya/sxitem/util/LocalizationUtil.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.util; 2 | 3 | import org.bukkit.plugin.java.JavaPlugin; 4 | 5 | import java.io.IOException; 6 | import java.net.URISyntaxException; 7 | 8 | /** 9 | * @see github.saukiya.tools.util.LocalizationUtil 10 | * @deprecated 11 | */ 12 | public class LocalizationUtil { 13 | 14 | @Deprecated 15 | public static void saveResource(JavaPlugin plugin) throws IOException, URISyntaxException { 16 | github.saukiya.tools.util.LocalizationUtil.saveResource(plugin); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nbt/TagNumber.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nbt; 2 | 3 | public abstract class TagNumber extends Number implements TagBase { 4 | 5 | @Override 6 | public int intValue() { 7 | return getValue().intValue(); 8 | } 9 | 10 | @Override 11 | public long longValue() { 12 | return getValue().longValue(); 13 | } 14 | 15 | @Override 16 | public float floatValue() { 17 | return getValue().floatValue(); 18 | } 19 | 20 | @Override 21 | public double doubleValue() { 22 | return getValue().doubleValue(); 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/expression/IExpression.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.expression; 2 | 3 | /** 4 | * 表达式接口 5 | */ 6 | public interface IExpression { 7 | 8 | /** 9 | * 替换字符串内容 10 | * 11 | * @param key 处理的key 12 | * @param handler 表达式处理器 13 | * @return 返回为空则删除此行 14 | */ 15 | String replace(String key, ExpressionHandler handler); 16 | 17 | /** 18 | * 验证字符串内容是否正常 19 | * 20 | * @param key 21 | * @param handler 22 | * @return 23 | */ 24 | default boolean validation(String key, ExpressionHandler handler) { 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/event/SXItemReloadEvent.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.event; 2 | 3 | import lombok.Getter; 4 | import org.bukkit.event.Event; 5 | import org.bukkit.event.HandlerList; 6 | 7 | /** 8 | * 插件重载事件 9 | */ 10 | public class SXItemReloadEvent extends Event { 11 | 12 | @Getter 13 | private static final SXItemReloadEvent inst = new SXItemReloadEvent(); 14 | 15 | private static final HandlerList handlers = new HandlerList(); 16 | 17 | public HandlerList getHandlers() { 18 | return handlers; 19 | } 20 | 21 | public static HandlerList getHandlerList() { 22 | return handlers; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/resources/Localization/zh/Config.yml: -------------------------------------------------------------------------------- 1 | # 日志等级: [OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL] 2 | LoggerLevel: "INFO" 3 | LoggerRecord: true 4 | # 小数保留精度,四舍五入 [2.3456 -> 2.35] 5 | DecimalPrecision: 2 6 | # 日期格式化 7 | TimeFormat: yyyy/MM/dd HH:mm 8 | # 引擎选择:默认采用JS引擎,该插件不自带引擎模块, 以下链接未经验证, 仅供参考 9 | # JS: https://github.com/eldoriarpg/NashornJS 10 | # Python: https://github.com/magicmq/PySpigot 11 | ScriptEngine: js 12 | # 如果要禁用引擎功能 13 | #ScriptEngine: ~ 14 | # 全局保护NBT列表 [自动更新时保护以下NBT不被更改] 15 | ProtectNBT: 16 | - "protect.data" 17 | # 给予物品时背包满了则掉落 [简单的拾取保护,只防护玩家的拾取] 18 | GiveOverflowDrop: true 19 | # 史诗怪物掉落的SX物品直接进入玩家背包 20 | MobDropToPlayerInventory: true -------------------------------------------------------------------------------- /src/test/java/github/saukiya/expression/operator/number/DivisionOperator.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.expression.operator.number; 2 | 3 | import github.saukiya.expression.operator.NumberOperator; 4 | import lombok.AllArgsConstructor; 5 | 6 | @AllArgsConstructor 7 | public class DivisionOperator implements NumberOperator { 8 | 9 | private NumberOperator left; 10 | private NumberOperator right; 11 | 12 | @Override 13 | public double evaluate() { 14 | double rightValue = right.evaluate(); 15 | if (rightValue == 0) { 16 | throw new ArithmeticException("Division by zero"); 17 | } 18 | return left.evaluate() / rightValue; 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/java/github/saukiya/expression/operator/number/ModulusOperator.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.expression.operator.number; 2 | 3 | import github.saukiya.expression.operator.NumberOperator; 4 | import lombok.AllArgsConstructor; 5 | 6 | @AllArgsConstructor 7 | public class ModulusOperator implements NumberOperator { 8 | 9 | private NumberOperator left; 10 | private NumberOperator right; 11 | 12 | @Override 13 | public double evaluate() { 14 | double rightValue = right.evaluate(); 15 | if (rightValue == 0) { 16 | throw new ArithmeticException("Modulus by zero"); 17 | } 18 | return left.evaluate() % rightValue; 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/java/github/saukiya/expression/operator/NumberOperator.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.expression.operator; 2 | 3 | /** 4 | * 数字操作符 5 | * AdditionOperator: A + B 6 | * DivisionOperator: A / B 7 | * DynamicOperator: Variable 8 | * ModulusOperator: A % B 9 | * MultiplicationOperator: A * B 10 | * SubtractionOperator: A - B 11 | * ValueOperator: 123 12 | */ 13 | public interface NumberOperator extends Operator { 14 | 15 | double evaluate(); 16 | 17 | static NumberOperator Convert(Operator operator) { 18 | // TOOD 来自其他的转换 19 | if (operator instanceof NumberOperator) { 20 | return (NumberOperator) operator; 21 | } 22 | return null; 23 | } 24 | } -------------------------------------------------------------------------------- /Module-Deprecated-v3/src/main/java/github/saukiya/sxitem/nbt/NBTTagWrapper.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.nbt; 2 | 3 | import github.saukiya.tools.nms.NbtUtil; 4 | import lombok.AllArgsConstructor; 5 | import lombok.experimental.Delegate; 6 | 7 | import javax.annotation.Nonnull; 8 | import javax.annotation.Nullable; 9 | 10 | /** 11 | * @see github.saukiya.tools.nms.NbtUtil.Wrapper 12 | * @deprecated 13 | */ 14 | @AllArgsConstructor 15 | public class NBTTagWrapper { 16 | 17 | @Deprecated 18 | @Delegate 19 | NbtUtil.Wrapper target; 20 | 21 | @Deprecated 22 | @Nullable 23 | public NBTTagWrapper getWrapper(@Nonnull String path) { 24 | return new NBTTagWrapper(target.getWrapper(path)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/expression/impl/UUIDExpression.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.expression.impl; 2 | 3 | import github.saukiya.sxitem.data.expression.ExpressionHandler; 4 | import github.saukiya.sxitem.data.expression.IExpression; 5 | 6 | import java.util.UUID; 7 | 8 | /** 9 | * {@code } 返回一串uuid 10 | *
{@code
11 |  *  "" - 随机生成UUID
12 |  *  "" - 按照格式生成UUID
13 |  * }
14 | */ 15 | public class UUIDExpression implements IExpression { 16 | 17 | @Override 18 | public String replace(String key, ExpressionHandler handler) { 19 | if (key.equals("random")) { 20 | return UUID.randomUUID().toString(); 21 | } 22 | return UUID.nameUUIDFromBytes(key.getBytes()).toString(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/github/saukiya/expression/operator/number/DynamicOperator.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.expression.operator.number; 2 | 3 | import github.saukiya.expression.operator.NumberOperator; 4 | import lombok.AllArgsConstructor; 5 | 6 | @AllArgsConstructor 7 | public class DynamicOperator implements NumberOperator { 8 | 9 | private String variable; 10 | 11 | @Override 12 | public double evaluate() { 13 | switch (variable) { 14 | case "AA": 15 | return 1; 16 | case "BB": 17 | return 2; 18 | case "CC": 19 | return 3; 20 | case "T1V2C32424": 21 | return 4; 22 | case "12B23": 23 | return 5; 24 | } 25 | System.out.println("????"); 26 | return 0; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/resources/Localization/en/Config.yml: -------------------------------------------------------------------------------- 1 | # Log Level: [OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL] 2 | LoggerLevel: "INFO" 3 | LoggerRecord: true 4 | # Decimal precision, rounding. [2.3456 -> 2.35] 5 | DecimalPrecision: 2 6 | # Date formatting 7 | TimeFormat: yyyy/MM/dd HH:mm 8 | # Engine selection: JS engine is used by default, this plugin does not come with an engine module, to disable it you can delete this line 9 | ScriptEngine: js 10 | # Global protection NBT list. [Protect the following NBT from being changed during auto-updates] 11 | ProtectNBT: 12 | - "protect.data" 13 | # If inventory is full when giving items, they will drop. [Simple pickup protection, only protects player's pickups] 14 | GiveOverflowDrop: true 15 | # SX-Items dropped by epic monsters go directly into player's inventory 16 | MobDropToPlayerInventory: true 17 | -------------------------------------------------------------------------------- /Module-Deprecated-v3/src/main/java/github/saukiya/sxitem/helper/PlaceholderHelper.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.helper; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.NoArgsConstructor; 5 | import org.bukkit.entity.Player; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @see github.saukiya.tools.helper.PlaceholderHelper 11 | * @deprecated 12 | */ 13 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 14 | public class PlaceholderHelper { 15 | 16 | @Deprecated 17 | public static List setPlaceholders(Player player, List list) { 18 | return github.saukiya.tools.helper.PlaceholderHelper.setPlaceholders(player, list); 19 | } 20 | 21 | @Deprecated 22 | public static String setPlaceholders(Player player, String text) { 23 | return github.saukiya.tools.helper.PlaceholderHelper.setPlaceholders(player, text); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nbt/TagBase.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nbt; 2 | 3 | import github.saukiya.tools.nms.ComponentUtil; 4 | 5 | import java.io.DataOutput; 6 | import java.io.IOException; 7 | 8 | public interface TagBase extends Cloneable { 9 | 10 | void write(DataOutput dataOutput) throws IOException; 11 | 12 | /** 13 | * 获取基础数据 14 | * 例如 List、Map、Array、byte、int 等 15 | * 16 | * @return 17 | */ 18 | T getValue(); 19 | 20 | TagType getTypeId(); 21 | 22 | /** 23 | * 将NBT以带制符表的方式显示出来 24 | * 无法显示带转义(\)的Json 25 | * 26 | * @return String 27 | */ 28 | default String toJsonString() { 29 | return ComponentUtil.getGson().toJson(getValue()); 30 | } 31 | 32 | @Deprecated 33 | static TagBase toTag(Object object) { 34 | return TagType.toTag(object); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/expression/impl/MaxExpression.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.expression.impl; 2 | 3 | import github.saukiya.sxitem.data.expression.ExpressionHandler; 4 | import github.saukiya.sxitem.data.expression.IExpression; 5 | 6 | /** 7 | * {@code } 获取最大值 8 | *
{@code
 9 |  *  "" - 从12.3/34.5/45.6中找出最大值: 45.6
10 |  * }
11 | */ 12 | public class MaxExpression implements IExpression { 13 | 14 | @Override 15 | public String replace(String key, ExpressionHandler handler) { 16 | String result = ""; 17 | double max = Double.MIN_VALUE; 18 | 19 | for (String part : key.split(":")) { 20 | double num = Double.parseDouble(part); 21 | if (num > max) { 22 | max = num; 23 | result = part; 24 | } 25 | } 26 | return result; 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/expression/impl/MinExpression.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.expression.impl; 2 | 3 | import github.saukiya.sxitem.data.expression.ExpressionHandler; 4 | import github.saukiya.sxitem.data.expression.IExpression; 5 | 6 | /** 7 | * {@code } 获取最小值 8 | *
{@code
 9 |  *  "" - 从12.3/34.5/45.6中找出最小值: 12.3
10 |  * }
11 | */ 12 | public class MinExpression implements IExpression { 13 | 14 | @Override 15 | public String replace(String key, ExpressionHandler handler) { 16 | String result = ""; 17 | double min = Double.MAX_VALUE; 18 | 19 | for (String part : key.split(":")) { 20 | double num = Double.parseDouble(part); 21 | if (num < min) { 22 | min = num; 23 | result = part; 24 | } 25 | } 26 | return result; 27 | } 28 | } -------------------------------------------------------------------------------- /src/test/java/github/saukiya/expression/operator/condition/LessThanOrEqualOperator.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.expression.operator.condition; 2 | 3 | import github.saukiya.expression.operator.ConditionOperator; 4 | import github.saukiya.expression.operator.NumberOperator; 5 | import github.saukiya.expression.operator.Operator; 6 | import lombok.AllArgsConstructor; 7 | 8 | /** 9 | * Range: String->Number 10 | * Format: A <= B 11 | */ 12 | @AllArgsConstructor 13 | public class LessThanOrEqualOperator implements ConditionOperator { 14 | 15 | NumberOperator left; 16 | NumberOperator right; 17 | 18 | public LessThanOrEqualOperator(Operator left, Operator right) { 19 | left = NumberOperator.Convert(left); 20 | right = NumberOperator.Convert(right); 21 | } 22 | 23 | @Override 24 | public boolean evaluate() { 25 | return left.evaluate() >= right.evaluate(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/expression/impl/DecimalExpression.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.expression.impl; 2 | 3 | import github.saukiya.sxitem.data.expression.ExpressionHandler; 4 | import github.saukiya.sxitem.data.expression.IExpression; 5 | import github.saukiya.sxitem.util.Util; 6 | 7 | /** 8 | * {@code } 得到一个随机小数 9 | *
10 |  * 特性: 支持负数, 不分顺序
11 |  * {@code
12 |  *  "" - 从1.5-2.5随机抽一个小数
13 |  *  "" - 从10-100随机抽一个小数(不分顺序)
14 |  * }
15 | */ 16 | public class DecimalExpression implements IExpression { 17 | 18 | @Override 19 | public String replace(String key, ExpressionHandler handler) { 20 | int index = key.indexOf('_'); 21 | if (index == -1) return key; 22 | double min = Double.parseDouble(key.substring(0, index)); 23 | double max = Double.parseDouble(key.substring(index + 1)); 24 | return Util.format(Util.random(min, max)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/expression/impl/IntExpression.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.expression.impl; 2 | 3 | import github.saukiya.sxitem.data.expression.ExpressionHandler; 4 | import github.saukiya.sxitem.data.expression.IExpression; 5 | import github.saukiya.sxitem.util.Util; 6 | 7 | /** 8 | * {@code } 得到一个随机整数 9 | *
10 |  * 特性: 支持负数, 不分顺序
11 |  * 别名: r
12 |  * {@code
13 |  *  "" - 从10-100随机抽一个整数
14 |  *  "" - 从10-100随机抽一个整数(不分顺序)
15 |  * }
16 | */ 17 | public class IntExpression implements IExpression { 18 | 19 | @Override 20 | public String replace(String key, ExpressionHandler handler) { 21 | int index = key.indexOf('_'); 22 | if (index == -1) return key; 23 | int min = Integer.parseInt(key.substring(0, index)); 24 | int max = Integer.parseInt(key.substring(index + 1)); 25 | return String.valueOf(Util.random(min, max)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/expression/impl/StringRandomExpression.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.expression.impl; 2 | 3 | import github.saukiya.sxitem.data.expression.ExpressionHandler; 4 | import github.saukiya.sxitem.data.expression.IExpression; 5 | import github.saukiya.sxitem.util.Util; 6 | import github.saukiya.tools.helper.PlaceholderHelper; 7 | 8 | /** 9 | * {@code } 获取一个随机文本 10 | *
{@code
11 |  *  "" - 从key集合中随机抽取一个值
12 |  *  "" - 从AAA/BBB/CCC中随机抽取一个值
13 |  * }
14 | */ 15 | public class StringRandomExpression implements IExpression { 16 | 17 | @Override 18 | public String replace(String key, ExpressionHandler handler) { 19 | if (key.indexOf(':') >= 0) { 20 | return PlaceholderHelper.setPlaceholders(handler.getPlayer(), Util.random(key.split(":"))); 21 | } 22 | return PlaceholderHelper.setPlaceholders(handler.getPlayer(), handler.random(key)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Module-Deprecated-v3/src/main/java/github/saukiya/sxitem/command/SubCommand.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.command; 2 | 3 | import org.bukkit.command.CommandSender; 4 | 5 | import java.util.Arrays; 6 | 7 | /** 8 | * @see github.saukiya.tools.command.SubCommand 9 | * @deprecated 10 | */ 11 | public abstract class SubCommand extends github.saukiya.tools.command.SubCommand { 12 | 13 | @Deprecated 14 | public SubCommand(String cmd, int priority) { 15 | super(cmd, priority); 16 | } 17 | 18 | @Deprecated 19 | protected final void setType(SenderType... types) { 20 | setType(Arrays.stream(types).map(senderType -> github.saukiya.tools.command.SenderType.valueOf(senderType.name())).toArray(github.saukiya.tools.command.SenderType[]::new)); 21 | } 22 | 23 | @Deprecated 24 | public boolean isUse(CommandSender sender, SenderType type) { 25 | return super.isUse(sender, github.saukiya.tools.command.SenderType.valueOf(type.name())); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/resources/Localization/zh/Message.yml: -------------------------------------------------------------------------------- 1 | GIVE: 2 | NO_ITEM: '&8[SX-Item] &c物品不存在' 3 | GIVE_ITEM: '&8[SX-Item] &c给予 &6{0} &a{1}&c 个 &6{2}&c 物品' 4 | GIVE_ITEM_ERROR: '&8[&4SX-Item&8] &4背包已满, 导致 &6{0}&4 物品获取失败' 5 | SAVE: 6 | HAS_ITEM: '&8[SX-Item] &a物品编号 &6{0} &a已经存在' 7 | SAVE_ITEM: '&8[SX-Item] &a物品编号 &6{0} &a成功保存' 8 | SAVE_NO_TYPE: '&8[SX-Item] &c物品编号 &4{0} &c保存失败, 请检查该生成器是否存在, 并支持保存物品' 9 | SAVE_ITEM_ERROR: '&8[SX-Item] &c物品 &4{0} &c保存出现不可预知的错误' 10 | NBT: 11 | CLICK_COPY: '点击复制' 12 | SCRIPT: 13 | NULL_FILE: '找不到该脚本文件: {0}' 14 | INVOKE_RESULT: '脚本调用回调: {0}, 回调类型: {1}' 15 | INVOKE_FAIL: '脚本调用失败: {0}' 16 | ADMIN: 17 | NO_PERMISSION_CMD: '&8[&c错误&8] &c你没有权限执行此指令' 18 | NO_CMD: '&8[&c错误&8] &c未找到此子指令' 19 | NO_FORMAT: '&8[&c错误&8] &c格式错误' 20 | NO_ONLINE: '&8[&c错误&8] &c玩家不在线或玩家不存在' 21 | PLUGIN_RELOAD: '&8[SX-Item] §c插件已重载' 22 | COMMAND: 23 | GIVE: 给予玩家物品 24 | SAVE: 保存当前的物品到配置文件 25 | NBT: 查看和修改物品NBT数据 26 | COMPONENT: 查看和修改物品组件数据 27 | SCRIPT: 调用脚本函数 28 | RELOAD: 重新加载这个插件的配置 -------------------------------------------------------------------------------- /Module-Deprecated-v3/src/main/java/github/saukiya/sxitem/util/MessageUtil.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.util; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Getter; 6 | import lombok.experimental.Delegate; 7 | import org.bukkit.command.CommandSender; 8 | 9 | /** 10 | * @see github.saukiya.tools.nms.MessageUtil 11 | * @deprecated 12 | */ 13 | @AllArgsConstructor(access = AccessLevel.PRIVATE) 14 | public final class MessageUtil { 15 | 16 | @Deprecated 17 | @Getter 18 | private static final MessageUtil inst = new MessageUtil(github.saukiya.tools.nms.MessageUtil.getInst()); 19 | 20 | @Delegate 21 | private github.saukiya.tools.nms.MessageUtil target; 22 | 23 | @Deprecated 24 | public final ComponentBuilder componentBuilder() { 25 | return new ComponentBuilder(builder()); 26 | } 27 | 28 | @Deprecated 29 | public static void send(CommandSender sender, String msg) { 30 | github.saukiya.tools.nms.MessageUtil.send(sender, msg); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nbt/TagListBase.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nbt; 2 | 3 | import lombok.NoArgsConstructor; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Collection; 7 | 8 | @NoArgsConstructor 9 | public abstract class TagListBase extends ArrayList implements TagBase { 10 | 11 | public TagListBase(Collection collection) { 12 | super(collection); 13 | } 14 | 15 | public String getToStringPrefix() { 16 | return ""; 17 | } 18 | 19 | public String getToStringSuffix() { 20 | return ""; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | StringBuilder sb = new StringBuilder(); 26 | sb.append("[").append(getToStringPrefix()); 27 | for (int i = 0; i < this.size(); i++) { 28 | if (i != 0) { 29 | sb.append(','); 30 | } 31 | sb.append(this.get(i)).append(getToStringSuffix()); 32 | } 33 | sb.append(']'); 34 | return sb.toString(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/resources/Localization/de/Config.yml: -------------------------------------------------------------------------------- 1 | # Protokollstufe: [OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL] 2 | LoggerLevel: "INFO" 3 | LoggerRecord: true 4 | # Dezimalgenauigkeit, Rundung. [2.3456 -> 2.35] 5 | DecimalPrecision: 2 6 | # Datumsformatierung 7 | TimeFormat: yyyy/MM/dd HH:mm 8 | # Engine-Auswahl: Standardmäßig wird die JS-Engine verwendet. Dieses Plugin enthält kein Engine-Modul. 9 | # Die folgenden Links wurden nicht verifiziert und dienen nur als Referenz. 10 | # JS: https://github.com/eldoriarpg/NashornJS 11 | # Python: https://github.com/magicmq/PySpigot 12 | ScriptEngine: js 13 | # Um die Engine-Funktion zu deaktivieren... 14 | #ScriptEngine: ~ 15 | # Globale geschützte NBT-Liste. [Schützt die folgenden NBTs vor Änderungen bei automatischen Updates] 16 | ProtectNBT: 17 | - "protect.data" 18 | # Wenn das Inventar voll ist, werden die Gegenstände beim Geben fallen gelassen. [mit einfachem Aufsammelschutz] 19 | GiveOverflowDrop: true 20 | # MythicMobs-Drops (SX-Item) gehen direkt in das Spielerinventar. 21 | MobDropToPlayerInventory: true -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/base/EmptyMap.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.base; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.AllArgsConstructor; 5 | 6 | import java.util.AbstractMap; 7 | import java.util.Collections; 8 | import java.util.Set; 9 | 10 | /** 11 | * 永远的空map, 12 | *
13 |  * 与 {@link Collections#emptyMap()} 功能类似
14 |  * 但是调用 put 时不会产生 {@link UnsupportedOperationException}
15 |  * {@code
16 |  *  return EmptyMap.emptyMap();
17 |  * }
18 |  * 
19 | */ 20 | @AllArgsConstructor(access = AccessLevel.PRIVATE) 21 | public class EmptyMap extends AbstractMap { 22 | 23 | private static final EmptyMap EMPTY = new EmptyMap<>(); 24 | 25 | @Override 26 | public Set> entrySet() { 27 | return Collections.emptySet(); 28 | } 29 | 30 | @Override 31 | public V put(K key, V value) { 32 | return null; 33 | } 34 | 35 | @SuppressWarnings("unchecked") 36 | public static EmptyMap emptyMap() { 37 | return (EmptyMap) EMPTY; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/item/impl/GeneratorReMaterial.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.item.impl; 2 | 3 | import github.saukiya.sxitem.data.item.IGenerator; 4 | import github.saukiya.tools.util.ReMaterial; 5 | import org.bukkit.configuration.MemoryConfiguration; 6 | import org.bukkit.entity.Player; 7 | import org.bukkit.inventory.ItemStack; 8 | 9 | /** 10 | * 基础物品生成器(数字ID/英文ID) 11 | */ 12 | public class GeneratorReMaterial extends IGenerator { 13 | 14 | public GeneratorReMaterial() { 15 | super("ReMaterial", new MemoryConfiguration(), "ReMaterial"); 16 | } 17 | 18 | @Override 19 | public String getType() { 20 | return "ReMaterial"; 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return "ReMaterial"; 26 | } 27 | 28 | @Override 29 | protected ItemStack getItem(Player player, Object... args) { 30 | if (args.length > 0 && args[0] instanceof String) { 31 | return ReMaterial.getItem((String) args[0]); 32 | } 33 | return null; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/event/SXItemSpawnEvent.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.event; 2 | 3 | import github.saukiya.sxitem.data.item.IGenerator; 4 | import lombok.AllArgsConstructor; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | import org.bukkit.entity.Player; 9 | import org.bukkit.event.Event; 10 | import org.bukkit.event.HandlerList; 11 | import org.bukkit.inventory.ItemStack; 12 | import org.bukkit.plugin.java.JavaPlugin; 13 | 14 | /** 15 | * 物品生成事件 16 | */ 17 | @Getter 18 | @Setter 19 | @AllArgsConstructor 20 | @EqualsAndHashCode(callSuper = true) 21 | public class SXItemSpawnEvent extends Event { 22 | 23 | private static final HandlerList handlers = new HandlerList(); 24 | 25 | private final JavaPlugin plugin; 26 | 27 | private final Player player; 28 | 29 | private final IGenerator ig; 30 | 31 | private ItemStack item; 32 | 33 | public HandlerList getHandlers() { 34 | return handlers; 35 | } 36 | 37 | public static HandlerList getHandlerList() { 38 | return handlers; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/expression/impl/CalculatorExpression.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.expression.impl; 2 | 3 | import github.saukiya.sxitem.data.expression.ExpressionHandler; 4 | import github.saukiya.sxitem.data.expression.IExpression; 5 | import github.saukiya.sxitem.util.Util; 6 | import github.saukiya.tools.util.CalculatorUtil; 7 | 8 | /** 9 | * {@code } - 计算表达式 10 | *
{@code
11 |  *  "" - 计算 100 / 3 并返回小数(33.33)
12 |  *  ">" - 计算 5 * (0.8~1.2) 并返回int整数(4/5/6)
13 |  *  " * >" - 结合其他随机模式, 套公式返回小数
14 |  * }
15 | */ 16 | public class CalculatorExpression implements IExpression { 17 | 18 | @Override 19 | public String replace(String key, ExpressionHandler handler) { 20 | if (key.startsWith("int")) { 21 | double result = CalculatorUtil.calculator(key.substring(3)); 22 | return String.valueOf(Math.round(result)); 23 | } 24 | double result = CalculatorUtil.calculator(key); 25 | return Util.format(result); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/event/SXItemMythicMobsGiveToInventoryEvent.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.event; 2 | 3 | import github.saukiya.sxitem.data.item.IGenerator; 4 | import lombok.Getter; 5 | import lombok.RequiredArgsConstructor; 6 | import lombok.Setter; 7 | import org.bukkit.entity.Player; 8 | import org.bukkit.event.Event; 9 | import org.bukkit.event.HandlerList; 10 | import org.bukkit.inventory.ItemStack; 11 | 12 | /** 13 | * 物品放入背包事件 14 | * 15 | * @author Ray_Hughes 16 | */ 17 | @Getter 18 | @Setter 19 | @RequiredArgsConstructor 20 | public class SXItemMythicMobsGiveToInventoryEvent extends Event { 21 | 22 | private static final HandlerList handlers = new HandlerList(); 23 | 24 | private final IGenerator item; 25 | 26 | private final Player player; 27 | 28 | private final String mobType; 29 | 30 | @Getter 31 | private final ItemStack itemStack; 32 | 33 | private boolean cancelled; 34 | 35 | public HandlerList getHandlers() { 36 | return handlers; 37 | } 38 | 39 | public static HandlerList getHandlerList() { 40 | return handlers; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Module-Deprecated-v3/src/main/java/github/saukiya/sxitem/nbt/NBTItemWrapper.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.nbt; 2 | 3 | import github.saukiya.tools.nms.NbtUtil; 4 | import lombok.AllArgsConstructor; 5 | 6 | /** 7 | * @see github.saukiya.tools.nms.NbtUtil.ItemWrapper 8 | * @deprecated 9 | */ 10 | public class NBTItemWrapper extends NBTTagWrapper { 11 | 12 | NbtUtil.ItemWrapper target; 13 | 14 | @Deprecated 15 | public NBTItemWrapper(NbtUtil.ItemWrapper target) { 16 | super(target); 17 | this.target = target; 18 | } 19 | 20 | @Deprecated 21 | public void save() { 22 | target.save(); 23 | } 24 | 25 | @Deprecated 26 | public Builder builder() { 27 | return new Builder(); 28 | } 29 | 30 | @Deprecated 31 | @AllArgsConstructor 32 | public class Builder { 33 | 34 | @Deprecated 35 | public Builder set(String key, Object value) { 36 | target.set(key, value); 37 | return this; 38 | } 39 | 40 | @Deprecated 41 | public void save() { 42 | target.save(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/random/nodes/MultipleNode.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.random.nodes; 2 | 3 | import github.saukiya.sxitem.SXItem; 4 | import github.saukiya.sxitem.data.random.INode; 5 | import github.saukiya.tools.base.Tuple; 6 | import lombok.ToString; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | @ToString 12 | public class MultipleNode implements INode { 13 | 14 | final List> list = new ArrayList<>(); 15 | private double maximum; 16 | 17 | public void add(Double weight, String value) { 18 | list.add(new Tuple<>(maximum += weight, value)); 19 | } 20 | 21 | public boolean isEmpty() { 22 | return list.isEmpty(); 23 | } 24 | 25 | @Override 26 | public String get() { 27 | double value = SXItem.getRandom().nextDouble() * maximum; 28 | int last = list.size() - 1; 29 | for (int i = 0; i < last; i++) { 30 | Tuple tuple = list.get(i); 31 | if (value < tuple.a()) return tuple.b(); 32 | } 33 | return list.get(last).b(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/event/SXItemUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.event; 2 | 3 | import github.saukiya.sxitem.data.item.IGenerator; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import org.bukkit.entity.Player; 7 | import org.bukkit.event.Cancellable; 8 | import org.bukkit.event.HandlerList; 9 | import org.bukkit.inventory.ItemStack; 10 | import org.bukkit.plugin.java.JavaPlugin; 11 | 12 | /** 13 | * 物品更新事件 14 | */ 15 | @Getter 16 | @Setter 17 | public class SXItemUpdateEvent extends SXItemSpawnEvent implements Cancellable { 18 | 19 | private static final HandlerList handlers = new HandlerList(); 20 | 21 | private final ItemStack oldItem; 22 | 23 | private boolean cancelled; 24 | 25 | public SXItemUpdateEvent(JavaPlugin plugin, Player player, IGenerator ig, ItemStack item, ItemStack oldItem) { 26 | super(plugin, player, ig, item); 27 | this.oldItem = oldItem; 28 | } 29 | 30 | public HandlerList getHandlers() { 31 | return handlers; 32 | } 33 | 34 | public static HandlerList getHandlerList() { 35 | return handlers; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/util/Util.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.util; 2 | 3 | import java.util.List; 4 | import java.util.Random; 5 | 6 | /** 7 | * 通用工具类(不知道放哪了) 8 | */ 9 | public class Util { 10 | 11 | private static final Random random = new Random(); 12 | 13 | protected static double decimalPrecision = 100; 14 | 15 | public static String format(double value) { 16 | return String.valueOf(Math.round(value * decimalPrecision) / decimalPrecision); 17 | } 18 | 19 | public static T random(T[] array) { 20 | return array[random.nextInt(array.length)]; 21 | } 22 | 23 | public static T random(List list) { 24 | return list.get(random.nextInt(list.size())); 25 | } 26 | 27 | public static int random(int v1, int v2) { 28 | return random.nextInt(1 + Math.abs(v2 - v1)) + Math.min(v1, v2); 29 | } 30 | 31 | public static double random(double v1, double v2) { 32 | return random.nextDouble() * (v2 - v1) + v1; 33 | } 34 | 35 | public static float random(float v1, float v2) { 36 | return random.nextFloat() * (v2 - v1) + v1; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'SX-Item' 2 | include 'Module-Base' 3 | include 'Module-Deprecated-v3' 4 | if (System.env.JITPACK) return; 5 | includeModule 'Module-NMS:V1_8_R3' 6 | includeModule 'Module-NMS:V1_11_R1' 7 | includeModule 'Module-NMS:V1_12_R1' 8 | includeModule 'Module-NMS:V1_13_R2' 9 | includeModule 'Module-NMS:V1_14_R1' 10 | includeModule 'Module-NMS:V1_15_R1' 11 | includeModule 'Module-NMS:V1_16_R3' 12 | includeModule 'Module-NMS:V1_17_R1' 13 | includeModule 'Module-NMS:V1_18_R2' 14 | includeModule 'Module-NMS:V1_19_R1' 15 | includeModule 'Module-NMS:V1_19_R3' 16 | includeModule 'Module-NMS:V1_20_R1' 17 | includeModule 'Module-NMS:V1_20_R2' 18 | includeModule 'Module-NMS:V1_20_R3' 19 | includeModule 'Module-NMS:V1_20_R4' 20 | includeModule 'Module-NMS:V1_21_R1' 21 | includeModule 'Module-NMS:V1_21_R2' 22 | includeModule 'Module-NMS:V1_21_R3' 23 | includeModule 'Module-NMS:V1_21_R4' 24 | includeModule 'Module-NMS:V1_21_R5' 25 | includeModule 'Module-NMS:V1_21_R6' 26 | includeModule 'Module-NMS:V1_21_R7' 27 | 28 | def includeModule(String moduleName) { 29 | if (!file(moduleName.replace(':', "/")).exists()) return 30 | include moduleName 31 | } -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nbt/TagEnd.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nbt; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.DataInput; 8 | import java.io.DataOutput; 9 | 10 | @NoArgsConstructor(access = AccessLevel.PACKAGE) 11 | public class TagEnd implements TagBase { 12 | 13 | @Getter 14 | private static final TagEnd inst = new TagEnd(); 15 | protected static final TagType.Method typeMethod = new TagType.Method() { 16 | @Override 17 | public TagEnd readTagBase(DataInput dataInput, int depth) { 18 | return inst; 19 | } 20 | 21 | @Override 22 | public TagEnd toTag(Object object) { 23 | return null; 24 | } 25 | }; 26 | 27 | @Override 28 | public void write(DataOutput dataOutput) { 29 | } 30 | 31 | @Override 32 | public Object getValue() { 33 | return null; 34 | } 35 | 36 | @Override 37 | public TagType getTypeId() { 38 | return TagType.END; 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return "END"; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Module-Deprecated-v3/src/main/java/github/saukiya/sxitem/util/NbtUtil.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.util; 2 | 3 | import github.saukiya.sxitem.nbt.NBTItemWrapper; 4 | import github.saukiya.sxitem.nbt.NBTTagWrapper; 5 | import github.saukiya.tools.nms.NMS; 6 | import lombok.AccessLevel; 7 | import lombok.AllArgsConstructor; 8 | import lombok.Getter; 9 | import lombok.experimental.Delegate; 10 | import org.bukkit.inventory.ItemStack; 11 | 12 | /** 13 | * @see github.saukiya.tools.nms.NbtUtil 14 | * @deprecated 15 | */ 16 | @AllArgsConstructor(access = AccessLevel.PRIVATE) 17 | public class NbtUtil { 18 | 19 | @Getter 20 | private final static NbtUtil inst = new NbtUtil(NMS.getInst(github.saukiya.tools.nms.NbtUtil.class)); 21 | 22 | @Delegate 23 | private github.saukiya.tools.nms.NbtUtil target; 24 | 25 | 26 | @Deprecated 27 | public NBTItemWrapper getItemTagWrapper(ItemStack itemStack) { 28 | return new NBTItemWrapper(target.getItemTagWrapper(itemStack)); 29 | } 30 | 31 | @Deprecated 32 | public NBTTagWrapper createTagWrapper(Object nbtTagCompound) { 33 | return new NBTTagWrapper(target.createTagWrapper(nbtTagCompound)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Module-NMS/V1_16_R3/src/main/java/github/saukiya/tools/nms/MessageUtil_v1_16_R3.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nms; 2 | 3 | import net.md_5.bungee.api.chat.HoverEvent; 4 | import net.md_5.bungee.api.chat.ItemTag; 5 | import net.md_5.bungee.api.chat.hover.content.Item; 6 | import net.md_5.bungee.api.chat.hover.content.Text; 7 | import org.bukkit.inventory.ItemStack; 8 | 9 | public class MessageUtil_v1_16_R3 extends MessageUtil { 10 | 11 | @Override 12 | public Builder builder() { 13 | return new BuilderImpl(); 14 | } 15 | 16 | static class BuilderImpl extends Builder { 17 | 18 | @Override 19 | public Builder show(String text) { 20 | current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("§7" + text))); 21 | return this; 22 | } 23 | 24 | @Override 25 | public Builder show(ItemStack item) { 26 | Object nbt = NbtUtil.getInst().getItemNBT(item); 27 | current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new Item(item.getType().getKey().getKey(), item.getAmount(), ItemTag.ofNbt(String.valueOf(nbt))))); 28 | return this; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/expression/ExpressionManager.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.expression; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * 表达式管理器 8 | */ 9 | public class ExpressionManager { 10 | 11 | protected static final Map RANDOMS = new HashMap<>(); 12 | 13 | /** 14 | * 注册新的表达式类型 15 | * 16 | * @param expression 表达式 17 | * @param types 类型 18 | */ 19 | public static void register(IExpression expression, char... types) { 20 | for (char type : types) { 21 | RANDOMS.put(String.valueOf(type), expression); 22 | } 23 | } 24 | 25 | /** 26 | * 注册新的表达式类型 27 | * 28 | * @param expression 表达式 29 | * @param types 类型 30 | */ 31 | public static void register(IExpression expression, String... types) { 32 | for (String type : types) { 33 | RANDOMS.put(type, expression); 34 | } 35 | } 36 | 37 | /** 38 | * 获取随机类型 39 | * 40 | * @param type 类型 41 | * @return 随机处理 42 | */ 43 | public static IExpression get(String type) { 44 | return RANDOMS.get(type); 45 | } 46 | } -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/base/CharStack.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.base; 2 | 3 | import java.util.EmptyStackException; 4 | import java.util.stream.Collectors; 5 | import java.util.stream.IntStream; 6 | 7 | /** 8 | * 基本类型char栈, 目的是减少拆装箱 9 | */ 10 | public class CharStack { 11 | 12 | char[] stack = new char[8]; 13 | int top = -1; 14 | 15 | public void push(char value) { 16 | if (++top == stack.length) resize(); 17 | stack[top] = value; 18 | } 19 | 20 | public char pop() { 21 | if (top == -1) throw new EmptyStackException(); 22 | return stack[top--]; 23 | } 24 | 25 | public char peek() { 26 | if (top == -1) throw new EmptyStackException(); 27 | return stack[top]; 28 | } 29 | 30 | public int size() { 31 | return top + 1; 32 | } 33 | 34 | private void resize() { 35 | char[] newStack = new char[stack.length * 2]; 36 | System.arraycopy(stack, 0, newStack, 0, stack.length); 37 | stack = newStack; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return "[" + IntStream.range(0, size()).mapToObj(i -> String.valueOf(stack[i])).collect(Collectors.joining(", ")) + "]"; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Module-Deprecated-v3/src/main/java/github/saukiya/sxitem/util/NMS.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.util; 2 | 3 | /** 4 | * @see github.saukiya.tools.nms.NMS 5 | * @deprecated 6 | */ 7 | public interface NMS extends github.saukiya.tools.nms.NMS { 8 | 9 | @Deprecated 10 | static T getInst(Class target, String... versions) { 11 | return github.saukiya.tools.nms.NMS.getInst(target, versions); 12 | } 13 | 14 | @Deprecated 15 | static T privateField(Object target, String fieldName) { 16 | return github.saukiya.tools.nms.NMS.privateField(target, fieldName); 17 | } 18 | 19 | @Deprecated 20 | static T privateInstance(Class target, Object... args) { 21 | return github.saukiya.tools.nms.NMS.privateInstance(target, args); 22 | } 23 | 24 | @Deprecated 25 | static int compareTo(String version) { 26 | return github.saukiya.tools.nms.NMS.compareTo(version); 27 | } 28 | 29 | @Deprecated 30 | static int compareTo(int... version) { 31 | return github.saukiya.tools.nms.NMS.compareTo(version); 32 | } 33 | 34 | @Deprecated 35 | static boolean hasClass(String className) { 36 | return github.saukiya.tools.nms.NMS.hasClass(className); 37 | } 38 | } -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nbt/TagLong.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nbt; 2 | 3 | import java.io.DataInput; 4 | import java.io.DataOutput; 5 | import java.io.IOException; 6 | 7 | public class TagLong extends TagNumber { 8 | 9 | protected static final TagType.Method typeMethod = new TagType.Method() { 10 | @Override 11 | public TagLong readTagBase(DataInput dataInput, int depth) throws IOException { 12 | return new TagLong(dataInput.readLong()); 13 | } 14 | 15 | @Override 16 | public TagLong toTag(Object object) { 17 | return object instanceof Long ? new TagLong((Long) object) : null; 18 | } 19 | }; 20 | 21 | private final long value; 22 | 23 | public TagLong(long value) { 24 | this.value = value; 25 | } 26 | 27 | @Override 28 | public void write(DataOutput dataOutput) throws IOException { 29 | dataOutput.writeLong(value); 30 | } 31 | 32 | @Override 33 | public Long getValue() { 34 | return value; 35 | } 36 | 37 | @Override 38 | public TagType getTypeId() { 39 | return TagType.LONG; 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | return getValue() + "L"; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nbt/TagInt.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nbt; 2 | 3 | import java.io.DataInput; 4 | import java.io.DataOutput; 5 | import java.io.IOException; 6 | 7 | public class TagInt extends TagNumber { 8 | 9 | protected static final TagType.Method typeMethod = new TagType.Method() { 10 | @Override 11 | public TagInt readTagBase(DataInput dataInput, int depth) throws IOException { 12 | return new TagInt(dataInput.readInt()); 13 | } 14 | 15 | @Override 16 | public TagInt toTag(Object object) { 17 | return object instanceof Integer ? new TagInt((Integer) object) : null; 18 | } 19 | }; 20 | 21 | private final int value; 22 | 23 | public TagInt(int value) { 24 | this.value = value; 25 | } 26 | 27 | @Override 28 | public void write(DataOutput dataOutput) throws IOException { 29 | dataOutput.writeInt(value); 30 | } 31 | 32 | @Override 33 | public Integer getValue() { 34 | return value; 35 | } 36 | 37 | @Override 38 | public TagType getTypeId() { 39 | return TagType.INT; 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | return String.valueOf(getValue()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nbt/TagFloat.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nbt; 2 | 3 | import java.io.DataInput; 4 | import java.io.DataOutput; 5 | import java.io.IOException; 6 | 7 | public class TagFloat extends TagNumber { 8 | 9 | protected static final TagType.Method typeMethod = new TagType.Method() { 10 | @Override 11 | public TagFloat readTagBase(DataInput dataInput, int depth) throws IOException { 12 | return new TagFloat(dataInput.readFloat()); 13 | } 14 | 15 | @Override 16 | public TagFloat toTag(Object object) { 17 | return object instanceof Float ? new TagFloat((Float) object) : null; 18 | } 19 | }; 20 | 21 | private final float value; 22 | 23 | public TagFloat(float value) { 24 | this.value = value; 25 | } 26 | 27 | @Override 28 | public void write(DataOutput dataOutput) throws IOException { 29 | dataOutput.writeFloat(value); 30 | } 31 | 32 | @Override 33 | public Float getValue() { 34 | return value; 35 | } 36 | 37 | @Override 38 | public TagType getTypeId() { 39 | return TagType.FLOAT; 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | return getValue() + "f"; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nbt/TagShort.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nbt; 2 | 3 | import java.io.DataInput; 4 | import java.io.DataOutput; 5 | import java.io.IOException; 6 | 7 | public class TagShort extends TagNumber { 8 | 9 | protected static final TagType.Method typeMethod = new TagType.Method() { 10 | @Override 11 | public TagShort readTagBase(DataInput dataInput, int depth) throws IOException { 12 | return new TagShort(dataInput.readShort()); 13 | } 14 | 15 | @Override 16 | public TagShort toTag(Object object) { 17 | return object instanceof Short ? new TagShort((Short) object) : null; 18 | } 19 | }; 20 | 21 | private final short value; 22 | 23 | public TagShort(short value) { 24 | this.value = value; 25 | } 26 | 27 | @Override 28 | public void write(DataOutput dataOutput) throws IOException { 29 | dataOutput.writeShort(value); 30 | } 31 | 32 | @Override 33 | public Short getValue() { 34 | return value; 35 | } 36 | 37 | @Override 38 | public TagType getTypeId() { 39 | return TagType.SHORT; 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | return getValue() + "s"; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nbt/TagDouble.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nbt; 2 | 3 | import java.io.DataInput; 4 | import java.io.DataOutput; 5 | import java.io.IOException; 6 | 7 | public class TagDouble extends TagNumber { 8 | 9 | protected static final TagType.Method typeMethod = new TagType.Method() { 10 | @Override 11 | public TagDouble readTagBase(DataInput dataInput, int depth) throws IOException { 12 | return new TagDouble(dataInput.readDouble()); 13 | } 14 | 15 | @Override 16 | public TagDouble toTag(Object object) { 17 | return object instanceof Double ? new TagDouble((Double) object) : null; 18 | } 19 | }; 20 | 21 | private final double value; 22 | 23 | public TagDouble(double value) { 24 | this.value = value; 25 | } 26 | 27 | @Override 28 | public void write(DataOutput dataOutput) throws IOException { 29 | dataOutput.writeDouble(value); 30 | } 31 | 32 | @Override 33 | public Double getValue() { 34 | return value; 35 | } 36 | 37 | @Override 38 | public TagType getTypeId() { 39 | return TagType.DOUBLE; 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | return getValue() + "d"; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nbt/TagString.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nbt; 2 | 3 | import java.io.DataInput; 4 | import java.io.DataOutput; 5 | import java.io.IOException; 6 | 7 | public class TagString implements TagBase { 8 | 9 | protected static final TagType.Method typeMethod = new TagType.Method() { 10 | @Override 11 | public TagString readTagBase(DataInput dataInput, int depth) throws IOException { 12 | return new TagString(dataInput.readUTF()); 13 | } 14 | 15 | @Override 16 | public TagString toTag(Object object) { 17 | return object instanceof String ? new TagString((String) object) : null; 18 | } 19 | }; 20 | 21 | private final String value; 22 | 23 | public TagString(String value) { 24 | this.value = value; 25 | } 26 | 27 | @Override 28 | public void write(DataOutput dataOutput) throws IOException { 29 | dataOutput.writeUTF(value); 30 | } 31 | 32 | @Override 33 | public String getValue() { 34 | return value; 35 | } 36 | 37 | @Override 38 | public TagType getTypeId() { 39 | return TagType.STRING; 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | return '"' + getValue() + '"'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/github/saukiya/retention/DeluxeMenusHelper.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.retention; 2 | 3 | public class DeluxeMenusHelper { 4 | 5 | public static void setup() { 6 | // val deluxeMenus = Bukkit.getPluginManager().getPlugin("DeluxeMenus"); 7 | // if (deluxeMenus == null) { 8 | // SXItem.getInst().getLogger().info("DeluxeMenusHelper Disable"); 9 | // return; 10 | // } 11 | // Map itemhook = NMS.privateField(deluxeMenus, "itemHooks"); 12 | // itemhook.put("sxitem", new SXItemHook()); 13 | // SXItem.getInst().getLogger().info("DeluxeMenusHelper Enabled"); 14 | } 15 | 16 | // private static class SXItemHook implements com.extendedclip.deluxemenus.hooks.ItemHook { 17 | // 18 | // @Override 19 | // public ItemStack getItem(String... args) { 20 | // SXItem.getInst().getLogger().info("Hook: " + Arrays.toString(args)); 21 | // val itemName = args.length > 0 ? args[0] : null; 22 | // val playerName = args.length > 1 ? args[1] : null; 23 | // if (args.length > 2) { 24 | // args = Arrays.copyOfRange(args, 2, args.length); 25 | // } 26 | // return SXItem.getItemManager().getItem(itemName, playerName, args); 27 | // } 28 | // } 29 | } 30 | -------------------------------------------------------------------------------- /Module-NMS/V1_13_R2/src/main/java/github/saukiya/tools/nms/MessageUtil_v1_13_R2.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nms; 2 | 3 | import lombok.val; 4 | import net.md_5.bungee.api.chat.BaseComponent; 5 | import net.md_5.bungee.api.chat.HoverEvent; 6 | import net.md_5.bungee.api.chat.TextComponent; 7 | import org.bukkit.inventory.ItemStack; 8 | 9 | public class MessageUtil_v1_13_R2 extends MessageUtil { 10 | 11 | @Override 12 | public Builder builder() { 13 | return new BuilderImpl(); 14 | } 15 | 16 | static class BuilderImpl extends Builder { 17 | 18 | @Override 19 | public Builder show(String text) { 20 | current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new BaseComponent[]{new TextComponent("§7" + text)})); 21 | return this; 22 | } 23 | 24 | @Override 25 | public Builder show(ItemStack item) { 26 | val wrapper = NbtUtil.getInst().createTagWrapper(); 27 | wrapper.set("id", item.getType().getKey().getKey()); 28 | wrapper.set("Count", (byte) item.getAmount()); 29 | wrapper.set("tag", NbtUtil.getInst().getItemNBT(item)); 30 | current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new BaseComponent[]{new TextComponent(wrapper.nbtToString())})); 31 | return this; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/resources/input.json: -------------------------------------------------------------------------------- 1 | { 2 | "tag": "+", 3 | "left": { 4 | "tag": "-", 5 | "left": { 6 | "value": 0.0 7 | }, 8 | "right": { 9 | "value": 3.0 10 | } 11 | }, 12 | "right": { 13 | "tag": "+", 14 | "left": { 15 | "tag": "-", 16 | "left": { 17 | "tag": "*", 18 | "left": { 19 | "value": 4.0 20 | }, 21 | "right": { 22 | "tag": "-", 23 | "left": { 24 | "value": 10.0 25 | }, 26 | "right": { 27 | "tag": "/", 28 | "left": { 29 | "value": 6.0 30 | }, 31 | "right": { 32 | "value": 2.0 33 | } 34 | } 35 | } 36 | }, 37 | "right": { 38 | "tag": "+", 39 | "left": { 40 | "value": 8.0 41 | }, 42 | "right": { 43 | "value": 3.0 44 | } 45 | } 46 | }, 47 | "right": { 48 | "tag": "+", 49 | "left": { 50 | "value": 5.0 51 | }, 52 | "right": { 53 | "tag": "/", 54 | "left": { 55 | "tag": "-", 56 | "left": { 57 | "value": 0.0 58 | }, 59 | "right": { 60 | "value": 7.0 61 | } 62 | }, 63 | "right": { 64 | "value": 2.0 65 | } 66 | } 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/expression/impl/LockStringExpression.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.expression.impl; 2 | 3 | import github.saukiya.sxitem.data.expression.ExpressionHandler; 4 | import github.saukiya.sxitem.data.expression.IExpression; 5 | import github.saukiya.sxitem.util.Util; 6 | 7 | /** 8 | * {@code } 获取并锁定一个随机文本 9 | *
{@code
10 |  *  "" - 从key集合中随机抽取一个值并锁定
11 |  *  "" - 从AAA/BBB中随机抽取一个值并锁定
12 |  * }
13 | */ 14 | public class LockStringExpression implements IExpression { 15 | 16 | @Override 17 | public String replace(String key, ExpressionHandler handler) { 18 | int indexOf = key.indexOf('#'); 19 | String temp = null; 20 | if (indexOf != -1) { 21 | temp = key.substring(indexOf + 1); 22 | key = key.substring(0, indexOf); 23 | } 24 | 25 | String value = handler.getLockMap().get(key); 26 | if (value != null) { 27 | return value; 28 | } 29 | 30 | if (temp != null) { 31 | value = handler.getOtherMap().get(key); 32 | if (value == null) { 33 | value = Util.random(temp.split(":")); 34 | } 35 | } else { 36 | value = handler.random(key); 37 | } 38 | 39 | handler.getLockMap().put(key, value = handler.replace(value)); 40 | return value; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/base/DoubleStack.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.base; 2 | 3 | import java.util.EmptyStackException; 4 | import java.util.stream.Collectors; 5 | import java.util.stream.IntStream; 6 | 7 | /** 8 | * 基本类型double栈, 目的是减少拆装箱 9 | */ 10 | public class DoubleStack { 11 | 12 | double[] stack; 13 | int top = -1; 14 | 15 | public DoubleStack() { 16 | this(8); 17 | } 18 | 19 | public DoubleStack(int size) { 20 | stack = new double[size]; 21 | } 22 | 23 | public void push(double value) { 24 | if (++top == stack.length) resize(); 25 | stack[top] = value; 26 | } 27 | 28 | public double pop() { 29 | if (top == -1) throw new EmptyStackException(); 30 | return stack[top--]; 31 | } 32 | 33 | public double peek() { 34 | if (top == -1) throw new EmptyStackException(); 35 | return stack[top]; 36 | } 37 | 38 | public int size() { 39 | return top + 1; 40 | } 41 | 42 | private void resize() { 43 | double[] newStack = new double[stack.length * 2]; 44 | System.arraycopy(stack, 0, newStack, 0, stack.length); 45 | stack = newStack; 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | return "[" + IntStream.range(0, size()).mapToObj(i -> Double.toString(stack[i])).collect(Collectors.joining(", ")) + "]"; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/util/TimingsUtil.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.util; 2 | 3 | import github.saukiya.tools.base.Tuple; 4 | 5 | import java.util.LinkedList; 6 | 7 | /** 8 | * 耗时检查工具 - 无意义 9 | */ 10 | public class TimingsUtil { 11 | 12 | private final LinkedList> timings = new LinkedList<>(); 13 | private final long startTime = System.nanoTime(); 14 | 15 | /** 16 | * 重置耗时 17 | */ 18 | public void dot() { 19 | dot(null); 20 | } 21 | 22 | /** 23 | * 记录耗时 24 | * 25 | * @param desc 描述 26 | */ 27 | public void dot(String desc) { 28 | long time = System.nanoTime(); 29 | timings.add(Tuple.of(desc, time)); 30 | } 31 | 32 | /** 33 | * 输出耗时 34 | */ 35 | public void print() { 36 | print(""); 37 | } 38 | 39 | /** 40 | * 输出耗时 41 | * @param name 名称 42 | */ 43 | public void print(String name) { 44 | System.out.println("timings: " + name); 45 | long lastValue = startTime; 46 | for (Tuple timing : timings) { 47 | if (timing.a() != null) { 48 | System.out.println("-\t" + timing.a() + ": " + ((timing.b() - lastValue) / 1000000D) + "ms"); 49 | } 50 | lastValue = timing.b(); 51 | } 52 | System.out.println("--\t*: " + ((lastValue - startTime) / 1000000D) + "ms\n"); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/resources/Localization/en/Message.yml: -------------------------------------------------------------------------------- 1 | GIVE: 2 | NO_ITEM: '&8[SX-Item] &cItem does not exist' 3 | GIVE_ITEM: '&8[SX-Item] &cGiven &6{0} &a{1}&c &6{2}&c item' 4 | GIVE_ITEM_ERROR: '&8[&4SX-Item&8] &4Failed to get &6{0}&4 item because backpack is full' 5 | SAVE: 6 | HAS_ITEM: '&8[SX-Item] &aItem ID &6{0} &aalready exists' 7 | SAVE_ITEM: '&8[SX-Item] &aItem ID &6{0} &asuccessfully saved' 8 | SAVE_NO_TYPE: '&8[SX-Item] &cFailed to save item ID &4{0}&c, please check if the generator exists and supports saving items' 9 | SAVE_ITEM_ERROR: '&8[SX-Item] &cUnpredictable error occurred while saving item &4{0}' 10 | NBT: 11 | CLICK_COPY: 'Click to copy' 12 | SCRIPT: 13 | NULL_FILE: 'Script file not found: {0}' 14 | INVOKE_RESULT: 'Script invocation callback: {0}, Callback type: {1}' 15 | INVOKE_FAIL: 'Script invocation failed: {0}' 16 | ADMIN: 17 | NO_PERMISSION_CMD: '&8[&cError&8] &cYou do not have permission to execute this command' 18 | NO_CMD: '&8[&cError&8] &cSubcommand not found' 19 | NO_FORMAT: '&8[&cError&8] &cFormat error' 20 | NO_ONLINE: '&8[&cError&8] &cPlayer not online or player does not exist' 21 | PLUGIN_RELOAD: '&8[SX-Item] §cPlugin reloaded' 22 | COMMAND: 23 | GIVE: Give an item to a player 24 | SAVE: Save the current item to the configuration file 25 | NBT: View and modify item nbt data 26 | COMPONENT: View and modify item component data 27 | SCRIPT: Invoke a script function 28 | RELOAD: Reload the configuration of this plugin 29 | -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nbt/TagByte.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nbt; 2 | 3 | import java.io.DataInput; 4 | import java.io.DataOutput; 5 | import java.io.IOException; 6 | 7 | public class TagByte extends TagNumber { 8 | 9 | protected static final TagByte TRUE = new TagByte((byte) 1); 10 | protected static final TagByte FALSE = new TagByte((byte) 0); 11 | protected static final TagType.Method typeMethod = new TagType.Method() { 12 | @Override 13 | public TagByte readTagBase(DataInput dataInput, int depth) throws IOException { 14 | return new TagByte(dataInput.readByte()); 15 | } 16 | 17 | @Override 18 | public TagByte toTag(Object object) { 19 | if (object instanceof Boolean) return ((Boolean) object) ? TRUE : FALSE; 20 | return object instanceof Byte ? new TagByte((Byte) object) : null; 21 | } 22 | }; 23 | private final byte value; 24 | 25 | public TagByte(byte value) { 26 | this.value = value; 27 | } 28 | 29 | @Override 30 | public void write(DataOutput dataOutput) throws IOException { 31 | dataOutput.writeByte(value); 32 | } 33 | 34 | @Override 35 | public Byte getValue() { 36 | return value; 37 | } 38 | 39 | @Override 40 | public TagType getTypeId() { 41 | return TagType.BYTE; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return getValue() + "b"; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/resources/Localization/zh/Scripts/Global/Event.js: -------------------------------------------------------------------------------- 1 | /*global Bukkit, Arrays, Utils, SXItem, listener*/ 2 | let EventPriority = Java.type("org.bukkit.event.EventPriority"); 3 | let EventExecutor = Java.type("org.bukkit.plugin.EventExecutor"); 4 | let plugin = SXItem.getInst(); 5 | 6 | let createExecutor = function (eventFunction) { 7 | let Executor = Java.extend(EventExecutor, { 8 | execute: function (listener, event) { 9 | eventFunction(event); 10 | } 11 | }); 12 | return new Executor(); 13 | } 14 | 15 | /** 16 | * 注册指定的Bukkit事件 17 | * 18 | * @example 代码示例 - 将代码放在函数外, 可以在加载/重载后直接调用 19 | * registerNormalEvent("org.bukkit.event.player.PlayerItemHeldEvent", function (event) { 20 | * let player = event.getPlayer(); 21 | * SXItem.getInst().getLogger().info("JS-" + event.getEventName() + ": " + player.getName()) 22 | * // implementation function 23 | * }); 24 | * @param eventName 事件类的全名 25 | * @param eventFunction 事件方法func(event) 26 | * @see [Bukkit API](https://bukkit.windit.net/javadoc/org/bukkit/event/package-summary.html) 27 | */ 28 | registerNormalEvent = function (eventName, eventFunction) { 29 | if (typeof eventFunction !== 'function') { 30 | throw new TypeError('eventFunction must be a function'); 31 | } 32 | let eventClass = Java.type(eventName).class; 33 | let priority = EventPriority.NORMAL; 34 | let executor = createExecutor(eventFunction); 35 | plugin.getLogger().info("JS-RegisterEvent: " + eventName); 36 | Bukkit.getPluginManager().registerEvent(eventClass, listener, priority, executor, plugin); 37 | } -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/expression/impl/BooleanExpression.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.expression.impl; 2 | 3 | import github.saukiya.sxitem.data.expression.ExpressionHandler; 4 | import github.saukiya.sxitem.data.expression.IExpression; 5 | 6 | /** 7 | * {@code } 判断首值与后续值是否相同 8 | *
{@code
 9 |  *  "" - 判断AA是否与AA相同, 相同则保留此行
10 |  *  "" - 判断AA是否与BB,CC相同, 不同则删除此行
11 |  *  "" - 与第一条逻辑相同
12 |  *  "" - 与第二条逻辑相同
13 |  * }
14 | */ 15 | public class BooleanExpression implements IExpression { 16 | 17 | @Override 18 | public String replace(String key, ExpressionHandler handler) { 19 | char[] chars = key.toCharArray(); 20 | int index = 0, check = 0, length = chars.length; 21 | 22 | for (int i = 0; i < length; i++) { 23 | switch (chars[i]) { 24 | case '#': 25 | case ':': 26 | check = i; 27 | break; 28 | default: 29 | continue; 30 | } 31 | break; 32 | } 33 | if (check == 0) return null; 34 | for (int i = check + 1; i < length; i++) { 35 | char c = chars[i]; 36 | if (c == ':') { 37 | if (index == check) { 38 | return ""; 39 | } 40 | index = 0; 41 | } else { 42 | if (index != -1 && chars[index++] != c) { 43 | index = -1; 44 | } 45 | } 46 | } 47 | return index == check ? "" : null; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/resources/Localization/de/Message.yml: -------------------------------------------------------------------------------- 1 | GIVE: 2 | NO_ITEM: '&8[SX-Item] &cGegenstand existiert nicht' 3 | GIVE_ITEM: '&8[SX-Item] &cGibt &6{0} &a{1}&c Stück &6{2}&c Gegenstand' 4 | GIVE_ITEM_ERROR: '&8[&4SX-Item&8] &4Inventar ist voll, daher konnte der Gegenstand &6{0}&4 nicht erhalten werden' 5 | SAVE: 6 | HAS_ITEM: '&8[SX-Item] &aGegenstand-ID &6{0} &aexistiert bereits' 7 | SAVE_ITEM: '&8[SX-Item] &aGegenstand-ID &6{0} &awurde erfolgreich gespeichert' 8 | SAVE_NO_TYPE: '&8[SX-Item] &cGegenstand-ID &4{0} &cspeichern fehlgeschlagen, bitte prüfen, ob dieser Generator existiert und das Speichern unterstützt' 9 | SAVE_ITEM_ERROR: '&8[SX-Item] &cUnvorhergesehener Fehler beim Speichern des Gegenstands &4{0}&c' 10 | NBT: 11 | CLICK_COPY: 'Klicken zum Kopieren' 12 | SCRIPT: 13 | NULL_FILE: 'Skriptdatei nicht gefunden: {0}' 14 | INVOKE_RESULT: 'Skriptaufruf Ergebnis: {0}, Rückgabetyp: {1}' 15 | INVOKE_FAIL: 'Skriptaufruf fehlgeschlagen: {0}' 16 | ADMIN: 17 | NO_PERMISSION_CMD: '&8[&cFehler&8] &cDu hast keine Berechtigung, diesen Befehl auszuführen' 18 | NO_CMD: '&8[&cFehler&8] &cUnterbefehl nicht gefunden' 19 | NO_FORMAT: '&8[&cFehler&8] &cFormatfehler' 20 | NO_ONLINE: '&8[&cFehler&8] &cSpieler ist nicht online oder existiert nicht' 21 | PLUGIN_RELOAD: '&8[SX-Item] §cPlugin wurde neu geladen' 22 | COMMAND: 23 | GIVE: 'Gibt dem Spieler einen Gegenstand' 24 | SAVE: 'Speichert den aktuellen Gegenstand in der Konfiguration' 25 | NBT: 'Zeigt und bearbeitet die NBT eines Gegenstands' 26 | COMPONENT: 'Zeigt und bearbeitet die Komponenten eines Gegenstands' 27 | SCRIPT: 'Ruft Skript-Funktionen auf' 28 | RELOAD: 'Lädt die Konfiguration dieses Plugins neu' -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/item/impl/GeneratorImport.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.item.impl; 2 | 3 | import github.saukiya.sxitem.data.item.IGenerator; 4 | import github.saukiya.tools.nms.MessageUtil; 5 | import lombok.Getter; 6 | import net.md_5.bungee.api.chat.BaseComponent; 7 | import org.bukkit.configuration.ConfigurationSection; 8 | import org.bukkit.entity.Player; 9 | import org.bukkit.inventory.ItemStack; 10 | 11 | @Getter 12 | public class GeneratorImport extends IGenerator { 13 | 14 | ItemStack item; 15 | 16 | public GeneratorImport(String key, ConfigurationSection config, String group) { 17 | super(key, config, group); 18 | this.item = config.getItemStack("Item"); 19 | } 20 | 21 | @Override 22 | public String getType() { 23 | return "Import"; 24 | } 25 | 26 | @Override 27 | public String getName() { 28 | return item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName() : item.getType().name(); 29 | } 30 | 31 | @Override 32 | public BaseComponent getNameComponent() { 33 | MessageUtil.Builder cb = MessageUtil.getInst().builder(); 34 | if (item.hasItemMeta() && item.getItemMeta().hasDisplayName()) { 35 | cb.add(item.getItemMeta().getDisplayName()); 36 | } else { 37 | cb.add(item.getType()); 38 | } 39 | return cb.getHandle(); 40 | } 41 | 42 | @Override 43 | protected ItemStack getItem(Player player, Object... args) { 44 | return item.clone(); 45 | } 46 | 47 | public static void save(ItemStack item, ConfigurationSection config) { 48 | config.set("Item", item); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/item/IUpdate.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.item; 2 | 3 | import github.saukiya.tools.nms.NbtUtil; 4 | import org.bukkit.configuration.ConfigurationSection; 5 | import org.bukkit.entity.Player; 6 | import org.bukkit.inventory.ItemStack; 7 | 8 | import java.util.HashSet; 9 | 10 | /** 11 | * 用于表示这个 IGenerator 适合更新 12 | */ 13 | public interface IUpdate { 14 | 15 | String getKey(); 16 | 17 | ConfigurationSection getConfig(); 18 | 19 | boolean isUpdate(); 20 | 21 | int updateCode(); 22 | 23 | ItemStack update(ItemStack oldItem, NbtUtil.Wrapper oldWrapper, Player player); 24 | 25 | 26 | /** 27 | * 保护自定义NBT标签 28 | *
{@code
29 |      * val newWrapper = NbtUtil.getInst().getItemTagWrapper(newItem);
30 |      * val oldWrapper = NbtUtil.getInst().getItemTagWrapper(oldItem);
31 |      * protectNBT(newWrapper, oldWrapper, globalProtectNBT);
32 |      * }
33 | * 34 | * @param newWrapper 更新后的物品NBT封装 35 | * @param oldWrapper 更新前的物品NBT封装 36 | * @param globalProtectNBT 全局保护配置 37 | */ 38 | default void protectNBT(NbtUtil.ItemWrapper newWrapper, NbtUtil.Wrapper oldWrapper, HashSet globalProtectNBT) { 39 | HashSet protectNBT = new HashSet<>(globalProtectNBT); 40 | getConfig().getStringList("ProtectNBT").forEach(nbt -> { 41 | if (nbt.startsWith("!")) { 42 | protectNBT.remove(nbt.substring(1)); 43 | return; 44 | } 45 | protectNBT.add(nbt); 46 | }); 47 | protectNBT.forEach(nbt -> newWrapper.set(nbt, oldWrapper.getNBTBase(nbt))); 48 | newWrapper.save(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/resources/Localization/en/Scripts/Global/Event.js: -------------------------------------------------------------------------------- 1 | /*global Bukkit, Arrays, Utils, SXItem, listener*/ 2 | let EventPriority = Java.type("org.bukkit.event.EventPriority"); 3 | let EventExecutor = Java.type("org.bukkit.plugin.EventExecutor"); 4 | let plugin = SXItem.getInst(); 5 | 6 | let createExecutor = function (eventFunction) { 7 | let Executor = Java.extend(EventExecutor, { 8 | execute: function (listener, event) { 9 | eventFunction(event); 10 | } 11 | }); 12 | return new Executor(); 13 | } 14 | 15 | /** 16 | * Register for the specified Bukkit event 17 | * 18 | * @example Code example-Place the code outside the function and can be called directly after loading/reloading 19 | * registerNormalEvent("org.bukkit.event.player.PlayerItemHeldEvent", function (event) { 20 | * let player = event.getPlayer(); 21 | * SXItem.getInst().getLogger().info("JS-" + event.getEventName() + ": " + player.getName()) 22 | * // implementation function 23 | * }); 24 | * @param eventName Full name of the event class 25 | * @param eventFunction Event function(event) 26 | * @see [Bukkit API](https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/event/package-summary.html) 27 | */ 28 | registerNormalEvent = function (eventName, eventFunction) { 29 | if (typeof eventFunction !== 'function') { 30 | throw new TypeError('eventFunction must be a function'); 31 | } 32 | let eventClass = Java.type(eventName).class; 33 | let priority = EventPriority.NORMAL; 34 | let executor = createExecutor(eventFunction); 35 | plugin.getLogger().info("JS-RegisterEvent: " + eventName); 36 | Bukkit.getPluginManager().registerEvent(eventClass, listener, priority, executor, plugin); 37 | } -------------------------------------------------------------------------------- /src/main/resources/Localization/de/Scripts/Global/Event.js: -------------------------------------------------------------------------------- 1 | /*global Bukkit, Arrays, Utils, SXItem, listener*/ 2 | let EventPriority = Java.type("org.bukkit.event.EventPriority"); 3 | let EventExecutor = Java.type("org.bukkit.plugin.EventExecutor"); 4 | let plugin = SXItem.getInst(); 5 | 6 | let createExecutor = function (eventFunction) { 7 | let Executor = Java.extend(EventExecutor, { 8 | execute: function (listener, event) { 9 | eventFunction(event); 10 | } 11 | }); 12 | return new Executor(); 13 | } 14 | 15 | /** 16 | * Registrierung eines bestimmten Bukkit-Events 17 | * 18 | * @example Codebeispiel - Platziere den Code außerhalb einer Funktion, damit er nach dem Laden/Neuladen direkt aufgerufen werden kann. 19 | * registerNormalEvent("org.bukkit.event.player.PlayerItemHeldEvent", function (event) { 20 | * let player = event.getPlayer(); 21 | * SXItem.getInst().getLogger().info("JS-" + event.getEventName() + ": " + player.getName()) 22 | * // implementation function 23 | * }); 24 | * @param eventName Vollständiger Name der Ereignisklasse 25 | * @param eventFunction Ereignismethode function(event) 26 | * @see [Bukkit API](https://bukkit.windit.net/javadoc/org/bukkit/event/package-summary.html) 27 | */ 28 | registerNormalEvent = function (eventName, eventFunction) { 29 | if (typeof eventFunction !== 'function') { 30 | throw new TypeError('eventFunction must be a function'); 31 | } 32 | let eventClass = Java.type(eventName).class; 33 | let priority = EventPriority.NORMAL; 34 | let executor = createExecutor(eventFunction); 35 | plugin.getLogger().info("JS-RegisterEvent: " + eventName); 36 | Bukkit.getPluginManager().registerEvent(eventClass, listener, priority, executor, plugin); 37 | } -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/command/ReloadCommand.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.command; 2 | 3 | import github.saukiya.sxitem.SXItem; 4 | import github.saukiya.sxitem.event.SXItemReloadEvent; 5 | import github.saukiya.sxitem.util.Config; 6 | import github.saukiya.sxitem.util.Message; 7 | import github.saukiya.tools.command.SubCommand; 8 | import github.saukiya.tools.nms.MessageUtil; 9 | import github.saukiya.tools.util.LocalizationUtil; 10 | import lombok.SneakyThrows; 11 | import org.bukkit.Bukkit; 12 | import org.bukkit.command.CommandSender; 13 | 14 | import java.util.Collections; 15 | import java.util.List; 16 | 17 | /** 18 | * 插件重载指令 19 | */ 20 | public class ReloadCommand extends SubCommand { 21 | 22 | public ReloadCommand() { 23 | super("reload", 100); 24 | } 25 | 26 | @SneakyThrows 27 | @Override 28 | public void onCommand(CommandSender sender, String[] args) { 29 | LocalizationUtil.saveResource(SXItem.getInst()); 30 | Config.loadConfig(); 31 | Config.setup(); 32 | Message.loadMessage(); 33 | SXItem.getScriptManager().reload(); 34 | SXItem.getRandomManager().loadData(); 35 | SXItem.getItemManager().loadItemData(); 36 | SXItem.getMainCommand().onReload(); 37 | SXItem.getSdf().remove(); 38 | Bukkit.getPluginManager().callEvent(SXItemReloadEvent.getInst()); 39 | MessageUtil.send(sender, Message.ADMIN__PLUGIN_RELOAD.get()); 40 | Bukkit.getOnlinePlayers().forEach(player -> SXItem.getItemManager().checkUpdateItem(player, player.getInventory().getContents())); 41 | } 42 | 43 | @Override 44 | public List onTabComplete(CommandSender sender, String[] args) { 45 | return Collections.emptyList(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/github/saukiya/expression/ConditionExpressionParser.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.expression; 2 | 3 | import github.saukiya.expression.operator.NumberOperator; 4 | import github.saukiya.expression.operator.number.*; 5 | 6 | public class ConditionExpressionParser { 7 | 8 | private static NumberOperator operator(NumberOperator a1, NumberOperator a2, char operator) { 9 | switch (operator) { 10 | case '+': 11 | return new AdditionOperator(a1, a2); 12 | case '-': 13 | return new SubtractionOperator(a1, a2); 14 | case '*': 15 | return new MultiplicationOperator(a1, a2); 16 | case '/': 17 | return new DivisionOperator(a1, a2); 18 | case '%': 19 | return new ModulusOperator(a1, a2); 20 | default: 21 | break; 22 | } 23 | throw new IllegalStateException("illegal operator: " + operator); 24 | } 25 | 26 | private static int getPriority(char operator) { 27 | switch (operator) { 28 | case '?': 29 | return 0; 30 | case '(': 31 | return 1; 32 | case '+': 33 | case '-': 34 | return 2; 35 | case '*': 36 | case '/': 37 | case '%': 38 | return 3; 39 | case '<': 40 | case '>': 41 | case '=': 42 | case '!': 43 | // 处理 >= <= == != > < 44 | return 4; 45 | case '&': 46 | case '|': 47 | return 5; 48 | default: 49 | break; 50 | } 51 | throw new IllegalStateException("illegal operator: " + operator); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Module-NMS/V1_20_R4/src/main/java/github/saukiya/tools/nms/MessageUtil_v1_20_R4.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nms; 2 | 3 | import com.google.gson.JsonElement; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Getter; 6 | import lombok.ToString; 7 | import net.md_5.bungee.api.chat.HoverEvent; 8 | import net.md_5.bungee.api.chat.hover.content.Content; 9 | import net.md_5.bungee.api.chat.hover.content.Text; 10 | import org.bukkit.inventory.ItemStack; 11 | 12 | public class MessageUtil_v1_20_R4 extends MessageUtil { 13 | 14 | @Override 15 | public Builder builder() { 16 | return new BuilderImpl(); 17 | } 18 | 19 | static class BuilderImpl extends Builder { 20 | 21 | @Override 22 | public Builder show(String text) { 23 | current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("§7" + text))); 24 | return this; 25 | } 26 | 27 | @Override 28 | public Builder show(ItemStack item) { 29 | Object nmsCopy = NbtUtil.getInst().getNMSItem(item); 30 | Object component = ComponentUtil.getInst().getDataComponentMap(nmsCopy); 31 | JsonElement data = ComponentUtil.getInst().mapToJson(component); 32 | current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new Item(item.getType().getKey().getKey(), item.getAmount(), data))); 33 | return this; 34 | } 35 | 36 | @ToString 37 | @Getter 38 | @AllArgsConstructor 39 | class Item extends Content { 40 | 41 | public String id; 42 | public int count; 43 | public Object components; 44 | 45 | @Override 46 | public HoverEvent.Action requiredAction() { 47 | return HoverEvent.Action.SHOW_ITEM; 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/util/Config.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.util; 2 | 3 | import github.saukiya.sxitem.SXItem; 4 | import lombok.Getter; 5 | import org.bukkit.configuration.file.YamlConfiguration; 6 | 7 | import java.io.File; 8 | import java.util.logging.Level; 9 | 10 | @Getter 11 | public class Config { 12 | 13 | public static final String LOGGER_LEVEL = "LoggerLevel"; 14 | public static final String LOGGER_RECORD = "LoggerRecord"; 15 | public static final String DECIMAL_PRECISION = "DecimalPrecision"; 16 | public static final String TIME_FORMAT = "TimeFormat"; 17 | public static final String SCRIPT_ENGINE = "ScriptEngine"; 18 | public static final String PROTECT_NBT = "ProtectNBT"; 19 | public static final String GIVE_OVERFLOW_DROP = "GiveOverflowDrop"; 20 | public static final String MOB_DROP_TO_PLAYER_INVENTORY = "MobDropToPlayerInventory"; 21 | public static final String COMPATIBILITY_MYTHIC_MOBS = "Compatibility.MythicMobs"; 22 | 23 | @Getter 24 | private static YamlConfiguration config; 25 | 26 | public static void loadConfig() { 27 | File file = new File(SXItem.getInst().getDataFolder(), "Config.yml"); 28 | if (!file.exists()) { 29 | SXItem.getInst().getLogger().warning("File is not exists: Config.yml"); 30 | config = new YamlConfiguration(); 31 | return; 32 | } 33 | config = YamlConfiguration.loadConfiguration(file); 34 | } 35 | 36 | public static void setup() { 37 | SXItem.getInst().getLogger().setLevel(Level.parse(config.getString(LOGGER_LEVEL, "INFO"))); 38 | Util.decimalPrecision = Math.pow(10, Math.max(config.getInt(DECIMAL_PRECISION, 2), 0)); 39 | SXItem.getItemManager().getProtectNbtList().clear(); 40 | SXItem.getItemManager().getProtectNbtList().addAll(Config.getConfig().getStringList(Config.PROTECT_NBT)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/item/IGenerator.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.item; 2 | 3 | import lombok.Getter; 4 | import net.md_5.bungee.api.chat.BaseComponent; 5 | import net.md_5.bungee.api.chat.TextComponent; 6 | import org.bukkit.configuration.ConfigurationSection; 7 | import org.bukkit.configuration.file.YamlConfiguration; 8 | import org.bukkit.entity.Player; 9 | import org.bukkit.inventory.ItemStack; 10 | 11 | /** 12 | * 物品生成器抽象类 13 | */ 14 | @Getter 15 | public abstract class IGenerator { 16 | 17 | protected String key; 18 | 19 | protected ConfigurationSection config; 20 | 21 | protected String configString; 22 | 23 | protected String group; 24 | 25 | public IGenerator(String key, ConfigurationSection config, String group) { 26 | this.key = key; 27 | this.config = config; 28 | YamlConfiguration yaml = new YamlConfiguration(); 29 | config.getValues(false).forEach(yaml::set); 30 | this.configString = yaml.saveToString().trim(); 31 | this.group = group; 32 | } 33 | 34 | /** 35 | * 返回生成器类型 36 | * 37 | * @return Type 38 | */ 39 | public abstract String getType(); 40 | 41 | /** 42 | * 返回物品展示名 43 | * 44 | * @return Name 45 | */ 46 | public abstract String getName(); 47 | 48 | /** 49 | * 返回展示组件 50 | * 51 | * @return BaseComponent 52 | */ 53 | public BaseComponent getNameComponent() { 54 | return new TextComponent(getName()); 55 | } 56 | 57 | /** 58 | * 获取物品 59 | * 60 | * @param player Player 61 | * @return Item 62 | */ 63 | protected abstract ItemStack getItem(Player player, Object... args); 64 | 65 | public interface Loader { 66 | IGenerator apply(String key, ConfigurationSection config, String group); 67 | } 68 | 69 | public interface Saver { 70 | void apply(ItemStack item, ConfigurationSection config); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Module-NMS/V1_8_R3/src/main/java/github/saukiya/tools/nms/ComponentUtil_v1_8_R3.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nms; 2 | 3 | import com.google.gson.JsonElement; 4 | 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | public class ComponentUtil_v1_8_R3 extends ComponentUtil { 9 | 10 | @Override 11 | public Object getDataComponentMap(Object nmsItem) { 12 | return null; 13 | } 14 | 15 | @Override 16 | public Object getDataComponentPatch(Object nmsItem) { 17 | return null; 18 | } 19 | 20 | @Override 21 | public void setDataComponentMap(Object nmsItem, Object dataComponentMap) { 22 | 23 | } 24 | 25 | @Override 26 | public void setDataComponentPatch(Object nmsItem, Object dataComponentPatch) { 27 | 28 | } 29 | 30 | @Override 31 | public JsonElement mapToJson(Object dataComponentMap) { 32 | return null; 33 | } 34 | 35 | @Override 36 | public JsonElement patchToJson(Object dataComponentPatch) { 37 | return null; 38 | } 39 | 40 | @Override 41 | public Object jsonToMap(JsonElement jsonElement) { 42 | return null; 43 | } 44 | 45 | @Override 46 | public Object jsonToPatch(JsonElement jsonElement) { 47 | return null; 48 | } 49 | 50 | @Override 51 | public Object mapToValue(Object dataComponentMap) { 52 | return null; 53 | } 54 | 55 | @Override 56 | public Object patchToValue(Object dataComponentPatch) { 57 | return null; 58 | } 59 | 60 | @Override 61 | public Object valueToMap(Object javaObject) { 62 | return null; 63 | } 64 | 65 | @Override 66 | public Object valueToPatch(Object javaObject) { 67 | return null; 68 | } 69 | 70 | @Override 71 | public List getItemKeys() { 72 | return Collections.emptyList(); 73 | } 74 | 75 | @Override 76 | public void setComponentMapValue(Object dataComponentMap, String type, Object value) { 77 | 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/resources/Localization/zh/Scripts/Default.js: -------------------------------------------------------------------------------- 1 | /*global SXItem, Bukkit, Arrays, Utils*/ 2 | 3 | /** 4 | * 指令: /si script Default testPlayer <玩家名> <参数> 5 | *

6 | * 所有参数里为在线的'玩家名', 则自动转成'玩家对象' 7 | * @param player 玩家名 8 | * @param args 参数 9 | * @see [Player](https://bukkit.windit.net/javadoc/org/bukkit/entity/Player.html) 10 | */ 11 | function testPlayer(player, args) { 12 | if (player != null) { 13 | player.sendMessage("收到了一条信息: " + args) 14 | } else { 15 | SXItem.getInst().getLogger().info("可以将在线成员作为实际参数运行在/si script 方法内") 16 | } 17 | } 18 | 19 | /** 20 | * JS随机格式: 21 | * @param handler JS随机当前的ExpressionHandler,具体参考 [ExpressionHandler](https://github.com/Saukiya/SX-Item/blob/master/src/main/java/github/saukiya/sxitem/data/expression/ExpressionHandler.java) 22 | * @param args JS随机所带的字符串数组 例如['QAQ', 'QWQ'] 23 | * @returns string 24 | */ 25 | function itemScript(handler, args) { 26 | if (handler.getPlayer() != null) { 27 | handler.getPlayer().sendMessage("把参数发给玩家: " + args[0] + args[1]) 28 | } 29 | return args[SXItem.getRandom().nextInt(args.length)]; 30 | } 31 | 32 | // 脚本加载后 注册Bukkit事件 具体查阅Event.js 33 | // registerNormalEvent("org.bukkit.event.player.PlayerItemHeldEvent", function (event) { 34 | // let player = event.getPlayer(); 35 | // SXItem.getInst().getLogger().info("JS-" + event.getEventName() + ": " + player.getName()) 36 | // }); 37 | 38 | // 代码示例 39 | // 40 | // 可实现列表方法 41 | // function newList1() { 42 | // return new Array("TEST4", "WER", "SDF", "SCV"); 43 | // } 44 | // 45 | // function newList2() { 46 | // return Arrays.asList("TEST3", "QAZ", "WSX", "EDC"); 47 | // } 48 | // 49 | // function newList3() { 50 | // return ["TEST6", "ERT", "DFG", "CVB"]; 51 | // } 52 | // 53 | // // ArrayList 在 Global.js文件夹中声明, 但是不推荐使用, 尽可能调用js自有函数, 尽量减少与java之间的交互. 54 | // function newList4() { 55 | // let list = new ArrayList(); 56 | // list.add("TEST2"); 57 | // list.add("ABC"); 58 | // list.add("BCD"); 59 | // list.add("CDE"); 60 | // return list 61 | // } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SX-Item 2 | 3 | [Minecraft-SpigotPlugin] 物品管理插件 4 | 5 | [下载](https://github.com/Saukiya/SX-Item/releases/latest) · 6 | [文档](https://www.maplex.top/archives/sxitem) · 7 | [统计](https://bstats.org/plugin/bukkit/SX-Item) · 8 | [MineBBS](https://www.minebbs.com/resources/sx-item-1-8-1-20-x.7252/) · 9 | [Spigot](https://www.spigotmc.org/resources/sx-item.119751) · 10 | [~~MCBBS~~](https://www.mcbbs.net/thread-1471655-1-1.html) 11 | 12 | 13 | 14 | * [SX-Item](#sx-item) 15 | * [Support Server](#support-server) 16 | * [Support Version](#support-version) 17 | * [Extension](#extension) 18 | * [Gradle](#gradle) 19 | 20 | 21 | 22 | ## Support Server 23 | 24 | - Spigot 25 | - Paper 26 | - Folia? 27 | - More... 28 | 29 | ## Support Version 30 | 31 | | Version | Version | Version | 32 | |:-------:|:-------:|:-------:| 33 | | 1.8.8 | 1.11.2 | 1.12.2 | 34 | | 1.13.2 | 1.14.4 | 1.15.2 | 35 | | 1.16.5 | 1.17.1 | 1.18.2 | 36 | | 1.19.2 | 1.19.4 | 1.20.1 | 37 | | 1.20.2 | 1.20.3 | 1.20.4 | 38 | | 1.20.5 | 1.20.6 | 1.21.1 | 39 | | 1.21.3 | 1.21.4 | 1.21.5 | 40 | | 1.21.6 | 1.21.7 | 1.21.8 | 41 | | 1.21.10 | | | 42 | 43 | 要什么版本就发 [Issue](https://github.com/Saukiya/SX-Item/issues/new/choose) 44 | 45 | ## Extension 46 | 47 | | Project | Version | Author | 48 | |-------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------|---------| 49 | | [SX-Attribute](https://github.com/Saukiya/SX-Attribute/releases/latest) | ![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/Saukiya/SX-Attribute?label=latest) | Saukiya | 50 | 51 | ## Gradle 52 | 53 | ```groovy 54 | repositories { 55 | // Github Project 56 | maven { url 'https://jitpack.io' } 57 | } 58 | 59 | dependencies { 60 | compileOnly 'com.github.Saukiya:SX-Item:4.4.9' 61 | } 62 | ``` 63 | -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nbt/TagByteArray.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nbt; 2 | 3 | import com.google.common.base.Preconditions; 4 | import lombok.NoArgsConstructor; 5 | 6 | import java.io.DataInput; 7 | import java.io.DataOutput; 8 | import java.io.IOException; 9 | import java.util.Collection; 10 | import java.util.stream.IntStream; 11 | 12 | @NoArgsConstructor 13 | public class TagByteArray extends TagListBase { 14 | 15 | protected static final TagType.Method typeMethod = new TagType.Method() { 16 | @Override 17 | public TagByteArray readTagBase(DataInput dataInput, int depth) throws IOException { 18 | int length = dataInput.readInt(); 19 | Preconditions.checkArgument(length < 16777216); 20 | byte[] bytes = new byte[length]; 21 | dataInput.readFully(bytes); 22 | return new TagByteArray(bytes); 23 | } 24 | 25 | @Override 26 | public TagByteArray toTag(Object object) { 27 | return object instanceof byte[] ? new TagByteArray((byte[]) object) : null; 28 | } 29 | }; 30 | 31 | public TagByteArray(Collection collection) { 32 | super(collection); 33 | } 34 | 35 | public TagByteArray(byte[] bytes) { 36 | for (byte value : bytes) { 37 | add(value); 38 | } 39 | } 40 | 41 | @Override 42 | public String getToStringPrefix() { 43 | return "B;"; 44 | } 45 | 46 | @Override 47 | public String getToStringSuffix() { 48 | return "B"; 49 | } 50 | 51 | @Override 52 | public void write(DataOutput dataOutput) throws IOException { 53 | dataOutput.writeInt(size()); 54 | dataOutput.write(getValue()); 55 | } 56 | 57 | @Override 58 | public byte[] getValue() { 59 | byte[] arrays = new byte[size()]; 60 | IntStream.range(0, size()).forEach(i -> arrays[i] = get(i)); 61 | return arrays; 62 | } 63 | 64 | @Override 65 | public TagType getTypeId() { 66 | return TagType.BYTE_ARRAY; 67 | } 68 | } -------------------------------------------------------------------------------- /src/test/java/github/saukiya/tools/TestBenchmark.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools; 2 | 3 | import lombok.val; 4 | import org.openjdk.jmh.annotations.Mode; 5 | import org.openjdk.jmh.runner.Runner; 6 | import org.openjdk.jmh.runner.RunnerException; 7 | import org.openjdk.jmh.runner.options.ChainedOptionsBuilder; 8 | import org.openjdk.jmh.runner.options.OptionsBuilder; 9 | import org.openjdk.jmh.runner.options.TimeValue; 10 | 11 | import java.util.concurrent.TimeUnit; 12 | 13 | public class TestBenchmark { 14 | 15 | public static void run(Class clazz, String... args) throws RunnerException { 16 | val builder = builder(); 17 | val className = clazz.getName().replace('$', '.'); 18 | if (args.length == 0) { 19 | builder.include(className); 20 | } else { 21 | for (String arg : args) { 22 | builder.include(className + '.' + arg); 23 | } 24 | } 25 | new Runner(builder.build()).run(); 26 | } 27 | 28 | public static void run(String... args) throws RunnerException { 29 | val builder = builder(); 30 | val className = Thread.currentThread().getStackTrace()[2].getClassName(); 31 | if (args.length == 0) { 32 | builder.include(className); 33 | } else { 34 | for (String arg : args) { 35 | builder.include(className + '.' + arg); 36 | } 37 | } 38 | new Runner(builder.build()).run(); 39 | } 40 | 41 | private static ChainedOptionsBuilder builder() { 42 | return new OptionsBuilder() 43 | .measurementTime(TimeValue.seconds(1)) 44 | .measurementIterations(4) 45 | .measurementBatchSize(4) 46 | .warmupTime(TimeValue.seconds(1)) 47 | .warmupIterations(4) 48 | .warmupBatchSize(4) 49 | .timeUnit(TimeUnit.NANOSECONDS) 50 | .mode(Mode.AverageTime) 51 | .threads(2) 52 | .forks(1) 53 | // .addProfiler(GCProfiler.class) 54 | ; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nbt/TagIntArray.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nbt; 2 | 3 | import com.google.common.base.Preconditions; 4 | import lombok.NoArgsConstructor; 5 | 6 | import java.io.DataInput; 7 | import java.io.DataOutput; 8 | import java.io.IOException; 9 | import java.util.Arrays; 10 | import java.util.Collection; 11 | import java.util.stream.IntStream; 12 | 13 | @NoArgsConstructor 14 | public class TagIntArray extends TagListBase { 15 | 16 | protected static final TagType.Method typeMethod = new TagType.Method() { 17 | @Override 18 | public TagIntArray readTagBase(DataInput dataInput, int depth) throws IOException { 19 | int length = dataInput.readInt(); 20 | Preconditions.checkArgument(length < 16777216); 21 | TagIntArray tagIntArray = new TagIntArray(); 22 | for (int i = 0; i < length; i++) { 23 | tagIntArray.add(dataInput.readInt()); 24 | } 25 | return tagIntArray; 26 | } 27 | 28 | @Override 29 | public TagIntArray toTag(Object object) { 30 | return object instanceof int[] ? new TagIntArray((int[]) object) : null; 31 | } 32 | }; 33 | 34 | public TagIntArray(Collection collection) { 35 | super(collection); 36 | } 37 | 38 | public TagIntArray(int[] bytes) { 39 | Arrays.stream(bytes).forEach(this::add); 40 | } 41 | 42 | @Override 43 | public String getToStringPrefix() { 44 | return "I;"; 45 | } 46 | 47 | @Override 48 | public void write(DataOutput dataOutput) throws IOException { 49 | dataOutput.writeInt(size()); 50 | for (Integer value : this) { 51 | dataOutput.writeInt(value); 52 | } 53 | } 54 | 55 | @Override 56 | public int[] getValue() { 57 | int[] arrays = new int[size()]; 58 | IntStream.range(0, size()).forEach(i -> arrays[i] = get(i)); 59 | return arrays; 60 | } 61 | 62 | @Override 63 | public TagType getTypeId() { 64 | return TagType.INT_ARRAY; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /.github/workflows/gradle-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | # This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created 6 | # For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle 7 | 8 | name: Gradle Package 9 | 10 | on: 11 | release: 12 | types: [created] 13 | workflow_dispatch: 14 | inputs: 15 | example_input: 16 | description: 'An example input' 17 | required: false 18 | default: 'default value' 19 | 20 | jobs: 21 | build: 22 | 23 | runs-on: ubuntu-latest 24 | 25 | permissions: 26 | contents: read 27 | packages: write 28 | 29 | steps: 30 | - name: Check Out 31 | uses: actions/checkout@v4 32 | - name: Set up JDK 21 33 | uses: actions/setup-java@v4 34 | with: 35 | java-version: '21' 36 | distribution: 'temurin' 37 | server-id: github # Value of the distributionManagement/repository/id field of the pom.xml 38 | settings-path: ${{ github.workspace }} # location for the settings.xml file 39 | 40 | - name: Setup Gradle 41 | uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 42 | 43 | - name: Grant execute permission for gradlew 44 | run: chmod +x gradlew 45 | 46 | - name: Build with Gradle 47 | run: ./gradlew build 48 | 49 | # The USERNAME and TOKEN need to correspond to the credentials environment variables used in 50 | # the publishing section of your build.gradle 51 | - name: Publish to GitHub Packages 52 | run: ./gradlew publish 53 | env: 54 | GITHUB_NAME: ${{ github.actor }} 55 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 56 | ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_NAME }} 57 | ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_TOKEN }} 58 | -------------------------------------------------------------------------------- /Module-Deprecated-v3/src/main/java/github/saukiya/sxitem/util/ComponentBuilder.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.util; 2 | 3 | import github.saukiya.tools.nms.MessageUtil; 4 | import lombok.AllArgsConstructor; 5 | import net.md_5.bungee.api.chat.BaseComponent; 6 | import org.bukkit.Material; 7 | import org.bukkit.command.CommandSender; 8 | import org.bukkit.inventory.ItemStack; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * @see github.saukiya.tools.nms.MessageUtil.Builder 14 | * @deprecated 15 | */ 16 | @AllArgsConstructor 17 | public class ComponentBuilder { 18 | 19 | MessageUtil.Builder target; 20 | 21 | @Deprecated 22 | public ComponentBuilder add(BaseComponent base) { 23 | target.add(base); 24 | return this; 25 | } 26 | 27 | @Deprecated 28 | public ComponentBuilder add(String text) { 29 | target.add(text); 30 | return this; 31 | } 32 | 33 | @Deprecated 34 | public ComponentBuilder add(Material material) { 35 | target.add(material); 36 | return this; 37 | } 38 | 39 | @Deprecated 40 | public ComponentBuilder add(ItemStack item) { 41 | target.add(item); 42 | return this; 43 | } 44 | 45 | @Deprecated 46 | public ComponentBuilder show(List list) { 47 | target.show(list); 48 | return this; 49 | } 50 | 51 | @Deprecated 52 | public ComponentBuilder show(String text) { 53 | target.show(text); 54 | return this; 55 | } 56 | 57 | @Deprecated 58 | public ComponentBuilder show(ItemStack item) { 59 | target.show(item); 60 | return this; 61 | } 62 | 63 | @Deprecated 64 | public ComponentBuilder openURL(String value) { 65 | target.openURL(value); 66 | return this; 67 | } 68 | 69 | @Deprecated 70 | public ComponentBuilder runCommand(String value) { 71 | target.runCommand(value); 72 | return this; 73 | } 74 | 75 | @Deprecated 76 | public ComponentBuilder suggestCommand(String value) { 77 | target.suggestCommand(value); 78 | return this; 79 | } 80 | 81 | @Deprecated 82 | public void send(CommandSender sender) { 83 | target.send(sender); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Module-NMS/V1_12_R1/src/main/java/github/saukiya/tools/nms/MessageUtil_v1_12_R1.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nms; 2 | 3 | import lombok.val; 4 | import net.md_5.bungee.api.chat.BaseComponent; 5 | import net.md_5.bungee.api.chat.HoverEvent; 6 | import net.md_5.bungee.api.chat.TextComponent; 7 | import net.md_5.bungee.api.chat.TranslatableComponent; 8 | import net.minecraft.server.v1_12_R1.Item; 9 | import net.minecraft.server.v1_12_R1.NBTTagCompound; 10 | import org.bukkit.Material; 11 | import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack; 12 | import org.bukkit.craftbukkit.v1_12_R1.util.CraftMagicNumbers; 13 | import org.bukkit.inventory.ItemStack; 14 | 15 | public class MessageUtil_v1_12_R1 extends MessageUtil { 16 | 17 | @Override 18 | public Builder builder() { 19 | return new BuilderImpl(); 20 | } 21 | 22 | static class BuilderImpl extends Builder { 23 | 24 | @Override 25 | public Builder add(Material material) { 26 | Item item = CraftMagicNumbers.getItem(material); 27 | add(new TranslatableComponent((item.k() ? new net.minecraft.server.v1_12_R1.ItemStack(item).a() : item.getName()) + ".name")); 28 | return this; 29 | } 30 | 31 | @Override 32 | public Builder show(String text) { 33 | current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new BaseComponent[]{new TextComponent("§7" + text)})); 34 | return this; 35 | } 36 | 37 | @Override 38 | public Builder show(ItemStack item) { 39 | // val wrapper = NbtUtil.getInst().createTagWrapper(); 40 | // wrapper.set("id", "minecraft:" + item.getType().name().toLowerCase(Locale.ROOT)); // // craftItem.a() 41 | // wrapper.set("Count", (byte) item.getAmount()); 42 | // wrapper.set("Damage", item.getDurability()); 43 | // wrapper.set("tag", NbtUtil.getInst().getItemNBT(item)); 44 | val nbtCompound = new NBTTagCompound(); 45 | CraftItemStack.asNMSCopy(item).save(nbtCompound); 46 | current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new BaseComponent[]{new TextComponent(nbtCompound.toString())})); 47 | return this; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/resources/Localization/en/Scripts/Default.js: -------------------------------------------------------------------------------- 1 | /*global SXItem, Bukkit, Arrays, Utils*/ 2 | 3 | /** 4 | * Command: /si script Default testPlayer 5 | *

6 | * If all parameters are online 'player name', it will be automatically converted to 'player object', 7 | * @param player playerName 8 | * @param args args 9 | * @see [Player](https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/Player.html) 10 | */ 11 | function testPlayer(player, args) { 12 | if (player != null) { 13 | player.sendMessage("received a message: " + args); 14 | } else { 15 | SXItem.getInst().getLogger().info("Online members can be run as actual parameters inside the /si script method") 16 | } 17 | } 18 | 19 | /** 20 | * JS random format: 21 | * @param handler JS random current ExpressionHandler, specific reference [ExpressionHandler](https://github.com/Saukiya/SX-Item/blob/master/src/main/java/github/saukiya/sxitem/data/expression/ExpressionHandler.java) 22 | * @param args JS random string array such as ['QAQ', 'QWQ'] 23 | * @returns string 24 | */ 25 | function itemScript(handler, args) { 26 | handler.getPlayer().sendMessage("Send parameters to players: " + args[0] + args[1]); 27 | return args[SXItem.getRandom().nextInt(args.length)]; 28 | } 29 | 30 | // After the script is loaded, register the Bukkit event. See Event.js for details. 31 | // registerNormalEvent("org.bukkit.event.player.PlayerItemHeldEvent", function (event) { 32 | // let player = event.getPlayer(); 33 | // SXItem.getInst().getLogger().info("JS-" + event.getEventName() + ": " + player.getName()) 34 | // }); 35 | 36 | // Code Sample 37 | // 38 | // List methods can be implemented 39 | // function newList1() { 40 | // return new Array("TEST4", "WER", "SDF", "SCV"); 41 | // } 42 | // 43 | // function newList2() { 44 | // return Arrays.asList("TEST3", "QAZ", "WSX", "EDC"); 45 | // } 46 | // 47 | // function newList3() { 48 | // return ["TEST6", "ERT", "DFG", "CVB"]; 49 | // } 50 | // 51 | // // The ArrayList is declared in the Global.js folder, but it is not recommend to use, to minimize the interaction with Java. 52 | // function newList4() { 53 | // let list = new ArrayList(); 54 | // list.add("TEST2"); 55 | // list.add("ABC"); 56 | // list.add("BCD"); 57 | // list.add("CDE"); 58 | // return list 59 | // } -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/expression/impl/ScriptExpression.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.expression.impl; 2 | 3 | import github.saukiya.sxitem.SXItem; 4 | import github.saukiya.sxitem.data.expression.ExpressionHandler; 5 | import github.saukiya.sxitem.data.expression.IExpression; 6 | import org.apache.commons.lang.StringUtils; 7 | import org.apache.commons.lang.Validate; 8 | import org.bukkit.Bukkit; 9 | import org.bukkit.entity.Player; 10 | 11 | import javax.script.Bindings; 12 | import java.util.Arrays; 13 | import java.util.Collection; 14 | 15 | /** 16 | * {@code } 调用脚本引擎方法 17 | *

{@code
18 |  *  "" - 执行无参数方法 File.function(handler,null)
19 |  *  "" - 执行有参数方法 File.function(handler,[AAA])
20 |  * }
21 | */ 22 | public class ScriptExpression implements IExpression { 23 | 24 | @Override 25 | public String replace(String key, ExpressionHandler handler) { 26 | if (!SXItem.getScriptManager().isEnabled()) return null; 27 | int index1 = key.indexOf('.'); 28 | Validate.isTrue(index1 != -1, key); 29 | String fileName = key.substring(0, index1++); 30 | 31 | int index2 = key.indexOf('#', index1); 32 | index2 = index2 != -1 ? index2 : key.length(); 33 | String functionName = key.substring(index1, index2++); 34 | 35 | Object[] args; 36 | if (index2 > key.length()) { 37 | args = null; 38 | } else { 39 | args = Arrays.stream(key.substring(index2).split(",")).map(arg -> { 40 | Player player = Bukkit.getPlayerExact(arg); 41 | if (player == null) return arg; 42 | return player; 43 | }).toArray(); 44 | } 45 | 46 | Object result; 47 | try { 48 | result = SXItem.getScriptManager().callFunction(fileName, functionName, handler, args); 49 | } catch (Exception e) { 50 | e.printStackTrace(); 51 | return null; 52 | } 53 | 54 | if (result instanceof Collection) return StringUtils.join((Collection) result, "\n"); 55 | if (result instanceof Bindings) { 56 | // ScriptObjectMirror 本质是 Bindings 57 | return StringUtils.join(((Bindings) result).values(), "\n"); 58 | } 59 | return result.toString(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Module-NMS/V1_11_R1/src/main/java/github/saukiya/tools/nms/MessageUtil_v1_11_R1.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nms; 2 | 3 | import lombok.val; 4 | import net.md_5.bungee.api.chat.BaseComponent; 5 | import net.md_5.bungee.api.chat.HoverEvent; 6 | import net.md_5.bungee.api.chat.TextComponent; 7 | import net.md_5.bungee.api.chat.TranslatableComponent; 8 | import net.minecraft.server.v1_11_R1.Item; 9 | import org.bukkit.Material; 10 | import org.bukkit.command.CommandSender; 11 | import org.bukkit.craftbukkit.v1_11_R1.util.CraftMagicNumbers; 12 | import org.bukkit.entity.Player; 13 | import org.bukkit.inventory.ItemStack; 14 | 15 | import java.util.Locale; 16 | 17 | public class MessageUtil_v1_11_R1 extends MessageUtil { 18 | 19 | @Override 20 | public Builder builder() { 21 | return new BuilderImpl(); 22 | } 23 | 24 | static class BuilderImpl extends Builder { 25 | 26 | @Override 27 | public Builder add(Material material) { 28 | Item item = CraftMagicNumbers.getItem(material); 29 | add(new TranslatableComponent((item.l() ? new net.minecraft.server.v1_11_R1.ItemStack(item).a() : item.getName()) + ".name")); 30 | return this; 31 | } 32 | 33 | @Override 34 | public Builder show(String text) { 35 | current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new BaseComponent[]{new TextComponent("§7" + text)})); 36 | return this; 37 | } 38 | 39 | @Override 40 | public Builder show(ItemStack item) { 41 | val wrapper = NbtUtil.getInst().createTagWrapper(); 42 | wrapper.set("id", "minecraft:" + item.getType().name().toLowerCase(Locale.ROOT)); 43 | wrapper.set("Count", (byte) item.getAmount()); 44 | wrapper.set("Damage", item.getDurability()); 45 | wrapper.set("tag", NbtUtil.getInst().getItemNBT(item)); 46 | current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new BaseComponent[]{new TextComponent(wrapper.nbtToString())})); 47 | return this; 48 | } 49 | 50 | @Override 51 | public void send(CommandSender sender) { 52 | if (sender instanceof Player) { 53 | ((Player) sender).spigot().sendMessage(handle); 54 | } else { 55 | sender.sendMessage(handle.toLegacyText()); 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nbt/TagLongArray.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nbt; 2 | 3 | import github.saukiya.tools.nms.NMS; 4 | import lombok.NoArgsConstructor; 5 | 6 | import java.io.DataInput; 7 | import java.io.DataOutput; 8 | import java.io.IOException; 9 | import java.util.Arrays; 10 | import java.util.Collection; 11 | import java.util.stream.Collectors; 12 | import java.util.stream.IntStream; 13 | 14 | @NoArgsConstructor 15 | public class TagLongArray extends TagListBase { 16 | 17 | protected static final TagType.Method typeMethod = new TagType.Method() { 18 | @Override 19 | public TagLongArray readTagBase(DataInput dataInput, int depth) throws IOException { 20 | int length = dataInput.readInt(); 21 | TagLongArray tagLongArray = new TagLongArray(); 22 | for (int i = 0; i < length; ++i) { 23 | tagLongArray.add(dataInput.readLong()); 24 | } 25 | return tagLongArray; 26 | } 27 | 28 | @Override 29 | public TagListBase toTag(Object object) { 30 | if (object instanceof long[]) { 31 | long[] longs = (long[]) object; 32 | if (NMS.compareTo(1, 12, 1) >= 0) return new TagLongArray(longs); 33 | return Arrays.stream(longs).mapToObj(TagLong::new).collect(Collectors.toCollection(TagList::new)); 34 | } 35 | return null; 36 | } 37 | }; 38 | 39 | public TagLongArray(Collection collection) { 40 | super(collection); 41 | } 42 | 43 | public TagLongArray(long[] bytes) { 44 | Arrays.stream(bytes).forEach(this::add); 45 | } 46 | 47 | @Override 48 | public String getToStringPrefix() { 49 | return "L;"; 50 | } 51 | 52 | @Override 53 | public String getToStringSuffix() { 54 | return "L"; 55 | } 56 | 57 | @Override 58 | public void write(DataOutput dataOutput) throws IOException { 59 | dataOutput.writeInt(size()); 60 | for (Long value : this) { 61 | dataOutput.writeLong(value); 62 | } 63 | } 64 | 65 | @Override 66 | public long[] getValue() { 67 | long[] arrays = new long[size()]; 68 | IntStream.range(0, size()).forEach(i -> arrays[i] = get(i)); 69 | return arrays; 70 | } 71 | 72 | @Override 73 | public TagType getTypeId() { 74 | return TagType.LONG_ARRAY; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/data/expression/impl/TimeExpression.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.data.expression.impl; 2 | 3 | import github.saukiya.sxitem.SXItem; 4 | import github.saukiya.sxitem.data.expression.ExpressionHandler; 5 | import github.saukiya.sxitem.data.expression.IExpression; 6 | import org.apache.commons.lang.StringUtils; 7 | 8 | import java.util.Calendar; 9 | 10 | /** 11 | * {@code } 动态生成时间文本 12 | *
{@code
13 |  *  "" - 10分钟后的时间文本,等价于10m
14 |  *  "" - 1年1月1天后的时间文本
15 |  *  "" - 1小时1分钟1秒后的时间文本
16 |  * }
17 | */ 18 | public class TimeExpression implements IExpression { 19 | 20 | @Override 21 | public String replace(String key, ExpressionHandler handler) { 22 | if (StringUtils.isNumeric(key)) { 23 | return SXItem.getSdf().get().format(System.currentTimeMillis() + Long.parseLong(key) * 1000); 24 | } 25 | Calendar calendar = Calendar.getInstance(); 26 | int num = 0; 27 | for (char c : key.toCharArray()) { 28 | switch (c) { 29 | case '0': 30 | case '1': 31 | case '2': 32 | case '3': 33 | case '4': 34 | case '5': 35 | case '6': 36 | case '7': 37 | case '8': 38 | case '9': 39 | num = c - 48 + num * 10; 40 | continue; 41 | case 'Y': 42 | case 'y': 43 | calendar.add(Calendar.YEAR, num); 44 | break; 45 | case 'M': 46 | calendar.add(Calendar.MONTH, num); 47 | break; 48 | case 'D': 49 | case 'd': 50 | calendar.add(Calendar.DATE, num); 51 | break; 52 | case 'H': 53 | case 'h': 54 | calendar.add(Calendar.HOUR_OF_DAY, num); 55 | break; 56 | case 'm': 57 | calendar.add(Calendar.MINUTE, num); 58 | break; 59 | case 'S': 60 | case 's': 61 | calendar.add(Calendar.SECOND, num); 62 | break; 63 | default: 64 | continue; 65 | } 66 | num = 0; 67 | } 68 | return SXItem.getSdf().get().format(calendar.getTime()); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/util/Message.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.util; 2 | 3 | import github.saukiya.sxitem.SXItem; 4 | import lombok.Getter; 5 | import org.bukkit.configuration.file.YamlConfiguration; 6 | 7 | import java.io.File; 8 | import java.text.MessageFormat; 9 | import java.util.Collections; 10 | import java.util.List; 11 | 12 | public enum Message { 13 | 14 | GIVE__NO_ITEM, 15 | GIVE__GIVE_ITEM, 16 | GIVE__GIVE_ITEM_ERROR, 17 | 18 | SAVE__HAS_ITEM, 19 | SAVE__SAVE_ITEM, 20 | SAVE__SAVE_NO_TYPE, 21 | SAVE__SAVE_ITEM_ERROR, 22 | 23 | NBT__CLICK_COPY, 24 | 25 | SCRIPT__NULL_FILE, 26 | SCRIPT__INVOKE_RESULT, 27 | SCRIPT__INVOKE_FAIL, 28 | 29 | ADMIN__NO_PERMISSION_CMD, 30 | ADMIN__NO_CMD, 31 | ADMIN__NO_FORMAT, 32 | ADMIN__NO_ONLINE, 33 | ADMIN__PLUGIN_RELOAD; 34 | 35 | @Getter 36 | private static YamlConfiguration messages; 37 | 38 | /** 39 | * 获取String 40 | * 41 | * @param args Object... 42 | * @return String 43 | */ 44 | public String get(Object... args) { 45 | return getString(toString(), args); 46 | } 47 | 48 | /** 49 | * 获取List 50 | * 51 | * @param args Object... 52 | * @return List 53 | */ 54 | public List getList(Object... args) { 55 | return getStringList(toString(), args); 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return name().replace("__", "."); 61 | } 62 | 63 | /** 64 | * 加载Message类 65 | */ 66 | public static void loadMessage() { 67 | File file = new File(SXItem.getInst().getDataFolder(), "Message.yml"); 68 | if (!file.exists()) { 69 | SXItem.getInst().getLogger().warning("File is not exists: Message.yml"); 70 | messages = new YamlConfiguration(); 71 | return; 72 | } 73 | messages = YamlConfiguration.loadConfiguration(file); 74 | } 75 | 76 | public static String getString(String loc, Object... args) { 77 | return MessageFormat.format(messages.getString(loc, "Null Message: " + loc), args).replace('&', '§'); 78 | } 79 | 80 | public static List getStringList(String loc, Object... args) { 81 | List list = messages.getStringList(loc); 82 | if (list.isEmpty()) return Collections.singletonList("Null Message: " + loc); 83 | list.replaceAll(str -> MessageFormat.format(str, args).replace('&', '§')); 84 | return list; 85 | } 86 | } -------------------------------------------------------------------------------- /src/main/resources/Localization/de/Scripts/Default.js: -------------------------------------------------------------------------------- 1 | /*global SXItem, Bukkit, Arrays, Utils*/ 2 | 3 | /** 4 | * Befehl: /si script Standard testPlayer 5 | *

6 | * Wenn alle Parameter ein online 'Spielername' sind, wird dieser automatisch in ein 'Spielerobjekt' umgewandelt. 7 | * @param player Spielername 8 | * @param args Parameter 9 | * @see [Player](https://bukkit.windit.net/javadoc/org/bukkit/entity/Player.html) 10 | */ 11 | function testPlayer(player, args) { 12 | if (player != null) { 13 | player.sendMessage("Eine Nachricht erhalten: " + args) 14 | } else { 15 | SXItem.getInst().getLogger().info("Online-Mitglieder können als tatsächliche Parameter innerhalb der /si script-Methode ausgeführt werden.") 16 | } 17 | } 18 | 19 | /** 20 | * JS-Zufallsformat: 21 | * @param handler JS-Zufall für das aktuelle ExpressionHandler, siehe [ExpressionHandler](https://github.com/Saukiya/SX-Item/blob/master/src/main/java/github/saukiya/sxitem/data/expression/ExpressionHandler.java) 22 | * @param args JS-Zufalls-String-Array, zum Beispiel ['QAQ', 'QWQ']. 23 | * @returns string 24 | */ 25 | function itemScript(handler, args) { 26 | if (handler.getPlayer() != null) { 27 | handler.getPlayer().sendMessage("Parameter an den Spieler senden: " + args[0] + args[1]) 28 | } 29 | return args[SXItem.getRandom().nextInt(args.length)]; 30 | } 31 | 32 | // Nach dem Laden des Skripts werden Bukkit-Events registriert. Einzelheiten findest du in Event.js. 33 | // registerNormalEvent("org.bukkit.event.player.PlayerItemHeldEvent", function (event) { 34 | // let player = event.getPlayer(); 35 | // SXItem.getInst().getLogger().info("JS-" + event.getEventName() + ": " + player.getName()) 36 | // }); 37 | 38 | // Codebeispiel 39 | // 40 | // Implementierbare Listenmethoden 41 | // function newList1() { 42 | // return new Array("TEST4", "WER", "SDF", "SCV"); 43 | // } 44 | // 45 | // function newList2() { 46 | // return Arrays.asList("TEST3", "QAZ", "WSX", "EDC"); 47 | // } 48 | // 49 | // function newList3() { 50 | // return ["TEST6", "ERT", "DFG", "CVB"]; 51 | // } 52 | // 53 | // // ArrayList wird im Global.js-Ordner deklariert, jedoch wird die Verwendung nicht empfohlen. 54 | // // Es ist besser, die eigenen Funktionen von JS zu verwenden und die Interaktion mit Java so weit wie möglich zu reduzieren. 55 | // function newList4() { 56 | // let list = new ArrayList(); 57 | // list.add("TEST2"); 58 | // list.add("ABC"); 59 | // list.add("BCD"); 60 | // list.add("CDE"); 61 | // return list 62 | // } -------------------------------------------------------------------------------- /src/test/java/github/saukiya/expression/operator/condition/EqualOperator.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.expression.operator.condition; 2 | 3 | import github.saukiya.expression.operator.ConditionOperator; 4 | import github.saukiya.expression.operator.NumberOperator; 5 | import github.saukiya.expression.operator.Operator; 6 | import github.saukiya.expression.operator.StringOperator; 7 | import lombok.AllArgsConstructor; 8 | 9 | /** 10 | * Range: String~Number 11 | * Format: A == B 12 | * Condition: A is Number && B is Number ? (Number==Number) : A is Boolean && B is Boolean ? (Boolean=Boolean) : (String==String) 13 | */ 14 | public abstract class EqualOperator implements ConditionOperator { 15 | 16 | public abstract boolean evaluate(); 17 | 18 | public static EqualOperator Convert(Operator left, Operator right) { 19 | if (left instanceof NumberOperator) { 20 | if (right instanceof NumberOperator) { 21 | return new NumberEqualOperator((NumberOperator) left, (NumberOperator) right); 22 | } 23 | if (right instanceof ConditionOperator) { 24 | throw new IllegalStateException("number不能与boolean进行比较"); 25 | } 26 | } 27 | if (left instanceof ConditionOperator) { 28 | if (right instanceof ConditionOperator) { 29 | return new BooleanEqualOperator((ConditionOperator) left, (ConditionOperator) right); 30 | } 31 | if (right instanceof NumberOperator) { 32 | throw new IllegalStateException("number不能与boolean进行比较"); 33 | } 34 | } 35 | return new StringEqualOperator(StringOperator.Convert(left), StringOperator.Convert(right)); 36 | } 37 | 38 | @AllArgsConstructor 39 | public static class StringEqualOperator extends EqualOperator { 40 | 41 | StringOperator left; 42 | StringOperator right; 43 | 44 | @Override 45 | public boolean evaluate() { 46 | return left.equals(right); 47 | } 48 | } 49 | 50 | @AllArgsConstructor 51 | public static class BooleanEqualOperator extends EqualOperator { 52 | 53 | ConditionOperator left; 54 | ConditionOperator right; 55 | 56 | @Override 57 | public boolean evaluate() { 58 | return left.evaluate() == right.evaluate(); 59 | } 60 | } 61 | 62 | @AllArgsConstructor 63 | public static class NumberEqualOperator extends EqualOperator { 64 | 65 | NumberOperator left; 66 | NumberOperator right; 67 | 68 | @Override 69 | public boolean evaluate() { 70 | return left.evaluate() == right.evaluate(); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/command/SaveCommand.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.command; 2 | 3 | import github.saukiya.sxitem.SXItem; 4 | import github.saukiya.sxitem.data.item.ItemManager; 5 | import github.saukiya.sxitem.util.Message; 6 | import github.saukiya.tools.command.SenderType; 7 | import github.saukiya.tools.command.SubCommand; 8 | import github.saukiya.tools.nms.MessageUtil; 9 | import org.bukkit.Material; 10 | import org.bukkit.command.CommandSender; 11 | import org.bukkit.entity.Player; 12 | import org.bukkit.inventory.ItemStack; 13 | 14 | import java.io.IOException; 15 | import java.util.ArrayList; 16 | import java.util.Arrays; 17 | import java.util.Collections; 18 | import java.util.List; 19 | 20 | /** 21 | * 保存物品指令 22 | *

23 |  *  /si save Temp1 - 将手持物品保存为 Default类型 的 Temp1物品
24 |  *  /si save Temp2 Import - 将手持物品保存为 Import类型 的 Temp2物品
25 |  * 
26 | */ 27 | public class SaveCommand extends SubCommand { 28 | 29 | public SaveCommand() { 30 | super("save", 20); 31 | setArg("[item] "); 32 | setType(SenderType.PLAYER); 33 | } 34 | 35 | @Override 36 | public void onCommand(CommandSender sender, String[] args) { 37 | if (args.length < 2) { 38 | MessageUtil.send(sender, Message.ADMIN__NO_FORMAT.get()); 39 | return; 40 | } 41 | String itemName = args[1]; 42 | Player player = (Player) sender; 43 | ItemStack itemStack = player.getEquipment().getItemInHand(); 44 | if (itemStack.getType() == Material.AIR) { 45 | MessageUtil.send(player, Message.GIVE__NO_ITEM.get()); 46 | return; 47 | } 48 | if (SXItem.getItemManager().hasItem(itemName)) { 49 | MessageUtil.send(player, Message.SAVE__HAS_ITEM.get(itemName)); 50 | return; 51 | } 52 | try { 53 | if (SXItem.getItemManager().saveItem(itemName, itemStack.clone(), args.length > 2 ? args[2] : "Default")) { 54 | MessageUtil.send(sender, Message.SAVE__SAVE_ITEM.get(itemName)); 55 | } else { 56 | MessageUtil.send(sender, Message.SAVE__SAVE_NO_TYPE.get(itemName)); 57 | } 58 | } catch (IOException e) { 59 | e.printStackTrace(); 60 | MessageUtil.send(sender, Message.SAVE__SAVE_ITEM_ERROR.get(itemName)); 61 | } 62 | } 63 | 64 | @Override 65 | public List onTabComplete(CommandSender sender, String[] args) { 66 | if (args.length == 2 && args[1].isEmpty()) return Arrays.asList("[itemName]", args[1]); 67 | if (args.length == 3) { 68 | return new ArrayList<>(ItemManager.getLoadFunction().keySet()); 69 | } 70 | return Collections.emptyList(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nbt/TagType.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nbt; 2 | 3 | import github.saukiya.tools.nms.NbtUtil; 4 | import lombok.Getter; 5 | import lombok.RequiredArgsConstructor; 6 | 7 | import java.io.DataInput; 8 | import java.io.IOException; 9 | 10 | @RequiredArgsConstructor 11 | public enum TagType { 12 | END(TagEnd.typeMethod), 13 | BYTE(TagByte.typeMethod), 14 | SHORT(TagShort.typeMethod), 15 | INT(TagInt.typeMethod), 16 | LONG(TagLong.typeMethod), 17 | FLOAT(TagFloat.typeMethod), 18 | DOUBLE(TagDouble.typeMethod), 19 | BYTE_ARRAY(TagByteArray.typeMethod), 20 | STRING(TagString.typeMethod), 21 | LIST(TagList.typeMethod), 22 | COMPOUND(TagCompound.typeMethod), 23 | INT_ARRAY(TagIntArray.typeMethod), 24 | LONG_ARRAY(TagLongArray.typeMethod);//v1_12_R1+ 25 | 26 | @Getter 27 | private final byte id = (byte) this.ordinal(); 28 | 29 | private final Method methods; 30 | 31 | /** 32 | * 获取{@link Method#readTagBase(DataInput, int)} 和 {@link Method#toTag(Object)} 方法 33 | * 34 | * @param index nmsNBT的id 35 | * @return Method 36 | */ 37 | public static TagType.Method getMethods(int index) { 38 | return index >= 0 && index < TagType.values().length ? TagType.values()[index].methods : null; 39 | } 40 | 41 | /** 42 | * 从基础数据类型中转换成TagBase 43 | * 例如: 44 | * {@link java.util.Map} 45 | * {@link java.util.List} 46 | * {@link java.lang.reflect.Array} 47 | * {@link org.bukkit.configuration.MemorySection} 48 | * 以及基础类型 49 | * 50 | * @param object 基础数据 51 | * @return TagBase 52 | */ 53 | public static TagBase toTag(Object object) { 54 | if (object == null) return TagEnd.getInst(); 55 | if (object instanceof TagBase) return (TagBase) object; 56 | if (object instanceof NbtUtil.Wrapper) return NbtUtil.getInst().toTag(((NbtUtil.Wrapper) object).getHandle()); 57 | TagBase tagBase; 58 | for (TagType type : TagType.values()) { 59 | if ((tagBase = type.methods.toTag(object)) != null) { 60 | return tagBase; 61 | } 62 | } 63 | //Log 不支持的转化类型 64 | System.out.println("TagType.toTag error : " + object); 65 | return TagEnd.getInst(); 66 | } 67 | 68 | public interface Method { 69 | 70 | /** 71 | * 从IO中读取TagBase 72 | * 73 | * @param dataInput 数据读取 74 | * @param depth 深度值 暂时保留 75 | * @return TagBase 76 | * @throws IOException 不可能出现的IO报错 77 | */ 78 | TagBase readTagBase(DataInput dataInput, int depth) throws IOException; 79 | 80 | /** 81 | * {@link TagType#toTag(Object)} 82 | * 83 | * @param object 基础数据 84 | * @return TagBase 85 | */ 86 | TagBase toTag(Object object); 87 | 88 | } 89 | } -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/command/SubCommand.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.command; 2 | 3 | import github.saukiya.tools.nms.MessageUtil; 4 | import lombok.RequiredArgsConstructor; 5 | import org.bukkit.command.CommandSender; 6 | 7 | import java.text.MessageFormat; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | import java.util.Locale; 11 | 12 | /** 13 | * 次级指令 14 | */ 15 | @RequiredArgsConstructor 16 | public abstract class SubCommand implements Comparable { 17 | 18 | public final String cmd; 19 | 20 | final int priority; 21 | 22 | String arg = ""; 23 | 24 | boolean hide = false; 25 | 26 | SenderType[] types = new SenderType[]{SenderType.ALL}; 27 | 28 | MainCommand mainCommand; 29 | 30 | public abstract void onCommand(CommandSender sender, String[] args); 31 | 32 | public List onTabComplete(CommandSender sender, String[] args) { 33 | return null; 34 | } 35 | 36 | public boolean isUse(CommandSender sender, SenderType type) { 37 | return sender.hasPermission(permission()) && Arrays.stream(types).anyMatch(senderType -> senderType.equals(type) || senderType.equals(SenderType.ALL)); 38 | } 39 | 40 | protected String permission() { 41 | return mainCommand.plugin.getName().toLowerCase(Locale.ROOT) + "." + cmd; 42 | } 43 | 44 | protected String getIntroduction() { 45 | return mainCommand.message.apply("COMMAND." + cmd.toUpperCase()); 46 | } 47 | 48 | /** 49 | * 监听插件开启方法 50 | */ 51 | public void onEnable() { 52 | } 53 | 54 | /** 55 | * 监听重载方法 56 | */ 57 | public void onReload() { 58 | } 59 | 60 | /** 61 | * 监听关闭方法 62 | */ 63 | public void onDisable() { 64 | } 65 | 66 | /** 67 | * 设置额外参数格式 68 | */ 69 | protected final void setArg(String arg) { 70 | this.arg = " " + arg; 71 | } 72 | 73 | /** 74 | * 隐藏/显示指令 75 | * 76 | * @param hide 是否隐藏 77 | */ 78 | protected final void setHide(boolean hide) { 79 | this.hide = hide; 80 | } 81 | 82 | /** 83 | * 设置指令发送者类型 84 | * 85 | * @param types 发送者类型 86 | */ 87 | protected final void setType(SenderType... types) { 88 | this.types = types; 89 | } 90 | 91 | public final void sendIntroduction(CommandSender sender, String color, String label) { 92 | String clickCommand = MessageFormat.format("/{0} {1}", label, cmd); 93 | MessageUtil.getInst().builder() 94 | .add(color + MessageFormat.format("/{0} {1}{2}§7 - §c" + getIntroduction(), label, cmd, arg)) 95 | .show(sender.isOp() ? "§8§oPermission: " + permission() : null) 96 | .runCommand(clickCommand) 97 | .send(sender); 98 | } 99 | 100 | @Override 101 | public final int compareTo(SubCommand cmd) { 102 | return Integer.compare(priority, cmd.priority); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/resources/Localization/zh/RandomString/DefaultRandom.yml: -------------------------------------------------------------------------------- 1 | 品质: 2 | - 普通 3 | - 普通 4 | - 普通 5 | - 普通 6 | - 普通 7 | - 普通 8 | - 普通 9 | - 优秀 10 | - 优秀 11 | - 史诗 12 | 职业: 13 | - 射手 14 | - 战士 15 | - 剑士 16 | 纹理: '&0' 17 | 普通基数: 18 | 优秀基数: 19 | 史诗基数: 20 | 射手ID: '261' 21 | 战士ID: ID> 22 | 剑士ID: ID> 23 | 普通属判: # 75% 概率删除此行 24 | - ~ 25 | - ~ 26 | - ~ 27 | - '' 28 | 优秀属判: # 50% 概率删除此行 29 | - ~ 30 | - '' 31 | 史诗属判: # 25% 概率删除此行 32 | - ~ 33 | - '' 34 | - '' 35 | - '' 36 | 战士普通ID: '258' 37 | 战士优秀ID: '286' 38 | 战士史诗ID: '279' 39 | 剑士普通ID: '267' 40 | 剑士优秀ID: '283' 41 | 剑士史诗ID: '276' 42 | 普通Color: '&7' 43 | 优秀Color: '&a' 44 | 史诗Color: '&5' 45 | 普通颜色: 46 | - 47 | - 48 | - 49 | - 50 | 优秀颜色: 51 | - 52 | - 53 | 史诗颜色: 54 | - 55 | - 56 | - 57 | - 58 | 好看Color: 59 | - '&a' 60 | - '&b' 61 | - '&c' 62 | - '&4' 63 | - '&d' 64 | - '&1' 65 | - '&3' 66 | - '&9' 67 | 好丑Color: 68 | - '&1' 69 | - '&8' 70 | - '&7' 71 | - '&5' 72 | - '&3' 73 | - '&2' 74 | 射手附魔: 75 | - - ARROW_DAMAGE: 76 | - ARROW_INFINITE: 77 | - - ARROW_DAMAGE: 78 | - ARROW_FIRE: 79 | - - ARROW_DAMAGE: 80 | - DURABILITY: 81 | 战士附魔: 82 | - - DAMAGE_ALL: 83 | - FIRE_ASPECT: 84 | - - DAMAGE_ARTHROPODS: 85 | - KNOCKBACK: 86 | - - DAMAGE_UNDEAD: 87 | - LOOT_BONUS_MOBS: 88 | 剑士附魔: 89 | - - DAMAGE_ALL: 90 | - FIRE_ASPECT: 91 | - - DAMAGE_ALL: 92 | - KNOCKBACK: 93 | - - DAMAGE_ALL: 94 | - LOOT_BONUS_MOBS: 95 | DefaultLore: 96 | - '&7&o在月光下显得格外锋利,仿佛能切开夜空' 97 | - '&7&o散发着炽热的火焰,仿佛能燃尽一切' 98 | - '&7&o火焰重塑、泯灭了这里,就这样诞生了' 99 | - '&7&o每次使用都会发出低沉的嗡鸣,仿佛在诉说着古老的故事' 100 | - '&7&o它的表面布满了复杂的符文,似乎蕴藏着无尽的魔力' 101 | DefaultPrefix: 102 | - '&c令人兴奋之' 103 | - '&c煞胁之' 104 | - '&e兴趣使然之' 105 | - '&e初心者之' 106 | - '&e丝质之' 107 | - '&e精灵之' 108 | DefaultSuffix: 109 | - '&e淦' 110 | - '&e武' 111 | - '&e衡' 112 | 攻随一: 113 | - 命中几率 114 | - 失明几率 115 | - 缓慢几率 116 | - 凋零几率 117 | 攻随二: 118 | - 雷霆几率 119 | - 破甲几率 120 | - 撕裂几率 121 | 普通宝石孔: '&a&l『&7武石槽&a&l』' 122 | 优秀宝石孔: '&a&l『&7武石槽&a&l』&a&l『&7武石槽&a&l』' 123 | 史诗宝石孔: '&a&l『&7武石槽&a&l』&a&l『&7武石槽&a&l』&a&l『&7武石槽&a&l』' 124 | 125 | 攻一-10: 126 | - - '颜色>暴击几率: + * 基数>>%' 127 | - '颜色>暴击伤害: + * 基数>>%' 128 | - - '颜色>攻击速度: + * 基数>>%' 129 | - '颜色>点燃几率: + * 基数>>%' 130 | - - '颜色>吸血几率: + * 基数>>%' 131 | - '颜色>吸血倍率: + * 基数>>%' 132 | 攻二-10: 133 | - '属判>颜色>: + * 基数>>%' 134 | 攻三-10: 135 | - '属判>颜色>: + * 基数>>%' -------------------------------------------------------------------------------- /Module-Deprecated-v3/src/main/java/github/saukiya/sxitem/util/ItemUtil.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.util; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Getter; 6 | import lombok.experimental.Delegate; 7 | import org.bukkit.inventory.ItemStack; 8 | 9 | import javax.annotation.Nonnull; 10 | import javax.annotation.Nullable; 11 | import java.util.List; 12 | import java.util.UUID; 13 | import java.util.stream.Collectors; 14 | 15 | /** 16 | * @see github.saukiya.tools.nms.ItemUtil 17 | * @deprecated 18 | */ 19 | @AllArgsConstructor(access = AccessLevel.PRIVATE) 20 | public final class ItemUtil { 21 | 22 | @Getter 23 | private static final ItemUtil inst = new ItemUtil(github.saukiya.tools.nms.ItemUtil.getInst()); 24 | 25 | @Delegate 26 | private github.saukiya.tools.nms.ItemUtil target; 27 | 28 | @Deprecated 29 | public List getAttributes(ItemStack item) { 30 | return target.getAttributes(item).stream().map(AttributeData::new).collect(Collectors.toList()); 31 | } 32 | 33 | @Deprecated 34 | public void setAttributes(ItemStack item, @Nullable List list) { 35 | if (list == null) { 36 | target.setAttributes(item, null); 37 | return; 38 | } 39 | target.setAttributes(item, list.stream().map(x -> x.target).collect(Collectors.toList())); 40 | } 41 | 42 | @Deprecated 43 | public void addAttributes(ItemStack item, @Nonnull List list) { 44 | target.addAttributes(item, list.stream().map(x -> x.target).collect(Collectors.toList())); 45 | } 46 | 47 | @Deprecated 48 | public void addAttribute(ItemStack item, @Nonnull AttributeData data) { 49 | target.addAttribute(item, data.target); 50 | } 51 | 52 | @Deprecated 53 | @AllArgsConstructor(access = AccessLevel.PRIVATE) 54 | public static class AttributeData { 55 | 56 | @Delegate 57 | github.saukiya.tools.nms.ItemUtil.AttributeData target; 58 | 59 | @Deprecated 60 | public AttributeData() { 61 | target = new github.saukiya.tools.nms.ItemUtil.AttributeData(); 62 | } 63 | 64 | @Deprecated 65 | public AttributeData(String attrName, UUID uniqueId, String name, double amount, int operation, String slot) { 66 | target = new github.saukiya.tools.nms.ItemUtil.AttributeData(attrName, uniqueId, name, amount, operation, slot); 67 | target.setAttrName(attrName); 68 | target.setUniqueId(uniqueId); 69 | target.setName(name); 70 | target.setAmount(amount); 71 | target.setOperation(operation); 72 | target.setSlot(slot); 73 | } 74 | 75 | @Deprecated 76 | public AttributeData setAttrName(String attrName) { 77 | target.setAttrName(attrName); 78 | return this; 79 | } 80 | 81 | @Deprecated 82 | public AttributeData setSlot(String slot) { 83 | target.setSlot(slot); 84 | return this; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" "-Dfile.encoding=UTF-8" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/command/InfoCommand.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.command; 2 | 3 | import github.saukiya.sxitem.SXItem; 4 | import github.saukiya.sxitem.data.item.IGenerator; 5 | import github.saukiya.tools.command.SubCommand; 6 | import github.saukiya.tools.nms.NMS; 7 | import org.bukkit.Bukkit; 8 | import org.bukkit.command.CommandSender; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.event.EventHandler; 11 | import org.bukkit.event.Listener; 12 | import org.bukkit.event.player.PlayerPickupItemEvent; 13 | import org.bukkit.inventory.ItemStack; 14 | 15 | import java.util.Collections; 16 | import java.util.HashMap; 17 | import java.util.List; 18 | import java.util.Map; 19 | import java.util.stream.Collectors; 20 | 21 | public class InfoCommand extends SubCommand implements Listener { 22 | 23 | public InfoCommand() { 24 | super("info", 0); 25 | setArg("[item] "); 26 | setHide(true); 27 | } 28 | 29 | @Override 30 | public void onCommand(CommandSender sender, String[] args) { 31 | if (args.length < 2) { 32 | SXItem.getItemManager().sendItemInfoToPlayer(sender, sender instanceof Player ? "" : null); 33 | return; 34 | } 35 | Player player = null; 36 | 37 | IGenerator ig = SXItem.getItemManager().getGenerator(args[1]); 38 | if (ig == null) { 39 | SXItem.getItemManager().sendItemInfoToPlayer(sender, args[1]); 40 | return; 41 | } 42 | if (args.length > 2) { 43 | player = Bukkit.getPlayerExact(args[2]); 44 | } else if (sender instanceof Player) { 45 | player = (Player) sender; 46 | } 47 | 48 | Map otherMap = null; 49 | if (args.length > 2) { 50 | otherMap = new HashMap<>(); 51 | for (int i = 2; i < args.length; i++) { 52 | String[] splits = args[i].split(":", 2); 53 | if (splits.length == 1) continue; 54 | otherMap.put(splits[0], splits[1]); 55 | } 56 | } 57 | ItemStack itemStack = SXItem.getItemManager().getItem(ig, player, otherMap); 58 | if (NMS.compareTo(1, 20, 5) >= 0) { 59 | ComponentCommand.sendData(sender, itemStack); 60 | } 61 | NBTCommand.sendNBT(sender, itemStack); 62 | } 63 | 64 | @Override 65 | public List onTabComplete(CommandSender sender, String[] args) { 66 | switch (args.length) { 67 | case 2: 68 | return SXItem.getItemManager().getItemList().stream().filter(itemName -> itemName.toLowerCase().contains(args[1].toLowerCase())).collect(Collectors.toList()); 69 | case 3: 70 | return null; 71 | default: 72 | return Collections.emptyList(); 73 | } 74 | } 75 | 76 | @EventHandler 77 | void on(PlayerPickupItemEvent event) { 78 | Player player = event.getPlayer(); 79 | if (event.getItem().hasMetadata("SX-Item|DropData") && !player.isOp() && event.getItem().getMetadata("SX-Item|DropData").stream().noneMatch(data -> data.value().equals(player.getName()))) { 80 | event.getItem().setPickupDelay(5); 81 | event.setCancelled(true); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/github/saukiya/sxitem/command/ScriptCommand.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.command; 2 | 3 | import github.saukiya.sxitem.SXItem; 4 | import github.saukiya.sxitem.util.Message; 5 | import github.saukiya.tools.command.SubCommand; 6 | import github.saukiya.tools.nms.MessageUtil; 7 | import org.bukkit.Bukkit; 8 | import org.bukkit.command.CommandSender; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.event.Listener; 11 | 12 | import javax.script.Bindings; 13 | import java.util.Arrays; 14 | import java.util.List; 15 | import java.util.stream.Collectors; 16 | 17 | /** 18 | * 调用脚本指令 (脚本启用时生效) 19 | *
20 |  *  /si script Default testPlayer player Hello - 调用 Default 的 testPlayer 方法
21 |  * 
22 | */ 23 | public class ScriptCommand extends SubCommand implements Listener { 24 | 25 | public ScriptCommand() { 26 | super("script", 80); 27 | setArg("[file] [func] "); 28 | } 29 | 30 | @Override 31 | public void onCommand(CommandSender sender, String[] args) { 32 | if (args.length < 3) { 33 | MessageUtil.send(sender, Message.ADMIN__NO_FORMAT.get()); 34 | return; 35 | } 36 | if (!SXItem.getScriptManager().containsFile(args[1])) { 37 | MessageUtil.send(sender, Message.SCRIPT__NULL_FILE.get(args[1])); 38 | return; 39 | } 40 | Object[] scriptArgs = new Object[args.length - 3]; 41 | for (int i = 3, index = 0; i < args.length; i++, index++) { 42 | Player player = Bukkit.getPlayerExact(args[i]); 43 | if (player != null) scriptArgs[index] = player; 44 | scriptArgs[index] = player != null ? player : args[i]; 45 | } 46 | try { 47 | Object result = SXItem.getScriptManager().callFunction(args[1], args[2], scriptArgs.length != 0 ? scriptArgs : null); 48 | String[] resultPrint = new String[2]; 49 | if (result instanceof Bindings) { 50 | resultPrint[0] = Arrays.toString(((Bindings) result).entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).toArray(String[]::new)); 51 | resultPrint[1] = "Bindings"; 52 | } else { 53 | resultPrint[0] = String.valueOf(result); 54 | resultPrint[1] = result != null ? result.getClass().getSimpleName() : "N/A"; 55 | } 56 | MessageUtil.send(sender, Message.SCRIPT__INVOKE_RESULT.get(resultPrint[0], resultPrint[1])); 57 | } catch (Exception e) { 58 | MessageUtil.send(sender, Message.SCRIPT__INVOKE_FAIL.get(e.getMessage())); 59 | } 60 | } 61 | 62 | @Override 63 | public List onTabComplete(CommandSender sender, String[] args) { 64 | switch (args.length) { 65 | case 2: 66 | return SXItem.getScriptManager().getScriptNames().stream().filter(name -> name.contains(args[1])).collect(Collectors.toList()); 67 | case 3: 68 | return SXItem.getScriptManager().getScriptFunc(args[1]).stream().filter(name -> name.contains(args[2])).collect(Collectors.toList()); 69 | } 70 | return null; 71 | } 72 | 73 | @Override 74 | public void onEnable() { 75 | onReload(); 76 | } 77 | 78 | @Override 79 | public void onReload() { 80 | setHide(!SXItem.getScriptManager().isEnabled()); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/resources/Localization/en/RandomString/DefaultRandom.yml: -------------------------------------------------------------------------------- 1 | Quality: 2 | - Ordinary 3 | - Ordinary 4 | - Ordinary 5 | - Ordinary 6 | - Ordinary 7 | - Ordinary 8 | - Ordinary 9 | - Excellent 10 | - Excellent 11 | - Epic 12 | Occupation: 13 | - Shooter 14 | - Warrior 15 | - Swordsman 16 | Texture: '&0' 17 | OrdinaryBase: 18 | ExcellentBase: 19 | EpicBase: 20 | ShooterID: '261' 21 | WarriorID: ID> 22 | SwordsmanID: ID> 23 | OrdinaryJudgment: # 75% Probability Delete this row 24 | - ~ 25 | - ~ 26 | - ~ 27 | - '' 28 | ExcellentJudgment: # 50% Probability Delete this row 29 | - ~ 30 | - '' 31 | EpicJudgment: # 25% Probability Delete this row 32 | - ~ 33 | - '' 34 | - '' 35 | - '' 36 | WarriorOrdinaryID: '258' 37 | WarriorExcellentID: '286' 38 | WarriorEpicID: '279' 39 | SwordsmanOrdinaryID: '267' 40 | SwordsmanExcellentID: '283' 41 | SwordsmanEpicID: '276' 42 | OrdinaryNmColor: '&7' 43 | ExcellentNmColor: '&a' 44 | EpicNmColor: '&5' 45 | OrdinaryAttrColor: 46 | - 47 | - 48 | - 49 | - 50 | ExcellentAttrColor: 51 | - 52 | - 53 | EpicAttrColor: 54 | - 55 | - 56 | - 57 | - 58 | HighColor: 59 | - '&a' 60 | - '&b' 61 | - '&c' 62 | - '&4' 63 | - '&d' 64 | - '&1' 65 | - '&3' 66 | - '&9' 67 | UnderColor: 68 | - '&1' 69 | - '&8' 70 | - '&7' 71 | - '&5' 72 | - '&3' 73 | - '&2' 74 | ShooterEnchant: 75 | - - ARROW_DAMAGE: 76 | - ARROW_INFINITE: 77 | - - ARROW_DAMAGE: 78 | - ARROW_FIRE: 79 | - - ARROW_DAMAGE: 80 | - DURABILITY: 81 | WarriorEnchant: 82 | - - DAMAGE_ALL: 83 | - FIRE_ASPECT: 84 | - - DAMAGE_ARTHROPODS: 85 | - KNOCKBACK: 86 | - - DAMAGE_UNDEAD: 87 | - LOOT_BONUS_MOBS: 88 | SwordsmanEnchant: 89 | - - DAMAGE_ALL: 90 | - FIRE_ASPECT: 91 | - - DAMAGE_ALL: 92 | - KNOCKBACK: 93 | - - DAMAGE_ALL: 94 | - LOOT_BONUS_MOBS: 95 | Attribute1: 96 | - Hit Probability 97 | - Blind Probability 98 | - Slow Probability 99 | - Wither Probability 100 | Attribute2: 101 | - Thunder Probability 102 | - ArmorBreak Probability 103 | - Tear probability 104 | OrdinaryGemSlot: '&a&l『&7GemSlot&a&l』' 105 | ExcellentGemSlot: '&a&l『&7GemSlot&a&l』&a&l『&7GemSlot&a&l』' 106 | EpicGemSlot: '&a&l『&7GemSlot&a&l』&a&l『&7GemSlot&a&l』&a&l『&7GemSlot&a&l』' 107 | 108 | ATK1-10: 109 | - - 'AttrColor>CriticalHit Probability: + * Base>>%' 110 | - 'AttrColor>Critical Hit Damage: + * Base>>%' 111 | - - 'AttrColor>Attack Speed: + * Base>>%' 112 | - 'AttrColor>Ignite Probability: + * Base>>%' 113 | - - 'AttrColor>LifeSteal Probability: + * Base>>%' 114 | - 'AttrColor>LifeSteal Multiplier: + * Base>>%' 115 | ATK2-10: 116 | - 'Judgment>AttrColor>: + * Base>>%' 117 | ATK3-10: 118 | - 'Judgment>AttrColor>: + * Base>>%' -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/util/LogUtil.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.util; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.SneakyThrows; 5 | import lombok.val; 6 | import org.bukkit.Bukkit; 7 | import org.bukkit.event.EventHandler; 8 | import org.bukkit.event.Listener; 9 | import org.bukkit.event.server.PluginDisableEvent; 10 | import org.bukkit.plugin.java.JavaPlugin; 11 | 12 | import java.io.File; 13 | import java.text.SimpleDateFormat; 14 | import java.time.ZonedDateTime; 15 | import java.util.Arrays; 16 | import java.util.Date; 17 | import java.util.logging.FileHandler; 18 | import java.util.logging.Formatter; 19 | import java.util.logging.LogRecord; 20 | 21 | /** 22 | * 记录日志工具 23 | *
{@code
24 |  *  @Override
25 |  *  public void onEnable() {
26 |  *      LogUtil.setup(this);
27 |  *      //...
28 |  *  }
29 |  * }
30 | */ 31 | public class LogUtil { 32 | 33 | private static int timeOffset = ZonedDateTime.now().getOffset().getTotalSeconds(); 34 | 35 | /** 36 | * 创建日志工具类并自动记录日志 (需要在{@link JavaPlugin#onEnable()}后调用) 37 | * 38 | * @param plugin JavaPlugin 39 | */ 40 | @SneakyThrows 41 | public static void setup(JavaPlugin plugin) { 42 | if (!plugin.isEnabled()) { 43 | plugin.getLogger().info("Plugin not enabled"); 44 | return; 45 | } 46 | File logsFile = new File(plugin.getDataFolder(), "logs"); 47 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 48 | String dateStr = sdf.format(new Date()); 49 | int index = 1; 50 | if (logsFile.exists()) { 51 | index += Arrays.stream(logsFile.listFiles()).filter(file -> file.getName().startsWith(dateStr)).count(); 52 | } else { 53 | logsFile.mkdirs(); 54 | } 55 | val fileHandler = new FileHandler(logsFile.getAbsolutePath() + File.separator + dateStr + "-" + index + ".log"); 56 | val pluginNameIndex = plugin.getName().length() + 3; 57 | fileHandler.setEncoding("UTF-8"); 58 | fileHandler.setFormatter(new Formatter() { 59 | @Override 60 | public String format(LogRecord record) { 61 | val time = record.getMillis() / 1000 + timeOffset; 62 | val hours = time % 86400 / 3600; 63 | val minutes = time % 3600 / 60; 64 | val seconds = time % 60; 65 | return String.format("[%s] [%02d:%02d:%02d] %s\n", 66 | record.getLevel(), 67 | hours, minutes, seconds, 68 | record.getMessage().substring(Math.min(pluginNameIndex, record.getMessage().length()))); 69 | } 70 | }); 71 | plugin.getLogger().addHandler(fileHandler); 72 | Bukkit.getPluginManager().registerEvents(new EventListener(plugin, fileHandler), plugin); 73 | } 74 | 75 | /** 76 | * 不想写if导致的 77 | */ 78 | public static void setup(JavaPlugin plugin, boolean enabled) { 79 | if (!enabled) return; 80 | setup(plugin); 81 | } 82 | 83 | @AllArgsConstructor 84 | static class EventListener implements Listener { 85 | 86 | private final JavaPlugin plugin; 87 | private final FileHandler fileHandler; 88 | 89 | @EventHandler 90 | public void on(PluginDisableEvent event) { 91 | if (event.getPlugin() != plugin) return; 92 | plugin.getLogger().removeHandler(fileHandler); 93 | fileHandler.close(); 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /Module-Base/src/main/java/github/saukiya/tools/nbt/TagList.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nbt; 2 | 3 | import github.saukiya.tools.nms.NMS; 4 | import lombok.NoArgsConstructor; 5 | 6 | import java.io.DataInput; 7 | import java.io.DataOutput; 8 | import java.io.IOException; 9 | import java.util.Collection; 10 | import java.util.List; 11 | import java.util.Set; 12 | import java.util.stream.Collectors; 13 | 14 | @NoArgsConstructor 15 | public class TagList extends TagListBase> { 16 | 17 | protected static final TagType.Method typeMethod = new TagType.Method() { 18 | @Override 19 | public TagList readTagBase(DataInput dataInput, int depth) throws IOException { 20 | if (depth > 512) { 21 | throw new RuntimeException("Tried to read NBT tag with too high complexity, depth > 512"); 22 | } else { 23 | byte typeId = dataInput.readByte(); 24 | int length = dataInput.readInt(); 25 | if (typeId == 0 && length > 0) { 26 | throw new RuntimeException("Missing type on ListTag"); 27 | } else { 28 | TagType.Method method = TagType.getMethods(typeId); 29 | TagList tagList = new TagList(); 30 | for (int i = 0; i < length; ++i) { 31 | tagList.add(method.readTagBase(dataInput, depth + 1)); 32 | } 33 | return tagList; 34 | } 35 | } 36 | } 37 | 38 | @Override 39 | public TagListBase toTag(Object object) { 40 | if (object instanceof List) { 41 | List objectList = (List) object; 42 | if (!objectList.isEmpty()) { 43 | Set classSet = objectList.stream().map(Object::getClass).collect(Collectors.toSet()); 44 | if (classSet.contains(Long.class) && NMS.compareTo(1, 12, 1) >= 0) { 45 | return objectList.stream().map(o -> ((Number) o).longValue()).collect(Collectors.toCollection(TagLongArray::new)); 46 | } else if (classSet.contains(Integer.class)) { 47 | return objectList.stream().map(o -> ((Number) o).intValue()).collect(Collectors.toCollection(TagIntArray::new)); 48 | } else if (classSet.contains(Byte.class)) { 49 | return objectList.stream().map(o -> ((Number) o).byteValue()).collect(Collectors.toCollection(TagByteArray::new)); 50 | } 51 | return objectList.stream().map(TagType::toTag).collect(Collectors.toCollection(TagList::new)); 52 | } 53 | } 54 | return null; 55 | } 56 | }; 57 | 58 | public TagList(Collection collection) { 59 | super(collection.stream().map(TagType::toTag).collect(Collectors.toList())); 60 | } 61 | 62 | @Override 63 | public void write(DataOutput dataOutput) throws IOException { 64 | TagType type = isEmpty() ? TagType.END : get(0).getTypeId(); 65 | dataOutput.writeByte(type.getId()); 66 | dataOutput.writeInt(size()); 67 | for (TagBase tagBase : this) { 68 | tagBase.write(dataOutput); 69 | } 70 | } 71 | 72 | @Override 73 | public List getValue() { 74 | return this.stream().map(TagBase::getValue).collect(Collectors.toList()); 75 | } 76 | 77 | @Override 78 | public TagType getTypeId() { 79 | return TagType.LIST; 80 | } 81 | 82 | @Override 83 | public Object[] toArray() { 84 | return this.stream().map(TagBase::getValue).toArray(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/test/java/github/saukiya/deprecated/MaterialManager.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.deprecated; 2 | 3 | import lombok.Getter; 4 | import org.bukkit.Material; 5 | 6 | import java.util.HashMap; 7 | import java.util.Locale; 8 | import java.util.Map; 9 | import java.util.Set; 10 | import java.util.stream.Collectors; 11 | 12 | /** 13 | * 旧版材质管理器 14 | */ 15 | public class MaterialManager { 16 | @Getter 17 | private static final Map materialMap = new HashMap<>(); 18 | 19 | /** 20 | * 读取Material数据 21 | */ 22 | public static void loadMaterialData() { 23 | // materialMap.clear(); 24 | // File file = new File(SXItem.getInst().getDataFolder(), "deprecated/Material.yml"); 25 | // if (!file.exists()) { 26 | // SXItem.getInst().saveResource("deprecated/Material.yml", true); 27 | // } 28 | // boolean change = false; 29 | // YamlConfiguration yaml = YamlConfiguration.loadConfiguration(file); 30 | // boolean methodUse = NMS.compareTo(1, 13, 1) >= 0; 31 | // for (Map.Entry entry : yaml.getValues(false).entrySet()) { 32 | // Material material = Material.getMaterial(entry.getKey()); 33 | // if (material == null) { 34 | // try { 35 | // if (methodUse) material = Material.getMaterial(entry.getKey(), true); 36 | // if (material == null) { 37 | // SXItem.getInst().getLogger().warning("Material.yml No Material - " + entry.getKey()); 38 | // continue; 39 | // } 40 | // change = true; 41 | // SXItem.getInst().getLogger().config("Material.yml Change MaterialName - " + entry.getKey() + " To " + material.name()); 42 | // if (yaml.contains(material.name())) { 43 | // yaml.set(material.name(), yaml.getString(material.name()) + "," + entry.getValue()); 44 | // } else { 45 | // yaml.set(material.name(), entry.getValue()); 46 | // } 47 | // yaml.set(entry.getKey(), null); 48 | // } catch (Exception ignored) { 49 | // SXItem.getInst().getLogger().warning("Material.yml No Material - " + entry.getKey()); 50 | // continue; 51 | // } 52 | // } 53 | // for (String key : entry.getValue().toString().split(",")) { 54 | // if (!key.isEmpty()) { 55 | // Object ret = materialMap.put(key, material); 56 | // if (ret != null) { 57 | // SXItem.getInst().getLogger().warning("Material.yml Repeat Key - " + key + " (" + ret + "/" + material + ")"); 58 | // materialMap.remove(key); 59 | // } 60 | // } 61 | // } 62 | // } 63 | // if (change) yaml.save(file); 64 | // SXItem.getInst().getLogger().info("Loaded " + materialMap.size() + " Materials"); 65 | } 66 | 67 | /** 68 | * 获取物品材质 69 | *
70 |      * 可能参数: 267,
71 |      * 
72 | * 73 | * @param key 索引 74 | * @return 材质 75 | */ 76 | public static Material getMaterial(String key) { 77 | Material material = materialMap.get(key); 78 | return material != null ? material : Material.getMaterial(key.replace(' ', '_').toUpperCase(Locale.ROOT)); 79 | } 80 | 81 | public static Set getMaterialString(Material value) { 82 | return materialMap.entrySet().stream().filter(e -> e.getValue().equals(value)).map(Map.Entry::getKey).collect(Collectors.toSet()); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /Module-Deprecated-v3/src/main/java/github/saukiya/sxitem/util/CommandUtil.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.sxitem.util; 2 | 3 | import github.saukiya.tools.helper.PlaceholderHelper; 4 | import github.saukiya.tools.nms.MessageUtil; 5 | import org.bukkit.Bukkit; 6 | import org.bukkit.Sound; 7 | import org.bukkit.entity.Player; 8 | import org.bukkit.plugin.Plugin; 9 | 10 | import java.util.List; 11 | import java.util.regex.Matcher; 12 | import java.util.regex.Pattern; 13 | 14 | /** 15 | * @deprecated 16 | */ 17 | public class CommandUtil { 18 | 19 | private static final Pattern PATTERN = Pattern.compile("^\\[(.*?)] *(.+)"); 20 | 21 | private static final Plugin plugin = Bukkit.getPluginManager().getPlugin("SX-Item"); 22 | 23 | @Deprecated 24 | public static void run(Player player, List commandList) { 25 | int delay = 0; 26 | Runnable runnable; 27 | for (String cmd : PlaceholderHelper.setPlaceholders(player, commandList)) { 28 | String command = cmd.replace("%player%", player.getName()).replace('&', '§'); 29 | Matcher matcher = PATTERN.matcher(command); 30 | if (matcher.find()) { 31 | if (matcher.group(1).equals("DELAY")) { 32 | delay += Integer.parseInt(matcher.group(2)); 33 | continue; 34 | } 35 | runnable = () -> run(player, matcher.group(1), matcher.group(2)); 36 | } else { 37 | runnable = () -> Bukkit.dispatchCommand(player, command); 38 | } 39 | Bukkit.getScheduler().runTaskLater(plugin, runnable, delay); 40 | } 41 | } 42 | 43 | @Deprecated 44 | public static void run(Player player, String command) { 45 | command = PlaceholderHelper.setPlaceholders(player, command).replace("%player%", player.getName()).replace('&', '§'); 46 | Matcher matcher = PATTERN.matcher(command); 47 | if (matcher.find()) { 48 | run(player, matcher.group(1), matcher.group(2)); 49 | } else { 50 | Bukkit.dispatchCommand(player, command); 51 | } 52 | } 53 | 54 | private static void run(Player player, String type, String command) { 55 | switch (type) { 56 | case "CONSOLE": 57 | Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); 58 | break; 59 | case "MESSAGE": 60 | player.sendMessage(command); 61 | break; 62 | case "CHAT": 63 | player.chat(command); 64 | break; 65 | case "BC": 66 | Bukkit.broadcastMessage(command); 67 | break; 68 | case "SOUND": 69 | String[] split = command.split(":"); 70 | player.playSound(player.getLocation(), Sound.valueOf(split[0]), Float.parseFloat(split[1]), Float.parseFloat(split[2])); 71 | break; 72 | case "ACTIONBAR": 73 | MessageUtil.getInst().sendActionBar(player, command); 74 | break; 75 | case "TITLE": 76 | String[] args = command.split(":"); 77 | int fadeIn = 5, stay = 20, fadeOut = 5; 78 | if (args.length > 4) { 79 | fadeIn = Integer.parseInt(args[2]); 80 | stay = Integer.parseInt(args[3]); 81 | fadeOut = Integer.parseInt(args[4]); 82 | } 83 | MessageUtil.getInst().sendTitle(player, args[0], args.length > 1 ? args[1] : null, fadeIn, stay, fadeOut); 84 | break; 85 | default: 86 | plugin.getLogger().warning("No Command To Type: " + type + " -> " + command); 87 | break; 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/test/java/github/saukiya/deprecated/CmdUtil.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.deprecated; 2 | 3 | import github.saukiya.sxitem.SXItem; 4 | import github.saukiya.tools.helper.PlaceholderHelper; 5 | import github.saukiya.tools.nms.MessageUtil; 6 | import org.bukkit.Bukkit; 7 | import org.bukkit.Sound; 8 | import org.bukkit.entity.Player; 9 | 10 | import java.util.List; 11 | import java.util.regex.Matcher; 12 | import java.util.regex.Pattern; 13 | 14 | 15 | public class CmdUtil { 16 | 17 | private static final Pattern PATTERN = Pattern.compile("^\\[(.*?)] *(.+)"); 18 | 19 | /** 20 | * 快速执行指令列表 21 | * 22 | * @param player Player 23 | * @param commandList List 24 | */ 25 | public static void run(Player player, List commandList) { 26 | int delay = 0; 27 | Runnable runnable; 28 | for (String cmd : PlaceholderHelper.setPlaceholders(player, commandList)) { 29 | String command = cmd.replace("%player%", player.getName()).replace('&', '§'); 30 | Matcher matcher = PATTERN.matcher(command); 31 | if (matcher.find()) { 32 | if (matcher.group(1).equals("DELAY")) { 33 | delay += Integer.parseInt(matcher.group(2)); 34 | continue; 35 | } 36 | runnable = () -> run(player, matcher.group(1), matcher.group(2)); 37 | } else { 38 | runnable = () -> Bukkit.dispatchCommand(player, command); 39 | } 40 | Bukkit.getScheduler().runTaskLater(SXItem.getInst(), runnable, delay); 41 | } 42 | } 43 | 44 | /** 45 | * 快速执行指令 46 | * 47 | * @param player Player 48 | * @param command Command 49 | */ 50 | public static void run(Player player, String command) { 51 | command = PlaceholderHelper.setPlaceholders(player, command).replace("%player%", player.getName()).replace('&', '§'); 52 | Matcher matcher = PATTERN.matcher(command); 53 | if (matcher.find()) { 54 | run(player, matcher.group(1), matcher.group(2)); 55 | } else { 56 | Bukkit.dispatchCommand(player, command); 57 | } 58 | } 59 | 60 | private static void run(Player player, String type, String command) { 61 | switch (type) { 62 | case "CONSOLE": 63 | Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); 64 | break; 65 | case "MESSAGE": 66 | player.sendMessage(command); 67 | break; 68 | case "CHAT": 69 | player.chat(command); 70 | break; 71 | case "BC": 72 | Bukkit.broadcastMessage(command); 73 | break; 74 | case "SOUND": 75 | String[] split = command.split(":"); 76 | player.playSound(player.getLocation(), Sound.valueOf(split[0]), Float.parseFloat(split[1]), Float.parseFloat(split[2])); 77 | break; 78 | case "ACTIONBAR": 79 | MessageUtil.getInst().sendActionBar(player, command); 80 | break; 81 | case "TITLE": 82 | String[] args = command.split(":"); 83 | int fadeIn = 5, stay = 20, fadeOut = 5; 84 | if (args.length > 4) { 85 | fadeIn = Integer.parseInt(args[2]); 86 | stay = Integer.parseInt(args[3]); 87 | fadeOut = Integer.parseInt(args[4]); 88 | } 89 | MessageUtil.getInst().sendTitle(player, args[0], args.length > 1 ? args[1] : null, fadeIn, stay, fadeOut); 90 | break; 91 | default: 92 | SXItem.getInst().getLogger().warning("No Command To Type: " + type + " -> " + command); 93 | break; 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Module-NMS/V1_8_R3/src/main/java/github/saukiya/tools/nms/MessageUtil_v1_8_R3.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nms; 2 | 3 | import lombok.val; 4 | import net.md_5.bungee.api.ChatMessageType; 5 | import net.md_5.bungee.api.chat.BaseComponent; 6 | import net.md_5.bungee.api.chat.HoverEvent; 7 | import net.md_5.bungee.api.chat.TextComponent; 8 | import net.md_5.bungee.api.chat.TranslatableComponent; 9 | import net.minecraft.server.v1_8_R3.Item; 10 | import net.minecraft.server.v1_8_R3.PacketPlayOutChat; 11 | import net.minecraft.server.v1_8_R3.PacketPlayOutTitle; 12 | import org.bukkit.Material; 13 | import org.bukkit.command.CommandSender; 14 | import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; 15 | import org.bukkit.craftbukkit.v1_8_R3.util.CraftChatMessage; 16 | import org.bukkit.craftbukkit.v1_8_R3.util.CraftMagicNumbers; 17 | import org.bukkit.entity.Player; 18 | import org.bukkit.inventory.ItemStack; 19 | 20 | import java.util.Locale; 21 | 22 | public class MessageUtil_v1_8_R3 extends MessageUtil { 23 | 24 | @Override 25 | public void sendActionBar(Player player, String message) { 26 | CraftPlayer craftPlayer = (CraftPlayer) player; 27 | PacketPlayOutChat packet = new PacketPlayOutChat(null, (byte) ChatMessageType.ACTION_BAR.ordinal()); 28 | packet.components = new BaseComponent[]{new TextComponent(message)}; 29 | craftPlayer.getHandle().playerConnection.sendPacket(packet); 30 | } 31 | 32 | @Override 33 | public void sendTitle(Player player, String title, String subtitle, int fadeIn, int stay, int fadeOut) { 34 | CraftPlayer craftPlayer = (CraftPlayer) player; 35 | 36 | PacketPlayOutTitle packetSubtitle = new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.TITLE, CraftChatMessage.fromString(title)[0], fadeIn, stay, fadeOut); 37 | craftPlayer.getHandle().playerConnection.sendPacket(packetSubtitle); 38 | 39 | if (subtitle != null) { 40 | packetSubtitle = new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.SUBTITLE, CraftChatMessage.fromString(subtitle)[0], fadeIn, stay, fadeOut); 41 | craftPlayer.getHandle().playerConnection.sendPacket(packetSubtitle); 42 | } 43 | } 44 | 45 | @Override 46 | public Builder builder() { 47 | return new BuilderImpl(); 48 | } 49 | 50 | static class BuilderImpl extends Builder { 51 | 52 | @Override 53 | public Builder add(Material material) { 54 | Item item = CraftMagicNumbers.getItem(material); 55 | add(new TranslatableComponent((item.k() ? new net.minecraft.server.v1_8_R3.ItemStack(item).a() : item.getName()) + ".name")); 56 | return this; 57 | } 58 | 59 | @Override 60 | public Builder show(String text) { 61 | current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new BaseComponent[]{new TextComponent("§7" + text)})); 62 | return this; 63 | } 64 | 65 | @Override 66 | public Builder show(ItemStack item) { 67 | val wrapper = NbtUtil.getInst().createTagWrapper(); 68 | wrapper.set("id", "minecraft:" + item.getType().name().toLowerCase(Locale.ROOT)); 69 | wrapper.set("Count", (byte) item.getAmount()); 70 | wrapper.set("Damage", item.getDurability()); 71 | wrapper.set("tag", NbtUtil.getInst().getItemNBT(item)); 72 | current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new BaseComponent[]{new TextComponent(wrapper.nbtToString())})); 73 | return this; 74 | } 75 | 76 | @Override 77 | public void send(CommandSender sender) { 78 | if (sender instanceof Player) { 79 | ((Player) sender).spigot().sendMessage(handle); 80 | } else { 81 | sender.sendMessage(handle.toLegacyText()); 82 | } 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Module-NMS/V1_11_R1/src/main/java/github/saukiya/tools/nms/ItemUtil_v1_11_R1.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nms; 2 | 3 | import lombok.val; 4 | import org.bukkit.inventory.ItemStack; 5 | import org.bukkit.inventory.meta.ItemMeta; 6 | import org.bukkit.inventory.meta.SkullMeta; 7 | 8 | import javax.annotation.Nonnull; 9 | import java.util.*; 10 | import java.util.function.Consumer; 11 | import java.util.function.Function; 12 | import java.util.stream.Collectors; 13 | 14 | public class ItemUtil_v1_11_R1 extends ItemUtil { 15 | 16 | public void editAttribute(ItemStack item, Consumer> computeListFunction) { 17 | editAttribute(item, wrapper -> (List) wrapper.getList("AttributeModifiers", new ArrayList<>()), computeListFunction); 18 | } 19 | 20 | public void editAttribute(ItemStack item, Function> toListFunction, Consumer> computeListFunction) { 21 | val wrapper = NbtUtil.getInst().getItemTagWrapper(item); 22 | List modifiers = toListFunction.apply(wrapper); 23 | computeListFunction.accept(modifiers); 24 | wrapper.set("AttributeModifiers", modifiers == null || modifiers.isEmpty() ? null : modifiers); 25 | wrapper.save(); 26 | } 27 | 28 | public void addAttribute(List list, AttributeData data) { 29 | if (data.getAttrNameNBT() == null) return; 30 | Map map = new HashMap<>(); 31 | map.put("AttributeName", data.getAttrNameNBT()); 32 | map.put("UUIDMost", data.getUniqueId().getMostSignificantBits()); 33 | map.put("UUIDLeast", data.getUniqueId().getLeastSignificantBits()); 34 | map.put("Name", data.getName()); 35 | map.put("Amount", data.getAmount()); 36 | map.put("Operation", data.getOperation()); 37 | map.put("Slot", data.getSlotNBT()); 38 | list.add(map); 39 | } 40 | 41 | @Override 42 | public boolean isUnbreakable(@Nonnull ItemMeta meta) { 43 | return meta.isUnbreakable(); 44 | } 45 | 46 | @Override 47 | public void setUnbreakable(@Nonnull ItemMeta meta, boolean unbreakable) { 48 | meta.setUnbreakable(unbreakable); 49 | } 50 | 51 | @Override 52 | public String getSkull(ItemMeta meta) { 53 | if (meta instanceof SkullMeta && ((SkullMeta) meta).hasOwner()) return ((SkullMeta) meta).getOwner(); 54 | return null; 55 | } 56 | 57 | @Override 58 | public void setSkull(ItemMeta meta, String value) { 59 | if (meta instanceof SkullMeta) ((SkullMeta) meta).setOwner(value); 60 | } 61 | 62 | @Override 63 | public List getAttributes(ItemStack item) { 64 | return ((List>) NbtUtil.getInst().getItemTagWrapper(item).getList("AttributeModifiers", new ArrayList<>())).stream().map( 65 | map -> new AttributeData( 66 | (String) map.get("AttributeName"), 67 | new UUID((long) map.get("UUIDMost"), (long) map.get("UUIDLeast")), 68 | (String) map.get("Name"), 69 | (double) map.get("Amount"), 70 | (int) map.get("Operation"), 71 | (String) map.get("Slot") 72 | ) 73 | ).collect(Collectors.toList()); 74 | } 75 | 76 | @Override 77 | public void setAttributes(ItemStack item, List list) { 78 | editAttribute(item, wrapper -> new ArrayList<>(), modifiers -> { 79 | if (list != null) { 80 | list.forEach(data -> addAttribute(modifiers, data)); 81 | } 82 | }); 83 | } 84 | 85 | @Override 86 | public void addAttributes(ItemStack item, List list) { 87 | editAttribute(item, modifiers -> list.forEach(data -> addAttribute(modifiers, data))); 88 | } 89 | 90 | @Override 91 | public void addAttribute(ItemStack item, AttributeData data) { 92 | editAttribute(item, modifiers -> addAttribute(modifiers, data)); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Module-NMS/V1_20_R4/src/main/java/github/saukiya/tools/nms/ComponentUtil_v1_20_R4.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nms; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.mojang.serialization.DynamicOps; 5 | import com.mojang.serialization.JavaOps; 6 | import com.mojang.serialization.JsonOps; 7 | import net.minecraft.core.IRegistryCustom; 8 | import net.minecraft.core.component.DataComponentMap; 9 | import net.minecraft.core.component.DataComponentPatch; 10 | import net.minecraft.core.component.DataComponentType; 11 | import net.minecraft.core.component.PatchedDataComponentMap; 12 | import net.minecraft.core.registries.BuiltInRegistries; 13 | import net.minecraft.resources.MinecraftKey; 14 | import org.bukkit.craftbukkit.v1_20_R4.CraftRegistry; 15 | 16 | import java.util.List; 17 | 18 | public class ComponentUtil_v1_20_R4 extends ComponentUtil { 19 | 20 | private final IRegistryCustom registry = CraftRegistry.getMinecraftRegistry(); 21 | 22 | private final DynamicOps jsonDynamic = registry.a(JsonOps.INSTANCE); 23 | private final DynamicOps javaDynamic = registry.a(JavaOps.INSTANCE); 24 | 25 | @Override 26 | public DataComponentMap getDataComponentMap(Object nmsItem) { 27 | return ((net.minecraft.world.item.ItemStack) nmsItem).a(); 28 | } 29 | 30 | @Override 31 | public DataComponentPatch getDataComponentPatch(Object nmsItem) { 32 | return ((net.minecraft.world.item.ItemStack) nmsItem).d(); 33 | } 34 | 35 | @Override 36 | public void setDataComponentMap(Object nmsItem, Object dataComponentMap) { 37 | ((net.minecraft.world.item.ItemStack) nmsItem).b((DataComponentMap) dataComponentMap); 38 | } 39 | 40 | @Override 41 | public void setDataComponentPatch(Object nmsItem, Object dataComponentPatch) { 42 | ((net.minecraft.world.item.ItemStack) nmsItem).b((DataComponentPatch) dataComponentPatch); 43 | } 44 | 45 | @Override 46 | public JsonElement mapToJson(Object dataComponentMap) { 47 | return DataComponentMap.b.encode((DataComponentMap) dataComponentMap, jsonDynamic, jsonDynamic.emptyMap()).getOrThrow(); 48 | } 49 | 50 | @Override 51 | public JsonElement patchToJson(Object dataComponentPatch) { 52 | return DataComponentPatch.b.encode((DataComponentPatch) dataComponentPatch, jsonDynamic, jsonDynamic.emptyMap()).getOrThrow(); 53 | } 54 | 55 | @Override 56 | public DataComponentMap jsonToMap(JsonElement jsonElement) { 57 | return DataComponentMap.b.decode(jsonDynamic, jsonElement).getOrThrow().getFirst(); 58 | } 59 | 60 | @Override 61 | public DataComponentPatch jsonToPatch(JsonElement jsonElement) { 62 | return DataComponentPatch.b.decode(jsonDynamic, jsonElement).getOrThrow().getFirst(); 63 | } 64 | 65 | @Override 66 | public Object mapToValue(Object dataComponentMap) { 67 | return DataComponentMap.b.encode((DataComponentMap) dataComponentMap, javaDynamic, javaDynamic.emptyMap()).getOrThrow(); 68 | } 69 | 70 | @Override 71 | public Object patchToValue(Object dataComponentPatch) { 72 | return DataComponentPatch.b.encode((DataComponentPatch) dataComponentPatch, javaDynamic, javaDynamic.emptyMap()).getOrThrow(); 73 | } 74 | 75 | @Override 76 | public Object valueToMap(Object javaObject) { 77 | return DataComponentMap.b.decode(javaDynamic, javaObject).getOrThrow().getFirst(); 78 | } 79 | 80 | @Override 81 | public Object valueToPatch(Object javaObject) { 82 | return DataComponentPatch.b.decode(javaDynamic, javaObject).getOrThrow().getFirst(); 83 | } 84 | 85 | @Override 86 | public void setComponentMapValue(Object dataComponentMap, String type, Object value) { 87 | DataComponentType dataComponentType = BuiltInRegistries.as.a(new MinecraftKey(type)); 88 | PatchedDataComponentMap map = (PatchedDataComponentMap) dataComponentMap; 89 | map.b(dataComponentType, value); 90 | } 91 | 92 | @Override 93 | public List getItemKeys() { 94 | return BuiltInRegistries.as.e().stream().map(MinecraftKey::toString).toList(); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Module-NMS/V1_21_R1/src/main/java/github/saukiya/tools/nms/ComponentUtil_v1_21_R1.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nms; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.mojang.serialization.DynamicOps; 5 | import com.mojang.serialization.JavaOps; 6 | import com.mojang.serialization.JsonOps; 7 | import net.minecraft.core.IRegistryCustom; 8 | import net.minecraft.core.component.DataComponentMap; 9 | import net.minecraft.core.component.DataComponentPatch; 10 | import net.minecraft.core.component.DataComponentType; 11 | import net.minecraft.core.component.PatchedDataComponentMap; 12 | import net.minecraft.core.registries.BuiltInRegistries; 13 | import net.minecraft.resources.MinecraftKey; 14 | import org.bukkit.craftbukkit.v1_21_R1.CraftRegistry; 15 | 16 | import java.util.List; 17 | 18 | public class ComponentUtil_v1_21_R1 extends ComponentUtil { 19 | 20 | private final IRegistryCustom registry = CraftRegistry.getMinecraftRegistry(); 21 | 22 | private final DynamicOps jsonDynamic = registry.a(JsonOps.INSTANCE); 23 | private final DynamicOps javaDynamic = registry.a(JavaOps.INSTANCE); 24 | 25 | @Override 26 | public DataComponentMap getDataComponentMap(Object nmsItem) { 27 | return ((net.minecraft.world.item.ItemStack) nmsItem).a(); 28 | } 29 | 30 | @Override 31 | public DataComponentPatch getDataComponentPatch(Object nmsItem) { 32 | return ((net.minecraft.world.item.ItemStack) nmsItem).d(); 33 | } 34 | 35 | @Override 36 | public void setDataComponentMap(Object nmsItem, Object dataComponentMap) { 37 | ((net.minecraft.world.item.ItemStack) nmsItem).b((DataComponentMap) dataComponentMap); 38 | } 39 | 40 | @Override 41 | public void setDataComponentPatch(Object nmsItem, Object dataComponentPatch) { 42 | ((net.minecraft.world.item.ItemStack) nmsItem).b((DataComponentPatch) dataComponentPatch); 43 | } 44 | 45 | @Override 46 | public JsonElement mapToJson(Object dataComponentMap) { 47 | return DataComponentMap.b.encode((DataComponentMap) dataComponentMap, jsonDynamic, jsonDynamic.emptyMap()).getOrThrow(); 48 | } 49 | 50 | @Override 51 | public JsonElement patchToJson(Object dataComponentPatch) { 52 | return DataComponentPatch.b.encode((DataComponentPatch) dataComponentPatch, jsonDynamic, jsonDynamic.emptyMap()).getOrThrow(); 53 | } 54 | 55 | @Override 56 | public DataComponentMap jsonToMap(JsonElement jsonElement) { 57 | return DataComponentMap.b.decode(jsonDynamic, jsonElement).getOrThrow().getFirst(); 58 | } 59 | 60 | @Override 61 | public DataComponentPatch jsonToPatch(JsonElement jsonElement) { 62 | return DataComponentPatch.b.decode(jsonDynamic, jsonElement).getOrThrow().getFirst(); 63 | } 64 | 65 | @Override 66 | public Object mapToValue(Object dataComponentMap) { 67 | return DataComponentMap.b.encode((DataComponentMap) dataComponentMap, javaDynamic, javaDynamic.emptyMap()).getOrThrow(); 68 | } 69 | 70 | @Override 71 | public Object patchToValue(Object dataComponentPatch) { 72 | return DataComponentPatch.b.encode((DataComponentPatch) dataComponentPatch, javaDynamic, javaDynamic.emptyMap()).getOrThrow(); 73 | } 74 | 75 | @Override 76 | public Object valueToMap(Object javaObject) { 77 | return DataComponentMap.b.decode(javaDynamic, javaObject).getOrThrow().getFirst(); 78 | } 79 | 80 | @Override 81 | public Object valueToPatch(Object javaObject) { 82 | return DataComponentPatch.b.decode(javaDynamic, javaObject).getOrThrow().getFirst(); 83 | } 84 | 85 | @Override 86 | public void setComponentMapValue(Object dataComponentMap, String type, Object value) { 87 | DataComponentType dataComponentType = BuiltInRegistries.aq.a(MinecraftKey.c(type)); 88 | PatchedDataComponentMap map = (PatchedDataComponentMap) dataComponentMap; 89 | map.b(dataComponentType, value); 90 | } 91 | 92 | @Override 93 | public List getItemKeys() { 94 | return BuiltInRegistries.aq.f().stream().map(MinecraftKey::toString).toList(); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Module-NMS/V1_21_R2/src/main/java/github/saukiya/tools/nms/ComponentUtil_v1_21_R2.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nms; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.mojang.serialization.DynamicOps; 5 | import com.mojang.serialization.JavaOps; 6 | import com.mojang.serialization.JsonOps; 7 | import net.minecraft.core.IRegistryCustom; 8 | import net.minecraft.core.component.DataComponentMap; 9 | import net.minecraft.core.component.DataComponentPatch; 10 | import net.minecraft.core.component.DataComponentType; 11 | import net.minecraft.core.component.PatchedDataComponentMap; 12 | import net.minecraft.core.registries.BuiltInRegistries; 13 | import net.minecraft.resources.MinecraftKey; 14 | import org.bukkit.craftbukkit.v1_21_R2.CraftRegistry; 15 | 16 | import java.util.List; 17 | 18 | public class ComponentUtil_v1_21_R2 extends ComponentUtil { 19 | 20 | // Registries 21 | private final IRegistryCustom registry = CraftRegistry.getMinecraftRegistry(); 22 | 23 | private final DynamicOps jsonDynamic = registry.a(JsonOps.INSTANCE); 24 | private final DynamicOps javaDynamic = registry.a(JavaOps.INSTANCE); 25 | 26 | @Override 27 | public DataComponentMap getDataComponentMap(Object nmsItem) { 28 | return ((net.minecraft.world.item.ItemStack) nmsItem).a(); 29 | } 30 | 31 | @Override 32 | public DataComponentPatch getDataComponentPatch(Object nmsItem) { 33 | return ((net.minecraft.world.item.ItemStack) nmsItem).e(); 34 | } 35 | 36 | @Override 37 | public void setDataComponentMap(Object nmsItem, Object dataComponentMap) { 38 | ((net.minecraft.world.item.ItemStack) nmsItem).b((DataComponentMap) dataComponentMap); 39 | } 40 | 41 | @Override 42 | public void setDataComponentPatch(Object nmsItem, Object dataComponentPatch) { 43 | ((net.minecraft.world.item.ItemStack) nmsItem).b((DataComponentPatch) dataComponentPatch); 44 | } 45 | 46 | @Override 47 | public JsonElement mapToJson(Object dataComponentMap) { 48 | return DataComponentMap.b.encode((DataComponentMap) dataComponentMap, jsonDynamic, jsonDynamic.emptyMap()).getOrThrow(); 49 | } 50 | 51 | @Override 52 | public JsonElement patchToJson(Object dataComponentPatch) { 53 | return DataComponentPatch.b.encode((DataComponentPatch) dataComponentPatch, jsonDynamic, jsonDynamic.emptyMap()).getOrThrow(); 54 | } 55 | 56 | @Override 57 | public DataComponentMap jsonToMap(JsonElement jsonElement) { 58 | return DataComponentMap.b.decode(jsonDynamic, jsonElement).getOrThrow().getFirst(); 59 | } 60 | 61 | @Override 62 | public DataComponentPatch jsonToPatch(JsonElement jsonElement) { 63 | return DataComponentPatch.b.decode(jsonDynamic, jsonElement).getOrThrow().getFirst(); 64 | } 65 | 66 | @Override 67 | public Object mapToValue(Object dataComponentMap) { 68 | return DataComponentMap.b.encode((DataComponentMap) dataComponentMap, javaDynamic, javaDynamic.emptyMap()).getOrThrow(); 69 | } 70 | 71 | @Override 72 | public Object patchToValue(Object dataComponentPatch) { 73 | return DataComponentPatch.b.encode((DataComponentPatch) dataComponentPatch, javaDynamic, javaDynamic.emptyMap()).getOrThrow(); 74 | } 75 | 76 | @Override 77 | public Object valueToMap(Object javaObject) { 78 | return DataComponentMap.b.decode(javaDynamic, javaObject).getOrThrow().getFirst(); 79 | } 80 | 81 | @Override 82 | public Object valueToPatch(Object javaObject) { 83 | return DataComponentPatch.b.decode(javaDynamic, javaObject).getOrThrow().getFirst(); 84 | } 85 | 86 | @Override 87 | public void setComponentMapValue(Object dataComponentMap, String type, Object value) { 88 | DataComponentType dataComponentType = BuiltInRegistries.ao.a(MinecraftKey.c(type)); 89 | PatchedDataComponentMap map = (PatchedDataComponentMap) dataComponentMap; 90 | map.b(dataComponentType, value); 91 | } 92 | 93 | @Override 94 | public List getItemKeys() { 95 | return BuiltInRegistries.ao.i().stream().map(MinecraftKey::toString).toList(); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Module-NMS/V1_21_R3/src/main/java/github/saukiya/tools/nms/ComponentUtil_v1_21_R3.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nms; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.mojang.serialization.DynamicOps; 5 | import com.mojang.serialization.JavaOps; 6 | import com.mojang.serialization.JsonOps; 7 | import net.minecraft.core.IRegistryCustom; 8 | import net.minecraft.core.component.DataComponentMap; 9 | import net.minecraft.core.component.DataComponentPatch; 10 | import net.minecraft.core.component.DataComponentType; 11 | import net.minecraft.core.component.PatchedDataComponentMap; 12 | import net.minecraft.core.registries.BuiltInRegistries; 13 | import net.minecraft.resources.MinecraftKey; 14 | import org.bukkit.craftbukkit.v1_21_R3.CraftRegistry; 15 | 16 | import java.util.List; 17 | 18 | public class ComponentUtil_v1_21_R3 extends ComponentUtil { 19 | 20 | // Registries 21 | private final IRegistryCustom registry = CraftRegistry.getMinecraftRegistry(); 22 | 23 | private final DynamicOps jsonDynamic = registry.a(JsonOps.INSTANCE); 24 | private final DynamicOps javaDynamic = registry.a(JavaOps.INSTANCE); 25 | 26 | @Override 27 | public DataComponentMap getDataComponentMap(Object nmsItem) { 28 | return ((net.minecraft.world.item.ItemStack) nmsItem).a(); 29 | } 30 | 31 | @Override 32 | public DataComponentPatch getDataComponentPatch(Object nmsItem) { 33 | return ((net.minecraft.world.item.ItemStack) nmsItem).d(); 34 | } 35 | 36 | @Override 37 | public void setDataComponentMap(Object nmsItem, Object dataComponentMap) { 38 | ((net.minecraft.world.item.ItemStack) nmsItem).b((DataComponentMap) dataComponentMap); 39 | } 40 | 41 | @Override 42 | public void setDataComponentPatch(Object nmsItem, Object dataComponentPatch) { 43 | ((net.minecraft.world.item.ItemStack) nmsItem).b((DataComponentPatch) dataComponentPatch); 44 | } 45 | 46 | @Override 47 | public JsonElement mapToJson(Object dataComponentMap) { 48 | return DataComponentMap.b.encode((DataComponentMap) dataComponentMap, jsonDynamic, jsonDynamic.emptyMap()).getOrThrow(); 49 | } 50 | 51 | @Override 52 | public JsonElement patchToJson(Object dataComponentPatch) { 53 | return DataComponentPatch.b.encode((DataComponentPatch) dataComponentPatch, jsonDynamic, jsonDynamic.emptyMap()).getOrThrow(); 54 | } 55 | 56 | @Override 57 | public DataComponentMap jsonToMap(JsonElement jsonElement) { 58 | return DataComponentMap.b.decode(jsonDynamic, jsonElement).getOrThrow().getFirst(); 59 | } 60 | 61 | @Override 62 | public DataComponentPatch jsonToPatch(JsonElement jsonElement) { 63 | return DataComponentPatch.b.decode(jsonDynamic, jsonElement).getOrThrow().getFirst(); 64 | } 65 | 66 | @Override 67 | public Object mapToValue(Object dataComponentMap) { 68 | return DataComponentMap.b.encode((DataComponentMap) dataComponentMap, javaDynamic, javaDynamic.emptyMap()).getOrThrow(); 69 | } 70 | 71 | @Override 72 | public Object patchToValue(Object dataComponentPatch) { 73 | return DataComponentPatch.b.encode((DataComponentPatch) dataComponentPatch, javaDynamic, javaDynamic.emptyMap()).getOrThrow(); 74 | } 75 | 76 | @Override 77 | public Object valueToMap(Object javaObject) { 78 | return DataComponentMap.b.decode(javaDynamic, javaObject).getOrThrow().getFirst(); 79 | } 80 | 81 | @Override 82 | public Object valueToPatch(Object javaObject) { 83 | return DataComponentPatch.b.decode(javaDynamic, javaObject).getOrThrow().getFirst(); 84 | } 85 | 86 | @Override 87 | public void setComponentMapValue(Object dataComponentMap, String type, Object value) { 88 | DataComponentType dataComponentType = BuiltInRegistries.ao.a(MinecraftKey.c(type)); 89 | PatchedDataComponentMap map = (PatchedDataComponentMap) dataComponentMap; 90 | map.b(dataComponentType, value); 91 | } 92 | 93 | @Override 94 | public List getItemKeys() { 95 | return BuiltInRegistries.ao.i().stream().map(MinecraftKey::toString).toList(); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Module-NMS/V1_21_R4/src/main/java/github/saukiya/tools/nms/ComponentUtil_v1_21_R4.java: -------------------------------------------------------------------------------- 1 | package github.saukiya.tools.nms; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.mojang.serialization.DynamicOps; 5 | import com.mojang.serialization.JavaOps; 6 | import com.mojang.serialization.JsonOps; 7 | import net.minecraft.core.IRegistryCustom; 8 | import net.minecraft.core.component.DataComponentMap; 9 | import net.minecraft.core.component.DataComponentPatch; 10 | import net.minecraft.core.component.DataComponentType; 11 | import net.minecraft.core.component.PatchedDataComponentMap; 12 | import net.minecraft.core.registries.BuiltInRegistries; 13 | import net.minecraft.resources.MinecraftKey; 14 | import org.bukkit.craftbukkit.v1_21_R4.CraftRegistry; 15 | 16 | import java.util.List; 17 | 18 | public class ComponentUtil_v1_21_R4 extends ComponentUtil { 19 | 20 | // Registries 21 | private final IRegistryCustom registry = CraftRegistry.getMinecraftRegistry(); 22 | 23 | private final DynamicOps jsonDynamic = registry.a(JsonOps.INSTANCE); 24 | private final DynamicOps javaDynamic = registry.a(JavaOps.INSTANCE); 25 | 26 | @Override 27 | public DataComponentMap getDataComponentMap(Object nmsItem) { 28 | return ((net.minecraft.world.item.ItemStack) nmsItem).a(); 29 | } 30 | 31 | @Override 32 | public DataComponentPatch getDataComponentPatch(Object nmsItem) { 33 | return ((net.minecraft.world.item.ItemStack) nmsItem).d(); 34 | } 35 | 36 | @Override 37 | public void setDataComponentMap(Object nmsItem, Object dataComponentMap) { 38 | ((net.minecraft.world.item.ItemStack) nmsItem).b((DataComponentMap) dataComponentMap); 39 | } 40 | 41 | @Override 42 | public void setDataComponentPatch(Object nmsItem, Object dataComponentPatch) { 43 | ((net.minecraft.world.item.ItemStack) nmsItem).b((DataComponentPatch) dataComponentPatch); 44 | } 45 | 46 | @Override 47 | public JsonElement mapToJson(Object dataComponentMap) { 48 | return DataComponentMap.b.encode((DataComponentMap) dataComponentMap, jsonDynamic, jsonDynamic.emptyMap()).getOrThrow(); 49 | } 50 | 51 | @Override 52 | public JsonElement patchToJson(Object dataComponentPatch) { 53 | return DataComponentPatch.b.encode((DataComponentPatch) dataComponentPatch, jsonDynamic, jsonDynamic.emptyMap()).getOrThrow(); 54 | } 55 | 56 | @Override 57 | public DataComponentMap jsonToMap(JsonElement jsonElement) { 58 | return DataComponentMap.b.decode(jsonDynamic, jsonElement).getOrThrow().getFirst(); 59 | } 60 | 61 | @Override 62 | public DataComponentPatch jsonToPatch(JsonElement jsonElement) { 63 | return DataComponentPatch.b.decode(jsonDynamic, jsonElement).getOrThrow().getFirst(); 64 | } 65 | 66 | @Override 67 | public Object mapToValue(Object dataComponentMap) { 68 | return DataComponentMap.b.encode((DataComponentMap) dataComponentMap, javaDynamic, javaDynamic.emptyMap()).getOrThrow(); 69 | } 70 | 71 | @Override 72 | public Object patchToValue(Object dataComponentPatch) { 73 | return DataComponentPatch.b.encode((DataComponentPatch) dataComponentPatch, javaDynamic, javaDynamic.emptyMap()).getOrThrow(); 74 | } 75 | 76 | @Override 77 | public Object valueToMap(Object javaObject) { 78 | return DataComponentMap.b.decode(javaDynamic, javaObject).getOrThrow().getFirst(); 79 | } 80 | 81 | @Override 82 | public Object valueToPatch(Object javaObject) { 83 | return DataComponentPatch.b.decode(javaDynamic, javaObject).getOrThrow().getFirst(); 84 | } 85 | 86 | @Override 87 | public void setComponentMapValue(Object dataComponentMap, String type, Object value) { 88 | DataComponentType dataComponentType = BuiltInRegistries.am.a(MinecraftKey.c(type)); 89 | PatchedDataComponentMap map = (PatchedDataComponentMap) dataComponentMap; 90 | map.b(dataComponentType, value); 91 | } 92 | 93 | @Override 94 | public List getItemKeys() { 95 | return BuiltInRegistries.am.i().stream().map(MinecraftKey::toString).toList(); 96 | } 97 | } 98 | --------------------------------------------------------------------------------