├── .gitattributes ├── .github ├── FUNDING.yml ├── dependabot.yml └── workflows │ ├── javadoc.yml │ ├── maven.yml │ └── wiki.yml ├── .gitignore ├── LICENSE ├── README.md ├── curseforge.md ├── formatter.xml ├── item-nbt-api ├── LICENSE ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── tr7zw │ └── changeme │ └── nbtapi │ ├── NBT.java │ ├── NBTBlock.java │ ├── NBTChunk.java │ ├── NBTCompound.java │ ├── NBTCompoundList.java │ ├── NBTContainer.java │ ├── NBTDoubleList.java │ ├── NBTEntity.java │ ├── NBTFile.java │ ├── NBTFloatList.java │ ├── NBTGameProfile.java │ ├── NBTIntArrayList.java │ ├── NBTIntegerList.java │ ├── NBTItem.java │ ├── NBTList.java │ ├── NBTListCompound.java │ ├── NBTLongList.java │ ├── NBTPersistentDataContainer.java │ ├── NBTReflectionUtil.java │ ├── NBTStringList.java │ ├── NBTTileEntity.java │ ├── NBTType.java │ ├── NBTUUIDList.java │ ├── NbtApiException.java │ ├── handler │ └── NBTHandlers.java │ ├── iface │ ├── NBTFileHandle.java │ ├── NBTHandler.java │ ├── ReadWriteItemNBT.java │ ├── ReadWriteNBT.java │ ├── ReadWriteNBTCompoundList.java │ ├── ReadWriteNBTList.java │ ├── ReadableItemNBT.java │ ├── ReadableNBT.java │ └── ReadableNBTList.java │ ├── utils │ ├── CheckUtil.java │ ├── DataFixerUtil.java │ ├── GameprofileUtil.java │ ├── GsonWrapper.java │ ├── Metrics.java │ ├── MinecraftVersion.java │ ├── NBTJsonUtil.java │ ├── PathUtil.java │ ├── ReflectionUtil.java │ ├── UUIDUtil.java │ ├── VersionChecker.java │ └── nmsmappings │ │ ├── ClassWrapper.java │ │ ├── Forge1710Mappings.java │ │ ├── MojangToMapping.java │ │ ├── ObjectCreator.java │ │ ├── PackageWrapper.java │ │ └── ReflectionMethod.java │ └── wrapper │ ├── Casing.java │ ├── DefaultMethodInvoker.java │ ├── NBTProxy.java │ ├── NBTTarget.java │ ├── ProxiedList.java │ ├── ProxyBuilder.java │ └── ProxyList.java ├── item-nbt-plugin ├── LICENSE ├── pom.xml └── src │ └── main │ ├── java │ └── de │ │ └── tr7zw │ │ └── nbtapi │ │ └── plugin │ │ ├── NBTAPI.java │ │ └── tests │ │ ├── GameprofileTest.java │ │ ├── NBTFileTest.java │ │ ├── Test.java │ │ ├── blocks │ │ └── BlockNBTTest.java │ │ ├── chunks │ │ └── ChunkNBTPersistentTest.java │ │ ├── compounds │ │ ├── CompoundDifferenceTest.java │ │ ├── EnumTest.java │ │ ├── EqualsTest.java │ │ ├── ForEachTest.java │ │ ├── GetterSetterTest.java │ │ ├── GsonTest.java │ │ ├── InterfaceTest.java │ │ ├── IteratorTest.java │ │ ├── ListTest.java │ │ ├── LongArrayTest.java │ │ ├── MergeTest.java │ │ ├── ModernSubCompoundsTest.java │ │ ├── RemovingKeys.java │ │ ├── ResolveTest.java │ │ ├── StreamTest.java │ │ ├── SubCompoundsTest.java │ │ └── TypeTest.java │ │ ├── entities │ │ ├── EntityCustomNbtPersistentTest.java │ │ └── EntityTest.java │ │ ├── items │ │ ├── ComponentsTest.java │ │ ├── DirectApplyMetaTest.java │ │ ├── DirectApplyTest.java │ │ ├── EmptyItemTest.java │ │ ├── ItemConversionTest.java │ │ ├── ItemJsonTest.java │ │ ├── ItemMergingTest.java │ │ ├── ItemStackConversionTest.java │ │ ├── LegacyItemTest.java │ │ ├── MetaTest.java │ │ ├── NBTModifyItemTest.java │ │ └── SmuggleTest.java │ │ ├── proxy │ │ ├── DataItemProxyTest.java │ │ └── SimpleProxyTest.java │ │ └── tiles │ │ ├── TileTest.java │ │ └── TilesCustomNBTPersistentTest.java │ └── resources │ ├── META-INF │ └── .mojang-mapped │ └── plugin.yml ├── mappings-parser ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── dev │ └── tr7zw │ └── mappingsparser │ └── MappingsParser.java ├── nbt-data-api ├── LICENSE ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── tr7zw │ └── changeme │ └── nbtapi │ └── data │ ├── NBTData.java │ ├── PlayerData.java │ ├── WorldData.java │ └── proxy │ └── NBTItemMeta.java ├── nbt-injector ├── LICENSE ├── pom.xml └── src │ └── main │ └── java │ └── de │ └── tr7zw │ └── nbtinjector │ ├── ClassGenerator.java │ ├── INBTWrapper.java │ ├── InternalInjectors.java │ └── NBTInjector.java ├── pom.xml ├── spigot.bb └── wiki ├── Example-Usages.md ├── FAQ.md ├── Home.md ├── Plugins.md ├── Using-Gradle.md ├── Using-Maven.md ├── Using-the-NBT-API.md ├── _Footer.md └── _Sidebar.md /.gitattributes: -------------------------------------------------------------------------------- 1 | text eol=lf -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | ko_fi: tr7zw 4 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: maven 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | ignore: 9 | - dependency-name: com.github.ekryd.sortpom:sortpom-maven-plugin 10 | versions: 11 | - 2.13.3-SNAPSHOT 12 | - 2.14.0 13 | - 2.14.1 14 | - 2.15.0 15 | -------------------------------------------------------------------------------- /.github/workflows/javadoc.yml: -------------------------------------------------------------------------------- 1 | name: Javadoc CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | permissions: 9 | contents: write 10 | jobs: 11 | javadoc: 12 | if: ${{ github.repository_owner == 'tr7zw' }} 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v3 18 | - name: Set up JDK 1.8 19 | uses: actions/setup-java@v3 20 | with: 21 | distribution: zulu 22 | java-version: 8 23 | - name: Build with Maven 24 | run: mvn package 25 | - name: Copy artifacts 26 | shell: bash 27 | run: | 28 | mkdir -p artifacts/v2-api && cp -r item-nbt-api/target/reports/apidocs/* artifacts/v2-api 29 | mkdir -p artifacts/v2-plugin && cp -r item-nbt-plugin/target/apidocs/* artifacts/v2-plugin 30 | - name: Deploy 🚀 31 | uses: JamesIves/github-pages-deploy-action@v4.4.1 32 | with: 33 | token: ${{ secrets.GITHUB_TOKEN }} 34 | branch: gh-pages 35 | clean: false 36 | folder: artifacts 37 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | name: Java CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v3 12 | - name: Set up JDK 1.8 13 | uses: actions/setup-java@v3 14 | with: 15 | distribution: zulu 16 | java-version: 8 17 | - name: Build with Maven 18 | run: mvn install --file pom.xml 19 | -------------------------------------------------------------------------------- /.github/workflows/wiki.yml: -------------------------------------------------------------------------------- 1 | name: Wiki CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | permissions: 9 | contents: write 10 | jobs: 11 | wiki: 12 | if: ${{ github.repository_owner == 'tr7zw' }} 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Checkout base code 18 | uses: actions/checkout@v3 19 | with: 20 | path: base-code 21 | - name: Checkout wiki code 22 | uses: actions/checkout@v3 23 | with: 24 | repository: ${{github.repository}}.wiki 25 | path: wiki 26 | - name: Push to wiki 27 | run: | 28 | cd wiki 29 | rm *.md 30 | cp ../base-code/wiki/* ./ 31 | git config --local user.email "action@github.com" 32 | git config --local user.name "GitHub Action" 33 | git add . 34 | git diff-index --quiet HEAD || (git commit -m "Add changes" && git push) 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Java files ### 2 | *.class 3 | 4 | # Package Files 5 | *.jar 6 | *.war 7 | *.ear 8 | 9 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 10 | hs_err_pid* 11 | 12 | 13 | ### Intellij ### 14 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm 15 | # Ignore project files 16 | *.iml 17 | 18 | # Ignore IDEA directory 19 | .idea/ 20 | 21 | # File-based project format: 22 | *.ipr 23 | *.iws 24 | 25 | ### Plugin-specific files: ### 26 | # IntelliJ 27 | /out/ 28 | 29 | # mpeltonen/sbt-idea plugin 30 | .idea_modules/ 31 | 32 | # JIRA plugin 33 | atlassian-ide-plugin.xml 34 | 35 | # Crashlytics plugin (for Android Studio and IntelliJ) 36 | com_crashlytics_export_strings.xml 37 | crashlytics.properties 38 | crashlytics-build.properties 39 | 40 | 41 | ### Eclipse ### 42 | *.pydevproject 43 | .metadata 44 | .gradle 45 | bin/ 46 | tmp/ 47 | *.tmp 48 | *.bak 49 | *.swp 50 | *~.nib 51 | local.properties 52 | .settings/ 53 | .loadpath 54 | .factorypath 55 | 56 | # Eclipse Core 57 | .project 58 | 59 | # External tool builders 60 | .externalToolBuilders/ 61 | 62 | # Locally stored "Eclipse launch configurations" 63 | *.launch 64 | 65 | # CDT-specific 66 | .cproject 67 | 68 | # JDT-specific (Eclipse Java Development Tools) 69 | .classpath 70 | 71 | # PDT-specific 72 | .buildpath 73 | 74 | # sbteclipse plugin 75 | .target 76 | 77 | # TeXlipse plugin 78 | .texlipse 79 | 80 | 81 | ### Maven ### 82 | target/ 83 | pom.xml.tag 84 | pom.xml.releaseBackup 85 | pom.xml.versionsBackup 86 | pom.xml.next 87 | release.properties 88 | dependency-reduced-pom.xml 89 | buildNumber.properties 90 | 91 | 92 | ### NetBeans ### 93 | nbproject/private/ 94 | build/ 95 | nbbuild/ 96 | dist/ 97 | nbdist/ 98 | nbactions.xml 99 | nb-configuration.xml 100 | .nb-gradle/ 101 | 102 | 103 | ### Git ### 104 | # Don't exclude the .gitignore itself 105 | !.gitignore 106 | .vscode/settings.json 107 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 - 2024, tr7zw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Item-NBT-API 2 | 3 | Add custom NBT tags to Items/Tiles/Entities without NMS! Modify NBT and store it in Files, other NBT, or as String in yaml/json/SQL/Redis. 4 | [Server Owner/Developer Wiki](https://github.com/tr7zw/Item-NBT-API/wiki) 5 | 6 | ### Build/Maven/Sonar Status 7 | 8 | [![Build Status](https://ci.codemc.org/buildStatus/icon?job=Tr7zw%2FItem-NBT-API)](https://ci.codemc.org/job/Tr7zw/job/Item-NBT-API/)[![](https://sonarcloud.io/api/project_badges/measure?project=tr7zw_Item-NBT-API&metric=ncloc)](https://sonarcloud.io/summary/overall?id=tr7zw_Item-NBT-API)[![](https://sonarcloud.io/api/project_badges/measure?project=tr7zw_Item-NBT-API&metric=duplicated_lines_density)](https://sonarcloud.io/summary/overall?id=tr7zw_Item-NBT-API)[![](https://sonarcloud.io/api/project_badges/measure?project=tr7zw_Item-NBT-API&metric=sqale_rating)](https://sonarcloud.io/summary/overall?id=tr7zw_Item-NBT-API) 9 | [![Discord](https://img.shields.io/discord/342814924310970398?color=%237289DA&label=Discord&logo=discord&logoColor=white)](https://discordapp.com/invite/yk4caxM) 10 | [![Patreon](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.vercel.app%2Fapi%3Fusername%3Dtr7zw%26type%3Dpatrons&style=for-the-badge)](https://www.patreon.com/tr7zw) 11 | 12 | ### SpigotMC Status 13 | 14 | [![Version](https://badges.spiget.org/resources/version/Version-yellow-7939.svg)](https://www.spigotmc.org/resources/item-entity-tile-nbt-api.7939/)[![Rating](https://badges.spiget.org/resources/rating/Rating-yellow-7939.svg)](https://www.spigotmc.org/resources/item-entity-tile-nbt-api.7939/)[![Rating](https://badges.spiget.org/resources/downloads/SpigotDownloads-yellow-7939.svg)](https://www.spigotmc.org/resources/item-entity-tile-nbt-api.7939/)[![bStats Servers](https://img.shields.io/bstats/servers/1058.svg?color=green&label=OnlineServers&style=plastic)](https://bstats.org/plugin/bukkit/ItemNBTAPI)[![bStats Players](https://img.shields.io/bstats/players/1058.svg?color=green&label=OnlinePlayers&style=plastic)](https://bstats.org/plugin/bukkit/ItemNBTAPI)[![All Contributors](https://img.shields.io/badge/all_contributors-13-green.svg?style=plastic)](#contributors-%e2%9c%a8) 15 | 16 | ## Getting started 17 | 18 | Import the API using [Maven](https://github.com/tr7zw/Item-NBT-API/wiki/Using-Maven) or [Gradle](https://github.com/tr7zw/Item-NBT-API/wiki/Using-Gradle), then check out the [basic usage](https://github.com/tr7zw/Item-NBT-API/wiki/Using-the-NBT-API) or code examples like [working with Skulls](https://github.com/tr7zw/Item-NBT-API/wiki/Example-Usages#set-a-skulls-skin). 19 | 20 | ### bStats 21 | 22 | [![bStats Stats](https://bstats.org/signatures/bukkit/ItemNBTAPI.svg)](https://bstats.org/plugin/bukkit/ItemNBTAPI) 23 | 24 | ### Github Stargazers 25 | 26 | stargazers 27 | 28 | ### Supported by YourKit 29 | 30 | ![](https://www.yourkit.com/images/yklogo.png) 31 | YourKit supports open source projects with innovative and intelligent tools 32 | for monitoring and profiling Java and .NET applications. 33 | YourKit is the creator of YourKit Java Profiler, 34 | YourKit .NET Profiler, 35 | and YourKit YouMonitor. 36 | -------------------------------------------------------------------------------- /curseforge.md: -------------------------------------------------------------------------------- 1 | # (Item-)NBT-API 2 | 3 | Add custom NBT tags to Items/Tiles/Entities without NMS! Modify NBT and store it in Files, other NBT, or as String in yaml/json/SQL/Redis. 4 | [Server Owner/Developer Wiki](https://github.com/tr7zw/Item-NBT-API/wiki) 5 | 6 | ### Build/Maven/Sonar Status 7 | 8 | [![Build Status](https://github.com/tr7zw/Item-NBT-API/workflows/Java%20CI/badge.svg)](https://ci.codemc.org/job/Tr7zw/job/Item-NBT-API/)[![](https://sonarcloud.io/api/project_badges/measure?project=de.tr7zw%3Aitem-nbt-parent&metric=alert_status)](https://sonarcloud.io/dashboard?id=de.tr7zw%3Aitem-nbt-parent)[![](https://sonarcloud.io/api/project_badges/measure?project=de.tr7zw%3Aitem-nbt-parent&metric=ncloc)](https://sonarcloud.io/dashboard?id=de.tr7zw%3Aitem-nbt-parent)[![](https://sonarcloud.io/api/project_badges/measure?project=de.tr7zw%3Aitem-nbt-parent&metric=duplicated_lines_density)](https://sonarcloud.io/dashboard?id=de.tr7zw%3Aitem-nbt-parent)[![](https://sonarcloud.io/api/project_badges/measure?project=de.tr7zw%3Aitem-nbt-parent&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=de.tr7zw%3Aitem-nbt-parent) 9 | Discord:[![Discord](https://img.shields.io/discord/342814924310970398?color=%237289DA&label=Discord&logo=discord&logoColor=white)](https://discordapp.com/invite/yk4caxM) 10 | 11 | ### SpigotMC Status 12 | 13 | [![Version](https://badges.spiget.org/resources/version/Version-yellow-7939.svg)](https://www.spigotmc.org/resources/item-entity-tile-nbt-api.7939/)[![Rating](https://badges.spiget.org/resources/rating/Rating-yellow-7939.svg)](https://www.spigotmc.org/resources/item-entity-tile-nbt-api.7939/)[![Rating](https://badges.spiget.org/resources/downloads/SpigotDownloads-yellow-7939.svg)](https://www.spigotmc.org/resources/item-entity-tile-nbt-api.7939/)[![bStats Servers](https://img.shields.io/bstats/servers/1058.svg?color=green&label=OnlineServers&style=plastic)](https://bstats.org/plugin/bukkit/ItemNBTAPI)[![bStats Players](https://img.shields.io/bstats/players/1058.svg?color=green&label=OnlinePlayers&style=plastic)](https://bstats.org/plugin/bukkit/ItemNBTAPI) 14 | 15 | ## Getting started 16 | 17 | Import the API using [Maven](https://github.com/tr7zw/Item-NBT-API/wiki/Using-Maven) or [Gradle](https://github.com/tr7zw/Item-NBT-API/wiki/Using-Gradle), then check out the [basic usage](https://github.com/tr7zw/Item-NBT-API/wiki/Using-the-NBT-API) or code examples like [working with Skulls](https://github.com/tr7zw/Item-NBT-API/wiki/Example-Usages#set-a-skulls-skin). 18 | 19 | ### bStats 20 | 21 | [![bStats Stats](https://bstats.org/signatures/bukkit/ItemNBTAPI.svg)](https://bstats.org/plugin/bukkit/ItemNBTAPI) 22 | -------------------------------------------------------------------------------- /item-nbt-api/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 - 2021, tr7zw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /item-nbt-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | de.tr7zw 7 | item-nbt-parent 8 | 2.15.0 9 | 10 | 11 | item-nbt-api 12 | jar 13 | 14 | 15 | 16 | com.mojang 17 | datafixerupper 18 | 4.0.26 19 | provided 20 | 21 | 22 | 23 | 24 | clean install javadoc:javadoc 25 | 26 | 27 | true 28 | src/main/resources 29 | 30 | 31 | 32 | 33 | org.apache.maven.plugins 34 | maven-shade-plugin 35 | 3.6.0 36 | 37 | false 38 | 39 | 40 | LICENSE 41 | 42 | 43 | 44 | 45 | 46 | shade 47 | 48 | shade 49 | 50 | package 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTBlock.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | import org.bukkit.block.Block; 4 | 5 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 6 | 7 | /** 8 | * Helper class to store NBT data to Block Locations. Use getData() to get the 9 | * NBT instance. Important notes: 10 | * 11 | * - Non BlockEntities can not have NBT data. This stores the data to the chunk 12 | * instead! 13 | * 14 | * - The data is really just on the location. If the block gets 15 | * broken/changed/exploded/moved etc., the data is still on that location! 16 | * 17 | * @author tr7zw 18 | * 19 | */ 20 | public class NBTBlock { 21 | 22 | private final Block block; 23 | private final NBTChunk nbtChunk; 24 | 25 | public NBTBlock(Block block) { 26 | this.block = block; 27 | if (!MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_16_R3)) { 28 | throw new NbtApiException("NBTBlock is only working for 1.16.4+!"); 29 | } 30 | nbtChunk = new NBTChunk(block.getChunk()); 31 | } 32 | 33 | public NBTCompound getData() { 34 | return nbtChunk.getPersistentDataContainer().getOrCreateCompound("blocks") 35 | .getOrCreateCompound(block.getX() + "_" + block.getY() + "_" + block.getZ()); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTChunk.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | import org.bukkit.Chunk; 4 | 5 | import de.tr7zw.changeme.nbtapi.utils.CheckUtil; 6 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 7 | 8 | public class NBTChunk { 9 | 10 | private final Chunk chunk; 11 | 12 | public NBTChunk(Chunk chunk) { 13 | this.chunk = chunk; 14 | } 15 | 16 | /** 17 | * Gets the NBTCompound used by spigots PersistentDataAPI. This method is only 18 | * available for 1.16.4+! 19 | * 20 | * @return NBTCompound containing the data of the PersistentDataAPI 21 | */ 22 | public NBTCompound getPersistentDataContainer() { 23 | CheckUtil.assertAvailable(MinecraftVersion.MC1_16_R3); 24 | return new NBTPersistentDataContainer(chunk.getPersistentDataContainer()); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTCompoundList.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 4 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBTCompoundList; 5 | import de.tr7zw.changeme.nbtapi.iface.ReadableNBT; 6 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 7 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper; 8 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod; 9 | 10 | /** 11 | * {@link NBTListCompound} implementation for NBTLists 12 | * 13 | * @author tr7zw 14 | * 15 | */ 16 | public class NBTCompoundList extends NBTList implements ReadWriteNBTCompoundList { 17 | 18 | protected NBTCompoundList(NBTCompound owner, String name, NBTType type, Object list) { 19 | super(owner, name, type, list); 20 | } 21 | 22 | /** 23 | * Adds a new Compound to the end of the List and returns it. 24 | * 25 | * @return The added {@link NBTListCompound} 26 | */ 27 | public NBTListCompound addCompound() { 28 | return (NBTListCompound) addCompound(null); 29 | } 30 | 31 | /** 32 | * Adds a copy of the Compound to the end of the List and returns it. When null 33 | * is given, a new Compound will be created 34 | * 35 | * @param comp 36 | * @return 37 | */ 38 | public NBTCompound addCompound(NBTCompound comp) { 39 | if (getParent().isReadOnly()) { 40 | throw new NbtApiException("Tried setting data in read only mode!"); 41 | } 42 | try { 43 | Object compound = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance(); 44 | if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) { 45 | ReflectionMethod.LIST_ADD.run(listObject, size(), compound); 46 | } else { 47 | ReflectionMethod.LEGACY_LIST_ADD.run(listObject, compound); 48 | } 49 | getParent().saveCompound(); 50 | NBTListCompound listcomp = new NBTListCompound(this, compound); 51 | if (comp != null) { 52 | listcomp.mergeCompound(comp); 53 | } 54 | return listcomp; 55 | } catch (Exception ex) { 56 | throw new NbtApiException(ex); 57 | } 58 | } 59 | 60 | @Override 61 | public ReadWriteNBT addCompound(ReadableNBT comp) { 62 | if (comp instanceof NBTCompound) { 63 | return addCompound((NBTCompound) comp); 64 | } 65 | return null; 66 | } 67 | 68 | /** 69 | * Adds a new Compound to the end of the List. 70 | * 71 | * 72 | * @deprecated Please use addCompound! 73 | * @param empty 74 | * @return True, if compound was added 75 | */ 76 | @Override 77 | @Deprecated 78 | public boolean add(ReadWriteNBT empty) { 79 | return addCompound(empty) != null; 80 | } 81 | 82 | @Override 83 | public void add(int index, ReadWriteNBT element) { 84 | if (element != null) { 85 | throw new NbtApiException("You need to pass null! ListCompounds from other lists won't work."); 86 | } 87 | if (getParent().isReadOnly()) { 88 | throw new NbtApiException("Tried setting data in read only mode!"); 89 | } 90 | try { 91 | Object compound = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance(); 92 | if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) { 93 | ReflectionMethod.LIST_ADD.run(listObject, index, compound); 94 | } else { 95 | ReflectionMethod.LEGACY_LIST_ADD.run(listObject, compound); 96 | } 97 | super.getParent().saveCompound(); 98 | } catch (Exception ex) { 99 | throw new NbtApiException(ex); 100 | } 101 | } 102 | 103 | @Override 104 | public NBTListCompound get(int index) { 105 | try { 106 | Object compound = ReflectionMethod.LIST_GET_COMPOUND.run(listObject, index); 107 | return new NBTListCompound(this, compound); 108 | } catch (Exception ex) { 109 | throw new NbtApiException(ex); 110 | } 111 | } 112 | 113 | @Override 114 | public NBTListCompound set(int index, ReadWriteNBT element) { 115 | throw new NbtApiException("This method doesn't work in the ListCompound context."); 116 | } 117 | 118 | @Override 119 | protected Object asTag(ReadWriteNBT object) { 120 | return null; 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTContainer.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | import java.io.InputStream; 4 | 5 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper; 6 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ObjectCreator; 7 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod; 8 | 9 | /** 10 | * A Standalone {@link NBTCompound} implementation. All data is just kept inside 11 | * this Object. 12 | * 13 | * @author tr7zw 14 | * 15 | */ 16 | public class NBTContainer extends NBTCompound { 17 | 18 | private Object nbt; 19 | private boolean closed; 20 | private boolean readOnly; 21 | 22 | /** 23 | * Creates an empty, standalone NBTCompound 24 | * 25 | * @deprecated use {@link NBT#createNBTObject()} 26 | */ 27 | @Deprecated 28 | public NBTContainer() { 29 | super(null, null); 30 | nbt = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance(); 31 | } 32 | 33 | /** 34 | * Takes in any NMS Compound to wrap it 35 | * 36 | * @param nbt 37 | * @deprecated Use NBT.wrapNMSTag 38 | */ 39 | @Deprecated 40 | public NBTContainer(Object nbt) { 41 | super(null, null); 42 | if (nbt == null) { 43 | nbt = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance(); 44 | } 45 | if (!ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().isAssignableFrom(nbt.getClass())) { 46 | throw new NbtApiException("The object '" + nbt.getClass() + "' is not a valid NBT-Object!"); 47 | } 48 | this.nbt = nbt; 49 | } 50 | 51 | /** 52 | * Reads in a NBT InputStream 53 | * 54 | * @param inputsteam 55 | * @deprecated Use NBT.readNBT 56 | */ 57 | @Deprecated 58 | public NBTContainer(InputStream inputsteam) { 59 | super(null, null); 60 | this.nbt = NBTReflectionUtil.readNBT(inputsteam); 61 | } 62 | 63 | /** 64 | * Parses in a NBT String to a standalone {@link NBTCompound}. Can throw a 65 | * {@link NbtApiException} in case something goes wrong. 66 | * 67 | * @param nbtString 68 | * @deprecated Use NBT.parseNBT 69 | */ 70 | @Deprecated 71 | public NBTContainer(String nbtString) { 72 | super(null, null); 73 | if (nbtString == null) { 74 | throw new NullPointerException("The String can't be null!"); 75 | } 76 | try { 77 | nbt = ReflectionMethod.PARSE_NBT.run(null, nbtString); 78 | } catch (Exception ex) { 79 | throw new NbtApiException("Unable to parse Malformed Json!", ex); 80 | } 81 | } 82 | 83 | @Override 84 | public Object getCompound() { 85 | return nbt; 86 | } 87 | 88 | @Override 89 | public void setCompound(Object tag) { 90 | nbt = tag; 91 | } 92 | 93 | @Override 94 | protected void setClosed() { 95 | this.closed = true; 96 | } 97 | 98 | @Override 99 | protected boolean isClosed() { 100 | return closed; 101 | } 102 | 103 | protected boolean isReadOnly() { 104 | return readOnly; 105 | } 106 | 107 | protected NBTContainer setReadOnly(boolean readOnly) { 108 | this.readOnly = true; 109 | return this; 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTDoubleList.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | import java.lang.reflect.Constructor; 4 | import java.lang.reflect.InvocationTargetException; 5 | 6 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper; 7 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod; 8 | 9 | /** 10 | * Double implementation for NBTLists 11 | * 12 | * @author tr7zw 13 | * 14 | */ 15 | public class NBTDoubleList extends NBTList { 16 | 17 | protected NBTDoubleList(NBTCompound owner, String name, NBTType type, Object list) { 18 | super(owner, name, type, list); 19 | } 20 | 21 | @Override 22 | protected Object asTag(Double object) { 23 | try { 24 | Constructor con = ClassWrapper.NMS_NBTTAGDOUBLE.getClazz().getDeclaredConstructor(double.class); 25 | con.setAccessible(true); 26 | return con.newInstance(object); 27 | } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException 28 | | NoSuchMethodException | SecurityException e) { 29 | throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e); 30 | } 31 | } 32 | 33 | @Override 34 | public Double get(int index) { 35 | try { 36 | Object obj = ReflectionMethod.LIST_GET.run(listObject, index); 37 | return Double.valueOf(obj.toString()); 38 | } catch (NumberFormatException nf) { 39 | return 0d; 40 | } catch (Exception ex) { 41 | throw new NbtApiException(ex); 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTEntity.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.entity.Entity; 5 | 6 | import de.tr7zw.changeme.nbtapi.utils.CheckUtil; 7 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 8 | 9 | /** 10 | * NBT class to access vanilla tags from Entities. Entities don't support custom 11 | * tags. Use the NBTInjector for custom tags. Changes will be instantly applied 12 | * to the Entity, use the merge method to do many things at once. 13 | * 14 | * @author tr7zw 15 | * 16 | */ 17 | public class NBTEntity extends NBTCompound { 18 | 19 | private final Entity ent; 20 | private final boolean readonly; 21 | private final Object compound; 22 | private boolean closed = false; 23 | 24 | /** 25 | * @param entity Any valid Bukkit Entity 26 | * @param readonly Readonly makes a copy at init, only reading from that copy 27 | */ 28 | protected NBTEntity(Entity entity, boolean readonly) { 29 | super(null, null); 30 | if (entity == null) { 31 | throw new NullPointerException("Entity can't be null!"); 32 | } 33 | this.readonly = readonly; 34 | ent = entity; 35 | if (readonly) { 36 | this.compound = getCompound(); 37 | } else { 38 | this.compound = null; 39 | } 40 | } 41 | 42 | /** 43 | * Deprecated: Please use the NBT class 44 | * 45 | * @param entity Any valid Bukkit Entity 46 | */ 47 | @Deprecated 48 | public NBTEntity(Entity entity) { 49 | super(null, null); 50 | if (entity == null) { 51 | throw new NullPointerException("Entity can't be null!"); 52 | } 53 | this.readonly = false; 54 | this.compound = null; 55 | ent = entity; 56 | } 57 | 58 | @Override 59 | protected void setClosed() { 60 | this.closed = true; 61 | } 62 | 63 | @Override 64 | protected boolean isClosed() { 65 | return closed; 66 | } 67 | 68 | @Override 69 | protected boolean isReadOnly() { 70 | return readonly; 71 | } 72 | 73 | @Override 74 | public Object getCompound() { 75 | // this runs before async check, since it's just a copy 76 | if (readonly && compound != null) { 77 | return compound; 78 | } 79 | if (!Bukkit.isPrimaryThread()) 80 | throw new NbtApiException("Entity NBT needs to be accessed sync!"); 81 | return NBTReflectionUtil.getEntityNBTTagCompound(NBTReflectionUtil.getNMSEntity(ent)); 82 | } 83 | 84 | @Override 85 | protected void setCompound(Object compound) { 86 | if (readonly) { 87 | throw new NbtApiException("Tried setting data in read only mode!"); 88 | } 89 | if (!Bukkit.isPrimaryThread()) 90 | throw new NbtApiException("Entity NBT needs to be accessed sync!"); 91 | NBTReflectionUtil.setEntityNBTTag(compound, NBTReflectionUtil.getNMSEntity(ent)); 92 | } 93 | 94 | /** 95 | * Gets the NBTCompound used by spigots PersistentDataAPI. This method is only 96 | * available for 1.14+! 97 | * 98 | * @return NBTCompound containing the data of the PersistentDataAPI 99 | */ 100 | public NBTCompound getPersistentDataContainer() { 101 | CheckUtil.assertAvailable(MinecraftVersion.MC1_14_R1); 102 | return new NBTPersistentDataContainer(ent.getPersistentDataContainer()); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTFile.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.nio.file.Files; 6 | 7 | import de.tr7zw.changeme.nbtapi.iface.NBTFileHandle; 8 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ObjectCreator; 9 | 10 | /** 11 | * {@link NBTCompound} implementation backed by a {@link File} 12 | * 13 | * @author tr7zw 14 | * 15 | */ 16 | public class NBTFile extends NBTCompound implements NBTFileHandle { 17 | 18 | private final File file; 19 | private Object nbt; 20 | 21 | /** 22 | * Creates a NBTFile that uses @param file to store its data. If this file 23 | * exists, the data will be loaded. 24 | * 25 | * @param file 26 | * @throws IOException 27 | * @deprecated Use NBT.getFileHandle(file) 28 | */ 29 | @Deprecated 30 | public NBTFile(File file) throws IOException { 31 | super(null, null); 32 | if (file == null) { 33 | throw new NullPointerException("File can't be null!"); 34 | } 35 | this.file = file; 36 | if (file.exists()) { 37 | nbt = NBTReflectionUtil.readNBT(Files.newInputStream(file.toPath())); 38 | } else { 39 | nbt = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance(); 40 | save(); 41 | } 42 | } 43 | 44 | /** 45 | * Saves the data to the file 46 | * 47 | * @throws IOException 48 | */ 49 | @Override 50 | public void save() throws IOException { 51 | try { 52 | getWriteLock().lock(); 53 | saveTo(file, this); 54 | } finally { 55 | getWriteLock().unlock(); 56 | } 57 | } 58 | 59 | /** 60 | * @return The File used to store the data 61 | */ 62 | @Override 63 | public File getFile() { 64 | return file; 65 | } 66 | 67 | @Override 68 | public Object getCompound() { 69 | return nbt; 70 | } 71 | 72 | @Override 73 | protected void setCompound(Object compound) { 74 | nbt = compound; 75 | } 76 | 77 | /** 78 | * Reads NBT data from the provided file. 79 | *

80 | * Returns empty NBTContainer if file does not exist. 81 | * 82 | * @param file file to read 83 | * @return NBTCompound holding file's nbt data 84 | * @throws IOException exception 85 | * @deprecated Use NBT.readFile(file) 86 | */ 87 | @Deprecated 88 | public static NBTCompound readFrom(File file) throws IOException { 89 | if (!file.exists()) 90 | return new NBTContainer(); 91 | return new NBTContainer(NBTReflectionUtil.readNBT(Files.newInputStream(file.toPath()))); 92 | } 93 | 94 | /** 95 | * Saves NBT data to the provided file. 96 | *

97 | * Will fully override the file if it already exists. 98 | * 99 | * @param file file 100 | * @param nbt NBT data 101 | * @throws IOException exception 102 | * @deprecated Use NBT.writeFile(file, nbt) 103 | */ 104 | @Deprecated 105 | public static void saveTo(File file, NBTCompound nbt) throws IOException { 106 | if (!file.exists()) { 107 | file.getParentFile().mkdirs(); 108 | if (!file.createNewFile()) 109 | throw new IOException("Unable to create file at " + file.getAbsolutePath()); 110 | } 111 | nbt.writeCompound(Files.newOutputStream(file.toPath())); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTFloatList.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | import java.lang.reflect.Constructor; 4 | import java.lang.reflect.InvocationTargetException; 5 | 6 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper; 7 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod; 8 | 9 | /** 10 | * Float implementation for NBTLists 11 | * 12 | * @author tr7zw 13 | * 14 | */ 15 | public class NBTFloatList extends NBTList { 16 | 17 | protected NBTFloatList(NBTCompound owner, String name, NBTType type, Object list) { 18 | super(owner, name, type, list); 19 | } 20 | 21 | @Override 22 | protected Object asTag(Float object) { 23 | try { 24 | Constructor con = ClassWrapper.NMS_NBTTAGFLOAT.getClazz().getDeclaredConstructor(float.class); 25 | con.setAccessible(true); 26 | return con.newInstance(object); 27 | } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException 28 | | NoSuchMethodException | SecurityException e) { 29 | throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e); 30 | } 31 | } 32 | 33 | @Override 34 | public Float get(int index) { 35 | try { 36 | Object obj = ReflectionMethod.LIST_GET.run(listObject, index); 37 | return Float.valueOf(obj.toString()); 38 | } catch (NumberFormatException nf) { 39 | return 0f; 40 | } catch (Exception ex) { 41 | throw new NbtApiException(ex); 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTGameProfile.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | import com.mojang.authlib.GameProfile; 4 | 5 | import de.tr7zw.changeme.nbtapi.utils.GameprofileUtil; 6 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 7 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ObjectCreator; 8 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod; 9 | 10 | public class NBTGameProfile { 11 | 12 | /** 13 | * Convert a GameProfile to NBT. The NBT then can be modified or be stored 14 | * 15 | * @param profile 16 | * @return A NBTContainer with all the GameProfile data 17 | */ 18 | @Deprecated 19 | public static NBTCompound toNBT(GameProfile profile) { 20 | if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) { 21 | return (NBTCompound) GameprofileUtil.writeGameProfile(NBT.createNBTObject(), profile); 22 | } 23 | return new NBTContainer(ReflectionMethod.GAMEPROFILE_SERIALIZE.run(null, 24 | ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance(), profile)); 25 | } 26 | 27 | /** 28 | * Reconstructs a GameProfile from a NBTCompound 29 | * 30 | * @param compound Has to contain GameProfile data 31 | * @return The reconstructed GameProfile 32 | */ 33 | @Deprecated 34 | public static GameProfile fromNBT(NBTCompound compound) { 35 | if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) { 36 | return GameprofileUtil.readGameProfile(compound); 37 | } 38 | return (GameProfile) ReflectionMethod.GAMEPROFILE_DESERIALIZE.run(null, 39 | NBTReflectionUtil.getToCompount(compound.getCompound(), compound)); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTIntArrayList.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | import java.lang.reflect.Constructor; 4 | import java.lang.reflect.InvocationTargetException; 5 | 6 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper; 7 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod; 8 | 9 | /** 10 | * Integer implementation for NBTLists 11 | * 12 | * @author tr7zw 13 | * 14 | */ 15 | public class NBTIntArrayList extends NBTList { 16 | 17 | private final NBTContainer tmpContainer; 18 | 19 | protected NBTIntArrayList(NBTCompound owner, String name, NBTType type, Object list) { 20 | super(owner, name, type, list); 21 | this.tmpContainer = new NBTContainer(); 22 | } 23 | 24 | @Override 25 | protected Object asTag(int[] object) { 26 | try { 27 | Constructor con = ClassWrapper.NMS_NBTTAGINTARRAY.getClazz().getDeclaredConstructor(int[].class); 28 | con.setAccessible(true); 29 | return con.newInstance(object); 30 | } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException 31 | | NoSuchMethodException | SecurityException e) { 32 | throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e); 33 | } 34 | } 35 | 36 | @Override 37 | public int[] get(int index) { 38 | try { 39 | Object obj = ReflectionMethod.LIST_GET.run(listObject, index); 40 | ReflectionMethod.COMPOUND_SET.run(tmpContainer.getCompound(), "tmp", obj); 41 | int[] val = tmpContainer.getIntArray("tmp"); 42 | tmpContainer.removeKey("tmp"); 43 | return val; 44 | } catch (NumberFormatException nf) { 45 | return null; 46 | } catch (Exception ex) { 47 | throw new NbtApiException(ex); 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTIntegerList.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | import java.lang.reflect.Constructor; 4 | import java.lang.reflect.InvocationTargetException; 5 | 6 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper; 7 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod; 8 | 9 | /** 10 | * Integer implementation for NBTLists 11 | * 12 | * @author tr7zw 13 | * 14 | */ 15 | public class NBTIntegerList extends NBTList { 16 | 17 | protected NBTIntegerList(NBTCompound owner, String name, NBTType type, Object list) { 18 | super(owner, name, type, list); 19 | } 20 | 21 | @Override 22 | protected Object asTag(Integer object) { 23 | try { 24 | Constructor con = ClassWrapper.NMS_NBTTAGINT.getClazz().getDeclaredConstructor(int.class); 25 | con.setAccessible(true); 26 | return con.newInstance(object); 27 | } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException 28 | | NoSuchMethodException | SecurityException e) { 29 | throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e); 30 | } 31 | } 32 | 33 | @Override 34 | public Integer get(int index) { 35 | try { 36 | Object obj = ReflectionMethod.LIST_GET.run(listObject, index); 37 | return Integer.valueOf(obj.toString()); 38 | } catch (NumberFormatException nf) { 39 | return 0; 40 | } catch (Exception ex) { 41 | throw new NbtApiException(ex); 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTListCompound.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | /** 4 | * Cut down version of the {@link NBTCompound} for inside 5 | * {@link NBTCompoundList} This Compound implementation is missing the ability 6 | * for further subCompounds and Lists. This class probably will change in the 7 | * future 8 | * 9 | * @author tr7zw 10 | * 11 | */ 12 | public class NBTListCompound extends NBTCompound { 13 | 14 | private NBTList owner; 15 | private Object compound; 16 | 17 | protected NBTListCompound(NBTList parent, Object obj) { 18 | super(null, null); 19 | owner = parent; 20 | compound = obj; 21 | } 22 | 23 | public NBTList getListParent() { 24 | return owner; 25 | } 26 | 27 | @Override 28 | protected boolean isClosed() { 29 | return owner.getParent().isClosed(); 30 | } 31 | 32 | @Override 33 | protected boolean isReadOnly() { 34 | return owner.getParent().isReadOnly(); 35 | } 36 | 37 | @Override 38 | public Object getCompound() { 39 | if (isClosed()) { 40 | throw new NbtApiException("Tried using closed NBT data!"); 41 | } 42 | return compound; 43 | } 44 | 45 | @Override 46 | protected void setCompound(Object compound) { 47 | if (isClosed()) { 48 | throw new NbtApiException("Tried using closed NBT data!"); 49 | } 50 | if (isReadOnly()) { 51 | throw new NbtApiException("Tried setting data in read only mode!"); 52 | } 53 | this.compound = compound; 54 | } 55 | 56 | @Override 57 | protected void saveCompound() { 58 | owner.save(); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTLongList.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | import java.lang.reflect.Constructor; 4 | import java.lang.reflect.InvocationTargetException; 5 | 6 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper; 7 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod; 8 | 9 | /** 10 | * Long implementation for NBTLists 11 | * 12 | * @author tr7zw 13 | * 14 | */ 15 | public class NBTLongList extends NBTList { 16 | 17 | protected NBTLongList(NBTCompound owner, String name, NBTType type, Object list) { 18 | super(owner, name, type, list); 19 | } 20 | 21 | @Override 22 | protected Object asTag(Long object) { 23 | try { 24 | Constructor con = ClassWrapper.NMS_NBTTAGLONG.getClazz().getDeclaredConstructor(long.class); 25 | con.setAccessible(true); 26 | return con.newInstance(object); 27 | } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException 28 | | NoSuchMethodException | SecurityException e) { 29 | throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e); 30 | } 31 | } 32 | 33 | @Override 34 | public Long get(int index) { 35 | try { 36 | Object obj = ReflectionMethod.LIST_GET.run(listObject, index); 37 | return Long.valueOf(obj.toString().replace("L", "")); 38 | } catch (NumberFormatException nf) { 39 | return 0l; 40 | } catch (Exception ex) { 41 | throw new NbtApiException(ex); 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTPersistentDataContainer.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | import java.util.Map; 4 | 5 | import org.bukkit.persistence.PersistentDataContainer; 6 | 7 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod; 8 | 9 | public class NBTPersistentDataContainer extends NBTCompound { 10 | 11 | private final PersistentDataContainer container; 12 | 13 | public NBTPersistentDataContainer(PersistentDataContainer container) { 14 | super(null, null); 15 | this.container = container; 16 | } 17 | 18 | @Override 19 | public Object getCompound() { 20 | return ReflectionMethod.CRAFT_PERSISTENT_DATA_CONTAINER_TO_TAG.run(container); 21 | } 22 | 23 | @Override 24 | protected void setCompound(Object compound) { 25 | @SuppressWarnings("unchecked") 26 | Map map = (Map) ReflectionMethod.CRAFT_PERSISTENT_DATA_CONTAINER_GET_MAP 27 | .run(container); 28 | map.clear(); 29 | ReflectionMethod.CRAFT_PERSISTENT_DATA_CONTAINER_PUT_ALL.run(container, compound); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTStringList.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | import java.lang.reflect.Constructor; 4 | import java.lang.reflect.InvocationTargetException; 5 | import java.util.Optional; 6 | 7 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper; 8 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod; 9 | 10 | /** 11 | * String implementation for NBTLists 12 | * 13 | * @author tr7zw 14 | * 15 | */ 16 | public class NBTStringList extends NBTList { 17 | 18 | protected NBTStringList(NBTCompound owner, String name, NBTType type, Object list) { 19 | super(owner, name, type, list); 20 | } 21 | 22 | @Override 23 | public String get(int index) { 24 | try { 25 | Object ret = ReflectionMethod.LIST_GET_STRING.run(listObject, index); 26 | if (ret instanceof Optional) { 27 | return ((Optional) ret).orElse(""); 28 | } 29 | return (String) ret; 30 | } catch (Exception ex) { 31 | throw new NbtApiException(ex); 32 | } 33 | } 34 | 35 | @Override 36 | protected Object asTag(String object) { 37 | try { 38 | Constructor con = ClassWrapper.NMS_NBTTAGSTRING.getClazz().getDeclaredConstructor(String.class); 39 | con.setAccessible(true); 40 | return con.newInstance(object); 41 | } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException 42 | | NoSuchMethodException | SecurityException e) { 43 | throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e); 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTTileEntity.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.block.BlockState; 5 | 6 | import de.tr7zw.changeme.nbtapi.utils.CheckUtil; 7 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 8 | 9 | /** 10 | * NBT class to access vanilla tags from TileEntities. TileEntities don't 11 | * support custom tags. Use the NBTInjector for custom tags. Changes will be 12 | * instantly applied to the Tile, use the merge method to do many things at 13 | * once. 14 | * 15 | * @author tr7zw 16 | * 17 | */ 18 | public class NBTTileEntity extends NBTCompound { 19 | 20 | private final BlockState tile; 21 | private final boolean readonly; 22 | private final Object compound; 23 | private boolean closed = false; 24 | 25 | /** 26 | * @param tile BlockState from any TileEntity 27 | * @param readonly Readonly makes a copy at init, only reading from that copy 28 | */ 29 | protected NBTTileEntity(BlockState tile, boolean readonly) { 30 | super(null, null); 31 | if (tile == null || (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_8_R3) && !tile.isPlaced())) { 32 | throw new NullPointerException("Tile can't be null/not placed!"); 33 | } 34 | this.tile = tile; 35 | this.readonly = readonly; 36 | if (readonly) { 37 | this.compound = getCompound(); 38 | } else { 39 | this.compound = null; 40 | } 41 | } 42 | 43 | /** 44 | * Deprecated: Please use the NBT class 45 | * 46 | * @param tile BlockState from any TileEntity 47 | */ 48 | @Deprecated 49 | public NBTTileEntity(BlockState tile) { 50 | super(null, null); 51 | if (tile == null || (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_8_R3) && !tile.isPlaced())) { 52 | throw new NullPointerException("Tile can't be null/not placed!"); 53 | } 54 | this.readonly = false; 55 | this.compound = null; 56 | this.tile = tile; 57 | } 58 | 59 | @Override 60 | protected void setClosed() { 61 | this.closed = true; 62 | } 63 | 64 | @Override 65 | protected boolean isClosed() { 66 | return closed; 67 | } 68 | 69 | @Override 70 | protected boolean isReadOnly() { 71 | return readonly; 72 | } 73 | 74 | @Override 75 | public Object getCompound() { 76 | // this runs before async check, since it's just a copy 77 | if (readonly && compound != null) { 78 | return compound; 79 | } 80 | if (!Bukkit.isPrimaryThread()) 81 | throw new NbtApiException("BlockEntity NBT needs to be accessed sync!"); 82 | return NBTReflectionUtil.getTileEntityNBTTagCompound(tile); 83 | } 84 | 85 | @Override 86 | protected void setCompound(Object compound) { 87 | if (readonly) { 88 | throw new NbtApiException("Tried setting data in read only mode!"); 89 | } 90 | if (!Bukkit.isPrimaryThread()) 91 | throw new NbtApiException("BlockEntity NBT needs to be accessed sync!"); 92 | NBTReflectionUtil.setTileEntityNBTTagCompound(tile, compound); 93 | } 94 | 95 | /** 96 | * Gets the NBTCompound used by spigots PersistentDataAPI. This method is only 97 | * available for 1.14+! 98 | * 99 | * @return NBTCompound containing the data of the PersistentDataAPI 100 | */ 101 | public NBTCompound getPersistentDataContainer() { 102 | CheckUtil.assertAvailable(MinecraftVersion.MC1_14_R1); 103 | if (hasTag("PublicBukkitValues")) { 104 | return getCompound("PublicBukkitValues"); 105 | } else { 106 | NBTContainer container = new NBTContainer(); 107 | container.addCompound("PublicBukkitValues").setString("__nbtapi", 108 | "Marker to make the PersistentDataContainer have content"); 109 | mergeCompound(container); 110 | return getCompound("PublicBukkitValues"); 111 | } 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTType.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | /** 4 | * Enum of all NBT Types Minecraft contains 5 | * 6 | * @author tr7zw 7 | * 8 | */ 9 | @SuppressWarnings("javadoc") 10 | public enum NBTType { 11 | NBTTagEnd(0, ""), NBTTagByte(1, "BYTE"), NBTTagShort(2, "SHORT"), NBTTagInt(3, "INT"), NBTTagLong(4, "LONG"), NBTTagFloat(5, "FLOAT"), NBTTagDouble(6, "DOUBLE"), 12 | NBTTagByteArray(7, "BYTE[]"), NBTTagString(8, "STRING"), NBTTagList(9, "LIST"), NBTTagCompound(10, "COMPOUND"), NBTTagIntArray(11, "INT[]"), NBTTagLongArray(12, "LONG[]"); 13 | 14 | NBTType(int i, String name) { 15 | id = i; 16 | this.name = name; 17 | } 18 | 19 | private final int id; 20 | private final String name; 21 | 22 | /** 23 | * @return Id used by Minecraft internally 24 | */ 25 | public int getId() { 26 | return id; 27 | } 28 | 29 | /** 30 | * @return Name of the NBTType 31 | */ 32 | public String getName() { 33 | return name; 34 | } 35 | 36 | /** 37 | * @param id Internal Minecraft id 38 | * @return Enum representing the id, NBTTagEnd for invalide ids 39 | */ 40 | public static NBTType valueOf(int id) { 41 | for (NBTType t : values()) 42 | if (t.getId() == id) 43 | return t; 44 | return NBTType.NBTTagEnd; 45 | } 46 | 47 | public static NBTType fromName(String name) { 48 | for (NBTType t : values()) 49 | if (t.getName().equals(name)) 50 | return t; 51 | return NBTType.NBTTagEnd; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NBTUUIDList.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | import java.lang.reflect.Constructor; 4 | import java.lang.reflect.InvocationTargetException; 5 | import java.util.UUID; 6 | 7 | import de.tr7zw.changeme.nbtapi.utils.UUIDUtil; 8 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper; 9 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod; 10 | 11 | /** 12 | * Integer implementation for NBTLists 13 | * 14 | * @author tr7zw 15 | * 16 | */ 17 | public class NBTUUIDList extends NBTList { 18 | 19 | private final NBTContainer tmpContainer; 20 | 21 | protected NBTUUIDList(NBTCompound owner, String name, NBTType type, Object list) { 22 | super(owner, name, type, list); 23 | this.tmpContainer = new NBTContainer(); 24 | } 25 | 26 | @Override 27 | protected Object asTag(UUID object) { 28 | try { 29 | Constructor con = ClassWrapper.NMS_NBTTAGINTARRAY.getClazz().getDeclaredConstructor(int[].class); 30 | con.setAccessible(true); 31 | return con.newInstance(UUIDUtil.uuidToIntArray(object)); 32 | } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException 33 | | NoSuchMethodException | SecurityException e) { 34 | throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e); 35 | } 36 | } 37 | 38 | @Override 39 | public UUID get(int index) { 40 | try { 41 | Object obj = ReflectionMethod.LIST_GET.run(listObject, index); 42 | ReflectionMethod.COMPOUND_SET.run(tmpContainer.getCompound(), "tmp", obj); 43 | int[] val = tmpContainer.getIntArray("tmp"); 44 | tmpContainer.removeKey("tmp"); 45 | return UUIDUtil.uuidFromIntArray(val); 46 | } catch (NumberFormatException nf) { 47 | return null; 48 | } catch (Exception ex) { 49 | throw new NbtApiException(ex); 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/NbtApiException.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi; 2 | 3 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 4 | 5 | /** 6 | * A generic {@link RuntimeException} that can be thrown by most methods in the 7 | * NBTAPI. 8 | * 9 | * @author tr7zw 10 | * 11 | */ 12 | public class NbtApiException extends RuntimeException { 13 | 14 | /** 15 | * 16 | */ 17 | private static final long serialVersionUID = -993309714559452334L; 18 | /** 19 | * Keep track of the plugin selfcheck. Null = not 20 | * checked(silentquickstart/shaded) true = selfcheck failed false = everything 21 | * should be fine, but apparently wasn't? 22 | */ 23 | public static Boolean confirmedBroken = null; 24 | 25 | /** 26 | * 27 | */ 28 | public NbtApiException() { 29 | super(); 30 | } 31 | 32 | /** 33 | * @param message 34 | * @param cause 35 | */ 36 | public NbtApiException(String message, Throwable cause) { 37 | super(generateMessage(message), cause); 38 | } 39 | 40 | /** 41 | * @param message 42 | */ 43 | public NbtApiException(String message) { 44 | super(generateMessage(message)); 45 | } 46 | 47 | /** 48 | * @param cause 49 | */ 50 | public NbtApiException(Throwable cause) { 51 | super(generateMessage(cause == null ? null : cause.toString()), cause); 52 | } 53 | 54 | private static String generateMessage(String message) { 55 | if (message == null) 56 | return null; 57 | if (confirmedBroken == null) { 58 | return "[?][" + MinecraftVersion.getNBTAPIVersion() + "]" + message; 59 | } else if (confirmedBroken == false) { 60 | return "[Selfchecked][" + MinecraftVersion.getNBTAPIVersion() + "]" + message; 61 | } 62 | 63 | return "[" + MinecraftVersion.getVersion() + "][" + MinecraftVersion.getNBTAPIVersion() 64 | + "]There were errors detected during the server self-check! Please, make sure that NBT-API is up to date. Error message: " 65 | + message; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/handler/NBTHandlers.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.handler; 2 | 3 | import org.bukkit.inventory.ItemStack; 4 | 5 | import de.tr7zw.changeme.nbtapi.NBT; 6 | import de.tr7zw.changeme.nbtapi.iface.NBTHandler; 7 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 8 | import de.tr7zw.changeme.nbtapi.iface.ReadableNBT; 9 | 10 | public class NBTHandlers { 11 | 12 | public static final NBTHandler ITEM_STACK = new NBTHandler() { 13 | 14 | @Override 15 | public boolean fuzzyMatch(Object obj) { 16 | return obj instanceof ItemStack; 17 | } 18 | 19 | @Override 20 | public void set(ReadWriteNBT nbt, String key, ItemStack value) { 21 | nbt.removeKey(key); 22 | ReadWriteNBT tag = nbt.getOrCreateCompound(key); 23 | tag.mergeCompound(NBT.itemStackToNBT(value)); 24 | } 25 | 26 | @Override 27 | public ItemStack get(ReadableNBT nbt, String key) { 28 | ReadableNBT tag = nbt.getCompound(key); 29 | if (tag != null) { 30 | return NBT.itemStackFromNBT(tag); 31 | } 32 | return null; 33 | } 34 | 35 | }; 36 | 37 | public static final NBTHandler STORE_READABLE_TAG = new NBTHandler() { 38 | 39 | @Override 40 | public boolean fuzzyMatch(Object obj) { 41 | return obj instanceof ReadableNBT; 42 | } 43 | 44 | @Override 45 | public void set(ReadWriteNBT nbt, String key, ReadableNBT value) { 46 | nbt.removeKey(key); 47 | nbt.getOrCreateCompound(key).mergeCompound(value); 48 | } 49 | 50 | @Override 51 | public ReadableNBT get(ReadableNBT nbt, String key) { 52 | ReadableNBT tag = nbt.getCompound(key); 53 | if (tag != null) { 54 | ReadWriteNBT value = NBT.createNBTObject(); 55 | value.mergeCompound(tag); 56 | return value; 57 | } 58 | return null; 59 | } 60 | 61 | }; 62 | 63 | public static final NBTHandler STORE_READWRITE_TAG = new NBTHandler() { 64 | 65 | @Override 66 | public boolean fuzzyMatch(Object obj) { 67 | return obj instanceof ReadWriteNBT; 68 | } 69 | 70 | @Override 71 | public void set(ReadWriteNBT nbt, String key, ReadWriteNBT value) { 72 | nbt.removeKey(key); 73 | nbt.getOrCreateCompound(key).mergeCompound(value); 74 | } 75 | 76 | @Override 77 | public ReadWriteNBT get(ReadableNBT nbt, String key) { 78 | ReadableNBT tag = nbt.getCompound(key); 79 | if (tag != null) { 80 | ReadWriteNBT value = NBT.createNBTObject(); 81 | value.mergeCompound(tag); 82 | return value; 83 | } 84 | return null; 85 | } 86 | 87 | }; 88 | 89 | } 90 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/iface/NBTFileHandle.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.iface; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | public interface NBTFileHandle extends ReadWriteNBT { 7 | 8 | /** 9 | * Saves the data to the file 10 | * 11 | * @throws IOException 12 | */ 13 | void save() throws IOException; 14 | 15 | /** 16 | * @return The File used to store the data 17 | */ 18 | File getFile(); 19 | 20 | } -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/iface/NBTHandler.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.iface; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | public interface NBTHandler { 6 | 7 | public default boolean fuzzyMatch(Object obj) { 8 | return false; 9 | } 10 | 11 | public void set(@Nonnull ReadWriteNBT nbt, @Nonnull String key, @Nonnull T value); 12 | 13 | public T get(@Nonnull ReadableNBT nbt, @Nonnull String key); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/iface/ReadWriteItemNBT.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.iface; 2 | 3 | import java.util.function.BiConsumer; 4 | 5 | import org.bukkit.inventory.ItemStack; 6 | import org.bukkit.inventory.meta.ItemMeta; 7 | 8 | import de.tr7zw.changeme.nbtapi.NBTItem; 9 | 10 | public interface ReadWriteItemNBT extends ReadWriteNBT, ReadableItemNBT { 11 | 12 | /** 13 | * True, if the item has any tags now known for this item type. 14 | * 15 | * @return true when custom tags are present 16 | */ 17 | public boolean hasCustomNbtData(); 18 | 19 | /** 20 | * Remove all custom (non-vanilla) NBT tags from the NBTItem. 21 | */ 22 | public void clearCustomNBT(); 23 | 24 | /** 25 | * Gives save access to the {@link ItemMeta} of the internal {@link ItemStack}. 26 | * Supported operations while inside this scope: - any get/set method of 27 | * {@link ItemMeta} - any getter on {@link NBTItem} 28 | * 29 | * All changes made to the {@link NBTItem} during this scope will be reverted at 30 | * the end. 31 | * 32 | * @param handler 33 | */ 34 | public void modifyMeta(BiConsumer handler); 35 | 36 | /** 37 | * Gives save access to the {@link ItemMeta} of the internal {@link ItemStack}. 38 | * Supported operations while inside this scope: - any get/set method of 39 | * {@link ItemMeta} - any getter on {@link NBTItem} 40 | * 41 | * All changes made to the {@link NBTItem} during this scope will be reverted at 42 | * the end. 43 | * 44 | * @param handler 45 | */ 46 | public void modifyMeta(Class type, BiConsumer handler); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/iface/ReadWriteNBTCompoundList.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.iface; 2 | 3 | import java.util.function.Predicate; 4 | 5 | public interface ReadWriteNBTCompoundList extends ReadableNBTList { 6 | 7 | /** 8 | * Adds a new compound tag to the current compound tag 9 | * 10 | * @return A new instance of the class. 11 | */ 12 | ReadWriteNBT addCompound(); 13 | 14 | /** 15 | * Adds a copy of the Compound to the end of the List and returns it. When null 16 | * is given, a new Compound will be created 17 | * 18 | * @param comp 19 | * @return 20 | */ 21 | ReadWriteNBT addCompound(ReadableNBT comp); 22 | 23 | /** 24 | * Removes the element at the specified position in this list 25 | * 26 | * @param i The index of the element to remove. 27 | * @return A new instance of the class. 28 | */ 29 | ReadWriteNBT remove(int i); 30 | 31 | /** 32 | * Clears the contents of the list 33 | */ 34 | void clear(); 35 | 36 | /** 37 | * Removes all elements of this list that satisfy the given predicate 38 | * 39 | * @param pred The predicate to use to test elements. 40 | * @return A boolean value. 41 | */ 42 | boolean removeIf(Predicate pred); 43 | 44 | } -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/iface/ReadWriteNBTList.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.iface; 2 | 3 | import java.util.Collection; 4 | import java.util.ListIterator; 5 | import java.util.function.Predicate; 6 | 7 | public interface ReadWriteNBTList extends ReadableNBTList { 8 | 9 | /** 10 | * Adds the specified element to this set if it is not already present. 11 | * 12 | * @param element The element to be added to the list. 13 | * @return A boolean value. 14 | */ 15 | boolean add(T element); 16 | 17 | /** 18 | * Adds the specified element at the specified position in this list. 19 | * 20 | * @param index The index at which the specified element is to be inserted 21 | * @param element The element to be added to the list. 22 | */ 23 | void add(int index, T element); 24 | 25 | /** 26 | * Replaces the element at the specified position in this list with the 27 | * specified element. 28 | * 29 | * @param index The index of the element to replace 30 | * @param element The element to be stored at the specified position 31 | * @return The element that was previously at the specified position. 32 | */ 33 | T set(int index, T element); 34 | 35 | /** 36 | * Remove the element at index i and return it. 37 | * 38 | * @param i the index of the element to be removed 39 | * @return The element that was removed. 40 | */ 41 | T remove(int i); 42 | 43 | /** 44 | * Clears the contents of the list 45 | */ 46 | void clear(); 47 | 48 | /** 49 | * Adds all of the elements in the specified collection to this collection. 50 | * 51 | * @param c The collection to be added to the list. 52 | * @return A boolean value. 53 | */ 54 | boolean addAll(Collection c); 55 | 56 | /** 57 | * Inserts all of the elements in the specified collection into this list, 58 | * starting at the specified position. 59 | * 60 | * @param index The index at which the elements of the specified collection are 61 | * to be inserted. 62 | * @param c The collection to be added to the list. 63 | * @return A boolean value. 64 | */ 65 | boolean addAll(int index, Collection c); 66 | 67 | /** 68 | * Removes from this collection all of its elements that are contained in the 69 | * specified collection 70 | * 71 | * @param c The collection to be removed from this list. 72 | * @return A boolean value. 73 | */ 74 | boolean removeAll(Collection c); 75 | 76 | /** 77 | * Removes all of this collection's elements that are not contained in the 78 | * specified collection. 79 | * 80 | * @param c The collection to be retained in this list 81 | * @return A boolean value. 82 | */ 83 | boolean retainAll(Collection c); 84 | 85 | /** 86 | * "Remove all elements from the list that match the given predicate." 87 | * 88 | * The Predicate interface is a functional interface that takes a single 89 | * argument and returns a boolean 90 | * 91 | * @param pred The predicate to apply to each element to determine if it should 92 | * be removed. 93 | * @return A boolean value. 94 | */ 95 | boolean removeIf(Predicate pred); 96 | 97 | /** 98 | * Removes the first occurrence of the specified element from this list, if it 99 | * is present. 100 | * 101 | * @param o The object to be removed from the list. 102 | * @return A boolean value. 103 | */ 104 | boolean remove(Object o); 105 | 106 | /** 107 | * Returns a list iterator over the elements in this list (in proper sequence), 108 | * starting at the specified position in the list 109 | * 110 | * @param startIndex The index of the first element to be returned from the list 111 | * iterator (by a call to the next method). 112 | * @return A list iterator of the list starting at the specified index. 113 | */ 114 | ListIterator listIterator(int startIndex); 115 | 116 | } -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/iface/ReadableItemNBT.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.iface; 2 | 3 | public interface ReadableItemNBT extends ReadableNBT { 4 | 5 | /** 6 | * Returns true if the item has NBT data. 7 | * 8 | * @return Does the ItemStack have a NBTCompound. 9 | */ 10 | public boolean hasNBTData(); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/iface/ReadableNBTList.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.iface; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.List; 6 | 7 | import de.tr7zw.changeme.nbtapi.NBTType; 8 | 9 | public interface ReadableNBTList extends Iterable { 10 | 11 | /** 12 | * Get the object with the given id. 13 | * 14 | * @param id The id of the object to get. 15 | * @return The object with the given id. 16 | */ 17 | T get(int id); 18 | 19 | /** 20 | * Returns the number of elements in this list. 21 | * 22 | * @return The size of the list. 23 | */ 24 | int size(); 25 | 26 | /** 27 | * Returns the type of this tag 28 | * 29 | * @return The type of the tag. 30 | */ 31 | NBTType getType(); 32 | 33 | /** 34 | * Returns true if the list is empty, false otherwise. 35 | * 36 | * @return A boolean value. 37 | */ 38 | boolean isEmpty(); 39 | 40 | /** 41 | * Returns true if this list contains the specified element. 42 | * 43 | * @param o The object to be searched for in the list. 44 | * @return A boolean value. 45 | */ 46 | boolean contains(Object o); 47 | 48 | /** 49 | * Returns the index of the first occurrence of the specified element in this 50 | * list, or -1 if this list does not contain the element. 51 | * 52 | * @param o The object to search for. 53 | * @return The index of the first occurrence of the specified element in this 54 | * list, or -1 if this list does not contain the element. 55 | */ 56 | int indexOf(Object o); 57 | 58 | /** 59 | * Returns true if this collection contains all of the elements in the specified 60 | * collection 61 | * 62 | * @param c The collection to be checked for containment in this list 63 | * @return A boolean value. 64 | */ 65 | boolean containsAll(Collection c); 66 | 67 | /** 68 | * Returns the index of the last occurrence of the specified element in this 69 | * list, or -1 if this list does not contain the element 70 | * 71 | * @param o The object to search for. 72 | * @return The index of the last occurrence of the specified element in this 73 | * list, or -1 if this list does not contain the element. 74 | */ 75 | int lastIndexOf(Object o); 76 | 77 | /** 78 | * Returns an array containing all of the elements in this list in proper 79 | * sequence (from first to last element). 80 | * 81 | * @return An array of objects. 82 | */ 83 | Object[] toArray(); 84 | 85 | /** 86 | * Returns an array containing all of the elements in this list in proper 87 | * sequence (from first to last element). 88 | * 89 | * @param a The array into which the elements of the list are to be stored, if 90 | * it is big enough; otherwise, a new array of the same runtime type is 91 | * allocated for this purpose. 92 | * @return An array of the elements in the list. 93 | */ 94 | E[] toArray(E[] a); 95 | 96 | /** 97 | * Returns a view of the portion of this list between the specified fromIndex, 98 | * inclusive, and toIndex, exclusive 99 | * 100 | * @param fromIndex The starting index of the sublist (inclusive). 101 | * @param toIndex The index of the last element in the sublist. 102 | * @return A view of the specified range within this list. 103 | */ 104 | List subList(int fromIndex, int toIndex); 105 | 106 | /** 107 | * Create a new list containing all entries of this list. 108 | * 109 | * @return A list of the elements in the stream. 110 | */ 111 | default List toListCopy() { 112 | List list = new ArrayList<>(); 113 | iterator().forEachRemaining(list::add); 114 | return list; 115 | } 116 | 117 | } -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/CheckUtil.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.utils; 2 | 3 | import de.tr7zw.changeme.nbtapi.NbtApiException; 4 | 5 | public class CheckUtil { 6 | 7 | private CheckUtil() { 8 | // util 9 | } 10 | 11 | public static void assertAvailable(MinecraftVersion version) { 12 | if (!MinecraftVersion.isAtLeastVersion(version)) 13 | throw new NbtApiException( 14 | "This Method is only avaliable for the version " + version.name() + " and above!"); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/GameprofileUtil.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.utils; 2 | 3 | import java.util.UUID; 4 | 5 | import javax.annotation.Nullable; 6 | 7 | import com.mojang.authlib.GameProfile; 8 | 9 | import de.tr7zw.changeme.nbtapi.NBTType; 10 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 11 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBTCompoundList; 12 | import de.tr7zw.changeme.nbtapi.iface.ReadableNBT; 13 | import de.tr7zw.changeme.nbtapi.iface.ReadableNBTList; 14 | 15 | public class GameprofileUtil { 16 | 17 | @Nullable 18 | public static GameProfile readGameProfile(ReadableNBT arg) { 19 | String string = null; 20 | UUID uUID = null; 21 | if (arg.hasTag("Name") && arg.getType("Name") == NBTType.NBTTagString) { 22 | string = arg.getString("Name"); 23 | } 24 | if (arg.hasTag("Id") && arg.getType("Id") == NBTType.NBTTagIntArray && arg.getIntArray("Id").length == 4) { 25 | uUID = arg.getUUID("Id"); 26 | } 27 | try { 28 | GameProfile gameProfile = new GameProfile(uUID, string); 29 | if (arg.hasTag("Properties") && arg.getType("Properties") == NBTType.NBTTagCompound) { 30 | ReadableNBT compoundTag = arg.getCompound("Properties"); 31 | for (String string2 : compoundTag.getKeys()) { 32 | ReadableNBTList listTag = compoundTag.getCompoundList(string); 33 | for (int i = 0; i < listTag.size(); ++i) { 34 | ReadableNBT compoundTag2 = listTag.get(i); 35 | String string3 = compoundTag2.getString("Value"); 36 | if (compoundTag2.hasTag("Signature") 37 | && compoundTag2.getType("Signature") == NBTType.NBTTagString) { 38 | gameProfile.getProperties().put(string2, new com.mojang.authlib.properties.Property(string2, 39 | string3, compoundTag2.getString("Signature"))); 40 | } else { 41 | gameProfile.getProperties().put(string2, 42 | new com.mojang.authlib.properties.Property(string2, string3)); 43 | } 44 | } 45 | } 46 | } 47 | return gameProfile; 48 | } catch (Throwable var11) { 49 | return null; 50 | } 51 | } 52 | 53 | public static ReadWriteNBT writeGameProfile(ReadWriteNBT arg, GameProfile gameProfile) { 54 | if (!(gameProfile.getName() == null || gameProfile.getName().isEmpty())) { 55 | arg.setString("Name", gameProfile.getName()); 56 | } 57 | if (gameProfile.getId() != null) { 58 | arg.setUUID("Id", gameProfile.getId()); 59 | } 60 | if (!gameProfile.getProperties().isEmpty()) { 61 | ReadWriteNBT compoundTag = arg.getOrCreateCompound("Properties"); 62 | for (String string : gameProfile.getProperties().keySet()) { 63 | ReadWriteNBTCompoundList list = compoundTag.getCompoundList(string); 64 | for (com.mojang.authlib.properties.Property property : gameProfile.getProperties().get(string)) { 65 | ReadWriteNBT tag = list.addCompound(); 66 | tag.setString("Value", property.getValue()); 67 | if (property.hasSignature()) { 68 | tag.setString("Signature", property.getSignature()); 69 | } 70 | } 71 | } 72 | } 73 | return arg; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/GsonWrapper.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.utils; 2 | 3 | import com.google.gson.Gson; 4 | 5 | import de.tr7zw.changeme.nbtapi.NbtApiException; 6 | 7 | /** 8 | * Helper class for 1.7 servers without Gson 9 | * 10 | * Please consider your own Gson/Jackson instance instead of the built in 11 | * methods. 12 | * 13 | * @author tr7zw 14 | * 15 | */ 16 | @Deprecated 17 | public class GsonWrapper { 18 | 19 | /** 20 | * Private constructor 21 | */ 22 | private GsonWrapper() { 23 | 24 | } 25 | 26 | private static Gson gson = new Gson(); 27 | 28 | /** 29 | * Turns Objects into Json Strings 30 | * 31 | * @param obj 32 | * @return Json, representing the Object 33 | */ 34 | public static String getString(Object obj) { 35 | return gson.toJson(obj); 36 | } 37 | 38 | public static void overwriteGsonInstance(Gson replacement) { 39 | gson = replacement; 40 | } 41 | 42 | /** 43 | * Creates an Object of the given type using the Json String 44 | * 45 | * @param json 46 | * @param type 47 | * @return Object that got created, or null if the json is null 48 | */ 49 | public static T deserializeJson(String json, Class type) { 50 | try { 51 | if (json == null) { 52 | return null; 53 | } 54 | 55 | T obj = gson.fromJson(json, type); 56 | return type.cast(obj); 57 | } catch (Exception ex) { 58 | throw new NbtApiException("Error while converting json to " + type.getName(), ex); 59 | } 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/NBTJsonUtil.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.utils; 2 | 3 | import java.util.Optional; 4 | 5 | import org.bukkit.inventory.ItemStack; 6 | 7 | import com.google.gson.JsonElement; 8 | import com.mojang.serialization.Codec; 9 | import com.mojang.serialization.DataResult; 10 | import com.mojang.serialization.JsonOps; 11 | 12 | import de.tr7zw.changeme.nbtapi.NbtApiException; 13 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper; 14 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.MojangToMapping; 15 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod; 16 | 17 | public class NBTJsonUtil { 18 | 19 | /** 20 | * 1.20.3-1.21.4 only. Used to convert items into Json, used in Chat Hover Components. 21 | * 22 | * @param itemStack 23 | * @return 24 | * @throws NbtApiException 25 | */ 26 | @SuppressWarnings("unchecked") 27 | public static JsonElement itemStackToJson(ItemStack itemStack) { 28 | try { 29 | Codec itemStackCodec = (Codec) ClassWrapper.NMS_ITEMSTACK.getClazz() 30 | .getField(MojangToMapping.getMapping().get("net.minecraft.world.item.ItemStack#CODEC")).get(null); 31 | Object stack = ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, itemStack); 32 | DataResult result = itemStackCodec.encode(stack, JsonOps.INSTANCE, 33 | JsonOps.INSTANCE.emptyMap()); 34 | Optional opt = (Optional) result.getClass().getMethod("result").invoke(result); 35 | return opt.orElse(null); 36 | } catch (Exception ex) { 37 | throw new NbtApiException("Error trying to get Json of an ItemStack.", ex); 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/PathUtil.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.utils; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.regex.Matcher; 6 | import java.util.regex.Pattern; 7 | 8 | public final class PathUtil { 9 | 10 | private static final Pattern pattern = Pattern.compile("[^\\\\](\\.)"); 11 | private static final Pattern indexPattern = Pattern.compile(".*\\[(-?[0-9]+)\\]"); 12 | 13 | public static List splitPath(String path) { 14 | List list = new ArrayList<>(); 15 | Matcher matcher = pattern.matcher(path); 16 | int startIndex = 0; 17 | while (matcher.find(startIndex)) { 18 | list.add(new PathSegment(path.substring(startIndex, matcher.end() - 1).replace("\\.", "."))); 19 | startIndex = matcher.end(); 20 | } 21 | list.add(new PathSegment(path.substring(startIndex).replace("\\.", "."))); 22 | return list; 23 | } 24 | 25 | public static class PathSegment { 26 | 27 | private final String path; 28 | private final Integer index; 29 | 30 | private PathSegment(String path) { 31 | Matcher matcher = indexPattern.matcher(path); 32 | if (matcher.find()) { 33 | this.path = path.substring(0, path.indexOf("[")); 34 | this.index = Integer.parseInt(matcher.group(1)); 35 | } else { 36 | this.path = path; 37 | this.index = null; 38 | } 39 | } 40 | 41 | public String getPath() { 42 | return path; 43 | } 44 | 45 | public int getIndex() { 46 | return index; 47 | } 48 | 49 | public boolean hasIndex() { 50 | return index != null; 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | return "PathSegment [path=" + path + ", index=" + index + "]"; 56 | } 57 | 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/ReflectionUtil.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.utils; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Method; 5 | import java.lang.reflect.Modifier; 6 | 7 | import de.tr7zw.changeme.nbtapi.NbtApiException; 8 | 9 | public final class ReflectionUtil { 10 | 11 | private static Field field_modifiers; 12 | 13 | static { 14 | try { 15 | field_modifiers = Field.class.getDeclaredField("modifiers"); 16 | field_modifiers.setAccessible(true); 17 | } catch (NoSuchFieldException ex) { 18 | try { 19 | // This hacky workaround is for newer jdk versions 11+? 20 | Method fieldGetter = Class.class.getDeclaredMethod("getDeclaredFields0", boolean.class); 21 | fieldGetter.setAccessible(true); 22 | Field[] fields = (Field[]) fieldGetter.invoke(Field.class, false); 23 | for (Field f : fields) 24 | if (f.getName().equals("modifiers")) { 25 | field_modifiers = f; 26 | field_modifiers.setAccessible(true); 27 | break; 28 | } 29 | } catch (Exception e) { 30 | throw new NbtApiException(e); 31 | } 32 | } 33 | if (field_modifiers == null) { 34 | throw new NbtApiException("Unable to init the modifiers Field."); 35 | } 36 | } 37 | 38 | public static Field makeNonFinal(Field field) throws IllegalArgumentException, IllegalAccessException { 39 | int mods = field.getModifiers(); 40 | if (Modifier.isFinal(mods)) { 41 | field_modifiers.set(field, mods & ~Modifier.FINAL); 42 | } 43 | return field; 44 | } 45 | 46 | public static void setFinal(Object obj, Field field, Object newValue) 47 | throws IllegalArgumentException, IllegalAccessException { 48 | field.setAccessible(true); 49 | field = makeNonFinal(field); 50 | field.set(obj, newValue); 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/UUIDUtil.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.utils; 2 | 3 | import java.util.UUID; 4 | 5 | public class UUIDUtil { 6 | 7 | public static UUID uuidFromIntArray(int[] is) { 8 | return new UUID((long) is[0] << 32 | (long) is[1] & 4294967295L, 9 | (long) is[2] << 32 | (long) is[3] & 4294967295L); 10 | } 11 | 12 | public static int[] uuidToIntArray(UUID uUID) { 13 | long l = uUID.getMostSignificantBits(); 14 | long m = uUID.getLeastSignificantBits(); 15 | return leastMostToIntArray(l, m); 16 | } 17 | 18 | private static int[] leastMostToIntArray(long l, long m) { 19 | return new int[] { (int) (l >> 32), (int) l, (int) (m >> 32), (int) m }; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/nmsmappings/ObjectCreator.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.utils.nmsmappings; 2 | 3 | import java.lang.reflect.Constructor; 4 | import java.util.logging.Level; 5 | 6 | import de.tr7zw.changeme.nbtapi.NbtApiException; 7 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 8 | 9 | import static de.tr7zw.changeme.nbtapi.utils.MinecraftVersion.getLogger; 10 | 11 | /** 12 | * This Enum wraps Constructors for NMS classes 13 | * 14 | * @author tr7zw 15 | * 16 | */ 17 | @SuppressWarnings("javadoc") 18 | public enum ObjectCreator { 19 | NMS_NBTTAGCOMPOUND(null, null, ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()), 20 | NMS_CUSTOMDATA(MinecraftVersion.MC1_20_R4, null, ClassWrapper.NMS_CUSTOMDATA.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()), 21 | NMS_BLOCKPOSITION(null, null, ClassWrapper.NMS_BLOCKPOSITION.getClazz(), int.class, int.class, int.class), 22 | NMS_COMPOUNDFROMITEM(MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_20_R3, ClassWrapper.NMS_ITEMSTACK.getClazz(), 23 | ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()),; 24 | 25 | private Constructor construct; 26 | private Class targetClass; 27 | 28 | ObjectCreator(MinecraftVersion from, MinecraftVersion to, Class clazz, Class... args) { 29 | if (clazz == null) 30 | return; 31 | if (from != null && MinecraftVersion.getVersion().getVersionId() < from.getVersionId()) 32 | return; 33 | if (to != null && MinecraftVersion.getVersion().getVersionId() > to.getVersionId()) 34 | return; 35 | try { 36 | this.targetClass = clazz; 37 | construct = clazz.getDeclaredConstructor(args); 38 | construct.setAccessible(true); 39 | } catch (Exception ex) { 40 | getLogger().log(Level.SEVERE, "Unable to find the constructor for the class '" + clazz.getName() + "'", ex); 41 | } 42 | } 43 | 44 | /** 45 | * Creates an Object instance with given args 46 | * 47 | * @param args 48 | * @return Object created 49 | */ 50 | public Object getInstance(Object... args) { 51 | try { 52 | return construct.newInstance(args); 53 | } catch (Exception ex) { 54 | throw new NbtApiException("Exception while creating a new instance of '" + targetClass + "'", ex); 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/nmsmappings/PackageWrapper.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.utils.nmsmappings; 2 | 3 | /** 4 | * Package enum 5 | * 6 | * @author tr7zw 7 | * 8 | */ 9 | @SuppressWarnings("javadoc") 10 | public enum PackageWrapper { 11 | NMS(new String(new byte[] { 'n', 'e', 't', '.', 'm', 'i', 'n', 'e', 'c', 'r', 'a', 'f', 't', '.', 's', 'e', 'r', 12 | 'v', 'e', 'r' })), 13 | CRAFTBUKKIT(new String(new byte[] { 'o', 'r', 'g', '.', 'b', 'u', 'k', 'k', 'i', 't', '.', 'c', 'r', 'a', 'f', 't', 14 | 'b', 'u', 'k', 'k', 'i', 't' })), 15 | NONE(""); 16 | 17 | private final String uri; 18 | 19 | private PackageWrapper(String uri) { 20 | this.uri = uri; 21 | } 22 | 23 | /** 24 | * @return The Uri for that package 25 | */ 26 | public String getUri() { 27 | return uri; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/wrapper/Casing.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.wrapper; 2 | 3 | import java.util.function.UnaryOperator; 4 | 5 | public enum Casing { 6 | camelCase(s -> { 7 | if (s.length() < 2) { 8 | return s.toLowerCase(); 9 | } 10 | return Character.toLowerCase(s.charAt(0)) + s.substring(1); 11 | }), snake_case(s -> { 12 | StringBuilder result = new StringBuilder(); 13 | // Convert the first letter to lowercase 14 | result.append(Character.toLowerCase(s.charAt(0))); 15 | // Iterate through the rest of the string 16 | for (int i = 1; i < s.length(); i++) { 17 | char currentChar = s.charAt(i); 18 | // Convert uppercase letters to lowercase and add underscore 19 | if (Character.isUpperCase(currentChar)) { 20 | result.append('_').append(Character.toLowerCase(currentChar)); 21 | } else { 22 | result.append(currentChar); 23 | } 24 | } 25 | return result.toString(); 26 | }), PascalCase(s -> { 27 | if (s.length() < 2) { 28 | return s.toUpperCase(); 29 | } 30 | return Character.toUpperCase(s.charAt(0)) + s.substring(1); 31 | }), lowercase(String::toLowerCase), UPPERCASE(String::toUpperCase); 32 | 33 | private UnaryOperator convert; 34 | 35 | Casing(UnaryOperator function) { 36 | this.convert = function; 37 | } 38 | 39 | public String convertString(String str) { 40 | return convert.apply(str); 41 | } 42 | } -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/wrapper/DefaultMethodInvoker.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.wrapper; 2 | 3 | import java.lang.invoke.MethodHandles.Lookup; 4 | import java.lang.reflect.Constructor; 5 | import java.lang.reflect.InvocationHandler; 6 | import java.lang.reflect.InvocationTargetException; 7 | import java.lang.reflect.Method; 8 | import java.util.Arrays; 9 | 10 | import de.tr7zw.changeme.nbtapi.NbtApiException; 11 | 12 | class DefaultMethodInvoker { 13 | 14 | private static Method invokeDefaultMethod; 15 | 16 | static { 17 | try { 18 | invokeDefaultMethod = InvocationHandler.class.getDeclaredMethod("invokeDefault", 19 | new Class[] { Object.class, Method.class, Object[].class }); 20 | invokeDefaultMethod.setAccessible(true); 21 | } catch (NoSuchMethodException | SecurityException e) { 22 | // we are in java 8, use the fallback 23 | } 24 | } 25 | 26 | /** 27 | * Using reflections to access reflections, since some are still on java 8. 28 | * 29 | * @param target 30 | * @param method 31 | * @param args 32 | * @return 33 | */ 34 | public static Object invokeDefault(Class srcInt, Object target, Method method, Object[] args) { 35 | if (invokeDefaultMethod != null) { // java 9+ 36 | try { 37 | return invokeDefaultMethod.invoke(null, target, method, args); 38 | } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { 39 | throw new NbtApiException("Error while trying to invoke a default method for Java 9+. " + target + " " 40 | + method + " " + Arrays.toString(args), e); 41 | } 42 | } else { 43 | try { 44 | Constructor constructor = Lookup.class.getDeclaredConstructor(Class.class); 45 | constructor.setAccessible(true); 46 | return constructor.newInstance(srcInt).in(srcInt).unreflectSpecial(method, srcInt).bindTo(target) 47 | .invokeWithArguments(args); 48 | } catch (Throwable e) { 49 | throw new NbtApiException("Error while trying to invoke a default method for Java 8. " + target + " " 50 | + method + " " + Arrays.toString(args), e); 51 | } 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/wrapper/NBTProxy.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.wrapper; 2 | 3 | import java.util.Collection; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import de.tr7zw.changeme.nbtapi.iface.NBTHandler; 8 | 9 | public interface NBTProxy { 10 | 11 | final Map, NBTHandler> handlers = new HashMap<>(); 12 | 13 | public default void init() { 14 | 15 | } 16 | 17 | public default Casing getCasing() { 18 | return Casing.PascalCase; 19 | } 20 | 21 | @SuppressWarnings("unchecked") 22 | public default NBTHandler getHandler(Class clazz) { 23 | return (NBTHandler) handlers.get(clazz); 24 | } 25 | 26 | public default Collection> getHandlers() { 27 | return handlers.values(); 28 | } 29 | 30 | @SuppressWarnings("unchecked") 31 | public default void registerHandler(Class clazz, NBTHandler handler) { 32 | handlers.put(clazz, (NBTHandler) handler); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/wrapper/NBTTarget.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.wrapper; 2 | 3 | import static java.lang.annotation.ElementType.METHOD; 4 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 5 | 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.Target; 8 | 9 | @Retention(RUNTIME) 10 | @Target(METHOD) 11 | public @interface NBTTarget { 12 | public String value(); 13 | 14 | public Type type() default Type.AUTOMATIC; 15 | 16 | public enum Type { 17 | AUTOMATIC, GET, SET, HAS 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/wrapper/ProxiedList.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.wrapper; 2 | 3 | import java.util.ConcurrentModificationException; 4 | import java.util.Iterator; 5 | import java.util.NoSuchElementException; 6 | 7 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 8 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBTCompoundList; 9 | 10 | class ProxiedList implements ProxyList { 11 | 12 | private final ReadWriteNBTCompoundList nbt; 13 | private final Class proxy; 14 | 15 | public ProxiedList(ReadWriteNBTCompoundList nbt, Class proxyClass) { 16 | this.nbt = nbt; 17 | this.proxy = proxyClass; 18 | } 19 | 20 | @Override 21 | public E get(int index) { 22 | ReadWriteNBT tag = nbt.get(index); 23 | return new ProxyBuilder(tag,proxy).build(); 24 | } 25 | 26 | @Override 27 | public int size() { 28 | return nbt.size(); 29 | } 30 | 31 | @Override 32 | public void remove(int index) { 33 | nbt.remove(index); 34 | } 35 | 36 | 37 | @Override 38 | public Iterator iterator() { 39 | return new Itr(); 40 | } 41 | 42 | @Override 43 | public E addCompound() { 44 | ReadWriteNBT tag = nbt.addCompound(); 45 | return new ProxyBuilder(tag,proxy).build(); 46 | } 47 | 48 | @Override 49 | public boolean isEmpty() { 50 | return nbt.isEmpty(); 51 | } 52 | 53 | private class Itr implements Iterator { 54 | /** 55 | * Index of element to be returned by subsequent call to next. 56 | */ 57 | int cursor = 0; 58 | 59 | /** 60 | * Index of element returned by most recent call to next or 61 | * previous. Reset to -1 if this element is deleted by a call 62 | * to remove. 63 | */ 64 | int lastRet = -1; 65 | 66 | public boolean hasNext() { 67 | return cursor != size(); 68 | } 69 | 70 | public E next() { 71 | try { 72 | int i = cursor; 73 | E next = get(i); 74 | lastRet = i; 75 | cursor = i + 1; 76 | return next; 77 | } catch (IndexOutOfBoundsException e) { 78 | throw new NoSuchElementException(); 79 | } 80 | } 81 | 82 | public void remove() { 83 | if (lastRet < 0) 84 | throw new IllegalStateException(); 85 | 86 | try { 87 | ProxiedList.this.remove(lastRet); 88 | if (lastRet < cursor) 89 | cursor--; 90 | lastRet = -1; 91 | } catch (IndexOutOfBoundsException e) { 92 | throw new ConcurrentModificationException(); 93 | } 94 | } 95 | 96 | } 97 | 98 | } 99 | 100 | -------------------------------------------------------------------------------- /item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/wrapper/ProxyList.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.wrapper; 2 | 3 | public interface ProxyList extends Iterable { 4 | 5 | /** 6 | * Adds a new compound tag to the current compound tag 7 | * 8 | * @return A new instance of the class. 9 | */ 10 | T addCompound(); 11 | 12 | /** 13 | * Returns the number of elements in this collection. If this collection 14 | * contains more than Integer.MAX_VALUE elements, returns Integer.MAX_VALUE. 15 | * 16 | * @return the number of elements in this collection 17 | */ 18 | int size(); 19 | 20 | /** 21 | * Returns true if this collection contains no elements. 22 | * 23 | * @return true if this collection contains no elements 24 | */ 25 | boolean isEmpty(); 26 | 27 | /** 28 | * Get the object with the given id. 29 | * 30 | * @param id The id of the object to get. 31 | * @return The object with the given id. 32 | */ 33 | T get(int id); 34 | 35 | /** 36 | * Removes the element at the specified position in this list 37 | * 38 | * @param i The index of the element to remove. 39 | */ 40 | void remove(int i); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /item-nbt-plugin/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 - 2021, tr7zw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/GameprofileTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests; 2 | 3 | import java.util.UUID; 4 | 5 | import com.mojang.authlib.GameProfile; 6 | 7 | import de.tr7zw.changeme.nbtapi.NBT; 8 | import de.tr7zw.changeme.nbtapi.NbtApiException; 9 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 10 | 11 | public class GameprofileTest implements Test { 12 | 13 | @Override 14 | public void test() throws Exception { 15 | UUID uuid = UUID.randomUUID(); 16 | GameProfile profile = new GameProfile(uuid, "random"); 17 | ReadWriteNBT nbt = NBT.gameProfileToNBT(profile); 18 | profile = null; 19 | profile = NBT.gameProfileFromNBT(nbt); 20 | if (profile == null || !profile.getId().equals(uuid)) { 21 | throw new NbtApiException("Error when converting a GameProfile from/to NBT!"); 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/NBTFileTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests; 2 | 3 | import java.io.File; 4 | import java.nio.file.Files; 5 | 6 | import de.tr7zw.changeme.nbtapi.NBT; 7 | import de.tr7zw.changeme.nbtapi.NbtApiException; 8 | import de.tr7zw.changeme.nbtapi.iface.NBTFileHandle; 9 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 10 | import de.tr7zw.nbtapi.plugin.NBTAPI; 11 | 12 | public class NBTFileTest implements Test { 13 | 14 | @Override 15 | public void test() throws Exception { 16 | NBTAPI.getInstance().getDataFolder().mkdirs(); 17 | File testFile = new File(NBTAPI.getInstance().getDataFolder(), "test.nbt"); 18 | Files.deleteIfExists(testFile.toPath()); 19 | NBTFileHandle file = NBT.getFileHandle(testFile); 20 | file.getOrCreateCompound("testcomp").setString("test1", "ok"); 21 | ReadWriteNBT comp = file.getOrCreateCompound("testcomp"); 22 | if (comp == null) { 23 | throw new NbtApiException("Error getting compound!"); 24 | } 25 | comp.setString("test2", "ok"); 26 | file.setLong("time", System.currentTimeMillis()); 27 | file.setString("test", "test"); 28 | ReadWriteNBT chunks = file.getOrCreateCompound("chunks"); 29 | ReadWriteNBT chunk = chunks.getOrCreateCompound("somechunk"); 30 | ReadWriteNBT block = chunk.getOrCreateCompound("someblock"); 31 | block.setString("type", "wool"); 32 | file.save(); 33 | 34 | if (!"wool".equals(block.getString("type"))) { 35 | throw new NbtApiException("SubCompounds did not work!"); 36 | } 37 | 38 | NBTFileHandle fileLoaded = NBT.getFileHandle(testFile); 39 | if (!fileLoaded.getString("test").equals("test")) { 40 | throw new NbtApiException("Wasn't able to load NBT File with the correct content!"); 41 | } 42 | Files.deleteIfExists(fileLoaded.getFile().toPath()); 43 | // String 44 | String str = fileLoaded.toString(); 45 | ReadWriteNBT rebuild = NBT.parseNBT(str); 46 | if (!str.equals(rebuild.toString())) { 47 | throw new NbtApiException("Wasn't able to parse NBT from a String!"); 48 | } 49 | 50 | ReadWriteNBT dummy = NBT.createNBTObject(); 51 | dummy.setString("test1", "key1"); 52 | NBT.writeFile(testFile, dummy); 53 | dummy = NBT.createNBTObject(); 54 | dummy.setString("test2", "key2"); 55 | NBT.writeFile(testFile, dummy); 56 | dummy = NBT.readFile(testFile); 57 | if (dummy.hasTag("test1") || !dummy.getString("test2").equals("key2")) { 58 | throw new NbtApiException("Wasn't able to save NBT File with the correct content!"); 59 | } 60 | Files.deleteIfExists(fileLoaded.getFile().toPath()); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/Test.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests; 2 | 3 | public interface Test { 4 | 5 | public void test() throws Exception; // NOSONAR 6 | 7 | } 8 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/blocks/BlockNBTTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.blocks; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.Chunk; 5 | import org.bukkit.World; 6 | import org.bukkit.block.Block; 7 | 8 | import de.tr7zw.changeme.nbtapi.NBTBlock; 9 | import de.tr7zw.changeme.nbtapi.NbtApiException; 10 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 11 | import de.tr7zw.nbtapi.plugin.tests.Test; 12 | 13 | public class BlockNBTTest implements Test { 14 | 15 | @Override 16 | public void test() throws Exception { 17 | if (MinecraftVersion.getVersion().getVersionId() < MinecraftVersion.MC1_16_R3.getVersionId()) 18 | return; 19 | if (!Bukkit.getWorlds().isEmpty()) { 20 | World world = Bukkit.getWorlds().get(0); 21 | try { 22 | if (world.getLoadedChunks().length > 1) { 23 | Chunk chunk = world.getLoadedChunks()[0]; 24 | Block block = chunk.getBlock(0, 254, 0); 25 | NBTBlock comp = new NBTBlock(block); 26 | comp.getData().removeKey("Too"); 27 | if (comp.getData().hasTag("Too")) { 28 | throw new NbtApiException("Unable to remove key from Block!"); 29 | } 30 | comp.getData().setString("Too", "Bar"); 31 | if (!new NBTBlock(block).getData().getString("Too").equals("Bar")) { 32 | throw new NbtApiException("Custom Data did not save to a Block!"); 33 | } 34 | } 35 | } catch (Exception ex) { 36 | throw new NbtApiException("Wasn't able to use NBTBlocks!", ex); 37 | } 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/chunks/ChunkNBTPersistentTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.chunks; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.Chunk; 5 | import org.bukkit.World; 6 | 7 | import de.tr7zw.changeme.nbtapi.NBTChunk; 8 | import de.tr7zw.changeme.nbtapi.NBTCompound; 9 | import de.tr7zw.changeme.nbtapi.NbtApiException; 10 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 11 | import de.tr7zw.nbtapi.plugin.tests.Test; 12 | 13 | public class ChunkNBTPersistentTest implements Test { 14 | 15 | @Override 16 | public void test() throws Exception { 17 | if (MinecraftVersion.getVersion().getVersionId() < MinecraftVersion.MC1_16_R3.getVersionId()) 18 | return; 19 | if (!Bukkit.getWorlds().isEmpty()) { 20 | World world = Bukkit.getWorlds().get(0); 21 | try { 22 | if (world.getLoadedChunks().length > 1) { 23 | Chunk chunk = world.getLoadedChunks()[0]; 24 | NBTChunk comp = new NBTChunk(chunk); 25 | NBTCompound persistentData = comp.getPersistentDataContainer(); 26 | persistentData.removeKey("Foo"); 27 | if (persistentData.hasTag("Foo")) { 28 | throw new NbtApiException("Unable to remove key from Chunk!"); 29 | } 30 | persistentData.setString("Foo", "Bar"); 31 | if (!new NBTChunk(chunk).getPersistentDataContainer().getString("Foo").equals("Bar")) { 32 | throw new NbtApiException("Custom Data did not save to the Chunk!"); 33 | } 34 | } 35 | } catch (Exception ex) { 36 | throw new NbtApiException("Wasn't able to use NBTChunks!", ex); 37 | } 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/compounds/CompoundDifferenceTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.compounds; 2 | 3 | import de.tr7zw.changeme.nbtapi.NBT; 4 | import de.tr7zw.changeme.nbtapi.NbtApiException; 5 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 6 | import de.tr7zw.nbtapi.plugin.tests.Test; 7 | 8 | import java.util.Arrays; 9 | 10 | public class CompoundDifferenceTest implements Test { 11 | 12 | @Override 13 | public void test() throws Exception { 14 | ReadWriteNBT nbt1 = NBT.createNBTObject(); 15 | nbt1.setInteger("intTag", 1); 16 | ReadWriteNBT tmp = NBT.createNBTObject(); 17 | tmp.setInteger("foo", 1); 18 | nbt1.getCompoundList("compoundList1").addCompound(tmp); 19 | nbt1.setIntArray("intArray", new int[]{1, 2, 3}); 20 | tmp = NBT.createNBTObject(); 21 | tmp.setIntArray("foo", new int[]{1, 2, 3}); 22 | nbt1.getCompoundList("compoundList2").addCompound(tmp); 23 | nbt1.getOrCreateCompound("compoundTag").setFloat("floatTag", 20F); 24 | nbt1.getOrCreateCompound("compoundTag").setBoolean("booleanTag", true); 25 | nbt1.getOrCreateCompound("compoundTag").getDoubleList("doubleList").addAll(Arrays.asList(1D, 2D, 3D)); 26 | nbt1.getOrCreateCompound("compoundTag").getFloatList("floatList").addAll(Arrays.asList(1F, 2F)); 27 | nbt1.getOrCreateCompound("compoundTagTwo").setString("stringTag", "string"); 28 | ReadWriteNBT nbt2 = NBT.createNBTObject(); 29 | nbt2.setInteger("intTag", 1); 30 | tmp = NBT.createNBTObject(); 31 | tmp.setInteger("foo", 1); 32 | nbt2.getCompoundList("compoundList1").addCompound(tmp); 33 | nbt2.setInteger("alsoIntTag", 2); 34 | tmp = NBT.createNBTObject(); 35 | tmp.setInteger("foo", 2); 36 | nbt2.getCompoundList("compoundList2").addCompound(tmp); 37 | nbt2.getOrCreateCompound("compoundTag").setFloat("floatTag", 20F); 38 | nbt2.getOrCreateCompound("compoundTag").setBoolean("booleanTag", false); 39 | nbt2.getOrCreateCompound("compoundTag").getDoubleList("doubleList").addAll(Arrays.asList(1D, 2D, 3D, 4D)); 40 | nbt2.getOrCreateCompound("compoundTag").getFloatList("floatList").addAll(Arrays.asList(1F, 2F)); 41 | nbt2.getOrCreateCompound("compoundTagTwo").setString("stringTag", "string"); 42 | 43 | ReadWriteNBT expectedDiff1 = NBT.createNBTObject(); 44 | tmp = NBT.createNBTObject(); 45 | tmp.setIntArray("foo", new int[]{1, 2, 3}); 46 | expectedDiff1.getCompoundList("compoundList2").addCompound(tmp); 47 | expectedDiff1.setIntArray("intArray", new int[]{1, 2, 3}); 48 | expectedDiff1.getOrCreateCompound("compoundTag").setBoolean("booleanTag", true); 49 | expectedDiff1.getOrCreateCompound("compoundTag").getDoubleList("doubleList").addAll(Arrays.asList(1D, 2D, 3D)); 50 | ReadWriteNBT expectedDiff2 = NBT.createNBTObject(); 51 | tmp = NBT.createNBTObject(); 52 | tmp.setInteger("foo", 2); 53 | expectedDiff2.getCompoundList("compoundList2").addCompound(tmp); 54 | expectedDiff2.setInteger("alsoIntTag", 2); 55 | expectedDiff2.getOrCreateCompound("compoundTag").setBoolean("booleanTag", false); 56 | expectedDiff2.getOrCreateCompound("compoundTag").getDoubleList("doubleList").addAll(Arrays.asList(1D, 2D, 3D, 4D)); 57 | 58 | ReadWriteNBT diff1 = nbt1.extractDifference(nbt2); 59 | ReadWriteNBT diff2 = nbt2.extractDifference(nbt1); 60 | 61 | if (!expectedDiff1.equals(diff1)) { 62 | throw new NbtApiException("Diff1: Compounds did not match! " + expectedDiff1 + " " + diff1); 63 | } 64 | if (!expectedDiff2.equals(diff2)) { 65 | throw new NbtApiException("Diff2: Compounds did not match! " + expectedDiff2 + " " + diff2); 66 | } 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/compounds/EnumTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.compounds; 2 | 3 | import de.tr7zw.changeme.nbtapi.NBT; 4 | import de.tr7zw.changeme.nbtapi.NBTType; 5 | import de.tr7zw.changeme.nbtapi.NbtApiException; 6 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 7 | import de.tr7zw.nbtapi.plugin.tests.Test; 8 | 9 | public class EnumTest implements Test { 10 | 11 | @Override 12 | public void test() throws Exception { 13 | ReadWriteNBT comp = NBT.createNBTObject(); 14 | comp.setEnum("test", NBTType.NBTTagEnd); 15 | NBTType type = comp.getEnum("test", NBTType.class); 16 | NBTType typeNonNull = comp.getOrNull("test", NBTType.class); 17 | NBTType typeDefault = comp.getOrDefault("invalid", NBTType.NBTTagByte); 18 | NBTType typeDefaultFound = comp.getOrDefault("test", NBTType.NBTTagByte); 19 | if (type != NBTType.NBTTagEnd || typeNonNull != NBTType.NBTTagEnd || typeDefaultFound != NBTType.NBTTagEnd 20 | || typeDefault != NBTType.NBTTagByte) 21 | throw new NbtApiException("One enum did not match what it should have been!"); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/compounds/EqualsTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.compounds; 2 | 3 | import java.util.Arrays; 4 | 5 | import org.bukkit.Material; 6 | import org.bukkit.inventory.ItemStack; 7 | 8 | import de.tr7zw.changeme.nbtapi.NBT; 9 | import de.tr7zw.changeme.nbtapi.NbtApiException; 10 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 11 | import de.tr7zw.nbtapi.plugin.tests.Test; 12 | 13 | public class EqualsTest implements Test { 14 | 15 | @Override 16 | public void test() throws Exception { 17 | ReadWriteNBT cont = NBT.createNBTObject(); 18 | cont.setString("hello", "world"); 19 | cont.setInteger("theAnswer", 42); 20 | cont.getOrCreateCompound("sub").setString("me", "too"); 21 | cont.getStringList("somelist").addAll(Arrays.asList("a", "b", "c")); 22 | ItemStack item = new ItemStack(Material.STONE); 23 | NBT.modify(item, nbti -> { 24 | ReadWriteNBT customData = nbti.getOrCreateCompound("customData"); 25 | // reverse order 26 | customData.getOrCreateCompound("sub").setString("me", "too"); 27 | customData.setInteger("theAnswer", 42); 28 | customData.setString("hello", "world"); 29 | customData.getStringList("somelist").addAll(Arrays.asList("a", "b", "c")); 30 | if (!customData.equals(cont)) { 31 | throw new NbtApiException("Compounds did not match! " + customData + " " + cont); 32 | } 33 | }); 34 | 35 | // empty test 36 | 37 | if (!NBT.createNBTObject().equals(NBT.createNBTObject())) { 38 | throw new NbtApiException("Two empty tags did not match!"); 39 | } 40 | 41 | // not equal test 42 | ReadWriteNBT part1 = NBT.createNBTObject(); 43 | part1.setString("a", "a"); 44 | part1.setString("b", "b"); 45 | ReadWriteNBT part2 = NBT.createNBTObject(); 46 | part2.setString("a", "a"); 47 | part2.setString("b", "a"); 48 | if (part1.equals(part2)) { 49 | throw new NbtApiException("Missmatched nbt did match!"); 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/compounds/ForEachTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.compounds; 2 | 3 | import java.util.ListIterator; 4 | 5 | import de.tr7zw.changeme.nbtapi.NBTCompoundList; 6 | import de.tr7zw.changeme.nbtapi.NBTContainer; 7 | import de.tr7zw.changeme.nbtapi.NbtApiException; 8 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 9 | import de.tr7zw.nbtapi.plugin.tests.Test; 10 | 11 | /** 12 | * Test requested by TAU on Discord 13 | * 14 | */ 15 | public class ForEachTest implements Test { 16 | 17 | @SuppressWarnings("unused") 18 | @Override 19 | public void test() throws Exception { 20 | NBTContainer comp = new NBTContainer(); 21 | NBTCompoundList compList = comp.getCompoundList("testkey"); 22 | if (compList != null) { 23 | compList.addCompound().setInteger("id", 1); 24 | compList.addCompound().setInteger("id", 2); 25 | compList.addCompound().setInteger("id", 3); 26 | int count = 0; 27 | for (ReadWriteNBT listComp : compList) { 28 | count++; 29 | } 30 | if (count != compList.size()) 31 | throw new NbtApiException("For loop did not get all Entries!"); 32 | count = 0; 33 | ListIterator lit = compList.listIterator(); 34 | while (lit.hasNext()) { 35 | lit.next(); 36 | count++; 37 | } 38 | if (count != compList.size()) 39 | throw new NbtApiException("ListIterator did not get all Entries!"); 40 | count = 0; 41 | while (lit.hasPrevious()) { 42 | lit.previous(); 43 | count++; 44 | } 45 | if (count != compList.size()) 46 | throw new NbtApiException("ListIterator previous did not get all Entries!"); 47 | } 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/compounds/GetterSetterTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.compounds; 2 | 3 | import de.tr7zw.changeme.nbtapi.NBT; 4 | import de.tr7zw.changeme.nbtapi.NbtApiException; 5 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 6 | import de.tr7zw.nbtapi.plugin.tests.Test; 7 | 8 | public class GetterSetterTest implements Test { 9 | 10 | private static final String STRING_TEST_KEY = "stringTest"; 11 | private static final String INT_TEST_KEY = "intTest"; 12 | private static final String DOUBLE_TEST_KEY = "doubleTest"; 13 | private static final String BOOLEAN_TEST_KEY = "booleanTest"; 14 | private static final String SHORT_TEST_KEY = "shortTest"; 15 | private static final String BYTE_TEST_KEY = "byteTest"; 16 | private static final String FLOAT_TEST_KEY = "floatTest"; 17 | private static final String LONG_TEST_KEY = "longTest"; 18 | private static final String INTARRAY_TEST_KEY = "intarrayTest"; 19 | private static final String BYTEARRAY_TEST_KEY = "bytearrayTest"; 20 | 21 | private static final String STRING_TEST_VALUE = "TestString"; 22 | private static final int INT_TEST_VALUE = 42; 23 | private static final double DOUBLE_TEST_VALUE = 1.5d; 24 | private static final boolean BOOLEAN_TEST_VALUE = true; 25 | private static final short SHORT_TEST_VALUE = 64; 26 | private static final byte BYTE_TEST_VALUE = 7; 27 | private static final float FLOAT_TEST_VALUE = 13.37f; 28 | private static final long LONG_TEST_VALUE = (long) Integer.MAX_VALUE + 42L; 29 | private static final int[] INTARRAY_TEST_VALUE = new int[] { 1337, 42, 69 }; 30 | private static final byte[] BYTEARRAY_TEST_VALUE = new byte[] { 8, 7, 3, 2 }; 31 | 32 | @Override 33 | public void test() throws Exception { 34 | ReadWriteNBT comp = NBT.createNBTObject(); 35 | 36 | comp.setString(STRING_TEST_KEY, STRING_TEST_VALUE); 37 | comp.setInteger(INT_TEST_KEY, INT_TEST_VALUE); 38 | comp.setDouble(DOUBLE_TEST_KEY, DOUBLE_TEST_VALUE); 39 | comp.setBoolean(BOOLEAN_TEST_KEY, BOOLEAN_TEST_VALUE); 40 | comp.setByte(BYTE_TEST_KEY, BYTE_TEST_VALUE); 41 | comp.setShort(SHORT_TEST_KEY, SHORT_TEST_VALUE); 42 | comp.setLong(LONG_TEST_KEY, LONG_TEST_VALUE); 43 | comp.setFloat(FLOAT_TEST_KEY, FLOAT_TEST_VALUE); 44 | comp.setIntArray(INTARRAY_TEST_KEY, INTARRAY_TEST_VALUE); 45 | comp.setByteArray(BYTEARRAY_TEST_KEY, BYTEARRAY_TEST_VALUE); 46 | 47 | if (!comp.hasTag(STRING_TEST_KEY)) { 48 | throw new NbtApiException("Wasn't able to check a key! The Item-NBT-API may not work!"); 49 | } 50 | int[] intArray = comp.getIntArray(INTARRAY_TEST_KEY); 51 | byte[] byteArray = comp.getByteArray(BYTEARRAY_TEST_KEY); 52 | if (!(STRING_TEST_VALUE).equals(comp.getString(STRING_TEST_KEY)) 53 | || comp.getInteger(INT_TEST_KEY) != INT_TEST_VALUE 54 | || comp.getDouble(DOUBLE_TEST_KEY) != DOUBLE_TEST_VALUE 55 | || comp.getByte(BYTE_TEST_KEY) != BYTE_TEST_VALUE || comp.getShort(SHORT_TEST_KEY) != SHORT_TEST_VALUE 56 | || comp.getFloat(FLOAT_TEST_KEY) != FLOAT_TEST_VALUE || comp.getLong(LONG_TEST_KEY) != LONG_TEST_VALUE 57 | || (intArray != null && intArray.length != (INTARRAY_TEST_VALUE).length) 58 | || (byteArray != null && byteArray.length != (BYTEARRAY_TEST_VALUE).length) 59 | || !comp.getBoolean(BOOLEAN_TEST_KEY).equals(BOOLEAN_TEST_VALUE)) { 60 | throw new NbtApiException("One key does not equal the original value! The Item-NBT-API may not work!"); 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/compounds/GsonTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.compounds; 2 | 3 | import org.bukkit.Material; 4 | import org.bukkit.inventory.ItemStack; 5 | 6 | import de.tr7zw.changeme.nbtapi.NBTItem; 7 | import de.tr7zw.changeme.nbtapi.NbtApiException; 8 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 9 | import de.tr7zw.nbtapi.plugin.tests.Test; 10 | 11 | public class GsonTest implements Test { 12 | 13 | @SuppressWarnings("deprecation") 14 | @Override 15 | public void test() throws Exception { 16 | if (!MinecraftVersion.hasGsonSupport()) { 17 | return; 18 | } 19 | try { 20 | ItemStack item = new ItemStack(Material.STONE, 1); 21 | NBTItem nbtItem = new NBTItem(item); 22 | 23 | nbtItem.setObject(JSON_TEST_KEY, new SimpleJsonTestObject()); 24 | 25 | if (!nbtItem.hasTag(JSON_TEST_KEY)) { 26 | throw new NbtApiException( 27 | "Wasn't able to find JSON key! The Item-NBT-API may not work with Json serialization/deserialization!"); 28 | } else { 29 | SimpleJsonTestObject simpleObject = nbtItem.getObject(JSON_TEST_KEY, SimpleJsonTestObject.class); 30 | if (simpleObject == null) { 31 | throw new NbtApiException( 32 | "Wasn't able to check JSON key! The Item-NBT-API may not work with Json serialization/deserialization!"); 33 | } else if (!(STRING_TEST_VALUE).equals(simpleObject.getTestString()) 34 | || simpleObject.getTestInteger() != INT_TEST_VALUE 35 | || simpleObject.getTestDouble() != DOUBLE_TEST_VALUE 36 | || !simpleObject.isTestBoolean() == BOOLEAN_TEST_VALUE) { 37 | throw new NbtApiException( 38 | "One key does not equal the original value in JSON! The Item-NBT-API may not work with Json serialization/deserialization!"); 39 | } 40 | } 41 | } catch (Exception ex) { 42 | throw new NbtApiException("Exception during Gson check!", ex); 43 | } 44 | } 45 | 46 | // region STATIC FINAL VARIABLES 47 | private static final String JSON_TEST_KEY = "jsonTest"; 48 | 49 | private static final String STRING_TEST_VALUE = "TestString"; 50 | private static final int INT_TEST_VALUE = 42; 51 | private static final double DOUBLE_TEST_VALUE = 1.5d; 52 | private static final boolean BOOLEAN_TEST_VALUE = true; 53 | 54 | // end region STATIC FINAL VARIABLES 55 | 56 | public static class SimpleJsonTestObject { 57 | private String testString = STRING_TEST_VALUE; 58 | private int testInteger = INT_TEST_VALUE; 59 | private double testDouble = DOUBLE_TEST_VALUE; 60 | private boolean testBoolean = BOOLEAN_TEST_VALUE; 61 | 62 | public String getTestString() { 63 | return testString; 64 | } 65 | 66 | public void setTestString(String testString) { 67 | this.testString = testString; 68 | } 69 | 70 | public int getTestInteger() { 71 | return testInteger; 72 | } 73 | 74 | public void setTestInteger(int testInteger) { 75 | this.testInteger = testInteger; 76 | } 77 | 78 | public double getTestDouble() { 79 | return testDouble; 80 | } 81 | 82 | public void setTestDouble(double testDouble) { 83 | this.testDouble = testDouble; 84 | } 85 | 86 | public boolean isTestBoolean() { 87 | return testBoolean; 88 | } 89 | 90 | public void setTestBoolean(boolean testBoolean) { 91 | this.testBoolean = testBoolean; 92 | } 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/compounds/InterfaceTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.compounds; 2 | 3 | import de.tr7zw.changeme.nbtapi.NBT; 4 | import de.tr7zw.changeme.nbtapi.NbtApiException; 5 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 6 | import de.tr7zw.nbtapi.plugin.tests.Test; 7 | 8 | public class InterfaceTest implements Test { 9 | 10 | @Override 11 | public void test() throws Exception { 12 | ReadWriteNBT src = NBT.createNBTObject(); 13 | src.setString("foo", "bar"); 14 | ReadWriteNBT target = NBT.createNBTObject(); 15 | target.mergeCompound(src); 16 | if (!"bar".equals(target.getString("foo"))) { 17 | throw new NbtApiException("Wasn't able to check the key! The Item-NBT-API may not work!"); 18 | } 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/compounds/IteratorTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.compounds; 2 | 3 | import de.tr7zw.changeme.nbtapi.NBTContainer; 4 | import de.tr7zw.changeme.nbtapi.NBTList; 5 | import de.tr7zw.changeme.nbtapi.NbtApiException; 6 | import de.tr7zw.nbtapi.plugin.tests.Test; 7 | 8 | import java.util.Iterator; 9 | import java.util.NoSuchElementException; 10 | 11 | public class IteratorTest implements Test { 12 | 13 | @Override 14 | public void test() throws Exception { 15 | NBTList testList; 16 | 17 | testList = initIntegerList(); 18 | testIterator(testList.iterator()); 19 | 20 | testList = initIntegerList(); 21 | testIterator(testList.listIterator()); 22 | } 23 | 24 | private NBTList initIntegerList() { 25 | NBTContainer comp = new NBTContainer(); 26 | NBTList list = comp.getIntegerList("test"); 27 | list.add(1); 28 | list.add(2); 29 | list.add(3); 30 | list.add(4); 31 | return list; 32 | } 33 | 34 | private static void testIterator(Iterator iterator) { 35 | assertTrue(iterator.hasNext()); 36 | assertTrue(iterator.next() == 1); 37 | assertTrue(iterator.hasNext()); 38 | assertTrue(iterator.next() == 2); 39 | iterator.remove(); 40 | assertTrue(iterator.hasNext()); 41 | assertTrue(iterator.next() == 3); 42 | assertTrue(iterator.hasNext()); 43 | assertTrue(iterator.next() == 4); 44 | testNoMoreElements(iterator); 45 | } 46 | 47 | private static void testNoMoreElements(Iterator iterator) { 48 | assertTrue(!iterator.hasNext()); 49 | try { 50 | iterator.next(); 51 | } catch (NoSuchElementException expected) { 52 | return; 53 | } catch (Exception e) { 54 | throw new NbtApiException("iterator threw wrong exception: " + e.toString()); 55 | } 56 | throw new NbtApiException("iterator did not throw exception"); 57 | } 58 | 59 | private static void assertTrue(boolean condition) { 60 | if (!condition) { 61 | throw new NbtApiException("iterator test failed"); 62 | } 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/compounds/LongArrayTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.compounds; 2 | 3 | import java.util.Arrays; 4 | 5 | import de.tr7zw.changeme.nbtapi.NBTContainer; 6 | import de.tr7zw.changeme.nbtapi.NbtApiException; 7 | import de.tr7zw.nbtapi.plugin.tests.Test; 8 | 9 | public class LongArrayTest implements Test { 10 | 11 | @Override 12 | public void test() throws Exception { 13 | NBTContainer comp = new NBTContainer(); 14 | 15 | comp.setLongArray("test", new long[] { 1, 2, 3, 4, Long.MAX_VALUE }); 16 | 17 | if (!comp.hasTag("test")) { 18 | throw new NbtApiException("Wasn't able to check a key! The Item-NBT-API may not work!"); 19 | } 20 | if (!Arrays.equals(comp.getLongArray("test"), new long[] { 1, 2, 3, 4, Long.MAX_VALUE })) { 21 | throw new NbtApiException("The long key does not equal the original value! The Item-NBT-API may not work!"); 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/compounds/MergeTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.compounds; 2 | 3 | import de.tr7zw.changeme.nbtapi.NBTContainer; 4 | import de.tr7zw.changeme.nbtapi.NbtApiException; 5 | import de.tr7zw.nbtapi.plugin.tests.Test; 6 | 7 | public class MergeTest implements Test { 8 | 9 | @Override 10 | public void test() throws Exception { 11 | NBTContainer test1 = new NBTContainer(); 12 | test1.setString("test1", "test"); 13 | NBTContainer test2 = new NBTContainer(); 14 | test2.setString("test2", "test"); 15 | test2.addCompound("test").setLong("time", System.currentTimeMillis()); 16 | test1.mergeCompound(test2); 17 | if (!test1.getString("test1").equals(test1.getString("test2"))) { 18 | throw new NbtApiException("Wasn't able to merge Compounds!"); 19 | } 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/compounds/ModernSubCompoundsTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.compounds; 2 | 3 | import de.tr7zw.changeme.nbtapi.NBT; 4 | import de.tr7zw.changeme.nbtapi.NbtApiException; 5 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 6 | import de.tr7zw.nbtapi.plugin.tests.Test; 7 | 8 | public class ModernSubCompoundsTest implements Test { 9 | 10 | private static final String COMP_TEST_KEY = "componentTest"; 11 | private static final String STRING_TEST_KEY = "stringTest"; 12 | private static final String INT_TEST_KEY = "intTest"; 13 | private static final String DOUBLE_TEST_KEY = "doubleTest"; 14 | private static final String BOOLEAN_TEST_KEY = "booleanTest"; 15 | private static final String STRING_TEST_VALUE = "TestString"; 16 | private static final int INT_TEST_VALUE = 42; 17 | private static final double DOUBLE_TEST_VALUE = 1.5d; 18 | private static final boolean BOOLEAN_TEST_VALUE = true; 19 | 20 | @Override 21 | public void test() throws Exception { 22 | ReadWriteNBT cont = NBT.createNBTObject(); 23 | 24 | ReadWriteNBT comp = cont.getOrCreateCompound(COMP_TEST_KEY); 25 | comp.setString(STRING_TEST_KEY, STRING_TEST_VALUE + "2"); 26 | comp.setInteger(INT_TEST_KEY, INT_TEST_VALUE * 2); 27 | comp.setDouble(DOUBLE_TEST_KEY, DOUBLE_TEST_VALUE * 2); 28 | 29 | if (cont.getCompound("invalide") != null) { 30 | throw new NbtApiException("An invalide compound did not return null!"); 31 | } 32 | 33 | comp = null; 34 | 35 | comp = cont.getCompound(COMP_TEST_KEY); 36 | if (comp == null) { 37 | throw new NbtApiException("Wasn't able to get the NBTCompound!"); 38 | } 39 | if (!comp.hasTag(STRING_TEST_KEY)) { 40 | throw new NbtApiException("Wasn't able to check a compound key!"); 41 | } 42 | if (!(STRING_TEST_VALUE + "2").equals(comp.getString(STRING_TEST_KEY)) 43 | || comp.getInteger(INT_TEST_KEY) != INT_TEST_VALUE * 2 44 | || comp.getDouble(DOUBLE_TEST_KEY) != DOUBLE_TEST_VALUE * 2 45 | || comp.getBoolean(BOOLEAN_TEST_KEY) == BOOLEAN_TEST_VALUE) { 46 | throw new NbtApiException("One key does not equal the original compound value!"); 47 | } 48 | 49 | // Using getOrCreateCompound twice 50 | comp.getOrCreateCompound("someName").setString("test", "abc"); 51 | if (!comp.getOrCreateCompound("someName").getString("test").equals("abc")) { 52 | throw new NbtApiException("getOrCreateCompound did not return the same compound!"); 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/compounds/RemovingKeys.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.compounds; 2 | 3 | import de.tr7zw.changeme.nbtapi.NBTContainer; 4 | import de.tr7zw.changeme.nbtapi.NbtApiException; 5 | import de.tr7zw.nbtapi.plugin.tests.Test; 6 | 7 | public class RemovingKeys implements Test { 8 | 9 | private static final String STRING_TEST_KEY = "stringTest"; 10 | private static final String INT_TEST_KEY = "intTest"; 11 | private static final String DOUBLE_TEST_KEY = "doubleTest"; 12 | private static final String BOOLEAN_TEST_KEY = "booleanTest"; 13 | private static final String SHORT_TEST_KEY = "shortTest"; 14 | private static final String BYTE_TEST_KEY = "byteTest"; 15 | private static final String FLOAT_TEST_KEY = "floatTest"; 16 | private static final String LONG_TEST_KEY = "longTest"; 17 | private static final String INTARRAY_TEST_KEY = "intarrayTest"; 18 | private static final String BYTEARRAY_TEST_KEY = "bytearrayTest"; 19 | 20 | private static final String STRING_TEST_VALUE = "TestString"; 21 | private static final int INT_TEST_VALUE = 42; 22 | private static final double DOUBLE_TEST_VALUE = 1.5d; 23 | private static final boolean BOOLEAN_TEST_VALUE = true; 24 | private static final short SHORT_TEST_VALUE = 64; 25 | private static final byte BYTE_TEST_VALUE = 7; 26 | private static final float FLOAT_TEST_VALUE = 13.37f; 27 | private static final long LONG_TEST_VALUE = (long) Integer.MAX_VALUE + 42L; 28 | private static final int[] INTARRAY_TEST_VALUE = new int[] { 1337, 42, 69 }; 29 | private static final byte[] BYTEARRAY_TEST_VALUE = new byte[] { 8, 7, 3, 2 }; 30 | 31 | @Override 32 | public void test() throws Exception { 33 | NBTContainer comp = new NBTContainer(); 34 | 35 | comp.setString(STRING_TEST_KEY, STRING_TEST_VALUE); 36 | comp.setInteger(INT_TEST_KEY, INT_TEST_VALUE); 37 | comp.setDouble(DOUBLE_TEST_KEY, DOUBLE_TEST_VALUE); 38 | comp.setBoolean(BOOLEAN_TEST_KEY, BOOLEAN_TEST_VALUE); 39 | comp.setByte(BYTE_TEST_KEY, BYTE_TEST_VALUE); 40 | comp.setShort(SHORT_TEST_KEY, SHORT_TEST_VALUE); 41 | comp.setLong(LONG_TEST_KEY, LONG_TEST_VALUE); 42 | comp.setFloat(FLOAT_TEST_KEY, FLOAT_TEST_VALUE); 43 | comp.setIntArray(INTARRAY_TEST_KEY, INTARRAY_TEST_VALUE); 44 | comp.setByteArray(BYTEARRAY_TEST_KEY, BYTEARRAY_TEST_VALUE); 45 | 46 | if (comp.getKeys().size() != 10) { 47 | throw new NbtApiException("Key amount did not match after setting keys!"); 48 | } 49 | 50 | comp.setString(STRING_TEST_KEY, null); 51 | comp.setInteger(INT_TEST_KEY, null); 52 | comp.setDouble(DOUBLE_TEST_KEY, null); 53 | comp.setBoolean(BOOLEAN_TEST_KEY, null); 54 | comp.setByte(BYTE_TEST_KEY, null); 55 | comp.setShort(SHORT_TEST_KEY, null); 56 | comp.setLong(LONG_TEST_KEY, null); 57 | comp.setFloat(FLOAT_TEST_KEY, null); 58 | comp.setIntArray(INTARRAY_TEST_KEY, null); 59 | comp.setByteArray(BYTEARRAY_TEST_KEY, null); 60 | 61 | if (comp.getKeys().size() != 0) { 62 | throw new NbtApiException("Keys where not removed using the setter with null!"); 63 | } 64 | 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/compounds/ResolveTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.compounds; 2 | 3 | import java.util.Arrays; 4 | 5 | import de.tr7zw.changeme.nbtapi.NBT; 6 | import de.tr7zw.changeme.nbtapi.NbtApiException; 7 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 8 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBTCompoundList; 9 | import de.tr7zw.changeme.nbtapi.iface.ReadableNBT; 10 | import de.tr7zw.nbtapi.plugin.tests.Test; 11 | 12 | public class ResolveTest implements Test { 13 | 14 | @Override 15 | public void test() throws Exception { 16 | ReadWriteNBT src = NBT.createNBTObject(); 17 | src.resolveOrCreateCompound("foo.bar.baz").setInteger("test", 42); 18 | if (src.resolveOrDefault("foo.bar.baz.test", 0) != 42) { 19 | throw new NbtApiException("Wasn't able to check the value! The Item-NBT-API may not work!"); 20 | } 21 | if (!Integer.valueOf(42).equals(src.resolveOrNull("foo.bar.baz.test", Integer.class))) { 22 | throw new NbtApiException("Wasn't able to check the value! The Item-NBT-API may not work!"); 23 | } 24 | src.resolveOrCreateCompound("foo.some\\.key.baz").setInteger("other", 123); 25 | if (src.getOrCreateCompound("foo").getOrCreateCompound("some.key").getOrCreateCompound("baz") 26 | .getInteger("other") != 123) { 27 | throw new NbtApiException("Wasn't able to check the value! The Item-NBT-API may not work!"); 28 | } 29 | ReadWriteNBT comp = src.resolveOrCreateCompound("foo.bar.baz"); 30 | comp.setIntArray("intarray", new int[] {1,2,3,4,5,6}); 31 | comp.getStringList("strlist").addAll(Arrays.asList("Hello", "World!")); 32 | ReadWriteNBTCompoundList list = comp.getCompoundList("somelist"); 33 | list.addCompound().setInteger("id", 1); 34 | list.addCompound().setInteger("id", 2); 35 | list.addCompound().setInteger("id", 3); 36 | list.addCompound().setInteger("id", 4); 37 | list.addCompound().setInteger("id", 5); 38 | list.addCompound().setInteger("id", 6); 39 | ReadableNBT listEntry = src.resolveCompound("foo.bar.baz.somelist[0]"); 40 | if(listEntry == null || listEntry.getInteger("id") != 1) { 41 | throw new NbtApiException("The value is not what was expected! The Item-NBT-API may not work!"); 42 | } 43 | ReadableNBT lastEntry = src.resolveOrCreateCompound("foo.bar.baz.somelist[-1]"); 44 | if(lastEntry == null || lastEntry.getInteger("id") != 6) { 45 | throw new NbtApiException("The value is not what was expected! The Item-NBT-API may not work!"); 46 | } 47 | if(src.resolveOrDefault("foo.bar.baz.intarray[1]", 0) != 2) { 48 | throw new NbtApiException("The value is not what was expected! The Item-NBT-API may not work!"); 49 | } 50 | if(src.resolveOrNull("foo.bar.baz.intarray[2]", Integer.class) != (Integer)3) { 51 | throw new NbtApiException("The value is not what was expected! The Item-NBT-API may not work!"); 52 | } 53 | if(!"World!".equals(src.resolveOrNull("foo.bar.baz.strlist[1]", String.class))) { 54 | throw new NbtApiException("The value is not what was expected! The Item-NBT-API may not work!"); 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/compounds/StreamTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.compounds; 2 | 3 | import java.io.ByteArrayInputStream; 4 | import java.io.ByteArrayOutputStream; 5 | 6 | import org.bukkit.Material; 7 | import org.bukkit.inventory.ItemStack; 8 | 9 | import de.tr7zw.changeme.nbtapi.NBT; 10 | import de.tr7zw.changeme.nbtapi.NBTContainer; 11 | import de.tr7zw.changeme.nbtapi.NbtApiException; 12 | import de.tr7zw.nbtapi.plugin.tests.Test; 13 | 14 | public class StreamTest implements Test { 15 | 16 | @Override 17 | public void test() throws Exception { 18 | NBTContainer base = new NBTContainer(); 19 | base.getOrCreateCompound("sub").setString("hello", "world"); 20 | ByteArrayOutputStream outStream = new ByteArrayOutputStream(); 21 | base.getOrCreateCompound("sub").writeCompound(outStream); 22 | byte[] data = outStream.toByteArray(); 23 | ByteArrayInputStream inputStream = new ByteArrayInputStream(data); 24 | NBTContainer container = new NBTContainer(inputStream); 25 | if (!container.toString().equals(base.getOrCreateCompound("sub").toString())) { 26 | throw new NbtApiException("Component content did not match! " + base.getCompound("sub") + " " + container); 27 | } 28 | ItemStack item = new ItemStack(Material.STICK); 29 | 30 | NBT.modify(item, nbt -> { 31 | nbt.writeCompound(outStream); 32 | }); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/compounds/SubCompoundsTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.compounds; 2 | 3 | import de.tr7zw.changeme.nbtapi.NBT; 4 | import de.tr7zw.changeme.nbtapi.NbtApiException; 5 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 6 | import de.tr7zw.nbtapi.plugin.tests.Test; 7 | 8 | public class SubCompoundsTest implements Test { 9 | 10 | private static final String COMP_TEST_KEY = "componentTest"; 11 | private static final String STRING_TEST_KEY = "stringTest"; 12 | private static final String INT_TEST_KEY = "intTest"; 13 | private static final String DOUBLE_TEST_KEY = "doubleTest"; 14 | private static final String BOOLEAN_TEST_KEY = "booleanTest"; 15 | private static final String STRING_TEST_VALUE = "TestString"; 16 | private static final int INT_TEST_VALUE = 42; 17 | private static final double DOUBLE_TEST_VALUE = 1.5d; 18 | private static final boolean BOOLEAN_TEST_VALUE = true; 19 | 20 | @Override 21 | public void test() throws Exception { 22 | ReadWriteNBT cont = NBT.createNBTObject(); 23 | 24 | ReadWriteNBT comp = cont.getOrCreateCompound(COMP_TEST_KEY); 25 | comp.setString(STRING_TEST_KEY, STRING_TEST_VALUE + "2"); 26 | comp.setInteger(INT_TEST_KEY, INT_TEST_VALUE * 2); 27 | comp.setDouble(DOUBLE_TEST_KEY, DOUBLE_TEST_VALUE * 2); 28 | 29 | if (cont.getCompound("invalide") != null) { 30 | throw new NbtApiException("An invalide compound did not return null!"); 31 | } 32 | 33 | comp = null; 34 | 35 | comp = cont.getCompound(COMP_TEST_KEY); 36 | if (comp == null) { 37 | throw new NbtApiException("Wasn't able to get the NBTCompound!"); 38 | } 39 | if (!comp.hasTag(STRING_TEST_KEY)) { 40 | throw new NbtApiException("Wasn't able to check a compound key!"); 41 | } 42 | if (!(STRING_TEST_VALUE + "2").equals(comp.getString(STRING_TEST_KEY)) 43 | || comp.getInteger(INT_TEST_KEY) != INT_TEST_VALUE * 2 44 | || comp.getDouble(DOUBLE_TEST_KEY) != DOUBLE_TEST_VALUE * 2 45 | || comp.getBoolean(BOOLEAN_TEST_KEY) == BOOLEAN_TEST_VALUE) { 46 | throw new NbtApiException("One key does not equal the original compound value!"); 47 | } 48 | 49 | // Using getOrCreateCompound twice 50 | comp.getOrCreateCompound("someName").setString("test", "abc"); 51 | if (!comp.getOrCreateCompound("someName").getString("test").equals("abc")) { 52 | throw new NbtApiException("getOrCreateCompound did not return the same compound!"); 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/compounds/TypeTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.compounds; 2 | 3 | import de.tr7zw.changeme.nbtapi.NBT; 4 | import de.tr7zw.changeme.nbtapi.NBTType; 5 | import de.tr7zw.changeme.nbtapi.NbtApiException; 6 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 7 | import de.tr7zw.nbtapi.plugin.tests.Test; 8 | 9 | public class TypeTest implements Test { 10 | 11 | @Override 12 | public void test() throws Exception { 13 | ReadWriteNBT comp = NBT.createNBTObject(); 14 | comp.setString("s", "test"); 15 | comp.setInteger("i", 42); 16 | comp.getOrCreateCompound("c"); 17 | if (comp.getType("s") != NBTType.NBTTagString || comp.getType("i") != NBTType.NBTTagInt 18 | || comp.getType("c") != NBTType.NBTTagCompound) 19 | throw new NbtApiException("One parsed type did not match what it should have been!"); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/entities/EntityCustomNbtPersistentTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.entities; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.World; 5 | import org.bukkit.entity.Animals; 6 | import org.bukkit.entity.Entity; 7 | import org.bukkit.entity.Monster; 8 | 9 | import de.tr7zw.changeme.nbtapi.NBT; 10 | import de.tr7zw.changeme.nbtapi.NbtApiException; 11 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 12 | import de.tr7zw.nbtapi.plugin.tests.Test; 13 | 14 | public class EntityCustomNbtPersistentTest implements Test { 15 | 16 | @Override 17 | public void test() throws Exception { 18 | if (MinecraftVersion.getVersion().getVersionId() < MinecraftVersion.MC1_14_R1.getVersionId()) 19 | return; 20 | if (!Bukkit.getWorlds().isEmpty()) { 21 | World world = Bukkit.getWorlds().get(0); 22 | try { 23 | if (!world.getEntitiesByClasses(Animals.class, Monster.class).isEmpty()) { 24 | Entity ent = world.getEntitiesByClasses(Animals.class, Monster.class).iterator().next(); 25 | NBT.modifyPersistentData(ent, comp -> { 26 | comp.setString("Hello", "World"); 27 | }); 28 | 29 | NBT.modifyPersistentData(ent, comp -> { 30 | if (!comp.toString().contains("Hello:\"World\"")) { 31 | throw new NbtApiException("Custom Data did not save to the Entity!"); 32 | } 33 | comp.removeKey("Hello"); 34 | }); 35 | 36 | } 37 | } catch (Exception ex) { 38 | throw new NbtApiException("Wasn't able to use NBTEntities!", ex); 39 | } 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/entities/EntityTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.entities; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.World; 5 | import org.bukkit.entity.Animals; 6 | import org.bukkit.entity.Monster; 7 | 8 | import de.tr7zw.changeme.nbtapi.NBTEntity; 9 | import de.tr7zw.changeme.nbtapi.NbtApiException; 10 | import de.tr7zw.nbtapi.plugin.tests.Test; 11 | 12 | public class EntityTest implements Test { 13 | 14 | @Override 15 | public void test() throws Exception { 16 | if (!Bukkit.getWorlds().isEmpty()) { 17 | World world = Bukkit.getWorlds().get(0); 18 | try { 19 | if (!world.getEntitiesByClasses(Animals.class, Monster.class).isEmpty()) { 20 | NBTEntity nbte = new NBTEntity( 21 | world.getEntitiesByClasses(Animals.class, Monster.class).iterator().next()); 22 | nbte.setString("INVALIDEKEY", "test"); 23 | } 24 | } catch (Exception ex) { 25 | throw new NbtApiException("Wasn't able to use NBTEntities!", ex); 26 | } 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/ComponentsTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.items; 2 | 3 | import org.bukkit.Material; 4 | import org.bukkit.inventory.ItemStack; 5 | import org.bukkit.inventory.meta.ItemMeta; 6 | 7 | import de.tr7zw.changeme.nbtapi.NBT; 8 | import de.tr7zw.changeme.nbtapi.NbtApiException; 9 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 10 | import de.tr7zw.nbtapi.plugin.tests.Test; 11 | 12 | public class ComponentsTest implements Test { 13 | 14 | @Override 15 | public void test() throws Exception { 16 | if(!MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) { 17 | return; 18 | } 19 | ItemStack item = new ItemStack(Material.STICK); 20 | ItemMeta meta = item.getItemMeta(); 21 | meta.setDisplayName("test"); 22 | item.setItemMeta(meta); 23 | String comp = NBT.modifyComponents(item, n -> { 24 | return n.toString(); 25 | }); 26 | if(!comp.contains("test")) { 27 | throw new NbtApiException("ReadComponent didn't work!"); 28 | } 29 | NBT.modifyComponents(item, nbt -> { 30 | if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R4)) { 31 | nbt.mergeCompound(NBT.parseNBT("{\"minecraft:custom_name\":[{\"text\":\"foobar\",\"italic\":false}]}")); 32 | } else { 33 | nbt.setString("minecraft:custom_name", "{\"extra\":[\"foobar\"],\"text\":\"\"}"); 34 | } 35 | }); 36 | if(!item.getItemMeta().getDisplayName().equals("foobar")) { 37 | throw new NbtApiException("ModifyComponent didn't work!"); 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/DirectApplyMetaTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.items; 2 | 3 | import org.bukkit.Material; 4 | import org.bukkit.inventory.ItemStack; 5 | import org.bukkit.inventory.meta.ItemMeta; 6 | 7 | import de.tr7zw.changeme.nbtapi.NBT; 8 | import de.tr7zw.changeme.nbtapi.NBTItem; 9 | import de.tr7zw.changeme.nbtapi.NbtApiException; 10 | import de.tr7zw.changeme.nbtapi.iface.ReadableNBT; 11 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 12 | import de.tr7zw.nbtapi.plugin.tests.Test; 13 | 14 | public class DirectApplyMetaTest implements Test { 15 | 16 | @Override 17 | public void test() throws Exception { 18 | if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) { 19 | return; // skip 20 | } 21 | ItemStack baseItem = new ItemStack(Material.STONE); 22 | NBTItem nbti = new NBTItem(baseItem, true); 23 | nbti.setString("SomeKey", "SomeValue"); 24 | nbti.modifyMeta(this::modifyMeta); 25 | 26 | if (!new NBTItem(baseItem).hasTag("SomeKey") || !"SomeValue".equals(baseItem.getItemMeta().getDisplayName())) { 27 | throw new NbtApiException("The item was not modified correctly! " + NBT.itemStackToNBT(baseItem)); 28 | } 29 | 30 | } 31 | 32 | private void modifyMeta(ReadableNBT nbt, ItemMeta meta) { 33 | meta.setDisplayName(nbt.getString("SomeKey")); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/DirectApplyTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.items; 2 | 3 | import org.bukkit.Material; 4 | import org.bukkit.inventory.ItemStack; 5 | 6 | import de.tr7zw.changeme.nbtapi.NBT; 7 | import de.tr7zw.changeme.nbtapi.NBTItem; 8 | import de.tr7zw.changeme.nbtapi.NbtApiException; 9 | import de.tr7zw.nbtapi.plugin.tests.Test; 10 | 11 | public class DirectApplyTest implements Test { 12 | 13 | @Override 14 | public void test() throws Exception { 15 | ItemStack baseItem = new ItemStack(Material.STONE); 16 | NBTItem nbti = new NBTItem(baseItem, true); 17 | nbti.setString("SomeKey", "SomeValue"); 18 | if (!baseItem.equals(nbti.getItem()) || !new NBTItem(baseItem).hasTag("SomeKey")) { 19 | throw new NbtApiException("The item's where not equal!"); 20 | } 21 | baseItem = new ItemStack(Material.STONE); 22 | String inside = NBT.modify(baseItem, nbt -> { 23 | nbt.setString("SomeKey", "SomeValue"); 24 | return nbt.getString("SomeKey"); 25 | }); 26 | baseItem = NBT.itemStackFromNBT(NBT.itemStackToNBT(baseItem)); // trick to force the item to be "real", not a 27 | // Spigot only item 28 | String outside = NBT.get(baseItem, nbt -> { 29 | return nbt.getString("SomeKey"); 30 | }); 31 | if (!new NBTItem(baseItem).hasTag("SomeKey")) { 32 | throw new NbtApiException("The data was not applied!"); 33 | } 34 | if (!"SomeValue".equals(inside)) { 35 | throw new NbtApiException("Inside returned the wrong value!"); 36 | } 37 | if (!"SomeValue".equals(outside)) { 38 | throw new NbtApiException("Outside returned the wrong value!"); 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/EmptyItemTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.items; 2 | 3 | import org.bukkit.Material; 4 | import org.bukkit.inventory.ItemStack; 5 | 6 | import de.tr7zw.changeme.nbtapi.NBT; 7 | import de.tr7zw.changeme.nbtapi.NBTItem; 8 | import de.tr7zw.changeme.nbtapi.NbtApiException; 9 | import de.tr7zw.nbtapi.plugin.tests.Test; 10 | 11 | public class EmptyItemTest implements Test { 12 | 13 | @Override 14 | public void test() throws Exception { 15 | ItemStack item = new ItemStack(Material.STONE); 16 | NBTItem nbti = new NBTItem(item); 17 | if (nbti.hasNBTData()) { 18 | throw new NbtApiException("Item reported to have data"); 19 | } 20 | if (nbti.getBoolean("test") == null || nbti.getString("test") == null || nbti.getFloatList("test") == null) { 21 | throw new NbtApiException("Getters return null instead of the default value"); 22 | } 23 | if (!nbti.getKeys().isEmpty()) { 24 | throw new NbtApiException("getKeys() returned keys!"); 25 | } 26 | nbti.removeKey("test"); 27 | if (nbti.hasNBTData()) { 28 | throw new NbtApiException("Item reported to have data after remove"); 29 | } 30 | nbti.setString("test", "test"); 31 | if (!nbti.hasNBTData()) { 32 | throw new NbtApiException("Item reported to have no data"); 33 | } 34 | nbti.removeKey("test"); 35 | if (nbti.hasNBTData()) { 36 | throw new NbtApiException("Item reported to have data after deletion"); 37 | } 38 | 39 | try { 40 | Material barrel = Material.valueOf("BARREL"); 41 | item = new ItemStack(barrel); 42 | nbti = new NBTItem(item); 43 | } catch (IllegalArgumentException ex) { 44 | // old version 45 | } 46 | 47 | item = new ItemStack(Material.STONE); 48 | NBT.modify(item, nbt -> { 49 | nbt.setString("test", "test"); 50 | }); 51 | NBT.get(item, nbt -> { 52 | if (!nbt.hasNBTData()) { 53 | throw new NbtApiException("Item reported to have no data"); 54 | } 55 | return nbt.hasNBTData(); 56 | }); 57 | NBT.modify(item, nbt -> { 58 | nbt.removeKey("test"); 59 | }); 60 | NBT.get(item, nbt -> { 61 | if (nbt.hasNBTData()) { 62 | throw new NbtApiException("Item reported to have data after deletion"); 63 | } 64 | return nbt.hasNBTData(); 65 | }); 66 | 67 | ItemStack testItem = new ItemStack(Material.STONE); 68 | NBTItem nbt = new NBTItem(testItem, true); 69 | nbt.removeKey("not there"); 70 | nbt.setBoolean("test", true); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/ItemConversionTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.items; 2 | 3 | import de.tr7zw.changeme.nbtapi.NBT; 4 | import de.tr7zw.changeme.nbtapi.NBTType; 5 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 6 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 7 | import org.bukkit.Material; 8 | import org.bukkit.inventory.ItemStack; 9 | import org.bukkit.inventory.meta.ItemMeta; 10 | 11 | import com.google.common.collect.Lists; 12 | 13 | import de.tr7zw.changeme.nbtapi.NbtApiException; 14 | import de.tr7zw.nbtapi.plugin.tests.Test; 15 | 16 | public class ItemConversionTest implements Test { 17 | 18 | @Override 19 | public void test() throws Exception { 20 | ItemStack item = new ItemStack(Material.STONE, 1); 21 | ItemMeta meta = item.getItemMeta(); 22 | meta.setLore(Lists.newArrayList("Firest Line", "Second Line")); 23 | item.setItemMeta(meta); 24 | 25 | ReadWriteNBT nbt = NBT.itemStackToNBT(item); 26 | if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_12_R1) 27 | && !nbt.hasTag("DataVersion", NBTType.NBTTagInt)) { 28 | throw new NbtApiException("The item nbt '" + nbt + "' didn't contain the data version"); 29 | } 30 | 31 | String nbtString = nbt.toString(); 32 | if (!nbtString.contains("Firest Line") || !nbtString.contains("Second Line")) 33 | throw new NbtApiException("The Item nbt '" + nbtString + "' didn't contain the lore"); 34 | ItemStack rebuild = NBT.itemStackFromNBT(NBT.parseNBT(nbtString)); 35 | if (!item.isSimilar(rebuild)) 36 | throw new NbtApiException("Rebuilt item did not match the original!"); 37 | 38 | ReadWriteNBT cont = NBT.createNBTObject(); 39 | cont.setItemStack("testItem", item); 40 | if (!item.isSimilar(cont.getItemStack("testItem"))) 41 | throw new NbtApiException("Rebuilt item did not match the original!"); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/ItemJsonTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.items; 2 | 3 | import org.bukkit.Material; 4 | import org.bukkit.inventory.ItemStack; 5 | import org.bukkit.inventory.meta.ItemMeta; 6 | 7 | import com.google.gson.JsonElement; 8 | 9 | import de.tr7zw.changeme.nbtapi.NbtApiException; 10 | import de.tr7zw.changeme.nbtapi.utils.NBTJsonUtil; 11 | import de.tr7zw.nbtapi.plugin.tests.Test; 12 | 13 | public class ItemJsonTest implements Test { 14 | 15 | @Override 16 | public void test() throws Exception { 17 | ItemStack item = new ItemStack(Material.STONE); 18 | ItemMeta meta = item.getItemMeta(); 19 | meta.setDisplayName("test"); 20 | meta.setUnbreakable(true); 21 | item.setItemMeta(meta); 22 | JsonElement elem = NBTJsonUtil.itemStackToJson(item); 23 | if (elem == null) { 24 | throw new NbtApiException("Getting the Json didn't work correctly! " + item); 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/ItemMergingTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.items; 2 | 3 | import org.bukkit.Material; 4 | import org.bukkit.inventory.ItemStack; 5 | import org.bukkit.inventory.meta.BookMeta; 6 | 7 | import de.tr7zw.changeme.nbtapi.NBTItem; 8 | import de.tr7zw.changeme.nbtapi.NbtApiException; 9 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 10 | import de.tr7zw.nbtapi.plugin.tests.Test; 11 | 12 | public class ItemMergingTest implements Test { 13 | 14 | @Override 15 | public void test() throws Exception { 16 | if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) { 17 | return; // skip, there is no vanilla nbt 18 | } 19 | ItemStack item = new ItemStack(Material.WRITTEN_BOOK); 20 | BookMeta bookMeta = (BookMeta) item.getItemMeta(); 21 | bookMeta.setAuthor("Author"); 22 | bookMeta.setDisplayName("name"); 23 | item.setItemMeta(bookMeta); 24 | 25 | NBTItem nbti = new NBTItem(item); 26 | nbti.setString("author", "New Author"); 27 | nbti.setString("test", "value"); 28 | 29 | nbti.mergeCustomNBT(item); 30 | if (!new NBTItem(item).hasTag("test")) 31 | throw new NbtApiException("Couldn't merge custom NBT tag!"); 32 | if ("New Author".equals(new NBTItem(item).getString("author"))) 33 | throw new NbtApiException("Vanilla NBT tag was merged when shouldn't!"); 34 | 35 | nbti.setString("test", "New Value"); 36 | nbti.mergeNBT(item); 37 | if (!"New Author".equals(new NBTItem(item).getString("author")) 38 | || !"New Value".equals(new NBTItem(item).getString("test"))) 39 | throw new NbtApiException("Couldn't replace NBT tag while merging!"); 40 | 41 | ItemStack test = new ItemStack(Material.WRITTEN_BOOK); 42 | nbti.applyNBT(test); 43 | if (!item.isSimilar(test)) 44 | throw new NbtApiException("ItemStacks didn't match! " + new NBTItem(item) + " " + new NBTItem(test)); 45 | 46 | test = new ItemStack(Material.STONE); 47 | nbti.applyNBT(test); 48 | if (!nbti.hasTag("test")) 49 | throw new NbtApiException("Couldn't merge custom NBT tag!"); 50 | if (!item.getItemMeta().getDisplayName().equals(test.getItemMeta().getDisplayName())) 51 | throw new NbtApiException("Couldn't merge vanilla NBT tag!"); 52 | 53 | nbti.setBoolean("remove", true); 54 | nbti.clearCustomNBT(); 55 | if (nbti.hasTag("remove")) 56 | throw new NbtApiException("Couldn't clear custom NBT tags!"); 57 | if (!nbti.hasTag("author")) 58 | throw new NbtApiException("Vanilla tag was removed!"); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/ItemStackConversionTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.items; 2 | 3 | import org.bukkit.Material; 4 | import org.bukkit.inventory.ItemStack; 5 | 6 | import de.tr7zw.changeme.nbtapi.NBT; 7 | import de.tr7zw.changeme.nbtapi.NbtApiException; 8 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 9 | import de.tr7zw.nbtapi.plugin.tests.Test; 10 | 11 | public class ItemStackConversionTest implements Test { 12 | 13 | @Override 14 | public void test() throws Exception { 15 | ItemStack[] src = new ItemStack[] { new ItemStack(Material.STONE), new ItemStack(Material.STICK), 16 | new ItemStack(Material.AIR), new ItemStack(Material.STONE) }; 17 | ReadWriteNBT comp = NBT.itemStackArrayToNBT(src); 18 | ItemStack[] recreated = NBT.itemStackArrayFromNBT(comp); 19 | if (recreated == null || src.length != recreated.length) { 20 | throw new NbtApiException("Size did not match!"); 21 | } 22 | for (int i = 0; i < src.length; i++) { 23 | if (!src[i].isSimilar(recreated[i])) { 24 | throw new NbtApiException("Rebuilt item did not match the original!"); 25 | } 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/LegacyItemTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.items; 2 | 3 | import org.bukkit.Material; 4 | import org.bukkit.enchantments.Enchantment; 5 | import org.bukkit.inventory.ItemStack; 6 | 7 | import de.tr7zw.changeme.nbtapi.NBT; 8 | import de.tr7zw.changeme.nbtapi.NbtApiException; 9 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 10 | import de.tr7zw.changeme.nbtapi.utils.DataFixerUtil; 11 | import de.tr7zw.nbtapi.plugin.tests.Test; 12 | 13 | public class LegacyItemTest implements Test { 14 | 15 | @Override 16 | public void test() throws Exception { 17 | ItemStack item = NBT 18 | .itemStackFromNBT(NBT.parseNBT("{id:cobblestone,Count:42,tag:{Enchantments:[{lvl:3,id:unbreaking}]}}")); 19 | if (item.getType() != Material.COBBLESTONE || item.getAmount() != 42 20 | || item.getEnchantmentLevel(Enchantment.DURABILITY) != 3) { 21 | throw new NbtApiException("1.20 item didn't load correctly! " + item); 22 | } 23 | ReadWriteNBT nbt = NBT 24 | .parseNBT("{id:cobblestone,Count:42,tag:{display:{Name:\"test\"},ench:[{lvl:3,id:34}]}}"); 25 | nbt = DataFixerUtil.fixUpItemData(nbt, DataFixerUtil.VERSION1_12_2, DataFixerUtil.getCurrentVersion()); 26 | item = NBT.itemStackFromNBT(nbt); 27 | if (item.getType() != Material.COBBLESTONE || item.getAmount() != 42 28 | || item.getEnchantmentLevel(Enchantment.DURABILITY) != 3 29 | || !"test".equals(item.getItemMeta().getDisplayName())) { 30 | throw new NbtApiException("1.12.2 item didn't load correctly! " + item); 31 | } 32 | 33 | ItemStack item2 = NBT.itemStackFromNBT(NBT.parseNBT("{DataVersion:" + DataFixerUtil.VERSION1_12_2 + ",id:cobblestone,Count:42,tag:{display:{Name:\"test\"},ench:[{lvl:3,id:34}]}}")); 34 | if (!item.equals(item2)) 35 | throw new NbtApiException("Data-fixed 1.12.2 item didn't load correctly! " + item2); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/MetaTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.items; 2 | 3 | import org.bukkit.Material; 4 | import org.bukkit.inventory.ItemFlag; 5 | import org.bukkit.inventory.ItemStack; 6 | 7 | import de.tr7zw.changeme.nbtapi.NBT; 8 | import de.tr7zw.changeme.nbtapi.NbtApiException; 9 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 10 | import de.tr7zw.nbtapi.plugin.tests.Test; 11 | 12 | public class MetaTest implements Test { 13 | 14 | @Override 15 | public void test() throws Exception { 16 | if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) { 17 | return; // skip 18 | } 19 | ItemStack item = new ItemStack(Material.STONE); 20 | NBT.modify(item, nbt -> { 21 | nbt.setInteger("HideFlags", 1); 22 | nbt.modifyMeta((rnbt, meta) -> { 23 | if (!meta.hasItemFlag(ItemFlag.HIDE_ENCHANTS) || rnbt.getInteger("HideFlags") != 1) { 24 | throw new NbtApiException("The meta did not correctly update or read! " + rnbt); 25 | } 26 | }); 27 | }); 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/NBTModifyItemTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.items; 2 | 3 | import org.bukkit.Material; 4 | import org.bukkit.inventory.ItemStack; 5 | 6 | import de.tr7zw.changeme.nbtapi.NBT; 7 | import de.tr7zw.changeme.nbtapi.NBTItem; 8 | import de.tr7zw.changeme.nbtapi.NbtApiException; 9 | import de.tr7zw.nbtapi.plugin.tests.Test; 10 | 11 | public class NBTModifyItemTest implements Test { 12 | 13 | @Override 14 | public void test() throws Exception { 15 | ItemStack baseItem = new ItemStack(Material.STONE); 16 | NBT.modify(baseItem, nbti -> { 17 | nbti.setString("SomeKey", "SomeValue"); 18 | }); 19 | if (baseItem.equals(new ItemStack(Material.STONE)) || !new NBTItem(baseItem).hasTag("SomeKey")) { 20 | throw new NbtApiException("The item's where not equal!"); 21 | } 22 | baseItem = new ItemStack(Material.STONE); 23 | // test using a "real" item 24 | baseItem = NBT.itemStackFromNBT(NBT.itemStackToNBT(baseItem)); 25 | String inside = NBT.modify(baseItem, nbt -> { 26 | nbt.setString("SomeKey", "SomeValue"); 27 | nbt.modifyMeta((r, meta) -> { 28 | meta.setDisplayName("Test"); 29 | }); 30 | nbt.getOrCreateCompound("sub").setInteger("val", 42); 31 | return nbt.getString("SomeKey"); 32 | }); 33 | String outside = NBT.get(baseItem, nbt -> { 34 | return nbt.getString("SomeKey"); 35 | }); 36 | if (baseItem == null) { 37 | throw new NbtApiException("Base item was null!"); 38 | } 39 | if (!new NBTItem(baseItem).hasTag("SomeKey")) { 40 | throw new NbtApiException("The data was not applied!"); 41 | } 42 | if (new NBTItem(baseItem).getOrCreateCompound("sub").getInteger("val") != 42) { 43 | throw new NbtApiException("The sub value was not applied!"); 44 | } 45 | if (!"SomeValue".equals(inside)) { 46 | throw new NbtApiException("Inside returned the wrong value!"); 47 | } 48 | if (!"SomeValue".equals(outside)) { 49 | throw new NbtApiException("Outside returned the wrong value!"); 50 | } 51 | if (!"Test".equals(baseItem.getItemMeta().getDisplayName())) { 52 | throw new NbtApiException("The display name was not applied!"); 53 | } 54 | baseItem = new ItemStack(Material.STONE); 55 | // test using a "fake" item 56 | inside = NBT.modify(baseItem, nbt -> { 57 | nbt.setString("SomeKey", "SomeValue"); 58 | nbt.modifyMeta((r, meta) -> { 59 | meta.setDisplayName("Test"); 60 | }); 61 | nbt.getOrCreateCompound("sub").setInteger("val", 42); 62 | return nbt.getString("SomeKey"); 63 | }); 64 | outside = NBT.get(baseItem, nbt -> (String) nbt.getString("SomeKey")); 65 | if (!new NBTItem(baseItem).hasTag("SomeKey")) { 66 | throw new NbtApiException("The data was not applied!"); 67 | } 68 | if (new NBTItem(baseItem).getOrCreateCompound("sub").getInteger("val") != 42) { 69 | throw new NbtApiException("The sub value was not applied!"); 70 | } 71 | if (!"SomeValue".equals(inside)) { 72 | throw new NbtApiException("Inside returned the wrong value!"); 73 | } 74 | if (!"SomeValue".equals(outside)) { 75 | throw new NbtApiException("Outside returned the wrong value!"); 76 | } 77 | if (!"Test".equals(baseItem.getItemMeta().getDisplayName())) { 78 | throw new NbtApiException("The display name was not applied!"); 79 | } 80 | // other ordering 81 | baseItem = new ItemStack(Material.STONE); 82 | NBT.modify(baseItem, nbti -> { 83 | nbti.setString("a", "SomeValue"); 84 | }); 85 | NBT.modify(baseItem, nbt -> { 86 | nbt.modifyMeta((r, meta) -> { 87 | meta.setDisplayName("Test"); 88 | }); 89 | nbt.setInteger("b", 12); 90 | }); 91 | if (!new NBTItem(baseItem).hasTag("a") || !new NBTItem(baseItem).hasTag("b") 92 | || !"Test".equals(baseItem.getItemMeta().getDisplayName())) { 93 | throw new NbtApiException("The data was not applied: " + new NBTItem(baseItem).toString()); 94 | } 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/items/SmuggleTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.items; 2 | 3 | import java.util.concurrent.atomic.AtomicReference; 4 | 5 | import org.bukkit.Material; 6 | import org.bukkit.inventory.ItemStack; 7 | 8 | import de.tr7zw.changeme.nbtapi.NBT; 9 | import de.tr7zw.changeme.nbtapi.NbtApiException; 10 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBTList; 11 | import de.tr7zw.changeme.nbtapi.iface.ReadableNBTList; 12 | import de.tr7zw.nbtapi.plugin.tests.Test; 13 | 14 | public class SmuggleTest implements Test { 15 | 16 | @Override 17 | public void test() throws Exception { 18 | ItemStack item = new ItemStack(Material.STONE); 19 | Exception error = null; 20 | try { 21 | ReadWriteNBTList list = NBT.modify(item, nbt -> { 22 | nbt.getLongList("test").add(123l); 23 | return nbt.getLongList("test"); 24 | }); 25 | error = new NbtApiException("Managed to smuggle nbt out of the context: " + list); 26 | } catch (Exception e) { 27 | // this is the excpected behavior 28 | } 29 | if (error != null) { 30 | throw error; 31 | } 32 | try { 33 | ReadableNBTList list = NBT.get(item, nbt -> { 34 | return nbt.getLongList("test"); 35 | }); 36 | error = new NbtApiException("Managed to smuggle nbt out of the context: " + list); 37 | } catch (Exception e) { 38 | // this is the excpected behavior 39 | } 40 | if (error != null) { 41 | throw error; 42 | } 43 | AtomicReference> list = new AtomicReference<>(); 44 | try { 45 | NBT.get(item, nbt -> { 46 | list.set(nbt.getLongList("test")); // smuggling the nbt out of the context 47 | return null; 48 | }); 49 | if (list.get().size() == 1) { 50 | error = new NbtApiException("Managed to smuggle nbt out of the context: " + list); 51 | } 52 | error = new NbtApiException("Managed to smuggle nbt out of the context: " + list); 53 | } catch (Exception e) { 54 | // this is the excpected behavior 55 | } 56 | if (error != null) { 57 | throw error; 58 | } 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/proxy/DataItemProxyTest.java: -------------------------------------------------------------------------------- 1 | //package de.tr7zw.nbtapi.plugin.tests.proxy; 2 | // 3 | //import org.bukkit.Material; 4 | //import org.bukkit.inventory.ItemStack; 5 | //import org.bukkit.inventory.meta.ItemMeta; 6 | // 7 | //import de.tr7zw.changeme.nbtapi.NBT; 8 | //import de.tr7zw.changeme.nbtapi.NBTItem; 9 | //import de.tr7zw.changeme.nbtapi.NbtApiException; 10 | //import de.tr7zw.changeme.nbtapi.data.proxy.NBTItemMeta; 11 | //import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 12 | //import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 13 | //import de.tr7zw.nbtapi.plugin.tests.Test; 14 | // 15 | //public class DataItemProxyTest implements Test { 16 | // 17 | // @Override 18 | // public void test() throws Exception { 19 | // if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) { 20 | // return; // skip 21 | // } 22 | // ItemStack item = new ItemStack(Material.STONE); 23 | // ItemMeta meta = item.getItemMeta(); 24 | // meta.setDisplayName("Test"); 25 | // item.setItemMeta(meta); 26 | // NBT.modify(item, NBTItemMeta.class, nmeta -> { 27 | // nmeta.setCustomModelData(123); 28 | // nmeta.setUnbreakable(true); 29 | // if (!nmeta.getDisplayData().getRawName().contains("Test")) { 30 | // throw new NbtApiException("Raw name didn't containg the expected String: " + nmeta); 31 | // } 32 | // ReadWriteNBT container = NBT.createNBTObject(); 33 | // container.setString("foo", "bar"); 34 | // nmeta.setBlockStateTag(container); 35 | // if (!container.equals(nmeta.getBlockStateTag())) { 36 | // throw new NbtApiException("BlockStateTag did not match! " + nmeta); 37 | // } 38 | // }); 39 | // 40 | // if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_16_R1)) { 41 | // meta = item.getItemMeta(); 42 | // if (!meta.hasCustomModelData() || meta.getCustomModelData() != 123) { 43 | // throw new NbtApiException("Custom Model Data did not match! " + new NBTItem(item)); 44 | // } 45 | // if (!meta.isUnbreakable()) { 46 | // throw new NbtApiException("Unbreakable did not set!"); 47 | // } 48 | // } 49 | // } 50 | // 51 | //} 52 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/proxy/SimpleProxyTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.proxy; 2 | 3 | import org.bukkit.Material; 4 | import org.bukkit.inventory.ItemStack; 5 | 6 | import de.tr7zw.changeme.nbtapi.NBT; 7 | import de.tr7zw.changeme.nbtapi.NBTItem; 8 | import de.tr7zw.changeme.nbtapi.NbtApiException; 9 | import de.tr7zw.changeme.nbtapi.handler.NBTHandlers; 10 | import de.tr7zw.changeme.nbtapi.wrapper.NBTProxy; 11 | import de.tr7zw.changeme.nbtapi.wrapper.NBTTarget; 12 | import de.tr7zw.changeme.nbtapi.wrapper.ProxyList; 13 | import de.tr7zw.changeme.nbtapi.wrapper.NBTTarget.Type; 14 | import de.tr7zw.nbtapi.plugin.tests.Test; 15 | 16 | public class SimpleProxyTest implements Test { 17 | 18 | @Override 19 | public void test() throws Exception { 20 | ItemStack item = new ItemStack(Material.STONE); 21 | NBT.modify(item, TestInterface.class, ti -> { 22 | if (ti.hasKills()) { 23 | throw new NbtApiException("Item reported to have kills before setting data!"); 24 | } 25 | ti.setKills(42); 26 | ti.addKill(); 27 | if (!ti.hasKills()) { 28 | throw new NbtApiException("Item reported to not have kills after setting data!"); 29 | } 30 | if (!"{Kills:43}".equals(ti.toString())) { 31 | throw new NbtApiException("ToString returned the wrong string. " + ti.toString()); 32 | } 33 | }); 34 | if (new NBTItem(item).getInteger("Kills") != 43) { 35 | throw new NbtApiException("The item was not modified correctly by the proxy!"); 36 | } 37 | NBT.modify(item, TestInterface.class, ti -> { 38 | if (ti.theKillsWithADifferentMethodNameAndNoGet() != 43) { 39 | throw new NbtApiException("The annotation didn't work correctly!"); 40 | } 41 | Statistic jumps = ti.getJumps(); 42 | jumps.setPoints(9000); 43 | jumps.addPoint(); 44 | if (ti.getJumps().getPoints() != 9001) { 45 | throw new NbtApiException("The stacked proxy didn't work correctly!"); 46 | } 47 | ItemStack stack = new ItemStack(Material.STONE, 42); 48 | ti.setItem(stack); 49 | if (!stack.equals(ti.getItem())) { 50 | throw new NbtApiException("The handler in the proxy didn't work correctly!"); 51 | } 52 | }); 53 | NBT.modify(item, TestInterface.class, ti -> { 54 | Statistic a = ti.getStatistics().addCompound(); 55 | a.setPoints(1); 56 | a.addPoint(); 57 | a.addPoint(); 58 | ti.getStatistics().addCompound(); 59 | if (ti.getStatistics().size() != 2) { 60 | throw new NbtApiException("List size not as expected!"); 61 | } 62 | ti.getStatistics().remove(1); 63 | if (ti.getStatistics().size() != 1) { 64 | throw new NbtApiException("List size not as expected!"); 65 | } 66 | if (ti.getStatistics().iterator().next().getPoints() != 3) { 67 | throw new NbtApiException("Points not as expected!"); 68 | } 69 | }); 70 | } 71 | 72 | public interface TestInterface extends NBTProxy { 73 | 74 | @Override 75 | default void init() { 76 | registerHandler(ItemStack.class, NBTHandlers.ITEM_STACK); 77 | } 78 | 79 | public boolean hasKills(); 80 | 81 | public void setKills(int amount); 82 | 83 | public int getKills(); 84 | 85 | public default void addKill() { 86 | setKills(getKills() + 1); 87 | } 88 | 89 | @NBTTarget(value = "Kills", type = Type.GET) 90 | public int theKillsWithADifferentMethodNameAndNoGet(); 91 | 92 | public Statistic getJumps(); 93 | 94 | public ItemStack getItem(); 95 | 96 | public void setItem(ItemStack item); 97 | 98 | public ProxyList getStatistics(); 99 | 100 | } 101 | 102 | public interface Statistic extends NBTProxy { 103 | public void setPoints(int amount); 104 | 105 | public int getPoints(); 106 | 107 | public default void addPoint() { 108 | setPoints(getPoints() + 1); 109 | } 110 | 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/tiles/TileTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.tiles; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.Material; 5 | import org.bukkit.World; 6 | import org.bukkit.block.Block; 7 | 8 | import de.tr7zw.changeme.nbtapi.NBT; 9 | import de.tr7zw.changeme.nbtapi.NBTTileEntity; 10 | import de.tr7zw.changeme.nbtapi.NbtApiException; 11 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 12 | import de.tr7zw.nbtapi.plugin.tests.Test; 13 | 14 | public class TileTest implements Test { 15 | 16 | @Override 17 | public void test() throws Exception { 18 | if (MinecraftVersion.isFoliaPresent()) { 19 | return; 20 | } 21 | if (!Bukkit.getWorlds().isEmpty()) { 22 | World world = Bukkit.getWorlds().get(0); 23 | try { 24 | Block block = world.getBlockAt(world.getSpawnLocation().getBlockX(), 254, 25 | world.getSpawnLocation().getBlockZ()); 26 | if (world.isChunkLoaded(block.getX() >> 4, block.getZ() >> 4) && block.getType() == Material.AIR) { 27 | block.setType(Material.CHEST); 28 | if (MinecraftVersion.isNewerThan(MinecraftVersion.MC1_21_R1)) { 29 | // 1.21 changed the lock logic. So just try to get/set data, dont check for now 30 | NBT.modify(block.getState(), nbt -> { 31 | nbt.setString("foo", "bar"); 32 | }); 33 | block.setType(Material.AIR); 34 | return; 35 | } 36 | NBTTileEntity tile = new NBTTileEntity(block.getState()); 37 | if (!MinecraftVersion.isNewerThan(MinecraftVersion.MC1_17_R1)) { 38 | if (tile.getInteger("y") != 254) { 39 | block.setType(Material.AIR); 40 | throw new NbtApiException("The Tile Y pos wasn't correct!"); 41 | } 42 | } 43 | tile.setString("Lock", "test"); 44 | if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_8_R3) && !tile.hasTag("Lock") 45 | && !"test".equals(tile.getString("test"))) { 46 | block.setType(Material.AIR); 47 | throw new NbtApiException("The Lock wasn't successfully set."); 48 | } 49 | block.setType(Material.AIR); 50 | } 51 | } catch (Exception ex) { 52 | throw new NbtApiException("Wasn't able to use NBTTiles!", ex); 53 | } 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/java/de/tr7zw/nbtapi/plugin/tests/tiles/TilesCustomNBTPersistentTest.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtapi.plugin.tests.tiles; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.Material; 5 | import org.bukkit.World; 6 | import org.bukkit.block.Block; 7 | 8 | import de.tr7zw.changeme.nbtapi.NBT; 9 | import de.tr7zw.changeme.nbtapi.NbtApiException; 10 | import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; 11 | import de.tr7zw.nbtapi.plugin.tests.Test; 12 | 13 | public class TilesCustomNBTPersistentTest implements Test { 14 | 15 | @Override 16 | public void test() throws Exception { 17 | if (MinecraftVersion.getVersion().getVersionId() < MinecraftVersion.MC1_14_R1.getVersionId()) 18 | return; 19 | if (MinecraftVersion.isFoliaPresent()) { 20 | return; 21 | } 22 | if (!Bukkit.getWorlds().isEmpty()) { 23 | World world = Bukkit.getWorlds().get(0); 24 | try { 25 | Block block = world.getBlockAt(world.getSpawnLocation().getBlockX(), 250, 26 | world.getSpawnLocation().getBlockZ()); 27 | if (world.isChunkLoaded(block.getX() >> 4, block.getZ() >> 4) && block.getType() == Material.AIR) { 28 | block.setType(Material.CHEST); 29 | NBT.modifyPersistentData(block.getState(), persistentData -> { 30 | persistentData.setString("Foo", "Bar"); 31 | }); 32 | NBT.getPersistentData(block.getState(), persistentData -> { 33 | if (!persistentData.getString("Foo").equals("Bar")) { 34 | block.setType(Material.AIR); 35 | throw new NbtApiException("Custom Data did not save to the Tile!"); 36 | } 37 | return null; 38 | }); 39 | block.setType(Material.AIR); 40 | } 41 | } catch (Exception ex) { 42 | throw new NbtApiException("Wasn't able to use NBTTiles!", ex); 43 | } 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/resources/META-INF/.mojang-mapped: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tr7zw/Item-NBT-API/35f541d3db100e9db5bff03c7abb9b4db9f8c152/item-nbt-plugin/src/main/resources/META-INF/.mojang-mapped -------------------------------------------------------------------------------- /item-nbt-plugin/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | main: de.tr7zw.nbtapi.plugin.NBTAPI 2 | name: NBTAPI 3 | version: ${project.version} 4 | author: tr7zw 5 | loadbefore: [ItemNBTAPI] 6 | api-version: 1.13 7 | folia-supported: true -------------------------------------------------------------------------------- /mappings-parser/.gitignore: -------------------------------------------------------------------------------- 1 | *.txt -------------------------------------------------------------------------------- /mappings-parser/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | de.tr7zw 6 | item-nbt-parent 7 | 2.15.0 8 | 9 | mappings-parser 10 | jar 11 | 12 | 13 | de.tr7zw 14 | item-nbt-api 15 | 2.15.0 16 | compile 17 | 18 | 19 | 20 | clean 21 | 22 | 23 | -------------------------------------------------------------------------------- /mappings-parser/src/main/java/dev/tr7zw/mappingsparser/MappingsParser.java: -------------------------------------------------------------------------------- 1 | package dev.tr7zw.mappingsparser; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.nio.file.Files; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.Map.Entry; 10 | 11 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper; 12 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.MojangToMapping; 13 | import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod; 14 | 15 | /** 16 | * Internal class to be used to port SpecialSource mapping txt files to nbt-api 17 | * internal mappings 18 | * 19 | * @author tr7zw 20 | * 21 | */ 22 | public class MappingsParser { 23 | 24 | public static StringBuilder builder = new StringBuilder(); 25 | 26 | public static void main(String[] args) throws IOException { 27 | File input = new File("minecraft_server.1.21.4.txt"); 28 | List lines = Files.readAllLines(input.toPath()); 29 | 30 | Map classes = new HashMap<>(); 31 | for (ClassWrapper wrapper : ClassWrapper.values()) { 32 | if (wrapper.getMojangName() != null) { 33 | classes.put(wrapper.getMojangName(), wrapper); 34 | } 35 | } 36 | 37 | String currentClass = null; 38 | String mojangName = null; 39 | String unmappedName = null; 40 | ClassWrapper nmsWrapper = null; 41 | Map mappedNames = null; 42 | for (String line : lines) { 43 | if (line.startsWith("#")) { 44 | continue; 45 | } 46 | if (!line.startsWith(" ")) { 47 | if (nmsWrapper != null && mappedNames != null) { 48 | proccessMapping(nmsWrapper, mappedNames); 49 | } 50 | currentClass = line.split(" ")[0]; 51 | nmsWrapper = classes.get(currentClass); 52 | mappedNames = new HashMap<>(); 53 | for (ReflectionMethod method : ReflectionMethod.values()) { 54 | if (method.getParentClassWrapper() == nmsWrapper && method.isCompatible()) { 55 | mappedNames.put(method, null); 56 | } 57 | } 58 | continue; 59 | } 60 | if (nmsWrapper == null) 61 | continue; 62 | mojangName = line.trim().split(" ")[1]; 63 | unmappedName = line.trim().split(" ")[3]; 64 | classes.remove(currentClass); 65 | if (mappedNames != null) { 66 | for (ReflectionMethod method : mappedNames.keySet()) { 67 | if (method.getSelectedVersionInfo() == null) 68 | continue; 69 | if (!mojangName.contains("(")) 70 | continue; 71 | if (mojangName.equals(method.getSelectedVersionInfo().name)) { 72 | mappedNames.put(method, unmappedName); 73 | } 74 | } 75 | } 76 | // System.out.println(currentClass + ": " + mojangName + " -> " + unmappedName); 77 | } 78 | System.out.println(builder); 79 | } 80 | 81 | public static void proccessMapping(ClassWrapper nmsWrapper, Map mappedNames) { 82 | for (Entry entry : mappedNames.entrySet()) { 83 | if (entry.getValue() == null) { 84 | System.out.println( 85 | "Missing mapping in class " + nmsWrapper.getMojangName() + " method " + entry.getKey().name()); 86 | } else { 87 | if(!entry.getValue().equals(MojangToMapping.getMapping().get(nmsWrapper.getMojangName() + "#" 88 | + entry.getKey().getSelectedVersionInfo().name))) 89 | builder.append("put(\"" + nmsWrapper.getMojangName() + "#" 90 | + entry.getKey().getSelectedVersionInfo().name + "\", \"" + entry.getValue() + "\");\n"); 91 | } 92 | } 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /nbt-data-api/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 - 2021, tr7zw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /nbt-data-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | de.tr7zw 7 | item-nbt-parent 8 | 2.15.0 9 | 10 | 11 | nbt-data-api 12 | jar 13 | 14 | 15 | de.tr7zw 16 | item-nbt-api 17 | 2.15.0 18 | compile 19 | 20 | 21 | 22 | 23 | clean install javadoc:javadoc 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /nbt-data-api/src/main/java/de/tr7zw/changeme/nbtapi/data/NBTData.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.data; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.util.UUID; 6 | 7 | import org.bukkit.Bukkit; 8 | import org.bukkit.World; 9 | import org.bukkit.plugin.Plugin; 10 | 11 | import de.tr7zw.changeme.nbtapi.NBTFile; 12 | import de.tr7zw.changeme.nbtapi.NbtApiException; 13 | 14 | public class NBTData { 15 | 16 | public static WorldData getWorldData(World world) { 17 | try { 18 | return new WorldData(world.getWorldFolder()); 19 | } catch (IOException e) { 20 | throw new NbtApiException("Error loading World Data!", e); 21 | } 22 | } 23 | 24 | public static WorldData getWorldData(File worldFolder) { 25 | try { 26 | return new WorldData(worldFolder); 27 | } catch (IOException e) { 28 | throw new NbtApiException("Error loading World Data!", e); 29 | } 30 | } 31 | 32 | public static PlayerData getOfflinePlayerData(UUID uuid) { 33 | for (World world : Bukkit.getWorlds()) { 34 | File dataFolder = new File(world.getWorldFolder(), "playerdata"); 35 | File playerFile = new File(dataFolder, uuid.toString() + ".dat"); 36 | if (playerFile.exists()) { 37 | try { 38 | return new PlayerData(playerFile); 39 | } catch (IOException e) { 40 | throw new NbtApiException("Error loading player data!", e); 41 | } 42 | } 43 | } 44 | return null; 45 | } 46 | 47 | public static NBTFile getPluginPlayerData(Plugin plugin, UUID uuid) { 48 | try { 49 | File dataFolder = new File(plugin.getDataFolder(), "nbt-playerdata"); 50 | dataFolder.mkdirs(); 51 | return new NBTFile(new File(dataFolder, uuid.toString() + ".dat")); 52 | } catch (IOException e) { 53 | throw new NbtApiException("Error getting Player Plugin data!", e); 54 | } 55 | } 56 | 57 | public static NBTFile getPluginData(Plugin plugin) { 58 | try { 59 | plugin.getDataFolder().mkdirs(); 60 | return new NBTFile(new File(plugin.getDataFolder(), "settings.dat")); 61 | } catch (IOException e) { 62 | throw new NbtApiException("Error getting Plugin data!", e); 63 | } 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /nbt-data-api/src/main/java/de/tr7zw/changeme/nbtapi/data/PlayerData.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.data; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import de.tr7zw.changeme.nbtapi.NBTCompound; 7 | import de.tr7zw.changeme.nbtapi.NBTFile; 8 | import de.tr7zw.changeme.nbtapi.NbtApiException; 9 | 10 | public class PlayerData { 11 | 12 | private final NBTFile file; 13 | 14 | protected PlayerData(File playerFile) throws IOException { 15 | file = new NBTFile(playerFile); 16 | } 17 | 18 | public NBTFile getFile() { 19 | return file; 20 | } 21 | 22 | public NBTCompound getCompound() { 23 | return file; 24 | } 25 | 26 | public void saveChanges() { 27 | try { 28 | file.save(); 29 | } catch (IOException e) { 30 | throw new NbtApiException("Error when saving level data!", e); 31 | } 32 | } 33 | 34 | public float getHealth() { 35 | return file.getFloat("Health"); 36 | } 37 | 38 | public void setHealth(float health) { 39 | file.setFloat("Health", health); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /nbt-data-api/src/main/java/de/tr7zw/changeme/nbtapi/data/WorldData.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.data; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.io.IOException; 6 | 7 | import org.bukkit.util.Vector; 8 | 9 | import de.tr7zw.changeme.nbtapi.NBTCompound; 10 | import de.tr7zw.changeme.nbtapi.NBTFile; 11 | import de.tr7zw.changeme.nbtapi.NbtApiException; 12 | 13 | public class WorldData { 14 | 15 | private final NBTFile file; 16 | 17 | protected WorldData(File worldFolder) throws IOException { 18 | if (!new File(worldFolder, "level.dat").exists()) 19 | throw new FileNotFoundException("Level.dat at: " + new File(worldFolder, "level.dat").getAbsolutePath()); 20 | file = new NBTFile(new File(worldFolder, "level.dat")); 21 | } 22 | 23 | public NBTFile getFile() { 24 | return file; 25 | } 26 | 27 | public NBTCompound getCompound() { 28 | return file; 29 | } 30 | 31 | public void saveChanges() { 32 | try { 33 | file.save(); 34 | } catch (IOException e) { 35 | throw new NbtApiException("Error when saving level data!", e); 36 | } 37 | } 38 | 39 | public String getWorldName() { 40 | return file.resolveOrNull("Data.LevelName", String.class); 41 | } 42 | 43 | public void setWorldName(String name) { 44 | file.getOrCreateCompound("Data").setString("LevelName", name); 45 | } 46 | 47 | public Vector getSpawnPosition() { 48 | NBTCompound data = file.getCompound("Data"); 49 | if (data == null) { 50 | return null; 51 | } 52 | return new Vector(data.getInteger("SpawnX"), data.getInteger("SpawnY"), data.getInteger("SpawnZ")); 53 | } 54 | 55 | public void setSpawnPosition(Vector vec) { 56 | NBTCompound data = file.getOrCreateCompound("Data"); 57 | data.setInteger("SpawnX", vec.getBlockX()); 58 | data.setInteger("SpawnY", vec.getBlockY()); 59 | data.setInteger("SpawnZ", vec.getBlockZ()); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /nbt-data-api/src/main/java/de/tr7zw/changeme/nbtapi/data/proxy/NBTItemMeta.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.changeme.nbtapi.data.proxy; 2 | 3 | import de.tr7zw.changeme.nbtapi.handler.NBTHandlers; 4 | import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; 5 | import de.tr7zw.changeme.nbtapi.iface.ReadableNBT; 6 | import de.tr7zw.changeme.nbtapi.wrapper.NBTProxy; 7 | import de.tr7zw.changeme.nbtapi.wrapper.NBTTarget; 8 | import de.tr7zw.changeme.nbtapi.wrapper.NBTTarget.Type; 9 | 10 | public interface NBTItemMeta extends NBTProxy { 11 | 12 | @Override 13 | default void init() { 14 | registerHandler(ReadableNBT.class, NBTHandlers.STORE_READABLE_TAG); 15 | registerHandler(ReadWriteNBT.class, NBTHandlers.STORE_READWRITE_TAG); 16 | } 17 | 18 | public int getCustomModelData(); 19 | 20 | public void setCustomModelData(int customModelData); 21 | 22 | @NBTTarget(type = Type.GET, value = "Unbreakable") 23 | public boolean isUnbreakable(); 24 | 25 | public void setUnbreakable(boolean unbreakable); 26 | 27 | public ReadWriteNBT getBlockStateTag(); 28 | 29 | public void setBlockStateTag(ReadableNBT blockState); 30 | 31 | @NBTTarget(value = "display") 32 | public DisplayData getDisplayData(); 33 | 34 | public interface DisplayData extends NBTProxy { 35 | 36 | @NBTTarget(value = "Name") 37 | public void setRawName(String rawName); 38 | 39 | @NBTTarget(value = "Name") 40 | public String getRawName(); 41 | 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /nbt-injector/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 - 2021, tr7zw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /nbt-injector/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | de.tr7zw 6 | item-nbt-parent 7 | 2.15.0 8 | 9 | nbt-injector 10 | jar 11 | 12 | 13 | de.tr7zw 14 | item-nbt-api 15 | 2.15.0 16 | compile 17 | 18 | 19 | org.javassist 20 | javassist 21 | 3.29.2-GA 22 | compile 23 | 24 | 25 | 26 | clean install javadoc:javadoc 27 | 28 | 29 | -------------------------------------------------------------------------------- /nbt-injector/src/main/java/de/tr7zw/nbtinjector/INBTWrapper.java: -------------------------------------------------------------------------------- 1 | package de.tr7zw.nbtinjector; 2 | 3 | import de.tr7zw.changeme.nbtapi.NBTCompound; 4 | 5 | /** 6 | * This interface gets placed on Tiles and Entities 7 | * 8 | * @author tr7zw 9 | * 10 | */ 11 | public interface INBTWrapper { 12 | 13 | /** 14 | * @return The custom NBT compound inside this Object 15 | */ 16 | NBTCompound getNbtData(); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /wiki/Example-Usages.md: -------------------------------------------------------------------------------- 1 | ## Set a skull's skin 2 | 3 | #### We will be using [this head](https://minecraft-heads.com/custom-heads/head/28194-cup-of-soda) as example. 4 | 5 | ```java 6 | // This is the base64 texture value from the bottom of the previously mentioned website. 7 | final String textureValue = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTQyY2M5MjAzYzkwYjg5YmRhYzFkZjI4NDE2NzI2NmI5NTNkZmViZjNjNDY5MGE3Y2QwYjE1NzkxYTYyZTU4MiJ9fX0="; 8 | 9 | 10 | // Creating ItemStack 11 | 12 | // For Minecraft 1.12.2 and below 13 | final ItemStack item = new ItemStack(Material.SKULL_ITEM); 14 | item.setDurability((short) 3); 15 | 16 | // For Minecraft 1.13 and newer 17 | final ItemStack item = new ItemStack(Material.PLAYER_HEAD); 18 | 19 | 20 | // Applying nbt 21 | 22 | // For Minecraft 1.20.4 and below 23 | NBT.modify(item, nbt -> { 24 | ReadWriteNBT skullOwnerCompound = nbt.getOrCreateCompound("SkullOwner"); 25 | 26 | // The owner UUID. Note that skulls with the same UUID but different textures will misbehave and only one texture will load. 27 | // They will share the texture. To avoid this limitation, it is recommended to use a random UUID. 28 | skullOwnerCompound.setUUID("Id", UUID.randomUUID()); 29 | 30 | skullOwnerCompound.getOrCreateCompound("Properties") 31 | .getCompoundList("textures") 32 | .addCompound() 33 | .setString("Value", textureValue); 34 | }); 35 | 36 | // Workaround for Minecraft 1.20.5+ 37 | NBT.modifyComponents(item, nbt -> { 38 | ReadWriteNBT profileNbt = nbt.getOrCreateCompound("minecraft:profile"); 39 | profileNbt.setUUID("id", uuid); 40 | ReadWriteNBT propertiesNbt = profileNbt.getCompoundList("properties").addCompound(); 41 | propertiesNbt.setString("name", "textures"); 42 | propertiesNbt.setString("value", textureValue); 43 | }); 44 | ``` 45 | 46 | > [!TIP] 47 | > If you are using Paper API on 1.12.2+, you may use the following code to create textured skulls 48 | 49 | ```java 50 | SkullMeta meta = (SkullMeta) item.getItemMeta(); 51 | PlayerProfile playerProfile = Bukkit.createProfile(uuid); 52 | playerProfile.setProperty(new ProfileProperty("textures", textureValue)); 53 | meta.setPlayerProfile(playerProfile); 54 | // You can also use item.editMeta(SkullMeta.class, meta -> {}); on 1.17+ 55 | item.setItemMeta(meta); 56 | ``` 57 | 58 | ## Zombie that can pick up loot and does 0.5 hearts of damage 59 | 60 | This code should serve only as a reference, the nbt structure might change between versions. 61 | 62 | ```java 63 | Zombie zombie = location.getWorld().spawn(location, Zombie.class); 64 | 65 | String attributeName = "minecraft:generic.attack_damage"; // Or generic.attackDamage prior to 1.16 66 | double damageValue = 0.5; 67 | 68 | // Modify vanilla data 69 | NBT.modify(zombie, nbt -> { 70 | nbt.setBoolean("CanPickUpLoot", true); 71 | 72 | ReadWriteNBTCompoundList list = nbt.getCompoundList("Attributes"); 73 | 74 | // Check if zombie already has attribute set. If so, modify it 75 | for (ReadWriteNBT listEntryNbt : list) { 76 | if (!listEntryNbt.getString("Name").equals(attributeName)) continue; 77 | 78 | listEntryNbt.setDouble("Base", damageValue); 79 | 80 | return; 81 | } 82 | 83 | // Attribute is missing, add it instead 84 | ReadWriteNBT listEntryNbt = list.addCompound(); 85 | listEntryNbt.setString("Name", attributeName); 86 | listEntryNbt.setDouble("Base", damageValue); 87 | }); 88 | 89 | // Modify custom data 90 | NBT.modifyPersistentData(zombie, nbt -> { 91 | // Let's mark our zombie as a custom one 92 | nbt.setBoolean("custom_zombie", true); 93 | }); 94 | ``` 95 | 96 | ## Reading world data 97 | 98 | ```java 99 | // Get main world's folder 100 | File worldDataFolder = Bukkit.getWorlds().getFirst().getWorldFolder(); 101 | 102 | // Read level data 103 | NBTFileHandle levelNbtFile = NBT.getFileHandle(new File(worldDataFolder, "level.dat")); 104 | 105 | // Obtain world name 106 | String worldName = levelNbtFile.resolveOrNull("Data.LevelName", String.class); 107 | 108 | // Read some player's data 109 | UUID playerUuid; 110 | File playerFile = new File(worldDataFolder, "playerdata/" + playerUuid + ".dat"); 111 | if (!playerFile.exists()) { 112 | // No offline player data for provided uuid 113 | return; 114 | } 115 | 116 | NBTFileHandle playerNbtFile = NBT.getFileHandle(playerFile); 117 | 118 | // Change player's health 119 | float health = playerNbtFile.getFloat("Health"); 120 | playerNbtFile.setFloat("Health", health + 5); 121 | 122 | // Once finished, save the file 123 | playerNbtFile.save(); 124 | ``` 125 | 126 | -------------------------------------------------------------------------------- /wiki/FAQ.md: -------------------------------------------------------------------------------- 1 | ## Frequently Asked Questions 2 | 3 | ### I've updated NBT-API, but it keeps saying that it's outdated 4 | 5 | Some other plugin on your server has a shaded version of NBT-API. Try looking at the logs to find out which plugin is it, or add/remove your plugins until you find a culprit. 6 | 7 | ### I've installed NBT-API, but the plugin keeps asking for ItemNBTAPI 8 | 9 | The plugin uses a very outdated version of NBT-API. In this case, download the version 1.8.3 from the versions tab. The outdated "ItemNBTAPI" and "NBTAPI" can be used both at the same time. 10 | 11 | ### 1.7 support 12 | 13 | - Use 1.7.10. 14 | - NBTLists may not work. 15 | - NBTTypes don't work as 1.7.x is missing this feature. 16 | - TLDR: 1.7.10 is a bit broken and not everything will work! Also, it's not supported anymore! 17 | 18 | ### Where did NBTInjector go? 19 | 20 | The experimental NBTInjector became unsupported since Minecraft 1.14 and was removed in 2.13.0 with Minecraft 1.21 release. 21 | 22 | NBTInjector is incompatible with reloads and may break things, and thus is not recommended. 23 | 24 | See [this wiki section](https://github.com/tr7zw/Item-NBT-API/wiki/Using-the-NBT-API#accessing-custom-data) on how to handle custom entity nbt data without NBTInjector. 25 | -------------------------------------------------------------------------------- /wiki/Home.md: -------------------------------------------------------------------------------- 1 | # Welcome to the NBT-API wiki 2 | 3 | NBT-API supports Spigot and Paper versions starting at 1.8. It runs on 1.7.10 too, but some features might not work (see [1.7 support](https://github.com/tr7zw/Item-NBT-API/wiki/FAQ#17-support)). 4 | 5 | Feel free to seek for support in [![Discord](https://img.shields.io/discord/342814924310970398?color=%237289DA&label=Discord&logo=discord&logoColor=white)](https://discordapp.com/invite/yk4caxM). 6 | 7 | ### What do I have to do as a server owner? 8 | 9 | Just download the jar and drop it in the plugins folder. Done! 10 | 11 | You might also want to check out some [plugins that use NBT-API](https://github.com/tr7zw/Item-NBT-API/wiki/Plugins). 12 | 13 | ### How can I use the API as a developer? 14 | 15 | Import the API using [Maven](https://github.com/tr7zw/Item-NBT-API/wiki/Using-Maven) or [Gradle](https://github.com/tr7zw/Item-NBT-API/wiki/Using-Gradle), then see the [basic usage](https://github.com/tr7zw/Item-NBT-API/wiki/Using-the-NBT-API) or code examples like [working with Skulls](https://github.com/tr7zw/Item-NBT-API/wiki/Example-Usages#set-a-skulls-skin) to familiarize yourself with the API. 16 | 17 | Full Javadoc can be found [here](https://tr7zw.github.io/Item-NBT-API/v2-api/)! 18 | -------------------------------------------------------------------------------- /wiki/Plugins.md: -------------------------------------------------------------------------------- 1 | ## List of some plugins on GitHub that utilize NBT-API 2 | 3 | - [IllegalStack](https://github.com/dniym/IllegalStack) 4 | - [Prison](https://github.com/PrisonTeam/Prison) 5 | - [CommandAPI](https://github.com/CommandAPI/CommandAPI) 6 | - [SkBee](https://github.com/ShaneBeee/SkBee/) 7 | - [Monumenta](https://github.com/TeamMonumenta/monumenta-plugins-public/) 8 | - [SummonFriendlyMobs](https://github.com/ArmyFury/SummonFriendlyMobs) 9 | - [EvenMoreFish](https://github.com/Oheers/EvenMoreFish) 10 | 11 | ___ 12 | 13 | Want your plugin added to this list? Submit a PR editing this file located in `~/wiki/Plugins.md`! 14 | -------------------------------------------------------------------------------- /wiki/Using-Gradle.md: -------------------------------------------------------------------------------- 1 | To start using NB-API, you either need to depend on its plugin version, or shade (include) it inside your plugin. 2 | 3 | > [!IMPORTANT] 4 | > Plugin and shaded versions have different ``artifactId``. Make sure to correctly choose the one you need! 5 | 6 | > [!IMPORTANT] 7 | > Alternative ways of loading the api like Libby are not supported on Discord/Github issues. 8 | 9 | # Option 1) NBT-API as a dependency (recommended) 10 | 11 | Add the following entries to your Gradle build at the correct locations: 12 | 13 | ```groovy 14 | repositories { 15 | ... 16 | maven { 17 | name = "CodeMC" 18 | url = uri("https://repo.codemc.io/repository/maven-public/") 19 | } 20 | ... 21 | } 22 | ``` 23 | 24 | ```groovy 25 | compileOnly("de.tr7zw:item-nbt-api-plugin:VERSION") 26 | ``` 27 | 28 | (Get the current ``VERSION`` from [here](https://modrinth.com/plugin/nbtapi/versions)) 29 | 30 | Add the API as dependency to your ``plugin.yml``: 31 | 32 | ```yml 33 | depend: [NBTAPI] 34 | ``` 35 | 36 | Or, if you are using ``paper-plugin.yml``: 37 | 38 | ```yml 39 | dependencies: 40 | server: 41 | NBTAPI: 42 | load: BEFORE 43 | required: true 44 | join-classpath: true 45 | ``` 46 | 47 | # Option 2) Shading the NBT-API into your plugin (Not recommended) 48 | 49 | > [!WARNING] 50 | > Due to the increasing amount of pitfalls in modern Paper, shading is not recommended. Please test with the normal plugin dependency before reporting issues. 51 | 52 | To include NBT-API directly in your plugin, you can use the [Gradle Shadow Plugin](https://gradleup.com/shadow/). 53 | 54 | Create an empty ``.mojang-mapped`` file in the META-INF folder of your plugin for 1.20+ Paper support. 55 | 56 | > [!WARNING] 57 | > Not adding this flag will make the shaded api not work on the latest Paper. It might also break other reflections/nms logic! 58 | 59 | Add the plugin to the build configuration, as shown here: 60 | 61 | ```groovy 62 | plugins { 63 | id("com.gradleup.shadow") version "VERSION" 64 | } 65 | ``` 66 | 67 | The latest version of the shadow plugin can be found [here](https://plugins.gradle.org/plugin/com.gradleup.shadow). 68 | 69 | Add NBT-API to your dependencies: 70 | 71 | ```groovy 72 | repositories { 73 | ... 74 | maven { 75 | name = "CodeMC" 76 | url = uri("https://repo.codemc.io/repository/maven-public/") 77 | } 78 | ... 79 | } 80 | ``` 81 | 82 | ```groovy 83 | implementation("de.tr7zw:item-nbt-api:VERSION") 84 | ``` 85 | 86 | (Get the current ``VERSION`` from [here](https://modrinth.com/plugin/nbtapi/versions)) 87 | 88 | > [!WARNING] 89 | > Make sure you're using ``item-nbt-api`` as ``artifactId``, never shade the ``-plugin`` artifact! 90 | 91 | After this you can add the shadowJar configuration to relocate the API package: 92 | 93 | ```groovy 94 | shadowJar { 95 | relocate("de.tr7zw.changeme.nbtapi", "YOUR PACKAGE WHERE THE API SHOULD END UP") 96 | } 97 | ``` 98 | 99 | If you want to run the shadowJar task when the build task is executed, you can use this: 100 | 101 | ```groovy 102 | build { 103 | dependsOn(shadowJar) 104 | } 105 | ``` 106 | 107 | ###### Initializing NBT-API early 108 | 109 | If you are shading NBT-API, you may call ``NBT.preloadApi()`` during ``onEnable`` to initialize NBT-API early and check whether everything works. If you omit this step, NBT-API will be initialized on the first call to the API. 110 | 111 | ```java 112 | @Override 113 | public void onEnable() { 114 | if (!NBT.preloadApi()) { 115 | getLogger().warning("NBT-API wasn't initialized properly, disabling the plugin"); 116 | getPluginLoader().disablePlugin(this); 117 | return; 118 | } 119 | // Load other things 120 | } 121 | ``` 122 | 123 | -------------------------------------------------------------------------------- /wiki/Using-Maven.md: -------------------------------------------------------------------------------- 1 | To start using NB-API, you either need to depend on its plugin version, or shade (include) it inside your plugin. 2 | 3 | > [!IMPORTANT] 4 | > Plugin and shaded versions have different ``artifactId``. Make sure to correctly choose the one you need! 5 | 6 | > [!IMPORTANT] 7 | > Alternative ways of loading the api like Libby are not supported on Discord/Github issues. 8 | 9 | # Option 1) NBT-API as a dependency (recommended) 10 | 11 | Add the following entries to your pom at the correct locations: 12 | 13 | ```xml 14 | 15 | ... 16 | 17 | 18 | codemc-repo 19 | https://repo.codemc.io/repository/maven-public/ 20 | default 21 | 22 | ... 23 | 24 | ``` 25 | 26 | ```xml 27 | 28 | de.tr7zw 29 | item-nbt-api-plugin 30 | VERSION 31 | provided 32 | 33 | ``` 34 | 35 | (Get the current ``VERSION`` from [here](https://modrinth.com/plugin/nbtapi/versions)) 36 | 37 | Add the API as dependency to your ``plugin.yml``: 38 | 39 | ```yaml 40 | depend: [NBTAPI] 41 | ``` 42 | 43 | Or, if you are using ``paper-plugin.yml``: 44 | 45 | ```yml 46 | dependencies: 47 | server: 48 | NBTAPI: 49 | load: BEFORE 50 | required: true 51 | join-classpath: true 52 | ``` 53 | 54 | # Option 2) Shading the NBT-API into your plugin (Not recommended) 55 | 56 | > [!WARNING] 57 | > Due to the increasing amount of pitfalls in modern Paper, shading is not recommended. Please test with the normal plugin dependency before reporting issues. 58 | 59 | To include NBT-API directly in your plugin, you can use the maven shade plugin. 60 | 61 | Create an empty ``.mojang-mapped`` file in the META-INF folder of your plugin for 1.20+ Paper support. 62 | 63 | > [!WARNING] 64 | > Not adding this flag will make the shaded api not work on the latest Paper. It might also break other reflections/nms logic! 65 | 66 | Add the plugin to the build configuration, as shown here: 67 | 68 | ```xml 69 | 70 | 71 | org.apache.maven.plugins 72 | maven-shade-plugin 73 | 3.6.0 74 | 75 | 76 | shade 77 | package 78 | 79 | shade 80 | 81 | 82 | 83 | 84 | 85 | 86 | de.tr7zw.changeme.nbtapi 87 | YOUR PACKAGE WHERE THE API SHOULD END UP 88 | 89 | 90 | 91 | 92 | 93 | ``` 94 | 95 | The latest version of the shade plugin can be found [here](https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-shade-plugin). 96 | 97 | Replace ``YOUR PACKAGE WHERE THE API SHOULD END UP`` with your own unique package. For example: 98 | 99 | ```xml 100 | 101 | de.tr7zw.changeme.nbtapi 102 | com.yourname.pluginname.nbtapi 103 | 104 | ``` 105 | 106 | Then, add NBT-API to your dependencies by including the following entries to your pom at the correct locations: 107 | 108 | ```xml 109 | 110 | ... 111 | 112 | 113 | codemc-repo 114 | https://repo.codemc.io/repository/maven-public/ 115 | default 116 | 117 | ... 118 | 119 | ``` 120 | 121 | ```xml 122 | 123 | de.tr7zw 124 | item-nbt-api 125 | VERSION 126 | 127 | ``` 128 | 129 | (Get the current ``VERSION`` from [here](https://modrinth.com/plugin/nbtapi/versions)) 130 | 131 | > [!WARNING] 132 | > Make sure you're using ``item-nbt-api`` as ``artifactId``, never shade the ``-plugin`` artifact! 133 | 134 | ###### Initializing NBT-API early 135 | 136 | If you are shading NBT-API, you may call ``NBT.preloadApi()`` during ``onEnable`` to initialize NBT-API early and check whether everything works. If you omit this step, NBT-API will be initialized on the first call to the API. 137 | 138 | ```java 139 | @Override 140 | public void onEnable() { 141 | if (!NBT.preloadApi()) { 142 | getLogger().warning("NBT-API wasn't initialized properly, disabling the plugin"); 143 | getPluginLoader().disablePlugin(this); 144 | return; 145 | } 146 | // Load other things 147 | } 148 | ``` 149 | 150 | -------------------------------------------------------------------------------- /wiki/_Footer.md: -------------------------------------------------------------------------------- 1 | [tr7zw](https://github.com/tr7zw) 2 | [Modrinth](https://modrinth.com/plugin/nbtapi) 3 | [Hangar](https://hangar.papermc.io/tr7zw/NBTAPI) 4 | [SpigotMC](https://www.spigotmc.org/resources/nbt-api.7939/) 5 | [Bukkit](https://dev.bukkit.org/projects/nbt-api) 6 | -------------------------------------------------------------------------------- /wiki/_Sidebar.md: -------------------------------------------------------------------------------- 1 | [Home](https://github.com/tr7zw/Item-NBT-API/wiki) 2 | 3 | [Using Maven](https://github.com/tr7zw/Item-NBT-API/wiki/Using-Maven) / 4 | [Using Gradle](https://github.com/tr7zw/Item-NBT-API/wiki/Using-Gradle) 5 | 6 | [FAQ](https://github.com/tr7zw/Item-NBT-API/wiki/FAQ) 7 | 8 | ## Code Examples 9 | 10 | ### General 11 | 12 | * [Basics](https://github.com/tr7zw/Item-NBT-API/wiki/Using-the-NBT-API) 13 | * [Items](https://github.com/tr7zw/Item-NBT-API/wiki/Using-the-NBT-API#working-with-items) 14 | * [Block-Entities/Entities](https://github.com/tr7zw/Item-NBT-API/wiki/Using-the-NBT-API#working-with-entities-and-block-entities) 15 | * [Blocks](https://github.com/tr7zw/Item-NBT-API/wiki/Using-the-NBT-API#working-with-blocks) 16 | 17 | ### Extras 18 | 19 | * [Example usages](https://github.com/tr7zw/Item-NBT-API/wiki/Example-Usages) 20 | * [NBT files](https://github.com/tr7zw/Item-NBT-API/wiki/Using-the-NBT-API#nbt-files) 21 | * [NBT objects](https://github.com/tr7zw/Item-NBT-API/wiki/Using-the-NBT-API#converting-minecraft-objects-to-nbt-and-strings) 22 | * [Interface proxies](https://github.com/tr7zw/Item-NBT-API/wiki/Using-the-NBT-API#interface-proxies) 23 | * [Data fixer utils](https://github.com/tr7zw/Item-NBT-API/wiki/Using-the-NBT-API#data-fixer-utils) 24 | 25 | --------------------------------------------------------------------------------