From c9e53353ffbd4dc9b8886607f5704cbffcfbafbd Mon Sep 17 00:00:00 2001 From: LoneDev <27242001+LoneDev6@users.noreply.github.com> Date: Tue, 14 May 2024 13:52:25 +0200 Subject: [PATCH] Initial commit --- .gitattributes | 2 + .gitignore | 119 ++++ LICENSE | 674 ++++++++++++++++++ VanillaCustomizer-core/.gitignore | 113 +++ VanillaCustomizer-core/pom.xml | 119 ++++ .../lone/vanillacustomizer/ChangeSession.java | 86 +++ .../vanillacustomizer/Customizations.java | 513 +++++++++++++ ...InvalidCustomizationPropertyExtension.java | 9 + .../java/dev/lone/vanillacustomizer/Main.java | 159 +++++ .../api/VanillaCustomizerApi.java | 75 ++ .../commands/CommandRun.java | 38 + .../vanillacustomizer/commands/Commands.java | 12 + .../commands/registered/MainCommand.java | 135 ++++ .../customization/Customization.java | 52 ++ .../customization/changes/AttributesAdd.java | 83 +++ .../changes/AttributesRemove.java | 64 ++ .../customization/changes/EnchantsAdd.java | 37 + .../customization/changes/EnchantsRemove.java | 30 + .../customization/changes/FlagsAdd.java | 24 + .../customization/changes/IChange.java | 23 + .../customization/changes/LoreInsert.java | 68 ++ .../customization/changes/LoreInsertJson.java | 53 ++ .../customization/changes/LoreSet.java | 34 + .../customization/changes/LoreSetJson.java | 39 + .../customization/changes/ProtectNbtData.java | 17 + .../customization/changes/Renamer.java | 29 + .../customization/changes/RenamerJson.java | 31 + .../changes/ReplaceCustomModelData.java | 23 + .../changes/ReplaceDurability.java | 24 + .../changes/ReplaceMaterial.java | 21 + .../changes/ReplaceWordDisplayName.java | 36 + .../changes/ReplaceWordLore.java | 46 ++ .../customization/matchers/ITextMatcher.java | 6 + .../customization/matchers/RegexMatcher.java | 19 + .../matchers/RuleNbtMatcher.java | 107 +++ .../matchers/WildcardsMatcher.java | 83 +++ .../customization/rules/IRule.java | 14 + .../customization/rules/RuleEdible.java | 22 + .../rules/RuleHardnessGraterThan.java | 20 + .../customization/rules/RuleMaterial.java | 20 + .../rules/RuleMaterialRegex.java | 22 + .../rules/RuleMaterialWildcards.java | 44 ++ .../customization/rules/RuleMaterials.java | 29 + .../customization/rules/RulePlaceable.java | 19 + .../customization/rules/RuleRarity.java | 21 + .../customization/rules/RuleSmelted.java | 23 + .../rules/RuleVanillaItemMatcher.java | 54 ++ .../dev/lone/vanillacustomizer/nms/Nms.java | 69 ++ .../nms/items/IItemsNms.java | 14 + .../vanillacustomizer/nms/items/ItemsNms.java | 46 ++ .../vanillacustomizer/nms/items/Rarity.java | 18 + .../vanillacustomizer/utils/ConfigFile.java | 539 ++++++++++++++ .../vanillacustomizer/utils/EnumUtil.java | 17 + .../lone/vanillacustomizer/utils/Packets.java | 36 + .../vanillacustomizer/utils/SmallCaps.java | 24 + .../lone/vanillacustomizer/utils/Utilz.java | 599 ++++++++++++++++ .../contents/example_settings/config.yml | 44 ++ .../src/main/resources/plugin.yml | 9 + VanillaCustomizer-jar/jar-no-dependencies.xml | 17 + VanillaCustomizer-jar/pom.xml | 122 ++++ VanillaCustomizer-nms-v1_17_R1/.gitignore | 113 +++ VanillaCustomizer-nms-v1_17_R1/pom.xml | 55 ++ .../nms/items/impl/v1_17_R1.java | 47 ++ VanillaCustomizer-nms-v1_18_R2/.gitignore | 113 +++ VanillaCustomizer-nms-v1_18_R2/pom.xml | 55 ++ .../nms/items/impl/v1_18_R2.java | 47 ++ VanillaCustomizer-nms-v1_19_R3/.gitignore | 113 +++ VanillaCustomizer-nms-v1_19_R3/pom.xml | 55 ++ .../nms/items/impl/v1_19_R3.java | 47 ++ VanillaCustomizer-nms-v1_20_R1/.gitignore | 113 +++ VanillaCustomizer-nms-v1_20_R1/pom.xml | 55 ++ .../nms/items/impl/v1_20_R1.java | 47 ++ VanillaCustomizer-nms-v1_20_R2/.gitignore | 113 +++ VanillaCustomizer-nms-v1_20_R2/pom.xml | 55 ++ .../nms/items/impl/v1_20_R2.java | 47 ++ VanillaCustomizer-nms-v1_20_R3/pom.xml | 55 ++ .../nms/items/impl/v1_20_R3.java | 47 ++ maven_exec/CopyFile.bat | 5 + pom.xml | 118 +++ 79 files changed, 6145 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 VanillaCustomizer-core/.gitignore create mode 100644 VanillaCustomizer-core/pom.xml create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/ChangeSession.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/Customizations.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/InvalidCustomizationPropertyExtension.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/Main.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/api/VanillaCustomizerApi.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/commands/CommandRun.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/commands/Commands.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/commands/registered/MainCommand.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/Customization.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/AttributesAdd.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/AttributesRemove.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/EnchantsAdd.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/EnchantsRemove.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/FlagsAdd.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/IChange.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/LoreInsert.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/LoreInsertJson.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/LoreSet.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/LoreSetJson.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ProtectNbtData.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/Renamer.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/RenamerJson.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceCustomModelData.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceDurability.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceMaterial.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceWordDisplayName.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceWordLore.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/matchers/ITextMatcher.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/matchers/RegexMatcher.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/matchers/RuleNbtMatcher.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/matchers/WildcardsMatcher.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/IRule.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleEdible.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleHardnessGraterThan.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleMaterial.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleMaterialRegex.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleMaterialWildcards.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleMaterials.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RulePlaceable.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleRarity.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleSmelted.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleVanillaItemMatcher.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/nms/Nms.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/nms/items/IItemsNms.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/nms/items/ItemsNms.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/nms/items/Rarity.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/ConfigFile.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/EnumUtil.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/Packets.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/SmallCaps.java create mode 100644 VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/Utilz.java create mode 100644 VanillaCustomizer-core/src/main/resources/contents/example_settings/config.yml create mode 100644 VanillaCustomizer-core/src/main/resources/plugin.yml create mode 100644 VanillaCustomizer-jar/jar-no-dependencies.xml create mode 100644 VanillaCustomizer-jar/pom.xml create mode 100644 VanillaCustomizer-nms-v1_17_R1/.gitignore create mode 100644 VanillaCustomizer-nms-v1_17_R1/pom.xml create mode 100644 VanillaCustomizer-nms-v1_17_R1/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_17_R1.java create mode 100644 VanillaCustomizer-nms-v1_18_R2/.gitignore create mode 100644 VanillaCustomizer-nms-v1_18_R2/pom.xml create mode 100644 VanillaCustomizer-nms-v1_18_R2/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_18_R2.java create mode 100644 VanillaCustomizer-nms-v1_19_R3/.gitignore create mode 100644 VanillaCustomizer-nms-v1_19_R3/pom.xml create mode 100644 VanillaCustomizer-nms-v1_19_R3/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_19_R3.java create mode 100644 VanillaCustomizer-nms-v1_20_R1/.gitignore create mode 100644 VanillaCustomizer-nms-v1_20_R1/pom.xml create mode 100644 VanillaCustomizer-nms-v1_20_R1/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_20_R1.java create mode 100644 VanillaCustomizer-nms-v1_20_R2/.gitignore create mode 100644 VanillaCustomizer-nms-v1_20_R2/pom.xml create mode 100644 VanillaCustomizer-nms-v1_20_R2/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_20_R2.java create mode 100644 VanillaCustomizer-nms-v1_20_R3/pom.xml create mode 100644 VanillaCustomizer-nms-v1_20_R3/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_20_R3.java create mode 100644 maven_exec/CopyFile.bat create mode 100644 pom.xml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2293b2e --- /dev/null +++ b/.gitignore @@ -0,0 +1,119 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +target/ + +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next + +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# Common working directory +run/ +/.cache/ +/output/ +/.paper-nms/ +/custom_mapping.txt +/.assets/ +target \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e62ec04 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ +GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/VanillaCustomizer-core/.gitignore b/VanillaCustomizer-core/.gitignore new file mode 100644 index 0000000..4788b4b --- /dev/null +++ b/VanillaCustomizer-core/.gitignore @@ -0,0 +1,113 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +target/ + +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next + +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# Common working directory +run/ diff --git a/VanillaCustomizer-core/pom.xml b/VanillaCustomizer-core/pom.xml new file mode 100644 index 0000000..58cc771 --- /dev/null +++ b/VanillaCustomizer-core/pom.xml @@ -0,0 +1,119 @@ + + + + VanillaCustomizer + dev.lone + VERSION + + 4.0.0 + + VanillaCustomizer-core + + + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + jitpack-repo + https://jitpack.io + + + maven-central + https://oss.sonatype.org/content/groups/public + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.spigotmc + spigot + 1.19.2-R0.1-SNAPSHOT + remapped-mojang + provided + + + + dev.lone.LoneLibs + LoneLibs + 1.0 + system + ${jars_libs_folder}/LoneLibs.jar + + + + libs + ProtocolLib + 1.0 + system + ${jars_libs_folder}/ProtocolLib.jar + + + + + \ No newline at end of file diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/ChangeSession.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/ChangeSession.java new file mode 100644 index 0000000..9fc7205 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/ChangeSession.java @@ -0,0 +1,86 @@ +package dev.lone.vanillacustomizer; + +import dev.lone.LoneLibs.nbt.nbtapi.NBTItem; +import dev.lone.LoneLibs.annotations.Nullable; +import dev.lone.vanillacustomizer.customization.rules.RuleVanillaItemMatcher; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +// TODO: find a better name for this +public class ChangeSession +{ + public final ItemStack item; + public final ItemStack originalItem; + + public ItemMeta meta; + + public NBTItem nbt; + + public final boolean isVanilla; + + @Nullable + private Boolean hasChanged_cached; + + public ChangeSession(ItemStack item, boolean trackChanges) + { + this.item = item; + if(trackChanges) + this.originalItem = item.clone(); + else + this.originalItem = null; + + isVanilla = RuleVanillaItemMatcher.satisfy(item); + } + + public ItemMeta refreshMeta() + { + // Meta always needs to be refreshed as Spigot caches it! + meta = item.getItemMeta(); + return meta; + } + + private void refreshNbt() + { + nbt = new NBTItem(item); + } + + public NBTItem nbt() + { + if(nbt != null) + return nbt; + refreshNbt(); + return nbt; + } + + /** + * Shorthand to call saveMetaChanges and avoid deprecation warning + */ + @SuppressWarnings("deprecation") + public void saveNbt() + { +// nbt.saveMetaChanges(); // TODO: idk if I need to somehow save the data or not, probably new NBT api lib doesn't require it anymore. + } + + public void applyMeta() + { + this.item.setItemMeta(this.meta); + refreshNbt(); + } + + public boolean hasChanged() + { + if(hasChanged_cached != null) + return hasChanged_cached; + if(originalItem == null) + return false; + + hasChanged_cached = !originalItem.equals(item); + return hasChanged_cached; + } + + public void refreshAll() + { + refreshNbt(); + refreshMeta(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/Customizations.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/Customizations.java new file mode 100644 index 0000000..46ac7a6 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/Customizations.java @@ -0,0 +1,513 @@ +package dev.lone.vanillacustomizer; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import dev.lone.LoneLibs.annotations.Nullable; +import dev.lone.vanillacustomizer.api.VanillaCustomizerApi; +import dev.lone.vanillacustomizer.commands.registered.MainCommand; +import dev.lone.vanillacustomizer.customization.changes.*; +import dev.lone.vanillacustomizer.customization.Customization; +import dev.lone.vanillacustomizer.customization.matchers.RuleNbtMatcher; +import dev.lone.vanillacustomizer.customization.rules.*; +import dev.lone.vanillacustomizer.nms.items.Rarity; +import dev.lone.vanillacustomizer.utils.*; +import org.apache.commons.io.FileUtils; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeModifier; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; + +import java.io.File; +import java.util.*; + +public class Customizations +{ + public LinkedHashMap customizations = new LinkedHashMap<>(); + + public void load() + { + customizations.clear(); + + for (File file : getAllYmlFiles()) + { + ConfigFile config = new ConfigFile(Main.inst(), false, file.toPath().toString(), false, false); + + ConfigurationSection cosmeticsSection = config.getConfigurationSection("customizations"); + if (cosmeticsSection == null) // File has no rules + continue; + + for (String key : cosmeticsSection.getKeys(false)) + { + Customization customization = new Customization(); + ConfigurationSection section = config.getConfigurationSection("customizations." + key); + assert section != null; + + if(!section.getBoolean("enabled", true)) + continue; + + // TODO: rules_match: ANY | ALL + ConfigurationSection rulesSection = section.getConfigurationSection("rules"); + if (rulesSection == null) + { + Main.msg.error("Error: Customization '" + key + "' missing 'rules'. File: " + config.getPartialFilePath()); + continue; + } + + for (String matcherKey : rulesSection.getKeys(false)) + { + try + { + switch (matcherKey) + { + case "material_wildcards" -> + { + List materialWildcards = rulesSection.getStringList(matcherKey); + RuleMaterialWildcards rule = new RuleMaterialWildcards(); + for (String noMatch : rule.init(materialWildcards)) + { + Main.msg.warn("Warning: 'material_wildcards' -> '" + noMatch + "' of '" + key + "' has matched 0 items. File: " + config.getPartialFilePath()); + } + customization.addRule(rule); + } + case "material" -> + { + String matStr = rulesSection.getString(matcherKey); + Material material = EnumUtil.safeGet(matStr, Material.class, null); + if (material == null) + { + throwInvalidPropertyValue("material", matStr); +// Main.msg.error("Error: Customization '" + key + "' has invalid 'material'. File: " + config.getPartialFilePath()); + break; + } + + customization.addRule(new RuleMaterial(material)); + } + case "materials" -> + { + List matStrings = rulesSection.getStringList(matcherKey); + List materials = new ArrayList<>(); + for (String matStr : matStrings) + { + Material material = EnumUtil.safeGet(matStr, Material.class, null); + if (material == null) + { + throwInvalidPropertyValue("material", matStr); +// Main.msg.error("Error: Customization '" + key + "' has invalid 'material'. File: " + config.getPartialFilePath()); + } + else + { + materials.add(material); + } + } + + customization.addRule(new RuleMaterials(materials)); + } + case "material_regex" -> + { + String regexStr = rulesSection.getString(matcherKey); + RuleMaterialRegex ruleMaterialRegex = new RuleMaterialRegex(regexStr); + customization.addRule(ruleMaterialRegex); + } + case "nbt" -> + { + RuleNbtMatcher nbtMatcher = new RuleNbtMatcher( + rulesSection.getString(matcherKey + ".path"), + rulesSection.getString(matcherKey + ".value"), + rulesSection.getString(matcherKey + ".type", "string") + ); + customization.addRule(nbtMatcher); + } + // Matches only items which don't have custom lore and colored display name. + case "is_vanilla_item" -> + { + boolean isVanilla = rulesSection.getBoolean(matcherKey); + customization.addRule(new RuleVanillaItemMatcher(isVanilla)); + } + case "rarity" -> + { + String rarityString = rulesSection.getString(matcherKey, "").toUpperCase(); + Rarity rarity = EnumUtil.safeGet(rarityString, + Rarity.class, + null); + + if(rarity == null) + { + throwInvalidPropertyValue("rarity", rarityString); + continue; + } + RuleRarity rule = new RuleRarity(rarity); + customization.addRule(rule); + } + case "placeable" -> + { + boolean is = rulesSection.getBoolean(matcherKey); + customization.addRule(new RulePlaceable(is)); + } + case "hardness_greater_than" -> + { + double val = rulesSection.getDouble(matcherKey); + customization.addRule(new RuleHardnessGraterThan(val)); + } + case "edible" -> + { + boolean val = rulesSection.getBoolean(matcherKey); + customization.addRule(new RuleEdible(val)); + } + case "smelted" -> + { + boolean val = rulesSection.getBoolean(matcherKey); + customization.addRule(new RuleSmelted(val)); + } + } + } + catch (Throwable ex) + { + if(ex instanceof InvalidCustomizationPropertyExtension) + { + Main.msg.error("Error loading customization '" + key + "'. File: " + config.getPartialFilePath()); + Main.msg.error(ex.getMessage()); + } + else + Main.msg.error("Error loading customization '" + key + "'. File: " + config.getPartialFilePath(), ex); + } + } + + ConfigurationSection changesSection = section.getConfigurationSection("changes"); + if (changesSection == null) + { + Main.msg.error("Error: Customization '" + key + "' missing 'changes'. File: " + config.getPartialFilePath()); + continue; + } + + for (String changeKey : changesSection.getKeys(false)) + { + try + { + switch (changeKey) + { + case "rename" -> + { + String name = changesSection.getString(changeKey); + assert name != null; + customization.addChange(new Renamer(name)); + } + case "rename_json" -> + { + String json = changesSection.getString(changeKey); + customization.addChange(new RenamerJson(json)); + } + case "replace_word_display_name" -> + { + ConfigurationSection thisSection = changesSection.getConfigurationSection(changeKey); + if (thisSection == null) + throwInvalidConfig(); + String from = thisSection.getString("from"); + String to = thisSection.getString("to"); + customization.addChange(new ReplaceWordDisplayName(from, to)); + } + case "lore_set" -> + { + List list = changesSection.getStringList(changeKey); + customization.addChange(new LoreSet(list)); + } + case "lore_set_json" -> + { + List list = changesSection.getStringList(changeKey); + customization.addChange(new LoreSetJson(list)); + } + case "lore_insert" -> + { + ConfigurationSection thisSection = changesSection.getConfigurationSection(changeKey); + if (thisSection == null) + throwInvalidConfig(); + List list = thisSection.getStringList("lines"); + int index = thisSection.getInt("index", 0); + customization.addChange(new LoreInsert(list, index)); + } + case "lore_insert_json" -> + { + ConfigurationSection thisSection = changesSection.getConfigurationSection(changeKey); + if (thisSection == null) + throwInvalidConfig(); + List list = thisSection.getStringList("lines"); + int index = thisSection.getInt("index", 0); + customization.addChange(new LoreInsertJson(list, index)); + } + case "replace_word_lore" -> + { + ConfigurationSection thisSection = changesSection.getConfigurationSection(changeKey); + if (thisSection == null) + throwInvalidConfig(); + String from = thisSection.getString("from"); + String to = thisSection.getString("to"); + customization.addChange(new ReplaceWordLore(from, to)); + } + case "protect_nbt_data" -> + { + customization.addChange(new ProtectNbtData()); + } + case "durability" -> + { + short amount = (short) changesSection.getInt(changeKey); + customization.addChange(new ReplaceDurability(amount)); + } + case "custom_model_data" -> + { + int id = changesSection.getInt(changeKey); + customization.addChange(new ReplaceCustomModelData(id)); + } + case "add_enchants" -> + { + HashMap enchants = new HashMap<>(); + List enchantsStrings = changesSection.getStringList(changeKey); + for (String enchantStringEntry : enchantsStrings) + { + String[] tmp = enchantStringEntry.split(":"); + + Enchantment enchant = null; + int enchantLevel = 1; + if (tmp.length == 1) + { + enchant = Enchantment.getByName(tmp[0]); + + if (enchant == null) + enchant = Enchantment.getByKey(NamespacedKey.minecraft(tmp[0])); + } + else if (tmp.length == 2) + { + if (Utilz.isNumeric(tmp[1])) + { + enchant = Enchantment.getByName(tmp[0]); + enchantLevel = Utilz.parseInt(tmp[1], 1); + + if (enchant == null) + enchant = Enchantment.getByKey(NamespacedKey.minecraft(tmp[0])); + } + else + { + enchant = Enchantment.getByKey(new NamespacedKey(tmp[0], tmp[1])); + } + } + else if (tmp.length == 3) + { + enchant = Enchantment.getByKey(new NamespacedKey(tmp[0], tmp[1])); + enchantLevel = Utilz.parseInt(tmp[2], 1); + } + + enchants.put(enchant, enchantLevel); + } + + customization.addChange(new EnchantsAdd(enchants)); + } + case "remove_enchants" -> + { + List enchants = new ArrayList<>(); + List enchantsStrings = changesSection.getStringList(changeKey); + for (String enchantStringEntry : enchantsStrings) + { + String[] tmp = enchantStringEntry.split(":"); + + Enchantment enchant = null; + if (tmp.length == 1) + { + enchant = Enchantment.getByName(tmp[0]); + + if (enchant == null) + enchant = Enchantment.getByKey(NamespacedKey.minecraft(tmp[0])); + } + else if (tmp.length == 2) + { + if (Utilz.isNumeric(tmp[1])) + { + enchant = Enchantment.getByName(tmp[0]); + if (enchant == null) + enchant = Enchantment.getByKey(NamespacedKey.minecraft(tmp[0])); + } + else + { + enchant = Enchantment.getByKey(new NamespacedKey(tmp[0], tmp[1])); + } + } + else if (tmp.length == 3) + { + enchant = Enchantment.getByKey(new NamespacedKey(tmp[0], tmp[1])); + } + + enchants.add(enchant); + } + + customization.addChange(new EnchantsRemove(enchants)); + } + case "add_attributes" -> + { + Multimap modifiers = ArrayListMultimap.create(); + ConfigurationSection thisSection = changesSection.getConfigurationSection(changeKey); + if (thisSection == null) + throwInvalidConfig(); + + Set attributeEntriesKeys = thisSection.getKeys(false); + for (String attributeEntryKey : attributeEntriesKeys) + { + ConfigurationSection attributeSection = thisSection.getConfigurationSection(attributeEntryKey); + if (attributeSection == null) + throwInvalidConfig(); + + @Nullable String attributeStr = getStringOrThrow(attributeSection, "attribute"); + Attribute attribute = Utilz.strToAttributeType(attributeStr); + if (attribute == null) + throwInvalidPropertyValue("attribute"); + @Nullable String slotStr = getStringOrThrow(attributeSection, "slot"); + EquipmentSlot slot = Utilz.strToVanillaEquipmentSlot(slotStr); + if (slot == null) + throwInvalidPropertyValue("slot"); + + @Nullable String name = getStringOrThrow(attributeSection, "name"); + @Nullable String uuid = attributeSection.getString("uuid"); + @Nullable String operation = getStringOrThrow(attributeSection, "operation"); + @Nullable double amount = attributeSection.getDouble("amount", 0); + + AttributeModifier modifier = AttributesAdd.generateModifier( + uuid, + name, + attribute, + amount, + operation, + slot + ); + + modifiers.put(attribute, modifier); + } + + customization.addChange(new AttributesAdd(modifiers)); + } + case "flags" -> + { + List flagsStrings = changesSection.getStringList(changeKey); + if (flagsStrings.size() == 0) + throwInvalidPropertyValue("flags"); + + List flags = new ArrayList<>(); + + for (String flagsString : flagsStrings) + { + ItemFlag flag = EnumUtil.safeGet(flagsString, ItemFlag.class, null); + if(flag == null) + { + throwInvalidPropertyValue("flags", flagsString); + continue; + } + + flags.add(flag); + } + + customization.addChange(new FlagsAdd(flags)); + } + case "material" -> + { + Material material = EnumUtil.safeGet(changesSection.getString(changeKey, "").toUpperCase(), + Material.class, + null); + if (material == null) + throwInvalidPropertyValue("material"); + customization.addChange(new ReplaceMaterial(material)); + } + } + } + catch (Throwable ex) + { + if(ex instanceof InvalidCustomizationPropertyExtension) + { + Main.msg.error("Error loading customization '" + key + "'. File: " + config.getPartialFilePath()); + Main.msg.error(ex.getMessage()); + } + else + Main.msg.error("Error loading customization '" + key + "'. File: " + config.getPartialFilePath(), ex); + } + } + + + if (!customization.isEmpty()) + { + customizations.put(key, customization); + } + } + } + } + + private String getStringOrThrow(ConfigurationSection section, String name) + { + @Nullable String value = section.getString(name); + if(value == null) + throwMissingProperty(name); + return value; + } + + private void throwInvalidConfig() + { + throw new InvalidCustomizationPropertyExtension("Invalid configuration. Please check the tutorials."); + } + + private void throwMissingProperty(String name) + { + throw new InvalidCustomizationPropertyExtension("Missing property '" + name + "'."); + } + + private void throwInvalidPropertyValue(String name) + { + throw new InvalidCustomizationPropertyExtension("Invalid value for property '" + name + "'."); + } + + private void throwInvalidPropertyValue(String name, String value) + { + throw new InvalidCustomizationPropertyExtension("Invalid value for property '" + name + "' -> '" + value + "'."); + } + + public void handle(ItemStack itemStack, Player player) + { + if (itemStack == null || itemStack.getType() == Material.AIR) + return; + + boolean trackChanges = MainCommand.hasDebugTag(player); + ChangeSession session = new ChangeSession(itemStack, trackChanges); + for (Map.Entry entry : customizations.entrySet()) + { + Customization customization = entry.getValue(); + customization.handle(session); + } + + // Warning! This doesn't edit the session data. Do not access use "customization" obj + // after this line since it would result not updated with changes done by the API handlers. + boolean apiExecuted = VanillaCustomizerApi.inst().executeHandlers(session.item, player); + // In case the API executed any code. + if(apiExecuted) + session.refreshAll(); + + if(trackChanges && session.hasChanged()) + { + // TODO make it configurable + LoreInsert.putLine(session, 0, ChatColor.GOLD + SmallCaps.apply("VANILLACUSTOMIZER")); + //noinspection DataFlowIssue + if(session.refreshMeta().getLore().size() > 1) + LoreInsert.putLine(session, 1, " "); + } + } + + private static List getAllYmlFiles() + { + File cosmeticsDir = new File(Main.inst().getDataFolder().getAbsolutePath() + "/contents/"); + if (!cosmeticsDir.exists()) + cosmeticsDir.mkdirs(); + return new ArrayList<>(FileUtils.listFiles( + cosmeticsDir, + new String[]{"yml"}, + true + )); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/InvalidCustomizationPropertyExtension.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/InvalidCustomizationPropertyExtension.java new file mode 100644 index 0000000..b2a2e7b --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/InvalidCustomizationPropertyExtension.java @@ -0,0 +1,9 @@ +package dev.lone.vanillacustomizer; + +public class InvalidCustomizationPropertyExtension extends IllegalArgumentException +{ + public InvalidCustomizationPropertyExtension(String text) + { + super(text); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/Main.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/Main.java new file mode 100644 index 0000000..f01a5e1 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/Main.java @@ -0,0 +1,159 @@ +package dev.lone.vanillacustomizer; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers; +import com.comphenix.protocol.wrappers.Pair; +import dev.lone.LoneLibs.chat.Msg; +import dev.lone.vanillacustomizer.commands.Commands; +import dev.lone.vanillacustomizer.nms.items.ItemsNms; +import dev.lone.vanillacustomizer.utils.Packets; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerGameModeChangeEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.MerchantRecipe; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.List; + +public final class Main extends JavaPlugin implements Listener +{ + // Useful: + // https://lingojam.com/MinecraftSmallFont + // https://game8.co/games/Minecraft/archives/378457#hl_1 + + //DO NOT SET AS "final" OR SPIGOT.MC won't replace it. + public static String b = "%%__USER__%%"; + public static Msg msg; + + private static Main inst; + + public static Main inst() + { + return inst; + } + + Customizations customizations; + + @Override + public void onEnable() + { + inst = this; + + msg = new Msg("[VanillaCustomizer] "); + + Bukkit.getPluginManager().registerEvents(this, this); + + ItemsNms.inst().initialize(); + + customizations = new Customizations(); + + // https://nms.screamingsandals.org/1.19/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.html + Packets.out(this, PacketType.Play.Server.WINDOW_ITEMS, e -> { + Player player = e.getPlayer(); + if(player.getGameMode() == GameMode.CREATIVE) + return; + + PacketContainer packet = e.getPacket(); + List items = packet.getItemListModifier().read(0); + ItemStack carriedItem = packet.getItemModifier().read(0); + + for (ItemStack item : items) + { + customizations.handle(item, player); + } + + customizations.handle(carriedItem, player); + }); + + // https://nms.screamingsandals.org/1.19/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.html + Packets.out(this, PacketType.Play.Server.ENTITY_EQUIPMENT, e -> { + Player player = e.getPlayer(); + if(player.getGameMode() == GameMode.CREATIVE) + return; + + PacketContainer packet = e.getPacket(); + List> slotsPairs = packet.getSlotStackPairLists().read(0); + + for (Pair pair : slotsPairs) + { + customizations.handle(pair.getSecond(), player); + } + }); + + // https://nms.screamingsandals.org/1.19.2/net/minecraft/network/protocol/game/ClientboundContainerSetSlotPacket.html + Packets.out(this, PacketType.Play.Server.SET_SLOT, e -> { + Player player = e.getPlayer(); + if(player.getGameMode() == GameMode.CREATIVE) + return; + + PacketContainer packet = e.getPacket(); + + ItemStack itemStack = packet.getItemModifier().read(0); + customizations.handle(itemStack, player); + }); + + // https://mappings.cephx.dev/1.20.1/net/minecraft/network/protocol/game/ClientboundMerchantOffersPacket.html + Packets.out(this, PacketType.Play.Server.OPEN_WINDOW_MERCHANT, e -> { + Player player = e.getPlayer(); + if(player.getGameMode() == GameMode.CREATIVE) + return; + + PacketContainer packet = e.getPacket(); + List recipes = packet.getMerchantRecipeLists().read(0); + for (int i = 0, recipesSize = recipes.size(); i < recipesSize; i++) + { + // NOTE: for some reason, I don't know why, if I don't clone the items they actually get edited in-game! + // I'm sure since if I quit the server, remove the plugin and join I still see the edited recipes! + MerchantRecipe recipe = recipes.get(i); + List ingredients = recipe.getIngredients(); + for (int j = 0, ingredientsSize = ingredients.size(); j < ingredientsSize; j++) + { + ItemStack itemStack = ingredients.get(j).clone(); + customizations.handle(itemStack, player); + ingredients.set(j, itemStack); + } + + ItemStack result = recipe.getResult().clone(); + customizations.handle(result, player); + + MerchantRecipe newRecipe = new MerchantRecipe(result, recipe.getMaxUses()); + newRecipe.setUses(recipe.getUses()); + newRecipe.setDemand(recipe.getDemand()); + newRecipe.setPriceMultiplier(recipe.getPriceMultiplier()); + newRecipe.setExperienceReward(recipe.hasExperienceReward()); + newRecipe.setSpecialPrice(recipe.getSpecialPrice()); + newRecipe.setIngredients(ingredients); + newRecipe.setVillagerExperience(recipe.getVillagerExperience()); + + recipes.set(i, newRecipe); + } + + packet.getMerchantRecipeLists().write(0, recipes); + }); + + Commands.register(this); + + reload(); + } + + public void reload() + { + customizations.load(); + } + + @EventHandler(ignoreCancelled = true) + private void onGamemode(PlayerGameModeChangeEvent e) + { + // This is important to force the player inventory to update ( #updateInventory() triggers WINDOW_ITEMS packet) + // so that the CREATIVE gamemode won't edit the items, as CREATIVE makes the client apply any visual change + // to the items, the game works like that, for example custom clients can create any NBT item while in CREATIVE. + Bukkit.getScheduler().runTaskLater(this, () -> { + e.getPlayer().updateInventory(); + }, 5L); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/api/VanillaCustomizerApi.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/api/VanillaCustomizerApi.java new file mode 100644 index 0000000..1e011e6 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/api/VanillaCustomizerApi.java @@ -0,0 +1,75 @@ +package dev.lone.vanillacustomizer.api; + +import dev.lone.vanillacustomizer.Main; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.server.PluginDisableEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@SuppressWarnings("unused") +public class VanillaCustomizerApi implements Listener +{ + // + public static VanillaCustomizerApi inst() + { + if(inst == null) + inst = new VanillaCustomizerApi(Main.inst()); + return inst; + } + + public void registerHandler(Plugin plugin, CustomizerHandler handler) + { + handlers.computeIfAbsent(plugin, plugin1 -> new ArrayList<>()).add(handler); + } + + @FunctionalInterface + public interface CustomizerHandler + { + void call(Player player, ItemStack itemStack); + } + // + + // + private static final HashMap> handlers = new HashMap<>(); + + private static VanillaCustomizerApi inst; + + VanillaCustomizerApi(Plugin plugin) + { + Bukkit.getPluginManager().registerEvents(this, plugin); + } + + public boolean executeHandlers(ItemStack itemStack, Player player) + { + if(handlers.size() == 0) + return false; + + boolean executedAnything = false; + for (Map.Entry> entry : handlers.entrySet()) + { + List handlers = entry.getValue(); + for (CustomizerHandler handler : handlers) + { + handler.call(player, itemStack); + executedAnything = true; + } + } + + return executedAnything; + } + + @EventHandler + private void pluginUnload(PluginDisableEvent e) + { + handlers.remove(e.getPlugin()); + } + // +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/commands/CommandRun.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/commands/CommandRun.java new file mode 100644 index 0000000..67309d4 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/commands/CommandRun.java @@ -0,0 +1,38 @@ +package dev.lone.vanillacustomizer.commands; + +import dev.lone.LoneLibs.annotations.NotNull; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.List; + +public abstract class CommandRun implements CommandExecutor, TabCompleter +{ + protected CommandRun(JavaPlugin plugin, String name) + { + plugin.getCommand(name).setExecutor(this); + plugin.getCommand(name).setTabCompleter(this); + } + + protected abstract void run(Player sender, Command command, String label, String[] args); + + protected abstract void run(ConsoleCommandSender sender, Command command, String label, String[] args); + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) + { + if(sender instanceof Player) + run((Player) sender, command, label, args); + else if(sender instanceof ConsoleCommandSender) + run((ConsoleCommandSender) sender, command, label, args); + + return true; + } + + @Override + public List onTabComplete(@NotNull CommandSender sender, Command command, @NotNull String alias, @NotNull String[] args) + { + return List.of(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/commands/Commands.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/commands/Commands.java new file mode 100644 index 0000000..b69457c --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/commands/Commands.java @@ -0,0 +1,12 @@ +package dev.lone.vanillacustomizer.commands; + +import dev.lone.vanillacustomizer.commands.registered.MainCommand; +import org.bukkit.plugin.java.JavaPlugin; + +public class Commands +{ + public static void register(JavaPlugin plugin) + { + new MainCommand(plugin, "vanillacustomizer"); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/commands/registered/MainCommand.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/commands/registered/MainCommand.java new file mode 100644 index 0000000..14581d6 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/commands/registered/MainCommand.java @@ -0,0 +1,135 @@ +package dev.lone.vanillacustomizer.commands.registered; + +import dev.lone.LoneLibs.annotations.NotNull; +import dev.lone.vanillacustomizer.Main; +import dev.lone.vanillacustomizer.commands.CommandRun; +import dev.lone.vanillacustomizer.utils.SmallCaps; +import fr.mrmicky.fastinv.FastInv; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.HashMap; +import java.util.List; +import java.util.stream.IntStream; + +public class MainCommand extends CommandRun +{ + HashMap playerPage = new HashMap<>(); + + public MainCommand(JavaPlugin plugin, String name) + { + super(plugin, name); + } + + public static boolean hasDebugTag(Player player) + { + return player.hasMetadata("showdebugtag"); + } + + @Override + public void run(Player player, Command command, String label, String[] args) + { + if(args.length >= 1) + { + switch (args[0]) + { + case "showdebugtag": + boolean showdebugtag = hasDebugTag(player); + if (showdebugtag) + Main.msg.send(player, "Disabled debug tag"); + + else + Main.msg.send(player, "Enabled debug tag"); + + if (!showdebugtag) + player.setMetadata("showdebugtag", new FixedMetadataValue(Main.inst(), 0)); + else + player.removeMetadata("showdebugtag", Main.inst()); + + // To trigger refresh + player.updateInventory(); + break; + + case "small": + + String text = args[1]; + Main.msg.send(player, SmallCaps.apply(text)); + break; + case "debugmenu": + + FastInv inv = new FastInv(54); + + int page = 0; + playerPage.put(player, page); + loadPage(inv, page); + + inv.setItem(52, new ItemStack(Material.WHITE_CONCRETE), e -> { + // todo check >= 0 + playerPage.put(player, playerPage.get(player) - 1); + loadPage(inv, playerPage.get(player)); + }); + + inv.setItem(53, new ItemStack(Material.RED_CONCRETE), e -> { + playerPage.put(player, playerPage.get(player) + 1); + loadPage(inv, playerPage.get(player)); + }); + + inv.open(player); + + break; + case "reload": + Main.inst().reload(); + Bukkit.getOnlinePlayers().forEach(Player::updateInventory); + Main.msg.send(player, "Reloaded configs."); + break; + } + } + } + + @Override + public void run(ConsoleCommandSender sender, Command command, String label, String[] args) + { + if(args.length >= 1) + { + switch (args[0]) + { + case "reload": + Main.inst().reload(); + Bukkit.getOnlinePlayers().forEach(Player::updateInventory); + Main.msg.send(sender, "Reloaded configs."); + return; + } + } + + sender.sendMessage("This command can be run only by players!"); + } + + private void loadPage(FastInv inv, int page) + { + inv.removeItems(IntStream.rangeClosed(0, 44).toArray()); + Material[] values = Material.values(); + int j = 0; + for (int i = page * 45; j < 45 && i < values.length; i++) + { + Material mat = values[i]; + if (mat.isItem()) + { + inv.addItem(new ItemStack(mat)); + j++; + } + } + } + + @Override + public List onTabComplete(@NotNull CommandSender sender, Command command, @NotNull String alias, @NotNull String[] args) + { + return List.of("reload", "showdebugtag", "small", "debugmenu"); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/Customization.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/Customization.java new file mode 100644 index 0000000..c347e1f --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/Customization.java @@ -0,0 +1,52 @@ +package dev.lone.vanillacustomizer.customization; + +import dev.lone.vanillacustomizer.ChangeSession; +import dev.lone.vanillacustomizer.customization.changes.IChange; +import dev.lone.vanillacustomizer.customization.rules.IRule; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.List; + +public class Customization +{ + public List rules = new ArrayList<>(); + public List changes = new ArrayList<>(); + + public boolean isEmpty() + { + return rules.isEmpty() && changes.isEmpty(); + } + + public void addRule(IRule rule) + { + rules.add(rule); + } + + public void addChange(IChange change) + { + changes.add(change); + } + + public boolean matchesAll(ChangeSession session) + { + for (IRule rule : rules) + { + if(!rule.matches(session)) + return false; + } + return true; + } + + //TODO: maybe implement also matchAny? + public void handle(ChangeSession session) + { + if(matchesAll(session)) + { + for (IChange change : changes) + { + change.apply(session); + } + } + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/AttributesAdd.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/AttributesAdd.java new file mode 100644 index 0000000..24ef2a1 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/AttributesAdd.java @@ -0,0 +1,83 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import dev.lone.vanillacustomizer.ChangeSession; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeModifier; +import org.bukkit.inventory.EquipmentSlot; +import dev.lone.LoneLibs.annotations.NotNull; +import dev.lone.LoneLibs.annotations.Nullable; + +import java.util.UUID; + +public class AttributesAdd implements IChange +{ + Multimap modifiers; + + public AttributesAdd(Multimap modifiers) + { + this.modifiers = modifiers; + } + + public static AttributeModifier generateModifier(@Nullable String uuid, + String name, + Attribute attribute, + double value, + @NotNull String operation, + EquipmentSlot slot) + { + AttributeModifier.Operation op; + if (operation.equals("multiply_base")) + op = AttributeModifier.Operation.ADD_SCALAR; + else if (operation.equals("multiply")) + op = AttributeModifier.Operation.MULTIPLY_SCALAR_1; + else + op = AttributeModifier.Operation.ADD_NUMBER; + + return new AttributeModifier( + uuid != null ? UUID.fromString(uuid) : UUID.nameUUIDFromBytes((attribute + op.name() + value + slot).getBytes()), + name, + value, + op, + slot + ); + } + + @Override + public void apply(ChangeSession session) + { + session.refreshMeta(); + + Multimap finalModifiers = ArrayListMultimap.create(); + if(session.meta.hasAttributeModifiers()) + { + Multimap originalAttributes = session.meta.getAttributeModifiers(); + assert originalAttributes != null; + originalAttributes.forEach((attribute, attributeModifier) -> { + modifiers.forEach((newAttr, newMod) -> { + // If the item already has the same attribute with same UUID I have to replace it with the + // new attribute provided in the configuration. + if(attributeModifier.getUniqueId().equals(newMod.getUniqueId())) + { + finalModifiers.put(newAttr, newMod); + } + // Otherwise I have to put both as they don't interfere. + else + { + finalModifiers.put(attribute, attributeModifier); + finalModifiers.put(newAttr, newMod); + } + }); + }); + modifiers.forEach(finalModifiers::put); + session.meta.setAttributeModifiers(finalModifiers); + } + else + { + session.meta.setAttributeModifiers(modifiers); + } + + session.applyMeta(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/AttributesRemove.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/AttributesRemove.java new file mode 100644 index 0000000..f58777f --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/AttributesRemove.java @@ -0,0 +1,64 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import dev.lone.vanillacustomizer.ChangeSession; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeModifier; +import org.bukkit.inventory.EquipmentSlot; +import dev.lone.LoneLibs.annotations.NotNull; +import dev.lone.LoneLibs.annotations.Nullable; + +import java.util.UUID; + +@Deprecated //TODO +public class AttributesRemove implements IChange +{ + Multimap modifiers; + + public AttributesRemove(Multimap modifiers) + { + this.modifiers = modifiers; + } + + @Override + public void apply(ChangeSession session) + { + session.refreshMeta(); + + if (!session.meta.hasAttributeModifiers()) + return; + + Multimap finalModifiers = ArrayListMultimap.create(); + Multimap originalAttributes = session.meta.getAttributeModifiers(); + assert originalAttributes != null; +// modifiers.forEach((attrRemove, modRemove) -> { +// +// if(originalAttributes.containsKey(attrRemove)) +// { +// if() +// } +// +// // If the item already has the same attribute with same UUID I have to replace it with the +// // new attribute provided in the configuration. +// if(attributeModifier.getUniqueId().equals(modRemove.getUniqueId())) +// { +// finalModifiers.put(attrRemove, modRemove); +// } +// // Otherwise I have to put both as they don't interfere. +// else +// { +// finalModifiers.put(attribute, attributeModifier); +// finalModifiers.put(attrRemove, modRemove); +// } +// }); +// +// originalAttributes.forEach((attribute, attributeModifier) -> { +// +// }); +// modifiers.forEach(finalModifiers::put); +// session.meta.setAttributeModifiers(finalModifiers); +// +// session.applyMeta(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/EnchantsAdd.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/EnchantsAdd.java new file mode 100644 index 0000000..8661043 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/EnchantsAdd.java @@ -0,0 +1,37 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import dev.lone.vanillacustomizer.ChangeSession; +import org.bukkit.enchantments.Enchantment; + +import java.util.HashMap; +import java.util.Map; + +public class EnchantsAdd implements IChange +{ + final HashMap enchants; + + public EnchantsAdd(HashMap enchants) + { + this.enchants = enchants; + } + + @Override + public void apply(ChangeSession session) + { + if(session.refreshMeta() == null) + return; + + for (Map.Entry e : enchants.entrySet()) + { + Enchantment enchantment = e.getKey(); + Integer level = e.getValue(); + + if(level <= 0) + session.meta.removeEnchant(enchantment); + else + session.meta.addEnchant(enchantment, level, true); + } + + session.applyMeta(); + } +} \ No newline at end of file diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/EnchantsRemove.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/EnchantsRemove.java new file mode 100644 index 0000000..6dba8e4 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/EnchantsRemove.java @@ -0,0 +1,30 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import dev.lone.vanillacustomizer.ChangeSession; +import org.bukkit.enchantments.Enchantment; + +import java.util.List; + +public class EnchantsRemove implements IChange +{ + final List enchants; + + public EnchantsRemove(List enchants) + { + this.enchants = enchants; + } + + @Override + public void apply(ChangeSession session) + { + if(session.refreshMeta() == null) + return; + + for (Enchantment enchant : enchants) + { + session.meta.removeEnchant(enchant); + } + + session.applyMeta(); + } +} \ No newline at end of file diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/FlagsAdd.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/FlagsAdd.java new file mode 100644 index 0000000..9f54bd1 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/FlagsAdd.java @@ -0,0 +1,24 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import dev.lone.vanillacustomizer.ChangeSession; +import org.bukkit.inventory.ItemFlag; + +import java.util.List; + +public class FlagsAdd implements IChange +{ + final ItemFlag[] flags; + + public FlagsAdd(List flags) + { + this.flags = flags.toArray(ItemFlag[]::new); + } + + @Override + public void apply(ChangeSession session) + { + session.refreshMeta(); + session.meta.addItemFlags(flags); + session.applyMeta(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/IChange.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/IChange.java new file mode 100644 index 0000000..50c466c --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/IChange.java @@ -0,0 +1,23 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import dev.lone.vanillacustomizer.ChangeSession; +import dev.lone.vanillacustomizer.nms.items.ItemsNms; + +public interface IChange +{ + void apply(ChangeSession session); + + static String replacePlaceholders(ChangeSession session, String str) + { + if(session.item.getType().isEdible()) + { + str = str.replace("{food}", String.valueOf(ItemsNms.nms().getNutrition(session.item))); + str = str.replace("{saturation}", String.valueOf(ItemsNms.nms().getSaturation(session.item))); + } + + if(session.item.getType().isBlock()) + str = str.replace("{hardness}", String.valueOf(ItemsNms.nms().getDestroySpeed(session.item))); + + return str; + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/LoreInsert.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/LoreInsert.java new file mode 100644 index 0000000..d45a963 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/LoreInsert.java @@ -0,0 +1,68 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import dev.lone.LoneLibs.nbt.nbtapi.NBTCompound; +import dev.lone.LoneLibs.nbt.nbtapi.NBTItem; +import dev.lone.LoneLibs.nbt.nbtapi.NBTList; +import dev.lone.vanillacustomizer.ChangeSession; +import dev.lone.LoneLibs.chat.Comp; +import dev.lone.vanillacustomizer.utils.ConfigFile; + +import java.util.List; + +public class LoreInsert implements IChange +{ + private final List lines; + private final int index; + + public LoreInsert(List lines, int index) + { + this.lines = ConfigFile.getColored(lines); + this.index = index; + } + + @Override + public void apply(ChangeSession session) + { + NBTItem nbt = session.nbt(); + NBTCompound display = nbt.getOrCreateCompound("display"); + + if(!display.hasTag("Lore")) + { + NBTList lore = display.getStringList("Lore"); + for (String line : lines) + lore.add(Comp.legacyToJson(IChange.replacePlaceholders(session, line))); + } + else + { + NBTList lore = display.getStringList("Lore"); + // If the index is correctly inside the already existing lore range I can put the new lines there. + if(index < lore.size()) + { + int i = index; + for (String line : lines) + { + lore.add(i, Comp.legacyToJson(IChange.replacePlaceholders(session, line))); + i++; + } + } + else // If it's out of bounds I just append at the end. + { + for (String line : lines) + lore.add(Comp.legacyToJson(IChange.replacePlaceholders(session, line))); + } + } + + session.saveNbt(); + } + + public static void putLine(ChangeSession session, int index, String line) + { + NBTItem nbt = session.nbt(); + NBTCompound display = nbt.getOrCreateCompound("display"); + + NBTList lore = display.getStringList("Lore"); + lore.add(index, Comp.legacyToJson(line)); + + session.saveNbt(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/LoreInsertJson.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/LoreInsertJson.java new file mode 100644 index 0000000..af93e63 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/LoreInsertJson.java @@ -0,0 +1,53 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import dev.lone.LoneLibs.nbt.nbtapi.NBTCompound; +import dev.lone.LoneLibs.nbt.nbtapi.NBTItem; +import dev.lone.LoneLibs.nbt.nbtapi.NBTList; +import dev.lone.vanillacustomizer.ChangeSession; +import dev.lone.vanillacustomizer.utils.Utilz; + +import java.util.ArrayList; +import java.util.List; + +public class LoreInsertJson implements IChange +{ + private final List linesJson; + private final int index; + + public LoreInsertJson(List linesJson, int index) + { + this.linesJson = Utilz.fixJsonFormatting(linesJson); + this.index = index; + } + + @Override + public void apply(ChangeSession session) + { + NBTItem nbt = session.nbt(); + NBTCompound display = nbt.getOrCreateCompound("display"); + + List newLinesJson = new ArrayList<>(); + for (String lineJson : linesJson) + newLinesJson.add(IChange.replacePlaceholders(session, lineJson)); + + if(!display.hasTag("Lore")) + { + NBTList lore = display.getStringList("Lore"); + lore.addAll(newLinesJson); + } + else + { + NBTList lore = display.getStringList("Lore"); + if(index < lore.size()) + { + lore.addAll(index, newLinesJson); + } + else + { + lore.addAll(newLinesJson); + } + } + + session.saveNbt(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/LoreSet.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/LoreSet.java new file mode 100644 index 0000000..6d8e501 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/LoreSet.java @@ -0,0 +1,34 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import dev.lone.LoneLibs.nbt.nbtapi.NBTCompound; +import dev.lone.LoneLibs.nbt.nbtapi.NBTItem; +import dev.lone.LoneLibs.nbt.nbtapi.NBTList; +import dev.lone.vanillacustomizer.ChangeSession; +import dev.lone.LoneLibs.chat.Comp; +import dev.lone.vanillacustomizer.utils.ConfigFile; + +import java.util.List; + +public class LoreSet implements IChange +{ + private final List lines; + + public LoreSet(List lines) + { + this.lines = ConfigFile.getColored(lines); + } + + @Override + public void apply(ChangeSession session) + { + NBTItem nbt = session.nbt(); + NBTCompound display = nbt.getOrCreateCompound("display"); + + display.removeKey("Lore"); + NBTList lore = display.getStringList("Lore"); + for (String line : lines) + lore.add(Comp.legacyToJson(IChange.replacePlaceholders(session, line))); + + session.saveNbt(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/LoreSetJson.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/LoreSetJson.java new file mode 100644 index 0000000..59ecc40 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/LoreSetJson.java @@ -0,0 +1,39 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import dev.lone.LoneLibs.nbt.nbtapi.NBTCompound; +import dev.lone.LoneLibs.nbt.nbtapi.NBTItem; +import dev.lone.LoneLibs.nbt.nbtapi.NBTList; +import dev.lone.vanillacustomizer.ChangeSession; +import dev.lone.LoneLibs.chat.Comp; +import dev.lone.vanillacustomizer.utils.Utilz; + +import java.util.ArrayList; +import java.util.List; + +public class LoreSetJson implements IChange +{ + private final List linesJson; + + public LoreSetJson(List linesJson) + { + this.linesJson = Utilz.fixJsonFormatting(linesJson); + } + + @Override + public void apply(ChangeSession session) + { + NBTItem nbt = session.nbt(); + NBTCompound display = nbt.getOrCreateCompound("display"); + + display.removeKey("Lore"); + NBTList lore = display.getStringList("Lore"); + + List newLinesJson = new ArrayList<>(); + for (String lineJson : linesJson) + newLinesJson.add(IChange.replacePlaceholders(session, lineJson)); + + lore.addAll(newLinesJson); + + session.saveNbt(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ProtectNbtData.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ProtectNbtData.java new file mode 100644 index 0000000..16bc599 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ProtectNbtData.java @@ -0,0 +1,17 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import dev.lone.LoneLibs.nbt.nbtapi.NBTItem; +import dev.lone.vanillacustomizer.ChangeSession; + +public class ProtectNbtData implements IChange +{ + @Override + public void apply(ChangeSession session) + { + NBTItem nbt = session.nbt(); + nbt.removeKey("PublicBukkitValues"); + nbt.removeKey("itemsadder"); + + session.saveNbt(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/Renamer.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/Renamer.java new file mode 100644 index 0000000..1b29920 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/Renamer.java @@ -0,0 +1,29 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import dev.lone.LoneLibs.nbt.nbtapi.NBTCompound; +import dev.lone.LoneLibs.nbt.nbtapi.NBTItem; +import dev.lone.vanillacustomizer.ChangeSession; +import dev.lone.LoneLibs.chat.Comp; +import dev.lone.vanillacustomizer.utils.ConfigFile; +import org.bukkit.ChatColor; + +public class Renamer implements IChange +{ + private final String name; + + public Renamer(String name) + { + name = ConfigFile.convertColor(name); + this.name = !name.startsWith("&f") ? ChatColor.WHITE + name : name; + } + + @Override + public void apply(ChangeSession session) + { + NBTItem nbt = session.nbt(); + NBTCompound display = nbt.getOrCreateCompound("display"); + display.setString("Name", Comp.legacyToJson(IChange.replacePlaceholders(session, name))); + + session.saveNbt(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/RenamerJson.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/RenamerJson.java new file mode 100644 index 0000000..d77af32 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/RenamerJson.java @@ -0,0 +1,31 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import dev.lone.LoneLibs.nbt.nbtapi.NBTCompound; +import dev.lone.LoneLibs.nbt.nbtapi.NBTItem; +import dev.lone.vanillacustomizer.ChangeSession; +import dev.lone.LoneLibs.chat.Comp; +import dev.lone.vanillacustomizer.utils.Utilz; + +public class RenamerJson implements IChange +{ + private final String json; + + public RenamerJson(String json) + { + // This should validate if the json is valid and throw an exception if not. + // NOTE: test if it is actually the case. + Comp.jsonToComponent(json); + + this.json = Utilz.fixJsonFormatting(json); + } + + @Override + public void apply(ChangeSession session) + { + NBTItem nbt = session.nbt(); + NBTCompound display = nbt.getOrCreateCompound("display"); + display.setString("Name", IChange.replacePlaceholders(session, json)); + + session.saveNbt(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceCustomModelData.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceCustomModelData.java new file mode 100644 index 0000000..f23ec9e --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceCustomModelData.java @@ -0,0 +1,23 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import dev.lone.LoneLibs.nbt.nbtapi.NBTItem; +import dev.lone.vanillacustomizer.ChangeSession; + +public class ReplaceCustomModelData implements IChange +{ + private final int id; + + public ReplaceCustomModelData(int id) + { + this.id = id; + } + + @Override + public void apply(ChangeSession session) + { + NBTItem nbt = session.nbt(); + nbt.setInteger("CustomModelData", id); + + session.saveNbt(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceDurability.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceDurability.java new file mode 100644 index 0000000..fa95f2d --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceDurability.java @@ -0,0 +1,24 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import dev.lone.vanillacustomizer.ChangeSession; +import org.bukkit.inventory.meta.Damageable; + +public class ReplaceDurability implements IChange +{ + private final short amount; + + public ReplaceDurability(short amount) + { + this.amount = amount; + } + + @Override + public void apply(ChangeSession session) + { + Damageable damageable = (Damageable) session.refreshMeta(); + assert damageable != null; + + short max = session.item.getType().getMaxDurability(); + damageable.setDamage(amount > max ? 0 : (short) (max - amount)); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceMaterial.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceMaterial.java new file mode 100644 index 0000000..566dc3a --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceMaterial.java @@ -0,0 +1,21 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import dev.lone.vanillacustomizer.ChangeSession; +import org.bukkit.Material; + +public class ReplaceMaterial implements IChange +{ + private final Material material; + + public ReplaceMaterial(Material material) + { + this.material = material; + } + + @Override + public void apply(ChangeSession session) + { + session.item.setType(material); + session.refreshAll(); // Idk if it's needed + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceWordDisplayName.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceWordDisplayName.java new file mode 100644 index 0000000..4b2320f --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceWordDisplayName.java @@ -0,0 +1,36 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import dev.lone.LoneLibs.nbt.nbtapi.NBTCompound; +import dev.lone.LoneLibs.nbt.nbtapi.NBTItem; +import dev.lone.vanillacustomizer.ChangeSession; +import dev.lone.LoneLibs.chat.Comp; +import dev.lone.vanillacustomizer.utils.ConfigFile; + +public class ReplaceWordDisplayName implements IChange +{ + private final String from; + private final String to; + + public ReplaceWordDisplayName(String from, String to) + { + this.from = ConfigFile.convertColor(from); + this.to = ConfigFile.convertColor(to); + } + + @Override + public void apply(ChangeSession session) + { + if(session.refreshMeta() == null) + return; + if(!session.refreshMeta().hasDisplayName()) + return; + + String name = session.refreshMeta().getDisplayName().replace(from, to); + + NBTItem nbt = session.nbt(); + NBTCompound display = nbt.getOrCreateCompound("display"); + display.setString("Name", Comp.legacyToJson(name)); + + session.saveNbt(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceWordLore.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceWordLore.java new file mode 100644 index 0000000..1243af6 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/changes/ReplaceWordLore.java @@ -0,0 +1,46 @@ +package dev.lone.vanillacustomizer.customization.changes; + +import dev.lone.LoneLibs.nbt.nbtapi.NBTCompound; +import dev.lone.LoneLibs.nbt.nbtapi.NBTItem; +import dev.lone.LoneLibs.nbt.nbtapi.NBTList; +import dev.lone.vanillacustomizer.ChangeSession; +import dev.lone.LoneLibs.chat.Comp; +import dev.lone.vanillacustomizer.utils.ConfigFile; +import lonelibs.net.kyori.adventure.text.Component; +import lonelibs.net.kyori.adventure.text.TextReplacementConfig; + +public class ReplaceWordLore implements IChange +{ + TextReplacementConfig textReplacement; + + public ReplaceWordLore(String from, String to) + { + from = ConfigFile.convertColor(from); + to = ConfigFile.convertColor(to); + + textReplacement = TextReplacementConfig.builder() + .match(from) + .replacement(to) + .build(); + } + + @Override + public void apply(ChangeSession session) + { + NBTItem nbt = session.nbt(); + NBTCompound display = nbt.getOrCreateCompound("display"); + if(!display.hasTag("Lore")) + return; + + NBTList lore = display.getStringList("Lore"); + for (int i = 0; i < lore.size(); i++) + { + String lineJson = lore.get(i); + Component component = Comp.jsonToComponent(lineJson); + component = component.replaceText(textReplacement); + lore.set(i, Comp.componentToJson(component)); + } + + session.saveNbt(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/matchers/ITextMatcher.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/matchers/ITextMatcher.java new file mode 100644 index 0000000..a3bfd2e --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/matchers/ITextMatcher.java @@ -0,0 +1,6 @@ +package dev.lone.vanillacustomizer.customization.matchers; + +public interface ITextMatcher +{ + boolean matches(String text); +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/matchers/RegexMatcher.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/matchers/RegexMatcher.java new file mode 100644 index 0000000..482b963 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/matchers/RegexMatcher.java @@ -0,0 +1,19 @@ +package dev.lone.vanillacustomizer.customization.matchers; + +import java.util.regex.Pattern; + +public class RegexMatcher implements ITextMatcher +{ + final Pattern regex; + + public RegexMatcher(String regexStr) + { + regex = Pattern.compile(regexStr); + } + + @Override + public boolean matches(String text) + { + return regex.matcher(text).matches(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/matchers/RuleNbtMatcher.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/matchers/RuleNbtMatcher.java new file mode 100644 index 0000000..c569622 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/matchers/RuleNbtMatcher.java @@ -0,0 +1,107 @@ +package dev.lone.vanillacustomizer.customization.matchers; + +import dev.lone.LoneLibs.nbt.nbtapi.NBTCompound; +import dev.lone.LoneLibs.nbt.nbtapi.NBTItem; +import dev.lone.LoneLibs.nbt.nbtapi.NBTType; +import dev.lone.vanillacustomizer.customization.rules.IRule; +import org.apache.commons.lang.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.inventory.ItemStack; + +public class RuleNbtMatcher implements IRule +{ + final String nbtPath; + Object nbtValue; + + String[] nbtPathSplit; + + NBTType nbtValueType; + + public RuleNbtMatcher(String nbtPath, String nbtValueStr, String nbtValueTypeStr) + { + this.nbtPath = nbtPath; + this.nbtValue = nbtValueStr; + + String nbtTypeFixed = "NBTTag" + StringUtils.capitalize(nbtValueTypeStr.toLowerCase()); + + try + { + nbtValueType = NBTType.valueOf(nbtTypeFixed); + } + catch(IllegalArgumentException exc) + { + throw new IllegalArgumentException("Unknown nbt.type '" + nbtValueTypeStr + "' for nbt path '" + nbtPath + "'." + + ChatColor.GRAY + " Allowed: string, int, float, double, byte, short"); + } + + switch (nbtValueType) + { + case NBTTagString: + break; + case NBTTagInt: + nbtValue = Integer.parseInt(nbtValueStr); + break; + case NBTTagFloat: + nbtValue = Float.parseFloat(nbtValueStr); + break; + case NBTTagDouble: + nbtValue = Double.parseDouble(nbtValueStr); + break; + case NBTTagByte: + nbtValue = Byte.parseByte(nbtValueStr); + case NBTTagShort: + nbtValue = Short.parseShort(nbtValueStr); + break; + } + + this.nbtPathSplit = nbtPath.split("\\."); + } + + public String getNbtPath() + { + return nbtPath; + } + + public Object getNbtValue() + { + return nbtValue; + } + + @Override + public boolean matches(ItemStack item) + { + NBTItem nbt = new NBTItem(item); + + if (!nbt.hasTag(nbtPathSplit[0])) + return false; + + NBTCompound currentCompound = nbt.getCompound(nbtPathSplit[0]); + for(int i=1; i wildcardStart; +// private List wildcardEnd; +// private List wildcardContains; + private List wildcards; + + public void addWildcard(String wildcard) + { +// String cleanMatcher = wildcard.replace("*", ""); +// if(wildcard.startsWith("*") && wildcard.endsWith("*")) +// { +// if (wildcardContains == null) +// wildcardContains = new ArrayList<>(); +// wildcardContains.add(cleanMatcher); +// } +// else +// { +// if (wildcard.startsWith("*")) +// { +// if (wildcardStart == null) +// wildcardStart = new ArrayList<>(); +// wildcardStart.add(cleanMatcher); +// } +// else +// { +// if (wildcardEnd == null) +// wildcardEnd = new ArrayList<>(); +// wildcardEnd.add(cleanMatcher); +// } +// } + if (wildcards == null) + wildcards = new ArrayList<>(); + wildcards.add(wildcard); + } + + @Override + public boolean matches(String text) + { + for (String wildcard : wildcards) + { + if(FilenameUtils.wildcardMatch(text, wildcard, IOCase.INSENSITIVE)) + return true; + } +// if(wildcardContains != null) +// { +// for (String wildcard : wildcardContains) +// { +// if(text.contains(wildcard)) +// return true; +// } +// } +// +// if(wildcardStart != null) +// { +// for (String wildcard : wildcardStart) +// { +// if(text.endsWith(wildcard)) +// return true; +// } +// } +// +// if(wildcardEnd != null) +// { +// for (String wildcard : wildcardEnd) +// { +// if(text.startsWith(wildcard)) +// return true; +// } +// } + + return false; + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/IRule.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/IRule.java new file mode 100644 index 0000000..29080e8 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/IRule.java @@ -0,0 +1,14 @@ +package dev.lone.vanillacustomizer.customization.rules; + +import dev.lone.vanillacustomizer.ChangeSession; +import org.bukkit.inventory.ItemStack; + +public interface IRule +{ + boolean matches(ItemStack item); + + default boolean matches(ChangeSession session) + { + return matches(session.item); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleEdible.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleEdible.java new file mode 100644 index 0000000..cd94c43 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleEdible.java @@ -0,0 +1,22 @@ +package dev.lone.vanillacustomizer.customization.rules; + +import org.bukkit.inventory.ItemStack; + +public class RuleEdible implements IRule +{ + private final boolean value; + + public RuleEdible(boolean value) + { + this.value = value; + } + + @Override + public boolean matches(ItemStack item) + { + if(value) + return item.getType().isEdible(); + else + return !item.getType().isEdible(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleHardnessGraterThan.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleHardnessGraterThan.java new file mode 100644 index 0000000..63ce033 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleHardnessGraterThan.java @@ -0,0 +1,20 @@ +package dev.lone.vanillacustomizer.customization.rules; + +import dev.lone.vanillacustomizer.nms.items.ItemsNms; +import org.bukkit.inventory.ItemStack; + +public class RuleHardnessGraterThan implements IRule +{ + private final double value; + + public RuleHardnessGraterThan(double value) + { + this.value = value; + } + + @Override + public boolean matches(ItemStack item) + { + return ItemsNms.nms().getDestroySpeed(item) > value; + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleMaterial.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleMaterial.java new file mode 100644 index 0000000..3a930bc --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleMaterial.java @@ -0,0 +1,20 @@ +package dev.lone.vanillacustomizer.customization.rules; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +public class RuleMaterial implements IRule +{ + Material material; + + public RuleMaterial(Material material) + { + this.material = material; + } + + @Override + public boolean matches(ItemStack item) + { + return item.getType() == material; + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleMaterialRegex.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleMaterialRegex.java new file mode 100644 index 0000000..309619a --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleMaterialRegex.java @@ -0,0 +1,22 @@ +package dev.lone.vanillacustomizer.customization.rules; + +import dev.lone.vanillacustomizer.customization.matchers.RegexMatcher; +import org.bukkit.inventory.ItemStack; + +import java.util.List; + +public class RuleMaterialRegex implements IRule +{ + RegexMatcher matcher; + + public RuleMaterialRegex(String regexStr) + { + matcher = new RegexMatcher(regexStr); + } + + @Override + public boolean matches(ItemStack item) + { + return matcher.matches(item.getType().toString()); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleMaterialWildcards.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleMaterialWildcards.java new file mode 100644 index 0000000..e0aebcd --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleMaterialWildcards.java @@ -0,0 +1,44 @@ +package dev.lone.vanillacustomizer.customization.rules; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOCase; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.List; + +public class RuleMaterialWildcards implements IRule +{ + List matches = new ArrayList<>(); + + public List init(List materialWildcards) + { + List noMatches = new ArrayList<>(); + for (String entry : materialWildcards) + { + boolean any = false; + for (Material material : Material.values()) + { + if(FilenameUtils.wildcardMatch(material.toString(), entry, IOCase.INSENSITIVE)) + { + matches.add(material); + any = true; + } + } + + if(!any) + { + noMatches.add(entry); + } + } + + return noMatches; + } + + @Override + public boolean matches(ItemStack item) + { + return matches.contains(item.getType()); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleMaterials.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleMaterials.java new file mode 100644 index 0000000..2433e5a --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleMaterials.java @@ -0,0 +1,29 @@ +package dev.lone.vanillacustomizer.customization.rules; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.util.List; + +public class RuleMaterials implements IRule +{ + List materials; + + public RuleMaterials(List materials) + { + this.materials = materials; + } + + @Override + public boolean matches(ItemStack item) + { + Material type = item.getType(); + for (Material entry : materials) + { + if(type == entry) + return true; + } + + return false; + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RulePlaceable.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RulePlaceable.java new file mode 100644 index 0000000..a8af794 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RulePlaceable.java @@ -0,0 +1,19 @@ +package dev.lone.vanillacustomizer.customization.rules; + +import org.bukkit.inventory.ItemStack; + +public class RulePlaceable implements IRule +{ + final boolean placeable; + + public RulePlaceable(boolean placeable) + { + this.placeable = placeable; + } + + @Override + public boolean matches(ItemStack item) + { + return item.getType().isBlock(); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleRarity.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleRarity.java new file mode 100644 index 0000000..c4f880f --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleRarity.java @@ -0,0 +1,21 @@ +package dev.lone.vanillacustomizer.customization.rules; + +import dev.lone.vanillacustomizer.nms.items.ItemsNms; +import dev.lone.vanillacustomizer.nms.items.Rarity; +import org.bukkit.inventory.ItemStack; + +public class RuleRarity implements IRule +{ + private Rarity rarity; + + public RuleRarity(Rarity rarity) + { + this.rarity = rarity; + } + + @Override + public boolean matches(ItemStack item) + { + return rarity.equals(ItemsNms.nms().getRarity(item)); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleSmelted.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleSmelted.java new file mode 100644 index 0000000..ebe8477 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleSmelted.java @@ -0,0 +1,23 @@ +package dev.lone.vanillacustomizer.customization.rules; + +import dev.lone.vanillacustomizer.nms.items.ItemsNms; +import org.bukkit.inventory.ItemStack; + +public class RuleSmelted implements IRule +{ + private final boolean value; + + public RuleSmelted(boolean value) + { + this.value = value; + } + + @Override + public boolean matches(ItemStack item) + { + if(value) + return ItemsNms.inst().SMELTED_MATERIALS.contains(item.getType()); + else + return !ItemsNms.inst().SMELTED_MATERIALS.contains(item.getType()); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleVanillaItemMatcher.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleVanillaItemMatcher.java new file mode 100644 index 0000000..d6d38b7 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/customization/rules/RuleVanillaItemMatcher.java @@ -0,0 +1,54 @@ +package dev.lone.vanillacustomizer.customization.rules; + +import dev.lone.vanillacustomizer.ChangeSession; +import dev.lone.vanillacustomizer.utils.Utilz; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +public class RuleVanillaItemMatcher implements IRule +{ + final boolean isVanilla; + + public RuleVanillaItemMatcher(boolean isVanilla) + { + this.isVanilla = isVanilla; + } + + public static boolean satisfy(ItemStack itemStack) + { + if(itemStack == null) + return false; + + if(!itemStack.hasItemMeta()) + return true; + + ItemMeta meta = itemStack.getItemMeta(); + if(meta == null) + return true; + + // TODO: warning, items with no lore would still be considered vanilla while they might be custom. + // might need to check NBT + if(meta.hasLore()) + { + return false; + } + + String displayName = meta.getDisplayName(); + displayName = Utilz.backColor(displayName); + + // Check if italic, means that might have been renamed using anvil. + return !displayName.startsWith("&o"); + } + + @Override + public boolean matches(ItemStack item) + { + return false; + } + + @Override + public boolean matches(ChangeSession session) + { + return session.isVanilla; + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/nms/Nms.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/nms/Nms.java new file mode 100644 index 0000000..963d79c --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/nms/Nms.java @@ -0,0 +1,69 @@ +package dev.lone.vanillacustomizer.nms; + +import dev.lone.LoneLibs.annotations.Nullable; +import dev.lone.LoneLibs.nbt.nbtapi.utils.MinecraftVersion; +import dev.lone.vanillacustomizer.Main; +import org.bukkit.Bukkit; + +import java.lang.reflect.InvocationTargetException; + +/** + * Utility to initialize NMS wrappers and avoid Maven circular dependency problems. + */ +public class Nms +{ + public static boolean is_v18_2_or_greater; + public static boolean is_v19_2_or_greater; + public static boolean is_v17_or_greater; + public static boolean is_v1_16_or_greater; + + static + { + is_v19_2_or_greater = MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_19_R1); + is_v18_2_or_greater = MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_18_R1); + is_v17_or_greater = MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_17_R1); + is_v1_16_or_greater = MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_16_R1); + } + + /** + * Gets a suitable implementaion for the current Minecraft server version. + * + * @param implClazz the interface class which every implementation implements. + * @param nmsHolder the wrapper which holds NMS methods as Singleton utility. + * @param ignoreError If loading errors should be ignored, for example if no implementation exists. This is hacky but can + * be useful in some cases. + * @return the correct implementation. + */ + @Nullable + @SuppressWarnings("unchecked") + public static T findImplementation(Class implClazz, Object nmsHolder, boolean ignoreError) + { + String nmsVersion = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; + + try + { + Class implClass = Class.forName(nmsHolder.getClass().getPackage().getName() + ".impl." + nmsVersion); + try + { + //To fix a bug: For example implementations of IBlockInfo class have BlockInfo has first param of the constructor. + return (T) implClass.getDeclaredConstructor(nmsHolder.getClass()).newInstance(nmsHolder); + } + catch (NoSuchMethodException e) + { + return (T) implClass.getDeclaredConstructor().newInstance(); + } + } + catch (ClassNotFoundException | InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) + { + if (ignoreError) + return null; + + Main.msg.error("Error getting implementation for " + nmsHolder.getClass() + " - NMS " + nmsVersion); + e.printStackTrace(); + + Bukkit.getPluginManager().disablePlugin(Main.inst()); + Bukkit.shutdown(); + } + return null; + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/nms/items/IItemsNms.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/nms/items/IItemsNms.java new file mode 100644 index 0000000..c7a6189 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/nms/items/IItemsNms.java @@ -0,0 +1,14 @@ +package dev.lone.vanillacustomizer.nms.items; + +import org.bukkit.inventory.ItemStack; + +public interface IItemsNms +{ + Rarity getRarity(ItemStack bukkitItem); + + float getDestroySpeed(ItemStack bukkitItem); + + int getNutrition(ItemStack bukkitItem); + + float getSaturation(ItemStack bukkitItem); +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/nms/items/ItemsNms.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/nms/items/ItemsNms.java new file mode 100644 index 0000000..388baa7 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/nms/items/ItemsNms.java @@ -0,0 +1,46 @@ +package dev.lone.vanillacustomizer.nms.items; + +import dev.lone.vanillacustomizer.nms.Nms; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.inventory.CookingRecipe; + +import java.util.ArrayList; +import java.util.List; + +public class ItemsNms +{ + public IItemsNms nms; + static ItemsNms instance; + + public List SMELTED_MATERIALS = new ArrayList<>(); + + ItemsNms() + { + nms = Nms.findImplementation(IItemsNms.class, this, false); + } + + public static ItemsNms inst() + { + if(instance == null) + instance = new ItemsNms(); + return instance; + } + + public static IItemsNms nms() + { + return inst().nms; + } + + public void initialize() + { + Bukkit.recipeIterator().forEachRemaining(recipe -> { + if(recipe instanceof CookingRecipe) + { + Material type = recipe.getResult().getType(); + if(!type.isEdible()) + SMELTED_MATERIALS.add(type); + } + }); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/nms/items/Rarity.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/nms/items/Rarity.java new file mode 100644 index 0000000..ed45363 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/nms/items/Rarity.java @@ -0,0 +1,18 @@ +package dev.lone.vanillacustomizer.nms.items; + +import org.bukkit.Color; + +public enum Rarity +{ + COMMON(Color.WHITE), + UNCOMMON(Color.YELLOW), + RARE(Color.AQUA), + EPIC(Color.PURPLE); + + public final Color color; + + Rarity(Color var2) + { + this.color = var2; + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/ConfigFile.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/ConfigFile.java new file mode 100644 index 0000000..18aa42c --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/ConfigFile.java @@ -0,0 +1,539 @@ +package dev.lone.vanillacustomizer.utils; + +import dev.lone.LoneLibs.annotations.NotNull; +import dev.lone.vanillacustomizer.Main; +import dev.lone.vanillacustomizer.nms.Nms; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.EntityType; +import org.bukkit.plugin.Plugin; +import org.bukkit.potion.PotionEffectType; +import dev.lone.LoneLibs.annotations.Nullable; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.logging.Level; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 2020-01-08 LoneDev + */ +public class ConfigFile +{ + private static final Pattern hexPattern = Pattern.compile("%#([A-Fa-f0-9]){6}%"); + + final Plugin plugin; + + private FileConfiguration config; + private final String filePath; + private final File configFile; + private boolean hasDefaultFile = true; + private boolean autoAddMissingProperties = false; + private String partialFilePath; + private boolean announceCustomLanguage; + + /** + * @param plugin Plugin + * @param filePath Partial path of the file (root = plugins/XXX/) + * @param hasDefaultFile If there is a default file in .jar resources + * @param autoAddMissingProperties Add properties that are missing from user config (useful on plugin updates if you create new properties in the config) + */ + public ConfigFile(Plugin plugin, boolean pluginsFolderRoot, String filePath, boolean hasDefaultFile, boolean autoAddMissingProperties) + { + this(plugin, pluginsFolderRoot, filePath, hasDefaultFile, autoAddMissingProperties, true); + } + + public ConfigFile(Plugin plugin, boolean pluginsFolderRoot, String filePath, boolean hasDefaultFile, boolean autoAddMissingProperties, boolean announceCustomLanguage) + { + this.plugin = plugin; + this.announceCustomLanguage = announceCustomLanguage; + + if (pluginsFolderRoot) + { + this.partialFilePath = filePath; + this.filePath = plugin.getDataFolder() + File.separator + filePath; + //this.filePath = "plugins/" + plugin.getName() + "/" + filePath; + } + else + { + this.partialFilePath = filePath.replace(plugin.getDataFolder().getAbsolutePath(), ""); + this.filePath = filePath; + } + + this.partialFilePath = this.partialFilePath.replace("\\", "/"); + + if (!new File(this.filePath).exists()) + new File(this.filePath).getParentFile().mkdirs(); + + this.hasDefaultFile = hasDefaultFile; + this.autoAddMissingProperties = autoAddMissingProperties; + this.configFile = new File(this.filePath); + + try + { + config = loadConfiguration(configFile);//seems to be the cause of lag on /iareload + initFile(); + } + catch (IOException | InvalidConfigurationException e) + { + e.printStackTrace(); + } + } + + public ConfigFile(Plugin plugin, boolean pluginsFolderRoot, String filePath, boolean hasDefaultFile) + { + this(plugin, pluginsFolderRoot, filePath, hasDefaultFile, false); + } + + @NotNull + public static YamlConfiguration loadConfiguration(@NotNull File file) throws IOException, InvalidConfigurationException + { + Validate.notNull(file, "File cannot be null"); + YamlConfiguration config = new YamlConfiguration(); + + try + { + config.load(file); + } + catch (FileNotFoundException ignored) + { + // Happens the first time since the file obviously doesn't exist. + } + catch (IOException | InvalidConfigurationException exc) + { + Bukkit.getLogger().log(Level.SEVERE, "Cannot load file: " + file, exc); + throw exc; + } + return config; + } + + private ConfigFile(Plugin plugin, String filePath) + { + this.plugin = plugin; + this.filePath = filePath; + this.configFile = new File(this.filePath); + config = YamlConfiguration.loadConfiguration(configFile); + } + + public ConfigFile clone() + { + ConfigFile clone = new ConfigFile(plugin, filePath); + clone.partialFilePath = partialFilePath; + clone.hasDefaultFile = hasDefaultFile; + clone.autoAddMissingProperties = autoAddMissingProperties; + return clone; + } + + public File getFile() + { + return configFile; + } + + /** + * Reloads from file + */ + public void reload() + { + config = YamlConfiguration.loadConfiguration(configFile); + } + + /** + * Inits file taking it from original file in .jar if not exists and adding missing attributes if autoAddMissingProperties + */ + public void initFile() + { + if (hasDefaultFile) + { + String resourceFilePath = this.filePath + .replace("plugins/" + plugin.getName() + "/", "") + .replace("plugins\\" + plugin.getName() + "\\", "") + .replace("plugins\\" + plugin.getName() + "/", ""); + try + { + if (!configFile.exists()) + { + // Load the default file from JAR resources + FileUtils.copyInputStreamToFile(plugin.getResource(resourceFilePath), configFile); + } + else + { + if (autoAddMissingProperties) + { + InputStream defaultFileStream = plugin.getResource(resourceFilePath); + if(defaultFileStream != null) + { + FileConfiguration c = YamlConfiguration + .loadConfiguration((new InputStreamReader(defaultFileStream, StandardCharsets.UTF_8))); + for (String k : c.getKeys(true)) + { + if (!config.contains(k)) + config.set(k, c.get(k)); + } + config.save(configFile); + } + } + } + config.load(configFile); + } + catch (IOException | InvalidConfigurationException | NullPointerException e) + { + //e.printStackTrace(); + //Main.msg.sendConsoleError("ERROR LOADING file '" + filePath + "'"); + if (announceCustomLanguage) + Main.msg.log(ChatColor.YELLOW + "Using custom language file '" + filePath + "'"); + e.printStackTrace(); + } + } + } + + public FileConfiguration getConfigFile() + { + return config; + } + + public String getFilePath() + { + return filePath; + } + + public String getPartialFilePath() + { + return partialFilePath; + } + + public static String convertColor(String string) + { + return convertColor0(string).replace("\\n", "\n"); + } + + private static String convertColor0(String message) + { + if (Nms.is_v1_16_or_greater) + { + Matcher matcher = hexPattern.matcher(message); + while (matcher.find()) + { + final net.md_5.bungee.api.ChatColor hexColor = net.md_5.bungee.api.ChatColor.of(matcher.group().substring(1, matcher.group().length() - 1)); + final String before = message.substring(0, matcher.start()); + final String after = message.substring(matcher.end()); + message = before + hexColor + after; + matcher = hexPattern.matcher(message); + } + } + return message.replace("&", "\u00A7"); + } + + protected void notifyMissingProperty(String path) + { + Main.msg.error("MISSING FILE PROPERTY! '" + path + "' in file '" + filePath + "'"); + } + + public void set(String path, Object value) + { + this.config.set(path, value); + } + + public void save() + { + try + { + this.config.save(configFile); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + + public void save(File newLocation) + { + try + { + this.config.save(newLocation); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + + public boolean hasKey(String path) + { + return config.contains(path); + } + + public void remove(String path) + { + config.set(path, null); + } + + public List getSectionKeysList(String path) + { + if (!hasKey(path)) + return new ArrayList<>(); + return new ArrayList<>(config.getConfigurationSection(path).getKeys(false)); + } + + public static List getSectionKeysListBySection(ConfigurationSection section) + { + return getSectionKeysListBySection(section, ""); + } + + public static List getSectionKeysListBySection(ConfigurationSection section, String path) + { + if (!section.contains(path)) + return new ArrayList<>(); + return new ArrayList<>(section.getKeys(false)); + } + + public Map getSectionKeysAndValues(String path) + { + if (!hasKey(path)) + return null; + return config.getConfigurationSection(path).getValues(false); + } + + public Object get(String path, Object defaultValue) + { + if (hasKey(path)) + return config.get(path); + return defaultValue; + } + + public String getString(String path) + { + return config.getString(path); + } + + public String getString(String path, String defaultValue) + { + if (!hasKey(path)) + return defaultValue; + return config.getString(path); + } + + public int getInt(String path) + { + return config.getInt(path); + } + + /** + * Riturna interno se trovato, se no ritorna defaultValue + * + * @param path + * @param defaultValue + * @return + */ + public int getInt(String path, int defaultValue) + { + if (hasKey(path)) + return config.getInt(path); + return defaultValue; + } + + /** + * Ritorna double se trovato, se no ritorna defaultValue + * + * @param path + * @param defaultValue + * @return + */ + public double getDouble(String path, double defaultValue) + { + if (hasKey(path)) + return config.getDouble(path); + return defaultValue; + } + + public float getFloat(String path, float defaultValue) + { + if (hasKey(path)) + return (float) config.getDouble(path); + return defaultValue; + } + + public float getFloat(String path) + { + return getFloat(path, 0f); + } + + public boolean getBoolean(String path) + { + return config.getBoolean(path); + } + + public boolean getBoolean(String path, boolean defaultValue) + { + if (hasKey(path)) + return config.getBoolean(path); + return defaultValue; + } + + public Material getMaterial(String path, Material defaultValue) + { + if (hasKey(path)) + return EnumUtil.safeGet(config.getString(path).toUpperCase(), Material.class, defaultValue); + else + return defaultValue; + } + + public static Material getMaterialByString(String value, Material defaultValue) + { + if(value == null) + return null; + return EnumUtil.safeGet(value.toUpperCase(), Material.class, defaultValue); + } + + public Material getMaterial(String path) + { + return getMaterial(path, null); + } + + public PotionEffectType getPotionEffectType(String path) + { + if (hasKey(path)) + return PotionEffectType.getByName(config.getString(path)); + else + return null; + } + + @Nullable + public static PotionEffectType getPotionEffectTypeByString(String value) + { + return PotionEffectType.getByName(value); + } + + public String getColored(String path) + { + return getColored(path, null); + } + + public String getColored(String path, String defaultValue) + { + if (hasKey(path)) + { + return convertColor(config.getString(path)); + } + else + { + //notifyMissingProperty(path); + //return ChatColor.RED + "Error in file " + filePath; + } + return defaultValue; + } + + public String getStripped(String name) + { + return ChatColor.stripColor(getColored(name)); + } + + + public String getStrippedColors(String name) + { + return ChatColor.stripColor(getColored(name)); + } + + /** + * Returns a list of strings with colors already converted to bukkit format + */ + public static List getColored(List list) + { + ArrayList colored = new ArrayList<>(); + for (String entry : list) + colored.add(convertColor(entry)); + return colored; + } + + /** + * Returns a list of strings with colors already converted to bukkit format + * + * @param path + * @param colored + * @return + */ + public List getStringList(String path, boolean colored) + { + if (colored) + { + ArrayList coloredList = new ArrayList<>(); + try + { + ArrayList list = (ArrayList) config.getStringList(path); + for (String entry : list) + coloredList.add(convertColor(entry)); + } + catch (NullPointerException exc) + { + exc.printStackTrace(); + notifyMissingProperty(path); + } + + return coloredList; + } + return config.getStringList(path); + } + + /** + * Returns a list of strings (without converting colors) + * + * @param path + * @return + */ + public List getStringList(String path) + { + return getStringList(path, false); + } + + public List getMaterialList(String path) + { + ArrayList coloredList = new ArrayList<>(); + + ArrayList list = (ArrayList) config.getStringList(path); + for (String material : list) + { + if (Material.valueOf(material.toUpperCase()) != null)//does this even work? + coloredList.add(Material.valueOf(material.toUpperCase())); + else + Main.msg.error("No material found with name " + material + ". Please check config '" + filePath + "'"); + } + + return coloredList; + } + + @Nullable + public ConfigurationSection getConfigurationSection(@NotNull String path) + { + return config.getConfigurationSection(path); + } + + @Nullable + public EntityType getEntityType(String key, EntityType armorStand, Consumer failAction) + { + if (hasKey(key)) + { + String val = getString(key).toUpperCase(); + try + { + return EntityType.valueOf(val); + } + catch (Exception exc) + { + failAction.accept(val); + return null; + } + } + return armorStand; + } +} \ No newline at end of file diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/EnumUtil.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/EnumUtil.java new file mode 100644 index 0000000..5805f4d --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/EnumUtil.java @@ -0,0 +1,17 @@ +package dev.lone.vanillacustomizer.utils; + +public class EnumUtil +{ + public static > T safeGet(String str, Class enumType, T fallback) + { + try + { + return Enum.valueOf(enumType, str); + } + catch (Exception e) + { + return fallback; + } + } + +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/Packets.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/Packets.java new file mode 100644 index 0000000..60f978a --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/Packets.java @@ -0,0 +1,36 @@ +package dev.lone.vanillacustomizer.utils; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketEvent; +import org.bukkit.plugin.Plugin; + +import java.util.function.Consumer; + +public class Packets +{ + /** + * Register Server->Client packet listener + */ + public static void out(Plugin plugin, PacketType packetType, Consumer handle) + { + ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter( + PacketAdapter.params() + .plugin(plugin) + .types(packetType) + .listenerPriority(ListenerPriority.MONITOR) + ) + { + @Override + public void onPacketSending(PacketEvent e) + { + if (e.isCancelled() || e.isPlayerTemporary()) + return; + + handle.accept(e); + } + }); + } +} diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/SmallCaps.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/SmallCaps.java new file mode 100644 index 0000000..b47ad75 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/SmallCaps.java @@ -0,0 +1,24 @@ +package dev.lone.vanillacustomizer.utils; + +import dev.lone.LoneLibs.annotations.NotNull; + +public class SmallCaps +{ + private static final char[] CHARS = "ᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢ".toCharArray(); + + public static String apply(@NotNull String string) + { + final StringBuilder sb = new StringBuilder(); + final char[] chars = string.toLowerCase().toCharArray(); + for (char c : chars) + { + final int index = c - 'a'; + if (index >= 0 && index < CHARS.length) + sb.append(CHARS[index]); + else + sb.append(c); + } + + return sb.toString(); + } +} \ No newline at end of file diff --git a/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/Utilz.java b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/Utilz.java new file mode 100644 index 0000000..163c328 --- /dev/null +++ b/VanillaCustomizer-core/src/main/java/dev/lone/vanillacustomizer/utils/Utilz.java @@ -0,0 +1,599 @@ +package dev.lone.vanillacustomizer.utils; + +import dev.lone.LoneLibs.chat.Comp; +import lonelibs.net.kyori.adventure.text.Component; +import lonelibs.net.kyori.adventure.text.format.TextColor; +import lonelibs.net.kyori.adventure.text.format.TextDecoration; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang.reflect.FieldUtils; +import org.bukkit.Bukkit; +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.attribute.Attribute; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; + +import java.io.File; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.text.CharacterIterator; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.text.StringCharacterIterator; +import java.util.*; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class Utilz +{ + public static Random random = new Random(); + + private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("##.00"); + private static final Pattern PATTERN_HEX = Pattern.compile("%#([A-Fa-f0-9]){6}%"); + private static final Pattern PATTERN_IS_NUMERIC = Pattern.compile("-?\\d+(\\.\\d+)?"); + + public static void removeEnchantments(ItemStack item) + { + item.getEnchantments().keySet().forEach(item::removeEnchantment); + } + + public static String addSpace(String s) + { + return s.replace("-", " "); + } + + public static float getRandom(String level) + { + if (level.contains("-")) + { + String[] spl = level.split("-"); + return round(randomNumber(Float.parseFloat(spl[0]), Float.parseFloat(spl[1])), 2); + } + else return Integer.parseInt(level); + } + + public static int getRandomInt(String level) + { + if (level.contains("-")) + { + String[] spl = level.split("-"); + return getRandomInt(Integer.parseInt(spl[0]), Integer.parseInt(spl[1])); + } + else return Integer.parseInt(level); + } + + public static float round(float d, int decimalPlace) + { + BigDecimal bd = new BigDecimal(Float.toString(d)); + bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP); + return bd.floatValue(); + } + + public static String round(double value, int places, boolean showZeroes) + { + if (places < 0) throw new IllegalArgumentException(); + + BigDecimal bd = BigDecimal.valueOf(value); + bd = bd.setScale(places, RoundingMode.HALF_UP); + + String result = bd.doubleValue() + ""; + if (!showZeroes) + result = result + .replace(".00", "") + .replace(".0", ""); + return result; + } + + public static float randomNumber(float f, float g) + { + return random.nextFloat() * (g - f) + f; + } + + /** + * Returns a 0 to 1 random double. + * + * @return A random double from 0 to 1. + */ + public static double randomNumber() + { + return random.nextDouble(); + } + + /** + * Supports negative min + */ + public static int getRandomInt(int min, int max) + { + if (max == min) + return max; + return random.nextInt((max - min) + 1) + min; + } + + /** + * Supports negative min + */ + public static int getRandomInt(Random random, int min, int max) + { + if (max == min) + return max; + return random.nextInt((max - min) + 1) + min; + } + + public static boolean getSuccess(int percent) + { + int i = getRandomInt(1, 100); + return i <= percent; + } + + public static boolean hasPermmision(Player p, String perm) + { + if (p.hasPermission(perm)) return true; + return p.isOp(); + } + + public static String backColor(String name) + { + return name.replace("\u00A7", "&"); + } + + public static boolean isColored(String str) + { + return str.contains("\u00A7([0-fk-or])") || str.contains("&([0-fk-or])"); + } + + /** + * @param strNum check if it is numeric + */ + public static boolean isNumeric(String strNum) + { + if (strNum == null) + return false; + return PATTERN_IS_NUMERIC.matcher(strNum).matches(); + } + + private static java.awt.Color hex2Rgb(String colorStr) + { + try + { + return new java.awt.Color( + Integer.valueOf(colorStr.substring(1, 3), 16), + Integer.valueOf(colorStr.substring(3, 5), 16), + Integer.valueOf(colorStr.substring(5, 7), 16) + ); + } + catch (Throwable e) + { + e.printStackTrace(); + } + return null; + } + + public static Color hexToBukkitColor(String colorStr) + { + if (colorStr == null) + return null; + //fix java.lang.NumberFormatException: For input string: ".0" + if (colorStr.endsWith(".0")) + colorStr = colorStr.replace(".0", ""); + colorStr = colorStr.replace(".", ""); + //fix java.lang.StringIndexOutOfBoundsException: String index out of range: 7 + while (colorStr.length() < 7) + colorStr = colorStr + "0"; + if (!colorStr.startsWith("#")) + colorStr = "#" + colorStr; + + java.awt.Color javaColor = hex2Rgb(colorStr); + return Color.fromRGB(javaColor.getRed(), javaColor.getGreen(), javaColor.getBlue()); + } + + public static String colorToHexString(int rgb) + { + java.awt.Color tmp = new java.awt.Color(rgb); + return colorToHexString(tmp.getRed(), tmp.getGreen(), tmp.getBlue()); + } + + public static String colorToHexString(Color color, boolean hashtagPrefix) + { + java.awt.Color tmp = new java.awt.Color(color.asRGB()); + return colorToHexString(tmp.getRed(), tmp.getGreen(), tmp.getBlue(), hashtagPrefix); + } + + public static String colorToHexString(int r, int g, int b) + { + return colorToHexString(r, g, b, true); + } + + public static String colorToHexString(int r, int g, int b, boolean hashtagPrefix) + { + if (hashtagPrefix) + return String.format("#%02x%02x%02x", r, g, b); + return String.format("%02x%02x%02x", r, g, b); + } + + public static Color bukkitColor(int rgb) + { + java.awt.Color tmp = new java.awt.Color(rgb); + return Color.fromRGB(tmp.getRed(), tmp.getGreen(), tmp.getBlue()); + } + + public static int ceilDivision(float a, float b) + { + return (int) Math.ceil(a / b); + + } + + public static int parseInt(String number, int defaultValue) + { + try + { + return Integer.parseInt(number); + } + catch (Throwable ignored){} + return defaultValue; + } + + public static float parseFloat(String number, float defaultValue) + { + try + { + return Float.parseFloat(number); + } + catch (Throwable ignored){} + return defaultValue; + } + + public static Color bukkitColorFromString(String potionColorStr) + { + try + { + return (Color) FieldUtils.readStaticField(Color.class, potionColorStr); + } + catch (Exception e) + { + try + { + if (!Utilz.isNumeric(potionColorStr)) + { + if (potionColorStr == null) + return null; + //fix java.lang.NumberFormatException: For input string: ".0" + if (potionColorStr.endsWith(".0")) + potionColorStr = potionColorStr.replace(".0", ""); + potionColorStr = potionColorStr.replace(".", ""); + //fix java.lang.StringIndexOutOfBoundsException: String index out of range: 7 + while (potionColorStr.length() < 7) + potionColorStr = potionColorStr + "0"; + if (!potionColorStr.startsWith("#")) + potionColorStr = "#" + potionColorStr; + + java.awt.Color javaColor = hex2Rgb(potionColorStr); + return Color.fromRGB(javaColor.getRed(), javaColor.getGreen(), javaColor.getBlue()); + } + else + { + Color.fromBGR(Integer.parseInt(potionColorStr)); + } + } + catch (Throwable ignored) + { + } + } + return null; + } + + public static int bukkitColorFromString_integer(String potionColorStr) + { + try + { + return ((Color) FieldUtils.readStaticField(Color.class, potionColorStr)).asRGB(); + } + catch (Exception e) + { + try + { + if (!Utilz.isNumeric(potionColorStr)) + { + if (potionColorStr == null) + return -1; + //fix java.lang.NumberFormatException: For input string: ".0" + if (potionColorStr.endsWith(".0")) + potionColorStr = potionColorStr.replace(".0", ""); + potionColorStr = potionColorStr.replace(".", ""); + //fix java.lang.StringIndexOutOfBoundsException: String index out of range: 7 + while (potionColorStr.length() < 7) + potionColorStr = potionColorStr + "0"; + if (!potionColorStr.startsWith("#")) + potionColorStr = "#" + potionColorStr; + + java.awt.Color javaColor = hex2Rgb(potionColorStr); + return Color.fromRGB(javaColor.getRed(), javaColor.getGreen(), javaColor.getBlue()).asRGB(); + } + else + { + return Integer.parseInt(potionColorStr); + } + } + catch (Throwable ignored){} + } + return -1; + } + + public static boolean isBetween(int number, int min, int max, boolean equals) + { + if (equals) + return number >= min && number <= max; + return number > min && number < max; + } + + public static boolean isBetween(int number, int min, int max) + { + return isBetween(number, min, max, true); + } + + public static String getDateNowFormatted() + { + return getDateFormatted(new Date()); + } + + public static String getDateFormatted(Date date) + { + return new SimpleDateFormat("yyyy-MM-dd_HH-mm").format(date); + } + + public static void printFunctionCaller() + { + try + { + StackTraceElement[] stackTrace = new Throwable().fillInStackTrace().getStackTrace(); + StringBuilder a = new StringBuilder(); + for (int i = 1; i < stackTrace.length; i++) + a.append(stackTrace[i].getMethodName() + ":" + stackTrace[i].getLineNumber()).append("->"); + System.out.println(a.toString()); + } + catch (Throwable ignored) + { + } + } + + public static void showBook(Player player, String json) + { + ItemStack book = new ItemStack(Material.WRITTEN_BOOK); + Bukkit.getUnsafe().modifyItemStack(book, json); + player.openBook(book); + } + + public static int rgb(int r, int g, int b) + { + return new java.awt.Color(r, g, b, 255).getRGB(); + } + + public static boolean mkdirs(String path, boolean printErrors) + { + File file = new File(path); + if (file.exists()) + return true; + + try + { + Files.createDirectories(file.toPath()); + } + catch (Throwable e) + { + if (printErrors) + e.printStackTrace(); + return false; + } + + return true; + } + + public static Set getKeysByValue(Map map, E value) + { + return map.entrySet() + .stream() + .filter(entry -> Objects.equals(entry.getValue(), value)) + .map(Map.Entry::getKey) + .collect(Collectors.toSet()); + } + + /** See: {@link Utilz#partialFilePath(String)}. */ + public static String partialFilePath(File file) + { + return partialFilePath(file.getAbsolutePath()); + } + + /** + * Input: + * "C:/Progetti/Minecraft/TestServer/1.19/plugins/ItemsAdder/contents/_iainternal/resourcepack/assets/_iainternal/textures/icons/icon_next_orange.png" + * "C:/Progetti/Minecraft/TestServer/blank_template/1.19.4/plugins/ModelEngine/resource pack/contents/prova/123/asd" + * Output: + * "contents/_iainternal/resourcepack/assets/_iainternal/textures/icons/icon_next_orange.png" + * "resource pack/contents/prova/123/asd" + */ + public static String partialFilePath(String fileAbsolutePath) + { + if (fileAbsolutePath == null) + return null; + + String finalPath = fileAbsolutePath.replace("\\", "/"); + + int indexOfPlugins = finalPath.indexOf("plugins/"); + if(indexOfPlugins != -1) + finalPath = finalPath.substring(indexOfPlugins); + + // Remove the plugins/XXX/ text + int indexOfSlash = finalPath.indexOf("/"); + if(indexOfSlash != -1) + finalPath = finalPath.substring(indexOfSlash + 1); + indexOfSlash = finalPath.indexOf("/"); + if(indexOfSlash != -1) + finalPath = finalPath.substring(indexOfSlash + 1); + + return finalPath; + } + + public static int getFilesCount(File dir) + { + String[] list = dir.list(); + if (list == null) + return 0; + return list.length; + } + + public static String getPathRelativeToServerRoot(File file) + { + String serveRootPath = Bukkit.getServer().getWorldContainer().getAbsolutePath(); + if (serveRootPath.endsWith(".")) + serveRootPath = serveRootPath.substring(0, serveRootPath.length() - 2); + File serverRootDir = new File(serveRootPath).getParentFile(); + return file.getAbsolutePath().replace(serverRootDir.getAbsolutePath(), ""); + } + + public static Path path(String path) + { + return new File(path).toPath(); + } + + /** + * Very important, zip files must use / not \\ or Minecraft won't recognize files.. + */ + public static String sanitizePath(String str) + { + str = str.replace("\\", "/"); + if (str.startsWith("/")) + str = str.substring(1); + return str; + } + + public static String sanitizedPath(File file) + { + return sanitizePath(file.getAbsolutePath()); + } + + public static String removeStartsWith(String str, String starsWith) + { + if (str.startsWith(starsWith)) + return str.substring(starsWith.length()); + return str; + } + + public static String removeEndsWith(String str, String endsWith) + { + return str.replaceFirst(endsWith + "$", ""); + } + + public static String getLastNormalizedPathEntry(String str) + { + return str.substring(str.lastIndexOf('/') + 1); + } + + public static String cloneString(String str) + { + return new String(str.getBytes(StandardCharsets.UTF_8)); + } + + public static T[] copy(T[] matrix) + { + return Arrays.copyOf(matrix, matrix.length); + } + + public static String fileExtension(File file) + { + return FilenameUtils.getExtension(file.getAbsolutePath()); + } + + public static String fileName(File file, boolean extension) + { + if(extension) + return file.getName(); + return FilenameUtils.getBaseName(file.getAbsolutePath()); + } + + public static String humanReadableByteCountSI(long bytes) + { + if (-1000 < bytes && bytes < 1000) + { + return bytes + " B"; + } + CharacterIterator ci = new StringCharacterIterator("kMGTPE"); + while (bytes <= -999_950 || bytes >= 999_950) + { + bytes /= 1000; + ci.next(); + } + return String.format("%.1f %cB", bytes / 1000.0, ci.current()); + } + + public static int minMax(int value, int min, int max) + { + if(value < min) + return min; + return Math.min(value, max); + } + + public static String substringBefore(String string, String before) + { + return string.substring(string.indexOf(before)); + } + + public static Attribute strToAttributeType(String attributeModifier) + { + attributeModifier = attributeModifier.replace("minecraft:", ""); + return switch (attributeModifier) + { + case "generic.max_health" -> Attribute.GENERIC_MAX_HEALTH; + case "generic.follow_range" -> Attribute.GENERIC_FOLLOW_RANGE; + case "generic.knockback_resistance" -> Attribute.GENERIC_KNOCKBACK_RESISTANCE; + case "generic.movement_speed" -> Attribute.GENERIC_MOVEMENT_SPEED; + case "generic.flying_speed" -> Attribute.GENERIC_FLYING_SPEED; + case "generic.attack_damage" -> Attribute.GENERIC_ATTACK_DAMAGE; + case "generic.attack_knockback" -> // 1.16+ + Attribute.GENERIC_ATTACK_KNOCKBACK; + case "generic.attack_speed" -> Attribute.GENERIC_ATTACK_SPEED; + case "generic.armor" -> Attribute.GENERIC_ARMOR; + case "generic.armor_toughness" -> Attribute.GENERIC_ARMOR_TOUGHNESS; + case "generic.luck" -> Attribute.GENERIC_LUCK; + case "zombie.spawn_reinforcements" -> Attribute.ZOMBIE_SPAWN_REINFORCEMENTS; + case "horse.jump_strength" -> Attribute.HORSE_JUMP_STRENGTH; + default -> null; + }; + } + + public static EquipmentSlot strToVanillaEquipmentSlot(String str) + { + return switch (str.toLowerCase()) + { + case "head" -> EquipmentSlot.HEAD; + case "chest" -> EquipmentSlot.CHEST; + case "legs" -> EquipmentSlot.LEGS; + case "feet" -> EquipmentSlot.FEET; + case "mainhand" -> EquipmentSlot.HAND; + case "offhand" -> EquipmentSlot.OFF_HAND; + default -> null; + }; + } + + public static List fixJsonFormatting(List linesJson) + { + for (int i = 0, linesJsonSize = linesJson.size(); i < linesJsonSize; i++) + { + String jsonLine = linesJson.get(i); + linesJson.set(i, fixJsonFormatting(jsonLine)); + } + + return linesJson; + } + + public static String fixJsonFormatting(String jsonString) + { + Component component = Comp.jsonToComponent(jsonString); + component = component.colorIfAbsent(TextColor.color(255, 255, 255)); + component = component.decorationIfAbsent(TextDecoration.ITALIC, TextDecoration.State.FALSE); + return Comp.componentToJson(component); + } +} \ No newline at end of file diff --git a/VanillaCustomizer-core/src/main/resources/contents/example_settings/config.yml b/VanillaCustomizer-core/src/main/resources/contents/example_settings/config.yml new file mode 100644 index 0000000..5fe09b1 --- /dev/null +++ b/VanillaCustomizer-core/src/main/resources/contents/example_settings/config.yml @@ -0,0 +1,44 @@ +customizations: + custom1: + rules: + material_wildcards: + - "*_SWORD" + changes: + rename: "Amogus" + custom2: + rules: + material: STONE + changes: + rename: "CUSTOM RULE 2!!!!" + custom3: + rules: + materials: + - DIAMOND + - EMERALD + changes: + rename: "CUSTOM RULE 3!!!" + custom4: + rules: + materials: + - DIAMOND_CHESTPLATE + - EMERALD + changes: + rename: "CUSTOM RULE 4!!!" + custom5: + rules: + materials: + - IRON_INGOT + changes: + replace_word_display_name: + from: "test" + to: "changed_text!!!" + custom6: + rules: + nbt: + path: "itemsadder.id" + value: ruby + type: string + changes: + replace_word_display_name: + from: "Rub" + to: "FOUND NBT RULE!" \ No newline at end of file diff --git a/VanillaCustomizer-core/src/main/resources/plugin.yml b/VanillaCustomizer-core/src/main/resources/plugin.yml new file mode 100644 index 0000000..79f5d4b --- /dev/null +++ b/VanillaCustomizer-core/src/main/resources/plugin.yml @@ -0,0 +1,9 @@ +name: VanillaCustomizer +version: 0.2 +main: dev.lone.vanillacustomizer.Main +api-version: 1.13 +commands: + vanillacustomizer: + description: Main admin plugin command + usage: / + permission: "vanillacustomizer.admin" diff --git a/VanillaCustomizer-jar/jar-no-dependencies.xml b/VanillaCustomizer-jar/jar-no-dependencies.xml new file mode 100644 index 0000000..a1cc6f7 --- /dev/null +++ b/VanillaCustomizer-jar/jar-no-dependencies.xml @@ -0,0 +1,17 @@ + + jar-no-dependencies + + jar + + false + + + / + false + false + true + + + \ No newline at end of file diff --git a/VanillaCustomizer-jar/pom.xml b/VanillaCustomizer-jar/pom.xml new file mode 100644 index 0000000..988946e --- /dev/null +++ b/VanillaCustomizer-jar/pom.xml @@ -0,0 +1,122 @@ + + + + VanillaCustomizer + dev.lone + VERSION + + 4.0.0 + + VanillaCustomizer-jar + jar + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + false + + + + + maven-assembly-plugin + 3.3.0 + + + package + + single + + + + + ${project.parent.artifactId} + ${basedir}/../output/ + + jar-no-dependencies.xml + + false + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + CopyFile + package + + cmd + ${project.parent.basedir} + + /C + maven_exec\CopyFile.bat + + + + exec + + + + + + maven-compiler-plugin + 3.8.1 + + false + 1.8 + 1.8 + 16 + + + + + + + + dev.lone + VanillaCustomizer-core + VERSION + + + + dev.lone + VanillaCustomizer-nms-v1_20_R3 + VERSION + + + dev.lone + VanillaCustomizer-nms-v1_20_R2 + VERSION + + + dev.lone + VanillaCustomizer-nms-v1_20_R1 + VERSION + + + dev.lone + VanillaCustomizer-nms-v1_19_R3 + VERSION + + + dev.lone + VanillaCustomizer-nms-v1_18_R2 + VERSION + + + dev.lone + VanillaCustomizer-nms-v1_17_R1 + VERSION + + + + \ No newline at end of file diff --git a/VanillaCustomizer-nms-v1_17_R1/.gitignore b/VanillaCustomizer-nms-v1_17_R1/.gitignore new file mode 100644 index 0000000..4788b4b --- /dev/null +++ b/VanillaCustomizer-nms-v1_17_R1/.gitignore @@ -0,0 +1,113 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +target/ + +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next + +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# Common working directory +run/ diff --git a/VanillaCustomizer-nms-v1_17_R1/pom.xml b/VanillaCustomizer-nms-v1_17_R1/pom.xml new file mode 100644 index 0000000..c3378bf --- /dev/null +++ b/VanillaCustomizer-nms-v1_17_R1/pom.xml @@ -0,0 +1,55 @@ + + + + VanillaCustomizer + dev.lone + VERSION + + 4.0.0 + + VanillaCustomizer-nms-v1_17_R1 + + + 17 + 17 + + + + + + + ca.bkaw + paper-nms-maven-plugin + 1.3.2 + + + process-classes + + remap + + + + + + + + + + + ca.bkaw + paper-nms + 1.17.1-SNAPSHOT + provided + + + + dev.lone + VanillaCustomizer-core + VERSION + provided + + + + \ No newline at end of file diff --git a/VanillaCustomizer-nms-v1_17_R1/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_17_R1.java b/VanillaCustomizer-nms-v1_17_R1/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_17_R1.java new file mode 100644 index 0000000..6a65d04 --- /dev/null +++ b/VanillaCustomizer-nms-v1_17_R1/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_17_R1.java @@ -0,0 +1,47 @@ +package dev.lone.vanillacustomizer.nms.items.impl; + +import dev.lone.vanillacustomizer.nms.items.IItemsNms; +import dev.lone.vanillacustomizer.nms.items.Rarity; +import net.minecraft.world.food.FoodProperties; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_17_R1.util.CraftMagicNumbers; +import org.bukkit.inventory.ItemStack; + +public class v1_17_R1 implements IItemsNms +{ + @Override + public Rarity getRarity(ItemStack bukkitItem) + { + net.minecraft.world.item.ItemStack item = CraftItemStack.asNMSCopy(bukkitItem); + return Rarity.values()[item.getRarity().ordinal()]; + } + + @Override + public float getDestroySpeed(ItemStack bukkitItem) + { + Block block = CraftMagicNumbers.getBlock(bukkitItem.getType()); + return block.defaultBlockState().destroySpeed; + } + + @Override + public int getNutrition(ItemStack bukkitItem) + { + Item item = CraftItemStack.asNMSCopy(bukkitItem).getItem(); + FoodProperties foodProperties = item.getFoodProperties(); + if(foodProperties == null) + return 0; + return foodProperties.getNutrition(); + } + + @Override + public float getSaturation(ItemStack bukkitItem) + { + Item item = CraftItemStack.asNMSCopy(bukkitItem).getItem(); + FoodProperties foodProperties = item.getFoodProperties(); + if(foodProperties == null) + return 0; + return foodProperties.getSaturationModifier(); + } +} diff --git a/VanillaCustomizer-nms-v1_18_R2/.gitignore b/VanillaCustomizer-nms-v1_18_R2/.gitignore new file mode 100644 index 0000000..4788b4b --- /dev/null +++ b/VanillaCustomizer-nms-v1_18_R2/.gitignore @@ -0,0 +1,113 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +target/ + +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next + +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# Common working directory +run/ diff --git a/VanillaCustomizer-nms-v1_18_R2/pom.xml b/VanillaCustomizer-nms-v1_18_R2/pom.xml new file mode 100644 index 0000000..e703893 --- /dev/null +++ b/VanillaCustomizer-nms-v1_18_R2/pom.xml @@ -0,0 +1,55 @@ + + + + VanillaCustomizer + dev.lone + VERSION + + 4.0.0 + + VanillaCustomizer-nms-v1_18_R2 + + + 17 + 17 + + + + + + + ca.bkaw + paper-nms-maven-plugin + 1.3.2 + + + process-classes + + remap + + + + + + + + + + + ca.bkaw + paper-nms + 1.18.2-SNAPSHOT + provided + + + + dev.lone + VanillaCustomizer-core + VERSION + provided + + + + \ No newline at end of file diff --git a/VanillaCustomizer-nms-v1_18_R2/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_18_R2.java b/VanillaCustomizer-nms-v1_18_R2/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_18_R2.java new file mode 100644 index 0000000..4ddd9e1 --- /dev/null +++ b/VanillaCustomizer-nms-v1_18_R2/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_18_R2.java @@ -0,0 +1,47 @@ +package dev.lone.vanillacustomizer.nms.items.impl; + +import dev.lone.vanillacustomizer.nms.items.IItemsNms; +import dev.lone.vanillacustomizer.nms.items.Rarity; +import net.minecraft.world.food.FoodProperties; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_18_R2.util.CraftMagicNumbers; +import org.bukkit.inventory.ItemStack; + +public class v1_18_R2 implements IItemsNms +{ + @Override + public Rarity getRarity(ItemStack bukkitItem) + { + net.minecraft.world.item.ItemStack item = CraftItemStack.asNMSCopy(bukkitItem); + return Rarity.values()[item.getRarity().ordinal()]; + } + + @Override + public float getDestroySpeed(ItemStack bukkitItem) + { + Block block = CraftMagicNumbers.getBlock(bukkitItem.getType()); + return block.defaultBlockState().destroySpeed; + } + + @Override + public int getNutrition(ItemStack bukkitItem) + { + Item item = CraftItemStack.asNMSCopy(bukkitItem).getItem(); + FoodProperties foodProperties = item.getFoodProperties(); + if(foodProperties == null) + return 0; + return foodProperties.getNutrition(); + } + + @Override + public float getSaturation(ItemStack bukkitItem) + { + Item item = CraftItemStack.asNMSCopy(bukkitItem).getItem(); + FoodProperties foodProperties = item.getFoodProperties(); + if(foodProperties == null) + return 0; + return foodProperties.getSaturationModifier(); + } +} diff --git a/VanillaCustomizer-nms-v1_19_R3/.gitignore b/VanillaCustomizer-nms-v1_19_R3/.gitignore new file mode 100644 index 0000000..4788b4b --- /dev/null +++ b/VanillaCustomizer-nms-v1_19_R3/.gitignore @@ -0,0 +1,113 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +target/ + +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next + +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# Common working directory +run/ diff --git a/VanillaCustomizer-nms-v1_19_R3/pom.xml b/VanillaCustomizer-nms-v1_19_R3/pom.xml new file mode 100644 index 0000000..7da79fd --- /dev/null +++ b/VanillaCustomizer-nms-v1_19_R3/pom.xml @@ -0,0 +1,55 @@ + + + + VanillaCustomizer + dev.lone + VERSION + + 4.0.0 + + VanillaCustomizer-nms-v1_19_R3 + + + 17 + 17 + + + + + + + ca.bkaw + paper-nms-maven-plugin + 1.3.2 + + + process-classes + + remap + + + + + + + + + + + ca.bkaw + paper-nms + 1.19.4-SNAPSHOT + provided + + + + dev.lone + VanillaCustomizer-core + VERSION + provided + + + + \ No newline at end of file diff --git a/VanillaCustomizer-nms-v1_19_R3/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_19_R3.java b/VanillaCustomizer-nms-v1_19_R3/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_19_R3.java new file mode 100644 index 0000000..585e217 --- /dev/null +++ b/VanillaCustomizer-nms-v1_19_R3/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_19_R3.java @@ -0,0 +1,47 @@ +package dev.lone.vanillacustomizer.nms.items.impl; + +import dev.lone.vanillacustomizer.nms.items.IItemsNms; +import dev.lone.vanillacustomizer.nms.items.Rarity; +import net.minecraft.world.food.FoodProperties; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_19_R3.util.CraftMagicNumbers; +import org.bukkit.inventory.ItemStack; + +public class v1_19_R3 implements IItemsNms +{ + @Override + public Rarity getRarity(ItemStack bukkitItem) + { + net.minecraft.world.item.ItemStack item = CraftItemStack.asNMSCopy(bukkitItem); + return Rarity.values()[item.getRarity().ordinal()]; + } + + @Override + public float getDestroySpeed(ItemStack bukkitItem) + { + Block block = CraftMagicNumbers.getBlock(bukkitItem.getType()); + return block.defaultBlockState().destroySpeed; + } + + @Override + public int getNutrition(ItemStack bukkitItem) + { + Item item = CraftItemStack.asNMSCopy(bukkitItem).getItem(); + FoodProperties foodProperties = item.getFoodProperties(); + if(foodProperties == null) + return 0; + return foodProperties.getNutrition(); + } + + @Override + public float getSaturation(ItemStack bukkitItem) + { + Item item = CraftItemStack.asNMSCopy(bukkitItem).getItem(); + FoodProperties foodProperties = item.getFoodProperties(); + if(foodProperties == null) + return 0; + return foodProperties.getSaturationModifier(); + } +} diff --git a/VanillaCustomizer-nms-v1_20_R1/.gitignore b/VanillaCustomizer-nms-v1_20_R1/.gitignore new file mode 100644 index 0000000..4788b4b --- /dev/null +++ b/VanillaCustomizer-nms-v1_20_R1/.gitignore @@ -0,0 +1,113 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +target/ + +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next + +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# Common working directory +run/ diff --git a/VanillaCustomizer-nms-v1_20_R1/pom.xml b/VanillaCustomizer-nms-v1_20_R1/pom.xml new file mode 100644 index 0000000..9a46a8e --- /dev/null +++ b/VanillaCustomizer-nms-v1_20_R1/pom.xml @@ -0,0 +1,55 @@ + + + + VanillaCustomizer + dev.lone + VERSION + + 4.0.0 + + VanillaCustomizer-nms-v1_20_R1 + + + 17 + 17 + + + + + + + ca.bkaw + paper-nms-maven-plugin + 1.3.2 + + + process-classes + + remap + + + + + + + + + + + ca.bkaw + paper-nms + 1.20.1-SNAPSHOT + provided + + + + dev.lone + VanillaCustomizer-core + VERSION + provided + + + + \ No newline at end of file diff --git a/VanillaCustomizer-nms-v1_20_R1/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_20_R1.java b/VanillaCustomizer-nms-v1_20_R1/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_20_R1.java new file mode 100644 index 0000000..2eadb73 --- /dev/null +++ b/VanillaCustomizer-nms-v1_20_R1/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_20_R1.java @@ -0,0 +1,47 @@ +package dev.lone.vanillacustomizer.nms.items.impl; + +import dev.lone.vanillacustomizer.nms.items.IItemsNms; +import dev.lone.vanillacustomizer.nms.items.Rarity; +import net.minecraft.world.food.FoodProperties; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_20_R1.util.CraftMagicNumbers; +import org.bukkit.inventory.ItemStack; + +public class v1_20_R1 implements IItemsNms +{ + @Override + public Rarity getRarity(ItemStack bukkitItem) + { + net.minecraft.world.item.ItemStack item = CraftItemStack.asNMSCopy(bukkitItem); + return Rarity.values()[item.getRarity().ordinal()]; + } + + @Override + public float getDestroySpeed(ItemStack bukkitItem) + { + Block block = CraftMagicNumbers.getBlock(bukkitItem.getType()); + return block.defaultBlockState().destroySpeed; + } + + @Override + public int getNutrition(ItemStack bukkitItem) + { + Item item = CraftItemStack.asNMSCopy(bukkitItem).getItem(); + FoodProperties foodProperties = item.getFoodProperties(); + if(foodProperties == null) + return 0; + return foodProperties.getNutrition(); + } + + @Override + public float getSaturation(ItemStack bukkitItem) + { + Item item = CraftItemStack.asNMSCopy(bukkitItem).getItem(); + FoodProperties foodProperties = item.getFoodProperties(); + if(foodProperties == null) + return 0; + return foodProperties.getSaturationModifier(); + } +} diff --git a/VanillaCustomizer-nms-v1_20_R2/.gitignore b/VanillaCustomizer-nms-v1_20_R2/.gitignore new file mode 100644 index 0000000..4788b4b --- /dev/null +++ b/VanillaCustomizer-nms-v1_20_R2/.gitignore @@ -0,0 +1,113 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +target/ + +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next + +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# Common working directory +run/ diff --git a/VanillaCustomizer-nms-v1_20_R2/pom.xml b/VanillaCustomizer-nms-v1_20_R2/pom.xml new file mode 100644 index 0000000..15e3b60 --- /dev/null +++ b/VanillaCustomizer-nms-v1_20_R2/pom.xml @@ -0,0 +1,55 @@ + + + + VanillaCustomizer + dev.lone + VERSION + + 4.0.0 + + VanillaCustomizer-nms-v1_20_R2 + + + 17 + 17 + + + + + + + ca.bkaw + paper-nms-maven-plugin + 1.3.2 + + + process-classes + + remap + + + + + + + + + + + ca.bkaw + paper-nms + 1.20.2-SNAPSHOT + provided + + + + dev.lone + VanillaCustomizer-core + VERSION + provided + + + + \ No newline at end of file diff --git a/VanillaCustomizer-nms-v1_20_R2/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_20_R2.java b/VanillaCustomizer-nms-v1_20_R2/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_20_R2.java new file mode 100644 index 0000000..f94c044 --- /dev/null +++ b/VanillaCustomizer-nms-v1_20_R2/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_20_R2.java @@ -0,0 +1,47 @@ +package dev.lone.vanillacustomizer.nms.items.impl; + +import dev.lone.vanillacustomizer.nms.items.IItemsNms; +import dev.lone.vanillacustomizer.nms.items.Rarity; +import net.minecraft.world.food.FoodProperties; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_20_R2.util.CraftMagicNumbers; +import org.bukkit.inventory.ItemStack; + +public class v1_20_R2 implements IItemsNms +{ + @Override + public Rarity getRarity(ItemStack bukkitItem) + { + net.minecraft.world.item.ItemStack item = CraftItemStack.asNMSCopy(bukkitItem); + return Rarity.values()[item.getRarity().ordinal()]; + } + + @Override + public float getDestroySpeed(ItemStack bukkitItem) + { + Block block = CraftMagicNumbers.getBlock(bukkitItem.getType()); + return block.defaultBlockState().destroySpeed; + } + + @Override + public int getNutrition(ItemStack bukkitItem) + { + Item item = CraftItemStack.asNMSCopy(bukkitItem).getItem(); + FoodProperties foodProperties = item.getFoodProperties(); + if(foodProperties == null) + return 0; + return foodProperties.getNutrition(); + } + + @Override + public float getSaturation(ItemStack bukkitItem) + { + Item item = CraftItemStack.asNMSCopy(bukkitItem).getItem(); + FoodProperties foodProperties = item.getFoodProperties(); + if(foodProperties == null) + return 0; + return foodProperties.getSaturationModifier(); + } +} diff --git a/VanillaCustomizer-nms-v1_20_R3/pom.xml b/VanillaCustomizer-nms-v1_20_R3/pom.xml new file mode 100644 index 0000000..b6e89d8 --- /dev/null +++ b/VanillaCustomizer-nms-v1_20_R3/pom.xml @@ -0,0 +1,55 @@ + + + + VanillaCustomizer + dev.lone + VERSION + + 4.0.0 + + VanillaCustomizer-nms-v1_20_R3 + + + 17 + 17 + + + + + + + ca.bkaw + paper-nms-maven-plugin + 1.3.2 + + + process-classes + + remap + + + + + + + + + + + ca.bkaw + paper-nms + 1.20.3-SNAPSHOT + provided + + + + dev.lone + VanillaCustomizer-core + VERSION + provided + + + + \ No newline at end of file diff --git a/VanillaCustomizer-nms-v1_20_R3/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_20_R3.java b/VanillaCustomizer-nms-v1_20_R3/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_20_R3.java new file mode 100644 index 0000000..b17a3a3 --- /dev/null +++ b/VanillaCustomizer-nms-v1_20_R3/src/main/java/dev/lone/vanillacustomizer/nms/items/impl/v1_20_R3.java @@ -0,0 +1,47 @@ +package dev.lone.vanillacustomizer.nms.items.impl; + +import dev.lone.vanillacustomizer.nms.items.IItemsNms; +import dev.lone.vanillacustomizer.nms.items.Rarity; +import net.minecraft.world.food.FoodProperties; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_20_R3.util.CraftMagicNumbers; +import org.bukkit.inventory.ItemStack; + +public class v1_20_R3 implements IItemsNms +{ + @Override + public Rarity getRarity(ItemStack bukkitItem) + { + net.minecraft.world.item.ItemStack item = CraftItemStack.asNMSCopy(bukkitItem); + return Rarity.values()[item.getRarity().ordinal()]; + } + + @Override + public float getDestroySpeed(ItemStack bukkitItem) + { + Block block = CraftMagicNumbers.getBlock(bukkitItem.getType()); + return block.defaultBlockState().destroySpeed; + } + + @Override + public int getNutrition(ItemStack bukkitItem) + { + Item item = CraftItemStack.asNMSCopy(bukkitItem).getItem(); + FoodProperties foodProperties = item.getFoodProperties(); + if(foodProperties == null) + return 0; + return foodProperties.getNutrition(); + } + + @Override + public float getSaturation(ItemStack bukkitItem) + { + Item item = CraftItemStack.asNMSCopy(bukkitItem).getItem(); + FoodProperties foodProperties = item.getFoodProperties(); + if(foodProperties == null) + return 0; + return foodProperties.getSaturationModifier(); + } +} diff --git a/maven_exec/CopyFile.bat b/maven_exec/CopyFile.bat new file mode 100644 index 0000000..4f7ceb8 --- /dev/null +++ b/maven_exec/CopyFile.bat @@ -0,0 +1,5 @@ +echo f | xcopy C:\Progetti\Minecraft\Spigot\VanillaCustomizer\output\VanillaCustomizer.jar C:\Progetti\Minecraft\TestServer\1.19_cosmetics\plugins\VanillaCustomizer.jar /Y +echo f | xcopy C:\Progetti\Minecraft\Spigot\VanillaCustomizer\output\VanillaCustomizer.jar C:\Progetti\Minecraft\TestServer\blank_template\server2\plugins\VanillaCustomizer.jar /Y +echo f | xcopy C:\Progetti\Minecraft\Spigot\VanillaCustomizer\output\VanillaCustomizer.jar C:\Progetti\Minecraft\TestServer\blank_template\1.20\plugins\VanillaCustomizer.jar /Y +echo f | xcopy C:\Progetti\Minecraft\Spigot\VanillaCustomizer\output\VanillaCustomizer.jar C:\Progetti\Minecraft\TestServer\blank_template\1.19.4\plugins\VanillaCustomizer.jar /Y +echo f | xcopy C:\Progetti\Minecraft\Spigot\VanillaCustomizer\output\VanillaCustomizer.jar C:\Progetti\Minecraft\TestServer\1.16\plugins\VanillaCustomizer.jar /Y \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8493618 --- /dev/null +++ b/pom.xml @@ -0,0 +1,118 @@ + + + 4.0.0 + + dev.lone + VanillaCustomizer + VERSION + + VanillaCustomizer + pom + + + 1.8 + UTF-8 + 16 + 16 + C:/Progetti/Minecraft/Spigot/_jars + + + + VanillaCustomizer-core + VanillaCustomizer-jar + VanillaCustomizer-nms-v1_20_R3 + VanillaCustomizer-nms-v1_20_R2 + VanillaCustomizer-nms-v1_20_R1 + VanillaCustomizer-nms-v1_19_R3 + VanillaCustomizer-nms-v1_18_R2 + VanillaCustomizer-nms-v1_17_R1 + + + + + bytecode.space + https://repo.bytecode.space/repository/maven-public/ + + + + + + ${project.basedir}/../.cache/targets/${project.artifactId}/target/ + + + org.apache.maven.extensions + maven-build-cache-extension + 1.0.1-SNAPSHOT-unofficial-1.0.0 + + + co.leantechniques + maven-buildtime-extension + 2.0.3 + + + + + + maven-compiler-plugin + 3.1 + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12.4 + + true + true + + + + + + + + + + org.apache.maven.plugins + maven-clean-plugin + 2.5 + default-clean none + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M4 + default-test none + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + false + 1.8 + 1.8 + 16 + + + default-testCompile none + + + + org.apache.maven.plugins + maven-resources-plugin + 3.3.1 + + default-testResources none + + + + + + + + + + +