Compare commits

..
285 Commits
Author SHA1 Message Date
NotAlexNoyle f3db78f103 Exclude CODEOWNERS from language statistics 2026-10-27 08:25:12 -04:00
NotAlexNoyle 1b496c6ac7 Add CODEOWNERS (one staff approval) 2026-10-27 08:25:12 -04:00
NotAlexNoyle 0322639be4 Use live TrueOG network config file 2026-05-20 09:17:44 -04:00
NotAlexNoyle 1357fb3902 1984 version checker 2026-04-13 06:31:43 -04:00
NotAlexNoyle a98c020e5b suppress warning about not being NBTAPI (we are) 2026-04-01 05:53:20 -04:00
NotAlexNoyle 46de66d16e Fix runtime warning 2026-04-01 00:01:17 -04:00
NotAlexNoyle 374431efc5 Update shadow 2026-03-25 11:13:06 -04:00
NotAlexNoyle d565082925 Sync in game plugin name with real plugin name 2026-03-25 10:58:54 -04:00
NotAlexNoyle fada94aa9c Update shadow to 8.3.6 2025-09-22 12:09:07 -04:00
NotAlexNoyle 115518fd6f Update eclipse.gradle.kts 2025-08-27 17:13:58 -04:00
NotAlexNoyle 1d0caf3d6b Maven -> Gradle 2025-08-27 16:32:49 -04:00
NotAlexNoyle 42d853d44c Rebase under true-og/Third-Party 2024-12-29 13:27:00 -05:00
tr7zw da6be72d29 Merge pull request #313 from SoSeDiK/wiki
Update wiki
2024-12-28 19:11:29 +00:00
SoSeDiK d9a93e9306 Add info about paper-plugin.yml 2024-12-28 15:57:04 +02:00
SoSeDiK ba374fe69c Update gradle shadow plugin info 2024-12-28 15:53:01 +02:00
SoSeDiK aa35ee8333 Fixup modifyMeta example 2024-12-28 15:51:28 +02:00
SoSeDiK 3bb0bdd74c Clarify persistent data storage availability 2024-12-28 15:50:49 +02:00
tr7zw f3af749b11 Merge pull request #309 from tr7zw/dependabot/maven/org.codehaus.mojo-license-maven-plugin-2.5.0
Bump org.codehaus.mojo:license-maven-plugin from 2.4.0 to 2.5.0
2024-12-21 23:44:01 +00:00
tr7zw d81c2b4e8e Merge pull request #311 from FireML/patch-1
Add EvenMoreFish to Plugins.md
2024-12-21 23:43:51 +00:00
tr7zw 94192feb8f Merge pull request #312 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.11.2
Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.1 to 3.11.2
2024-12-21 23:43:29 +00:00
tr7zw af3d9c8502 Start 2.14.2-SNAPSHOT 2024-12-22 00:42:03 +01:00
tr7zw ae98859524 Tag 2.14.1 2024-12-16 17:11:16 +01:00
tr7zw 70f0bb62f9 Add Util to get ItemStacks in Json Format for hover components 2024-12-14 21:58:53 +01:00
dependabot[bot] 505e172955 Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.11.1 to 3.11.2
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.11.1 to 3.11.2.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.11.1...maven-javadoc-plugin-3.11.2)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-09 23:45:07 +00:00
FireML d2b2b6a506 Add EvenMoreFish to Plugins.md, and Update CommandAPI URL 2024-12-08 01:31:10 +00:00
tr7zw e2e8aad70a Merge pull request #310 from ArmyFury/patch-1
Update Plugins.md
2024-12-07 13:17:51 +00:00
ArmyFury 4874366e30 Update Plugins.md
added SummonFriendlyMobs to plugins list
2024-12-07 12:47:39 +05:30
tr7zw d2de90ee25 Add 1.21.4 support 2024-12-03 23:28:21 +01:00
dependabot[bot] a0f93e575e Bump org.codehaus.mojo:license-maven-plugin from 2.4.0 to 2.5.0
Bumps [org.codehaus.mojo:license-maven-plugin](https://github.com/mojohaus/license-maven-plugin) from 2.4.0 to 2.5.0.
- [Release notes](https://github.com/mojohaus/license-maven-plugin/releases)
- [Commits](https://github.com/mojohaus/license-maven-plugin/compare/2.4.0...2.5.0)

---
updated-dependencies:
- dependency-name: org.codehaus.mojo:license-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-29 23:30:47 +00:00
tr7zw b339c9e9c2 Merge pull request #306 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.11.1
Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.10.1 to 3.11.1
2024-11-13 23:54:08 +01:00
tr7zw 3425a6672d Merge pull request #308 from SoSeDiK/wiki-changes
Update wiki
2024-11-13 23:53:54 +01:00
tr7zw 67616266da Start snapshots 2.14.1 2024-11-13 23:53:07 +01:00
SoSeDiK b08e4aa12f Update wiki to reflect some 2.14.0 changes
ItemMeta usage clarifications
2024-11-12 14:28:06 +02:00
dependabot[bot] 27411e90da Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.10.1 to 3.11.1
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.10.1 to 3.11.1.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.10.1...maven-javadoc-plugin-3.11.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-04 23:48:38 +00:00
tr7zw 73776cfec4 Sneak quick fix into release 2024-11-02 15:18:16 +01:00
tr7zw bd674e31c0 Tag 2.14.0 2024-11-02 15:07:50 +01:00
tr7zw 3405ffe0a3 Fix javadoc deploy 2024-11-02 13:24:22 +01:00
tr7zw f1317bcb04 Fix BlockEntity test. Fix #304 2024-11-02 13:06:19 +01:00
tr7zw 4a32343b95 Add 1.21.3 2024-10-28 18:56:04 +01:00
tr7zw 3de6ed83eb Hide NBTFile/NBTContainer fully behind NBT. Update tests to new format. Add missing addCompound(ReadableNBT comp) to ReadWriteNBTCompoundList 2024-10-22 23:45:16 +02:00
tr7zw e5bdce73ea Merge pull request #300 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.10.1
Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.10.0 to 3.10.1
2024-10-22 22:42:25 +02:00
tr7zw 410e88a35b Add getComponents methods 2024-10-22 22:39:35 +02:00
tr7zw e3142b4869 Add 1.21.2 support 2024-10-22 22:24:59 +02:00
tr7zw 243a5c2bcd Fix really stupid edge case of writeCompound 2024-10-22 22:08:04 +02:00
dependabot[bot] 045c710366 Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.10.0 to 3.10.1
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.10.0 to 3.10.1.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.10.0...maven-javadoc-plugin-3.10.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-01 23:20:24 +00:00
tr7zw 4cd118671f Merge pull request #297 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.10.0
Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.8.0 to 3.10.0
2024-08-27 23:03:05 +02:00
dependabot[bot] d86c91f2e6 Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.8.0 to 3.10.0
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.8.0 to 3.10.0.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.8.0...maven-javadoc-plugin-3.10.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-27 16:08:01 +00:00
tr7zw f8736c8188 Also update old items with "Count" tags 2024-08-27 18:07:27 +02:00
tr7zw b3aec54205 Start 2.13.3-SNAPSHOT 2024-08-27 18:06:56 +02:00
tr7zw 0f926998f6 Tag 2.13.2 2024-08-10 20:28:54 +02:00
tr7zw 3a44a5e989 Add 1.21.1 Paper support 2024-08-10 20:21:32 +02:00
tr7zw 30b931945c Merge pull request #288 from SoSeDiK/chunkload
Prevent chunk loading during tile entity tests
2024-08-10 20:20:58 +02:00
tr7zw 88d8629541 Merge pull request #290 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.8.0
Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.7.0 to 3.8.0
2024-07-21 20:56:57 +02:00
dependabot[bot] 00ae0448f4 Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.7.0 to 3.8.0
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.7.0 to 3.8.0.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.7.0...maven-javadoc-plugin-3.8.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-21 18:53:26 +00:00
tr7zw ce26e180e6 Merge branch 'master' of https://github.com/tr7zw/Item-NBT-API 2024-07-21 20:51:52 +02:00
tr7zw c939105e45 Start 2.13.2-SNAPSHOT 2024-07-21 20:51:48 +02:00
tr7zw 2079123a42 Merge pull request #287 from SoSeDiK/wiki
Small wiki changes
2024-07-21 20:48:08 +02:00
SoSeDiK 31b17fe9c9 Update wiki
- Fix broken (block-)entities link in sidebar
- Change "(block)-entities" to "entities and block entities" in titles to better reflect title in links
- Move repository above artifact in Maven/Gradle usage
- Add info about preloadApi
- Add title for ItemMeta usage
- Small text changes
2024-07-01 15:53:10 +03:00
SoSeDiK b565902006 Prevent chunk loading during tile entity tests 2024-07-01 15:20:52 +03:00
tr7zw 5280ba82a2 Tag 2.13.1 2024-06-20 22:37:58 +02:00
tr7zw 522f732ed1 Fix wiki and update the datafixer 2024-06-20 22:34:21 +02:00
tr7zw ac84a4d69a Fix another dead link 2024-06-20 22:20:04 +02:00
tr7zw d7e18c1cb6 Fix dead link 2024-06-20 22:18:41 +02:00
tr7zw ffa612634a Merge pull request #282 from SoSeDiK/wiki
Update wiki
2024-06-20 22:13:01 +02:00
tr7zw 739682122b Remove the usage of the word "tile" entity 2024-06-20 22:07:38 +02:00
tr7zw 2e20af40e5 Add NBT.preloadApi 2024-06-20 21:39:39 +02:00
SoSeDiK e6527515be Update Maven/Gradle usage 2024-06-17 01:05:07 +03:00
SoSeDiK e6f33a35ae Small clarifications/grammar 2024-06-17 01:05:07 +03:00
SoSeDiK 39801ada18 Update saving entity nbt example 2024-06-17 01:05:07 +03:00
SoSeDiK 75fab7622a Update examples 2024-06-17 01:05:07 +03:00
tr7zw 33eef1bcf1 Update FAQ.md 2024-06-17 01:05:07 +03:00
SoSeDiK 877a42fd06 Even more TODOs 2024-06-17 01:05:07 +03:00
SoSeDiK 0a7e560e2e Fill out some TODOs 2024-06-17 01:05:07 +03:00
SoSeDiK 174728a681 mvn spottless:apply 2024-06-17 01:05:07 +03:00
SoSeDiK 79ba1dd275 [WIP] Started updating wiki 2024-06-17 01:05:07 +03:00
tr7zw 25c59b0eae Fix build 2024-06-16 22:51:48 +02:00
tr7zw 0057d3f2e8 Remove nbtinjector/dataapi from the build 2024-06-16 00:35:20 +02:00
tr7zw 59c67a3f0b Remove unused code/private some methods/classes 2024-06-16 00:31:36 +02:00
tr7zw 3ec606ae21 Disable old method mappings 2024-06-15 23:39:40 +02:00
tr7zw ff0a94f279 Add nullable flag 2024-06-15 23:27:41 +02:00
tr7zw 53216d3b7d Overwrite resolveCompound to be ReadWriteNBT 2024-06-15 23:06:38 +02:00
tr7zw 7cf23201ce Hotfix Paper 1.21 2024-06-14 21:30:01 +02:00
tr7zw fe1d586f44 Start 2.13.1 snapshots 2024-06-14 12:33:35 +02:00
tr7zw 956ef15a1d Bump version 2024-06-13 21:15:01 +02:00
tr7zw ed867749f8 Delete data api/injector logic 2024-06-13 20:56:49 +02:00
tr7zw 88fbc0140e Remove nbt-injector and nbt-data-api 2024-06-13 20:48:36 +02:00
tr7zw 82e52267b8 More deprecation, use the NBT class 2024-06-13 20:27:23 +02:00
tr7zw c16548ff4e New "modifyComponents" api 2024-06-13 20:26:39 +02:00
tr7zw cf30cf996e Update to 1.21 2024-06-13 19:56:59 +02:00
tr7zw 633433d6d0 Merge pull request #278 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-shade-plugin-3.6.0
Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.3 to 3.6.0
2024-06-08 21:02:14 +02:00
tr7zw 153c72818a Merge pull request #279 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.7.0
Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.3 to 3.7.0
2024-06-08 21:02:06 +02:00
dependabot[bot] 4798880a53 Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.3 to 3.7.0
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.6.3 to 3.7.0.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.6.3...maven-javadoc-plugin-3.7.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-31 23:20:47 +00:00
dependabot[bot] 1f149dbae4 Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.3 to 3.6.0
Bumps [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.5.3 to 3.6.0.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.5.3...maven-shade-plugin-3.6.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-31 23:20:38 +00:00
tr7zw 8570c6f77e Improve error when trying to get NBT from non BlockEntity BlockStates. Fix #276 2024-05-19 01:07:24 +02:00
tr7zw 30f75e0714 Deprecate usage of NBTItem/NBTEntity/NBTTileEntity 2024-05-19 00:55:15 +02:00
tr7zw af7a6b0a1c Start 2.12.5-SNAPSHOT 2024-05-19 00:47:46 +02:00
tr7zw c0a9197113 Tag 2.12.4 2024-04-30 15:27:10 +02:00
tr7zw e14dd4f82a Add 1.20.6 2024-04-30 00:13:20 +02:00
tr7zw 198dbfabae Fix wiki page 2024-04-29 19:46:11 +02:00
tr7zw 8bd49db49b Fix incorrect MojangMapping, breaking on mojmapped servers like paper 1.20.5 2024-04-28 19:30:10 +02:00
tr7zw caf1d7cd98 Add utility method to get the current versions DataFixer id 2024-04-25 18:57:12 +02:00
tr7zw 027f2a2edd Add more version ids, test loading 1.12.2 items in 1.20.5 2024-04-25 18:39:40 +02:00
tr7zw b74b0b852e Pull down the 1.20.4 id 2024-04-25 18:04:39 +02:00
tr7zw 6ea6ab7e13 Bump the datafixer id to the actual 1.20.5 id 2024-04-25 18:03:59 +02:00
tr7zw 372225626c Use an older datafixerupper for compiling 2024-04-24 16:04:03 +02:00
tr7zw 2483f9b947 Add Datafixer. Auto update 1.20.4 items to 1.20.5 2024-04-24 15:59:20 +02:00
tr7zw fdc16aad69 Fix issues on older versions 2024-04-24 01:47:21 +02:00
tr7zw c723eef68b Merge pull request #277 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-shade-plugin-3.5.3
Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.2 to 3.5.3
2024-04-24 01:41:02 +02:00
tr7zw 03299012ac Fix BlockEntities for 1.20.5 2024-04-24 01:40:33 +02:00
dependabot[bot] eabf0a9696 Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.2 to 3.5.3
Bumps [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.5.2 to 3.5.3.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.5.2...maven-shade-plugin-3.5.3)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-23 23:17:03 +00:00
tr7zw 9367942b54 Re-implement gameprofile methods for 1.20.5+ 2024-04-24 00:08:48 +02:00
tr7zw 167487e6ab Deprecate/disable more stuff not applying to 1.20.5 2024-04-23 23:47:49 +02:00
tr7zw 6395dd1964 Disable invalid tests for 1.20.5+ 2024-04-23 23:04:15 +02:00
tr7zw d3ef690f2e Fix version mapping 2024-04-23 22:56:44 +02:00
tr7zw 012f32dca9 Start update to 1.20.5 2024-04-23 22:55:50 +02:00
tr7zw 0b8d5b153c Merge pull request #273 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-source-plugin-3.3.1
Bump org.apache.maven.plugins:maven-source-plugin from 3.3.0 to 3.3.1
2024-04-06 18:54:51 +02:00
tr7zw 246e3fa38e Start 2.12.4-SNAPSHOT 2024-04-06 18:54:26 +02:00
dependabot[bot] 19777de6d4 Bump org.apache.maven.plugins:maven-source-plugin from 3.3.0 to 3.3.1
Bumps [org.apache.maven.plugins:maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.3.0 to 3.3.1.
- [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.3.0...maven-source-plugin-3.3.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-source-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-04 23:45:13 +00:00
tr7zw 3afd9df2ae Tag 2.12.3 2024-03-24 17:27:30 +01:00
tr7zw 2cb16ed0c4 Merge pull request #270 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.13.0
Bump org.apache.maven.plugins:maven-compiler-plugin from 3.12.1 to 3.13.0
2024-03-21 21:38:09 +01:00
dependabot[bot] ac64acf271 Bump org.apache.maven.plugins:maven-compiler-plugin
Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.12.1 to 3.13.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.12.1...maven-compiler-plugin-3.13.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-18 23:52:09 +00:00
tr7zw 85cc13a817 Update wiki code 2024-03-18 19:45:36 +01:00
tr7zw 75c8575b5b Merge pull request #267 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-shade-plugin-3.5.2
Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.1 to 3.5.2
2024-02-22 19:56:42 +01:00
dependabot[bot] 67557d5f94 Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.1 to 3.5.2
Bumps [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.5.1 to 3.5.2.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.5.1...maven-shade-plugin-3.5.2)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-20 23:24:58 +00:00
tr7zw 330fb7711c Turns out Map.of is Java 9... 2024-02-13 00:22:48 +01:00
tr7zw e7f48c72bd Add marker that paper doesn't need to remap the nbtapi 2024-02-12 17:48:59 +01:00
tr7zw 3eefb1d315 Add support for un-remapped Paper 1.20+ 2024-02-12 16:55:16 +01:00
tr7zw a37a2c6729 Merge pull request #265 from tr7zw/dependabot/maven/org.codehaus.mojo-license-maven-plugin-2.4.0
Bump org.codehaus.mojo:license-maven-plugin from 2.3.0 to 2.4.0
2024-01-24 00:43:02 +01:00
dependabot[bot] e42fad0761 Bump org.codehaus.mojo:license-maven-plugin from 2.3.0 to 2.4.0
Bumps [org.codehaus.mojo:license-maven-plugin](https://github.com/mojohaus/license-maven-plugin) from 2.3.0 to 2.4.0.
- [Release notes](https://github.com/mojohaus/license-maven-plugin/releases)
- [Commits](https://github.com/mojohaus/license-maven-plugin/compare/2.3.0...2.4.0)

---
updated-dependencies:
- dependency-name: org.codehaus.mojo:license-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-23 23:42:13 +00:00
tr7zw eee2dfa181 Merge pull request #264 from SmartGecko44/master
Update LICENSE copyright to 2024
2024-01-01 16:10:25 +01:00
Gecko! 4728449294 Update LICENSE copyright to 2024 2024-01-01 15:07:02 +01:00
tr7zw ccd78d1b00 Merge pull request #263 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.12.1
Bump org.apache.maven.plugins:maven-compiler-plugin from 3.12.0 to 3.12.1
2023-12-27 22:17:53 +01:00
dependabot[bot] 83bea69710 Bump org.apache.maven.plugins:maven-compiler-plugin
Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.12.0 to 3.12.1.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.12.0...maven-compiler-plugin-3.12.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-25 23:36:12 +00:00
tr7zw 87fd1ee8ee Merge pull request #261 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.12.0
Bump org.apache.maven.plugins:maven-compiler-plugin from 3.11.0 to 3.12.0
2023-12-19 19:50:31 +01:00
tr7zw af0528328f Start 2.12.3-SNAPSHOT 2023-12-19 19:50:04 +01:00
dependabot[bot] 86c802e2db Bump org.apache.maven.plugins:maven-compiler-plugin
Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.11.0 to 3.12.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.11.0...maven-compiler-plugin-3.12.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 23:26:00 +00:00
tr7zw 7bf91d0510 2.12.2 release 2023-12-10 14:27:42 +01:00
tr7zw aed5af12a2 Add 1.20.4 support 2023-12-08 21:41:03 +01:00
tr7zw dd6e9e8312 Merge pull request #258 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.6.3
Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.2 to 3.6.3
2023-12-05 16:23:22 +01:00
dependabot[bot] 42871b6c06 Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.2 to 3.6.3
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.6.2 to 3.6.3.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.6.2...maven-javadoc-plugin-3.6.3)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-04 23:53:19 +00:00
tr7zw 4ad7a172a0 Merge pull request #256 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.6.2
Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.0 to 3.6.2
2023-11-11 17:26:34 +01:00
tr7zw 6f112c0130 Start 2.12.2-SNAPSHOT 2023-11-11 17:26:02 +01:00
dependabot[bot] 5a948f017a Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.0 to 3.6.2
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.6.0 to 3.6.2.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.6.0...maven-javadoc-plugin-3.6.2)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 23:25:24 +00:00
tr7zw f5a1b21761 Tag 2.12.1 2023-11-04 17:49:07 +01:00
tr7zw 4af722752e Use the correct mappings for 1.19.4. Fix #254 2023-11-03 21:21:47 +01:00
tr7zw af3b7a49d0 Fix Version Id of 1.20R2 2023-10-26 21:11:57 +02:00
tr7zw 189ff2f369 Merge pull request #253 from tr7zw/dependabot/maven/org.codehaus.mojo-license-maven-plugin-2.3.0
Bump org.codehaus.mojo:license-maven-plugin from 2.2.0 to 2.3.0
2023-10-25 01:04:49 +02:00
dependabot[bot] ddf8ab3c9b Bump org.codehaus.mojo:license-maven-plugin from 2.2.0 to 2.3.0
Bumps [org.codehaus.mojo:license-maven-plugin](https://github.com/mojohaus/license-maven-plugin) from 2.2.0 to 2.3.0.
- [Release notes](https://github.com/mojohaus/license-maven-plugin/releases)
- [Commits](https://github.com/mojohaus/license-maven-plugin/compare/2.2.0...2.3.0)

---
updated-dependencies:
- dependency-name: org.codehaus.mojo:license-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-24 23:03:14 +00:00
tr7zw a8a81eee83 Merge pull request #250 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-shade-plugin-3.5.1
Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.0 to 3.5.1
2023-10-22 17:44:19 +02:00
tr7zw fb384784f0 Start 2.12.1 snapshots 2023-10-22 17:43:27 +02:00
dependabot[bot] 256abbc500 Bump org.apache.maven.plugins:maven-shade-plugin from 3.5.0 to 3.5.1
Bumps [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.5.0 to 3.5.1.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.5.0...maven-shade-plugin-3.5.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-25 23:45:49 +00:00
tr7zw dc333ae25a Release 2.12.0 2023-09-21 23:20:21 +02:00
tr7zw d18adb459d Try to disable jitpack 2023-09-21 23:00:13 +02:00
tr7zw bc914b73bc oops, remove debug code 2023-09-21 20:50:01 +02:00
tr7zw 60172ea2a7 Correct copy paste fail 2023-09-21 20:24:39 +02:00
tr7zw 7b30c1533e Add 1.20.2 support 2023-09-21 20:16:11 +02:00
tr7zw a1c90658f3 Merge pull request #248 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.6.0
Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.5.0 to 3.6.0
2023-09-19 22:26:41 +02:00
dependabot[bot] 0b0fdeaa60 Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.5.0 to 3.6.0
Bumps [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.5.0 to 3.6.0.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.5.0...maven-javadoc-plugin-3.6.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-15 23:09:02 +00:00
tr7zw d989797453 Add support for ProxyLists 2023-09-15 01:15:11 +02:00
tr7zw c70aefe670 Allow using "[123]" and "[-1]" to navigate lists/arrays for resolve methods
Also god, some of this code needs heavy refactoring
2023-09-14 23:56:45 +02:00
tr7zw 7d0fc09470 Fix formatting 2023-09-13 18:54:02 +02:00
tr7zw 427113e6f0 Add YourKit 2023-09-13 18:50:33 +02:00
tr7zw 20ae1cb178 Document inconsistency of hasNBTData() 2023-09-13 00:20:53 +02:00
tr7zw 83b011fafa Allow passing null into NBTContainer 2023-09-13 00:03:44 +02:00
tr7zw 3affeee151 Remove dead code, simplify remove handling for empty items 2023-09-13 00:01:09 +02:00
tr7zw 06da2114ad Fix getKeys with empty ItemsStacks 2023-09-12 23:52:31 +02:00
tr7zw a3efdc622b Return to snapshots to fix issues with items without nbt 2023-09-12 23:45:59 +02:00
tr7zw 9b60978af6 Tag 2.12.0-RC1 2023-09-08 20:06:14 +02:00
tr7zw 598db19d8d Merge pull request #244 from tr7zw/proxyPrototype
Add Proxy system (Preview)
2023-09-08 19:32:05 +02:00
tr7zw 7a914d00e7 Merge branch 'master' into proxyPrototype 2023-09-08 19:12:34 +02:00
tr7zw 7141c56319 Merge pull request #243 from SoSeDiK/fixes
Fix Folia detection and NBT#modify for tile entities
2023-09-04 13:00:42 +02:00
SoSeDiK 992d9717ec Fix NBT#modify fot tile entities 2023-09-04 13:40:13 +03:00
SoSeDiK c5c2652d42 Fix Folia detection 2023-09-04 13:39:51 +03:00
SoSeDiK fb8e2272b3 Some javadoc grammar corrections 2023-09-04 13:33:14 +03:00
tr7zw 120d087edc Add "has" support 2023-08-11 18:52:40 +02:00
tr7zw 12c98d7d94 Make the casing changable 2023-08-11 18:45:50 +02:00
tr7zw 51d06817bc Merge branch 'master' into proxyPrototype 2023-08-11 18:18:17 +02:00
tr7zw 3bb4d7b449 Remove all-contributors since no one ever pr'd to it. Enable spotless for markdown files 2023-08-11 01:07:02 +02:00
tr7zw f562994d18 Update to bStats 3.0.2. Fix #230 2023-08-11 01:02:43 +02:00
tr7zw f86d234c9c Update NBTItemMeta.java 2023-08-10 22:27:58 +02:00
tr7zw cb8e24428b Fix 2023-08-10 22:12:25 +02:00
tr7zw 30bd0bcbaf Add hasCustomModelData 2023-08-10 21:40:52 +02:00
tr7zw bb4d3bb9b0 Add test 2023-08-10 21:19:21 +02:00
tr7zw 523ce8cf60 Start adding an NBTItemMeta wrapper. Add NBT Handlers 2023-08-09 18:01:12 +02:00
tr7zw d3d7a3138c Thanks, merge conflict 2023-08-08 20:11:10 +02:00
tr7zw e71bf88d12 Make a readonly view during meta modification 2023-08-08 20:07:41 +02:00
tr7zw 1ba6fc8706 Fix formatting 2023-08-06 19:40:43 +02:00
tr7zw a341034de0 Add a generic get/set method for NBTHandlers 2023-08-06 19:36:43 +02:00
tr7zw b45b25c255 Add the NBT methods to use Proxies 2023-08-06 19:23:36 +02:00
tr7zw c7eaa51bdb Merge branch 'master' into proxyPrototype 2023-08-06 17:50:12 +02:00
tr7zw 6b1d4e28ed Update NBTModifyItemTest.java 2023-08-06 16:15:51 +02:00
tr7zw 4341cb33ea Merge branch 'master' into proxyPrototype 2023-08-06 16:03:27 +02:00
tr7zw bde0bf7c8d Fix build 2023-08-06 16:03:20 +02:00
tr7zw 55ab9a2918 Merge branch 'master' into proxyPrototype 2023-08-06 15:57:29 +02:00
tr7zw 7f4d134bd0 Add getters with Consumers, so no return is required 2023-08-06 15:55:50 +02:00
tr7zw 6e8b8f3565 Add NBT.readNbt, fix resolveOrDefault 2023-08-06 00:06:47 +02:00
tr7zw a009b521c0 Remove static 2023-08-05 23:48:12 +02:00
tr7zw 54d0db8189 Handler prototype 2023-08-05 23:06:00 +02:00
tr7zw 66ffcf2866 Merge branch 'master' into proxyPrototype 2023-08-05 22:08:15 +02:00
tr7zw d653bc67d8 Fix typo 2023-08-04 21:01:11 +02:00
tr7zw 533765ba74 Add more readonly Validation 2023-08-03 00:49:11 +02:00
tr7zw 0232f720cb Close NBTItems/Entity/BlockEntity after the NBT context, to prevent people leaking objects 2023-08-03 00:29:22 +02:00
tr7zw 205ca93977 Catch attempts trying to smuggle NBT to outside the scope 2023-08-02 23:36:54 +02:00
tr7zw fa62c9825d Fix 2023-08-02 22:42:18 +02:00
tr7zw 5051bc834d Add more sanity checks 2023-08-02 22:33:42 +02:00
tr7zw 10ea4b1767 Don't merge empty tags 2023-08-02 22:24:00 +02:00
tr7zw b801b46bce Set Items nbt tag to null when empty, Add ReadableItemNBT with hasNBTData, add tests 2023-08-02 19:33:09 +02:00
tr7zw fc94dac05b Fix nbt getting lost when modifying meta first, add test, quick return setCompound for finalizer 2023-07-28 17:25:52 +02:00
tr7zw 1ab5f70c88 Merge pull request #242 from U5B/usb-wiki-plugins
add honorable plugin list mentions
2023-07-26 15:35:43 +02:00
usb af6a11d649 add honorable plugin list mentions 2023-07-26 05:53:33 -07:00
tr7zw c90636970a Add and enforce nullable annotations on some interfaces 2023-07-26 00:18:11 +02:00
tr7zw f3b1cc27e7 Add new resolve methods 2023-07-25 23:13:40 +02:00
tr7zw 33eddbaece Further cache during readonly mode 2023-07-25 21:16:45 +02:00
tr7zw 20f9b2f1ce Cache the tag in readOnly mode 2023-07-24 02:59:02 +02:00
tr7zw e8c24c6bc5 Skip making a copy for nms itemstacks during modifications 2023-07-24 02:53:37 +02:00
tr7zw affad0d92c Optimize NBT.modify calls for items 2023-07-24 00:07:08 +02:00
tr7zw ba169438ba Fix NBTFile.saveTo, Boolean -> boolean 2023-07-17 19:53:11 +02:00
tr7zw c2e23af84f Allow sub proxies 2023-07-06 19:40:22 +02:00
tr7zw 9ff2e38d07 Merge pull request #238 from BlackBaroness/patch-1
Fix minor English mistakes in documentation
2023-07-06 00:28:23 +02:00
BlackBaroness 5b12aa70e7 Update Set-a-skull's-skin-using-NBT-API.md 2023-07-06 01:23:14 +03:00
BlackBaroness 5424282fe6 Update Set-a-skull's-skin-using-NBT-API.md 2023-07-06 01:19:52 +03:00
tr7zw 8b76359143 Merge pull request #237 from BlackBaroness/patch-1
Update "set skull skin" documentation
2023-07-06 00:19:19 +02:00
BlackBaroness 2c6d54b32c Update "set skull skin" documentation 2023-07-06 01:15:47 +03:00
tr7zw a341c6a81e Update sonar badges 2023-07-05 00:41:52 +02:00
tr7zw 23b9f9128f Only mention Gson if something went wrong 2023-07-05 00:19:01 +02:00
tr7zw 81c3b75dc9 Add Folia support. Fix #225 2023-07-05 00:16:09 +02:00
tr7zw d3b1d00e15 Missing ! 2023-07-05 00:06:38 +02:00
tr7zw 177d1fe5b7 Update javadoc 2023-07-04 23:34:33 +02:00
tr7zw f1682205d8 Remove functional-annotations, add version checks 2023-07-04 23:19:22 +02:00
tr7zw ced5b15023 Add long[] to the proxy builder 2023-07-04 23:08:27 +02:00
tr7zw f6a150d5be Merge branch 'master' into proxyPrototype 2023-07-04 23:06:00 +02:00
tr7zw 1bfdb93622 Merge pull request #236 from tr7zw/readOnlyOptimization
Read only optimization
2023-07-04 23:05:06 +02:00
tr7zw 09af2df542 Merge pull request #235 from tr7zw/dependabot/maven/org.codehaus.mojo-license-maven-plugin-2.2.0
Bump license-maven-plugin from 2.1.0 to 2.2.0
2023-07-04 23:04:39 +02:00
tr7zw cd1bdc0436 Add Mojmaped jar support 2023-07-04 22:55:29 +02:00
tr7zw b2ea170f9e Add long array support. Fix #219 2023-07-04 22:02:07 +02:00
dependabot[bot] 769ba78aa1 Bump license-maven-plugin from 2.1.0 to 2.2.0
Bumps [license-maven-plugin](https://github.com/mojohaus/license-maven-plugin) from 2.1.0 to 2.2.0.
- [Release notes](https://github.com/mojohaus/license-maven-plugin/releases)
- [Commits](https://github.com/mojohaus/license-maven-plugin/compare/2.1.0...2.2.0)

---
updated-dependencies:
- dependency-name: org.codehaus.mojo:license-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-03 23:46:55 +00:00
tr7zw 0228b68a7c Change NBT.modify calls on (Block-)Entities to be atomic 2023-07-03 23:47:43 +02:00
tr7zw 2a80e8ff63 Add readonly modes for Entity/TileEntity 2023-07-02 20:48:53 +02:00
tr7zw 9bdd79ef7d Add a different error for people accidentally shading the plugin 2023-06-27 14:41:40 +02:00
tr7zw 55893bac8a Add nbtapi version to error messages 2023-06-27 14:27:08 +02:00
tr7zw bfe627658e Make a note that it's 2 different artifacts, add example 2023-06-21 14:10:53 +02:00
tr7zw a929bd2ddc Merge pull request #232 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-shade-plugin-3.5.0
Bump maven-shade-plugin from 3.4.1 to 3.5.0
2023-06-17 01:58:14 +02:00
dependabot[bot] 3a966e0478 Bump maven-shade-plugin from 3.4.1 to 3.5.0
Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.4.1 to 3.5.0.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.4.1...maven-shade-plugin-3.5.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-16 23:57:38 +00:00
tr7zw 62105ead48 Merge pull request #229 from tr7zw/dependabot/maven/org.codehaus.mojo-license-maven-plugin-2.1.0
Bump license-maven-plugin from 2.0.1 to 2.1.0
2023-06-15 16:51:56 +02:00
tr7zw cfd04fffa6 Format 2023-06-12 18:21:35 +02:00
tr7zw c8231eb050 Testing readOnly mode for NBT.get(ItemStack) 2023-06-12 18:17:37 +02:00
tr7zw f7bceec594 Start 2.12.0-SNAPSHOT 2023-06-12 18:02:11 +02:00
tr7zw c377927ee6 Tag 2.11.3 2023-06-07 20:20:15 +02:00
tr7zw 0653f47bc1 Add 1.20 support 2023-06-07 20:14:05 +02:00
dependabot[bot] 84e096d8b4 Bump license-maven-plugin from 2.0.1 to 2.1.0
Bumps [license-maven-plugin](https://github.com/mojohaus/license-maven-plugin) from 2.0.1 to 2.1.0.
- [Release notes](https://github.com/mojohaus/license-maven-plugin/releases)
- [Commits](https://github.com/mojohaus/license-maven-plugin/compare/2.0.1...2.1.0)

---
updated-dependencies:
- dependency-name: org.codehaus.mojo:license-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-06 23:57:51 +00:00
tr7zw 8bc066872c Allow annotations to customize the interface methods 2023-05-29 21:32:12 +02:00
tr7zw 4491f6780a Spotless 2023-05-28 23:15:56 +02:00
tr7zw af19868289 Add support for default methods 2023-05-28 23:06:24 +02:00
tr7zw 5588fc60b4 Merge pull request #227 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-source-plugin-3.3.0
Bump maven-source-plugin from 3.2.1 to 3.3.0
2023-05-23 10:08:50 +02:00
dependabot[bot] 7c27630c10 Bump maven-source-plugin from 3.2.1 to 3.3.0
Bumps [maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.2.1 to 3.3.0.
- [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.2.1...maven-source-plugin-3.3.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-source-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-22 23:58:27 +00:00
tr7zw 4c538aad7b Innitial test, prototyping proxies 2023-05-20 21:33:36 +02:00
tr7zw 45dd70afad Merge pull request #224 from tom-devv/typo
Fix a small typo in nbt-injector
2023-05-10 21:50:05 +02:00
tom-devv 280ce7a50d Fix typo 2023-05-10 20:40:00 +01:00
tr7zw 175065dac4 Try to use the actual plugin name for issues.
Add a warning for using "de.tr7zw.nbtapi" as relocation target in other plugins.
Fix #206
2023-05-08 00:14:48 +02:00
tr7zw f4bfca8ba8 Disable the update check by default for shaded versions 2023-05-07 20:14:17 +02:00
tr7zw 37378b4ee1 Merge pull request #221 from tr7zw/dependabot/maven/org.codehaus.mojo-license-maven-plugin-2.0.1
Bump license-maven-plugin from 2.0.0 to 2.0.1
2023-05-06 16:16:23 +02:00
tr7zw 662c0bb92d Merge pull request #223 from SoSeDiK/tagcheck
Allow checking nbt type alongside the key
2023-05-06 16:15:57 +02:00
SoSeDiK c485f8c967 Allow checking nbt type alongside the key 2023-05-06 17:01:23 +03:00
tr7zw 5759b68d89 Merge pull request #222 from SoSeDiK/bool
Add support for boolean in getOrDefault/getOrNull
2023-05-06 15:50:28 +02:00
tr7zw c22cbaaaf0 Start next snapshot 2023-05-06 15:49:40 +02:00
SoSeDiK 4a0e1b5557 Add support for boolean in getOrDefault/getOrNull 2023-05-06 16:48:45 +03:00
dependabot[bot] 1c2e61875e Bump license-maven-plugin from 2.0.0 to 2.0.1
Bumps [license-maven-plugin](https://github.com/mojohaus/license-maven-plugin) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/mojohaus/license-maven-plugin/releases)
- [Commits](https://github.com/mojohaus/license-maven-plugin/compare/license-maven-plugin-2.0.0...2.0.1)

---
updated-dependencies:
- dependency-name: org.codehaus.mojo:license-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-05 23:57:37 +00:00
tr7zw 6f25881eda Add 1.19.4 as supported version. 2.11.2 2023-03-16 19:15:55 +01:00
tr7zw bd69504f54 Merge pull request #216 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.11.0
Bump maven-compiler-plugin from 3.10.1 to 3.11.0
2023-03-09 21:08:23 +01:00
dependabot[bot] 85d7224fdd Bump maven-compiler-plugin from 3.10.1 to 3.11.0
Bumps [maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.10.1 to 3.11.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.10.1...maven-compiler-plugin-3.11.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-28 00:00:07 +00:00
tr7zw 8dc51a3d30 Merge pull request #214 from tr7zw/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.5.0
Bump maven-javadoc-plugin from 3.4.1 to 3.5.0
2023-02-16 10:03:07 +01:00
dependabot[bot] 8a440889b0 Bump maven-javadoc-plugin from 3.4.1 to 3.5.0
Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.4.1 to 3.5.0.
- [Release notes](https://github.com/apache/maven-javadoc-plugin/releases)
- [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.4.1...maven-javadoc-plugin-3.5.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-javadoc-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-15 23:57:59 +00:00
tr7zw 4a93fdc869 Fix issue with ReadWriteNBT returning ReadableNBT 2023-02-15 22:06:17 +01:00
tr7zw c905de852d Merge pull request #210 from tr7zw/revert-209-dependabot/maven/com.diffplug.spotless-spotless-maven-plugin-2.31.0
Revert "Bump spotless-maven-plugin from 2.30.0 to 2.31.0"
2023-01-31 12:16:37 +01:00
tr7zw fd7da1e3fb Revert "Bump spotless-maven-plugin from 2.30.0 to 2.31.0" 2023-01-31 12:03:09 +01:00
tr7zw 1123e27b10 Merge pull request #209 from tr7zw/dependabot/maven/com.diffplug.spotless-spotless-maven-plugin-2.31.0
Bump spotless-maven-plugin from 2.30.0 to 2.31.0
2023-01-31 11:42:42 +01:00
dependabot[bot] a97ed32097 Bump spotless-maven-plugin from 2.30.0 to 2.31.0
Bumps [spotless-maven-plugin](https://github.com/diffplug/spotless) from 2.30.0 to 2.31.0.
- [Release notes](https://github.com/diffplug/spotless/releases)
- [Changelog](https://github.com/diffplug/spotless/blob/main/CHANGES.md)
- [Commits](https://github.com/diffplug/spotless/compare/lib/2.30.0...lib/2.31.0)

---
updated-dependencies:
- dependency-name: com.diffplug.spotless:spotless-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-26 23:01:52 +00:00
tr7zw 05b4249bb4 Merge pull request #207 from tr7zw/dependabot/maven/com.diffplug.spotless-spotless-maven-plugin-2.30.0
Bump spotless-maven-plugin from 2.29.0 to 2.30.0
2023-01-25 20:33:17 +01:00
tr7zw e399590d1d Bump for 2.11.2-SNAPSHOT 2023-01-25 20:32:30 +01:00
tr7zw 310682ea25 Merge pull request #208 from FREE2WIN2/master
Fix Wiki repository url for maven and gradle.
2023-01-24 11:02:17 +01:00
FREE2WIN2 6b70966926 Wiki: Fix repository url of codemc repo 2023-01-20 23:03:47 +01:00
FREE2WIN2 79275c0c19 Wiki: Fix repository url of codemc repo 2023-01-20 23:03:03 +01:00
dependabot[bot] 2b21ef46bb Bump spotless-maven-plugin from 2.29.0 to 2.30.0
Bumps [spotless-maven-plugin](https://github.com/diffplug/spotless) from 2.29.0 to 2.30.0.
- [Release notes](https://github.com/diffplug/spotless/releases)
- [Changelog](https://github.com/diffplug/spotless/blob/main/CHANGES.md)
- [Commits](https://github.com/diffplug/spotless/compare/lib/2.29.0...lib/2.30.0)

---
updated-dependencies:
- dependency-name: com.diffplug.spotless:spotless-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-16 23:03:41 +00:00
tr7zw 79e1e62862 Merge pull request #205 from tr7zw/dependabot/maven/com.diffplug.spotless-spotless-maven-plugin-2.29.0
Bump spotless-maven-plugin from 2.28.0 to 2.29.0
2023-01-03 23:51:49 +01:00
dependabot[bot] 852ddf4a22 Bump spotless-maven-plugin from 2.28.0 to 2.29.0
Bumps [spotless-maven-plugin](https://github.com/diffplug/spotless) from 2.28.0 to 2.29.0.
- [Release notes](https://github.com/diffplug/spotless/releases)
- [Changelog](https://github.com/diffplug/spotless/blob/main/CHANGES.md)
- [Commits](https://github.com/diffplug/spotless/compare/lib/2.28.0...lib/2.29.0)

---
updated-dependencies:
- dependency-name: com.diffplug.spotless:spotless-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-02 23:03:22 +00:00
153 changed files with 9466 additions and 2903 deletions

No files matched your search

-176
View File
@@ -1,176 +0,0 @@
{
"projectName": "Item-NBT-API",
"projectOwner": "tr7zw",
"imageSize": 100,
"contributorsPerLine": 7,
"repoHost": "https://github.com",
"types": {
"discord": {
"symbol": "🤝",
"description": "Discord help"
}
},
"contributors": [
{
"login": "sgdc3",
"name": "Gabriele C.",
"avatar_url": "https://avatars3.githubusercontent.com/u/8779252?s=460&v=4",
"profile": "https://github.com/sgdc3",
"contributions": [
"code",
"infra"
],
"links": {
"infra": "https://codemc.io/"
}
},
{
"login": "SoSeDiK",
"name": "SoSeDiK",
"avatar_url": "https://avatars0.githubusercontent.com/u/19875118?s=460&v=4",
"profile": "https://github.com/SoSeDiK",
"contributions": [
"code",
"userTesting"
],
"links": {
"userTesting": "https://github.com/SoSeDiK?tab=repositories"
}
},
{
"login": "e3ndr",
"name": "Ender",
"avatar_url": "https://avatars1.githubusercontent.com/u/33337309?s=460&v=4",
"profile": "https://github.com/e3ndr",
"contributions": [
"doc",
"discord"
],
"links": {
"doc": "https://github.com/tr7zw/Item-NBT-API/wiki"
}
},
{
"login": "inventivetalentdev",
"name": "Haylee Schäfer",
"avatar_url": "https://avatars3.githubusercontent.com/u/6525296?s=460&v=4",
"profile": "https://github.com/inventivetalentdev",
"contributions": [
"code",
"ideas"
],
"links": {
"code": "https://github.com/tr7zw/Item-NBT-API/tree/master/nbt-injector",
"ideas": "https://github.com/InventivetalentDev/NBTInjector"
}
},
{
"login": "SpiGet",
"name": "SpiGet",
"avatar_url": "https://avatars3.githubusercontent.com/u/15632072?s=200&v=4",
"profile": "https://spiget.org/",
"contributions": [
"plugin"
],
"links": {
"plugin": "https://github.com/tr7zw/Item-NBT-API/blob/master/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/VersionChecker.java"
}
},
{
"login": "bStats",
"name": "bStats",
"avatar_url": "https://avatars2.githubusercontent.com/u/5033001?s=460&v=4",
"profile": "https://github.com/Bastian/bStats",
"contributions": [
"plugin"
],
"links": {
"plugin": "https://bstats.org/plugin/bukkit/ItemNBTAPI/1058"
}
},
{
"login": "MrAxeTv",
"name": "MrAxeTv",
"avatar_url": "https://avatars0.githubusercontent.com/u/17033332?s=460&v=4",
"profile": "https://github.com/MrAxeTv",
"contributions": [
"financial",
"userTesting",
"discord"
],
"links": {
"financial": "https://tr7zw.dev/donate/",
"userTesting": "https://www.spigotmc.org/resources/beastwithdraw-multy-withdraw-plugin.13896/"
}
},
{
"login": "MrDienns",
"name": "Dennis van der Veeke",
"avatar_url": "https://avatars3.githubusercontent.com/u/15938901?s=460&v=4",
"profile": "https://github.com/MrDienns",
"contributions": [
"financial"
],
"links": {
"financial": "https://tr7zw.dev/donate/"
}
},
{
"login": "iGabyTM",
"name": "Gabriel Dumitru",
"avatar_url": "https://avatars2.githubusercontent.com/u/32105478?s=460&v=4",
"profile": "https://github.com/iGabyTM",
"contributions": [
"discord"
]
},
{
"login": "TauCubed",
"name": "TauCubed",
"avatar_url": "https://avatars0.githubusercontent.com/u/35522873?s=460&v=4",
"profile": "https://github.com/TauCubed",
"contributions": [
"discord"
]
},
{
"login": "LoneDev",
"name": "LoneDev",
"avatar_url": "https://www.spigotmc.org/data/avatars/l/88/88296.jpg?1563463602",
"profile": "https://www.spigotmc.org/members/lonedev.88296",
"contributions": [
"code",
"ideas",
"financial"
],
"links": {
"ideas": "https://www.spigotmc.org/threads/nbt-api.70503/page-7#post-3652832",
"financial": "https://tr7zw.dev/donate/"
}
},
{
"login": "GC.",
"name": "GC.",
"avatar_url": "https://www.spigotmc.org/data/avatars/l/25/25090.jpg?1502396477",
"profile": "https://www.spigotmc.org/members/gc.25090",
"contributions": [
"financial"
],
"links": {
"financial": "https://tr7zw.dev/donate/"
}
},
{
"login": "Peaches_MLG",
"name": "Peaches_MLG",
"avatar_url": "https://www.spigotmc.org/data/avatars/l/194/194338.jpg?1561235996",
"profile": "https://www.spigotmc.org/members/peaches_mlg100.194338/",
"contributions": [
"financial"
],
"links": {
"financial": "https://tr7zw.dev/donate/"
}
}
]
}
+2 -1
View File
@@ -1 +1,2 @@
text eol=lf
text eol=lf
.gitea/CODEOWNERS linguist-detectable=false
+3
View File
@@ -0,0 +1,3 @@
# Pull requests request review from the eligible staff team(s).
# One approval from either an Admin or Developer satisfies branch protection.
* @trueog/Admins @trueog/Developers
-3
View File
@@ -1,3 +0,0 @@
# These are supported funding model platforms
ko_fi: tr7zw
-14
View File
@@ -1,14 +0,0 @@
version: 2
updates:
- package-ecosystem: maven
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
ignore:
- dependency-name: com.github.ekryd.sortpom:sortpom-maven-plugin
versions:
- 2.13.1
- 2.14.0
- 2.14.1
- 2.15.0
-36
View File
@@ -1,36 +0,0 @@
name: Javadoc CI
on:
push:
branches:
- master
permissions:
contents: write
jobs:
javadoc:
if: ${{ github.repository_owner == 'tr7zw' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 1.8
uses: actions/setup-java@v3
with:
distribution: zulu
java-version: 8
- name: Build with Maven
run: mvn package
- name: Copy artifacts
shell: bash
run: |
mkdir -p artifacts/v2-api && cp -r item-nbt-api/target/apidocs/* artifacts/v2-api
mkdir -p artifacts/v2-plugin && cp -r item-nbt-plugin/target/apidocs/* artifacts/v2-plugin
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@v4.4.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: gh-pages
clean: false
folder: artifacts
-18
View File
@@ -1,18 +0,0 @@
name: Java CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 1.8
uses: actions/setup-java@v3
with:
distribution: zulu
java-version: 8
- name: Build with Maven
run: mvn install --file pom.xml
-34
View File
@@ -1,34 +0,0 @@
name: Wiki CI
on:
push:
branches:
- master
permissions:
contents: write
jobs:
wiki:
if: ${{ github.repository_owner == 'tr7zw' }}
runs-on: ubuntu-latest
steps:
- name: Checkout base code
uses: actions/checkout@v3
with:
path: base-code
- name: Checkout wiki code
uses: actions/checkout@v3
with:
repository: ${{github.repository}}.wiki
path: wiki
- name: Push to wiki
run: |
cd wiki
rm *.md
cp ../base-code/wiki/* ./
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add .
git diff-index --quiet HEAD || (git commit -m "Add changes" && git push)
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2015 - 2021, tr7zw
Copyright (c) 2015 - 2024, tr7zw
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+15 -34
View File
@@ -1,54 +1,35 @@
# Item-NBT-API
Add custom NBT tags to Items/Tiles/Entities without NMS! Modify NBT and store it Files, other NBT or as String in yaml/json/SQL/Redis.
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.
[Server Owner/Developer Wiki](https://github.com/tr7zw/Item-NBT-API/wiki)
### Build/Maven/Sonar Status
[![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=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)
[![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)
[![Discord](https://img.shields.io/discord/342814924310970398?color=%237289DA&label=Discord&logo=discord&logoColor=white)](https://discordapp.com/invite/yk4caxM)
[![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)
### SpigotMC Status
[![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)
## Getting started
Import the API [using Maven](https://github.com/tr7zw/Item-NBT-API/wiki/Using-Maven), 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/Set-a-skull's-skin-using-NBT-API).
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).
### bStats
[![bStats Stats](https://bstats.org/signatures/bukkit/ItemNBTAPI.svg)](https://bstats.org/plugin/bukkit/ItemNBTAPI)
### Github Stargazers
<img src="https://starchart.cc/tr7zw/Item-NBT-API.svg" alt="stargazers" width="800"/>
## Contributors ✨
### Supported by YourKit
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tr>
<td align="center"><a href="https://github.com/sgdc3"><img src="https://avatars3.githubusercontent.com/u/8779252?s=460&v=4" width="100px;" alt=""/><br /><sub><b>Gabriele C.</b></sub></a><br /><a href="https://github.com/tr7zw/Item-NBT-API/commits?author=sgdc3" title="Code">💻</a> <a href="https://codemc.io/" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
<td align="center"><a href="https://github.com/SoSeDiK"><img src="https://avatars0.githubusercontent.com/u/19875118?s=460&v=4" width="100px;" alt=""/><br /><sub><b>SoSeDiK</b></sub></a><br /><a href="https://github.com/tr7zw/Item-NBT-API/commits?author=SoSeDiK" title="Code">💻</a> <a href="https://github.com/SoSeDiK?tab=repositories" title="User Testing">📓</a></td>
<td align="center"><a href="https://github.com/e3ndr"><img src="https://avatars1.githubusercontent.com/u/33337309?s=460&v=4" width="100px;" alt=""/><br /><sub><b>Ender</b></sub></a><br /><a href="https://github.com/tr7zw/Item-NBT-API/wiki" title="Documentation">📖</a> <a href="#discord-e3ndr" title="Discord help">🤝</a></td>
<td align="center"><a href="https://github.com/inventivetalentdev"><img src="https://avatars3.githubusercontent.com/u/6525296?s=460&v=4" width="100px;" alt=""/><br /><sub><b>Haylee Schäfer</b></sub></a><br /><a href="https://github.com/tr7zw/Item-NBT-API/tree/master/nbt-injector" title="Code">💻</a> <a href="https://github.com/InventivetalentDev/NBTInjector" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center"><a href="https://spiget.org/"><img src="https://avatars3.githubusercontent.com/u/15632072?s=200&v=4" width="100px;" alt=""/><br /><sub><b>SpiGet</b></sub></a><br /><a href="https://github.com/tr7zw/Item-NBT-API/blob/master/item-nbt-api/src/main/java/de/tr7zw/changeme/nbtapi/utils/VersionChecker.java" title="Plugin/utility libraries">🔌</a></td>
<td align="center"><a href="https://github.com/Bastian/bStats"><img src="https://avatars2.githubusercontent.com/u/5033001?s=460&v=4" width="100px;" alt=""/><br /><sub><b>bStats</b></sub></a><br /><a href="https://bstats.org/plugin/bukkit/ItemNBTAPI/1058" title="Plugin/utility libraries">🔌</a></td>
<td align="center"><a href="https://github.com/MrAxeTv"><img src="https://avatars0.githubusercontent.com/u/17033332?s=460&v=4" width="100px;" alt=""/><br /><sub><b>MrAxeTv</b></sub></a><br /><a href="https://tr7zw.dev/donate/" title="Financial Support">💵</a> <a href="https://www.spigotmc.org/resources/beastwithdraw-multy-withdraw-plugin.13896/" title="User Testing">📓</a> <a href="#discord-MrAxeTv" title="Discord help">🤝</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/MrDienns"><img src="https://avatars3.githubusercontent.com/u/15938901?s=460&v=4" width="100px;" alt=""/><br /><sub><b>Dennis van der Veeke</b></sub></a><br /><a href="https://tr7zw.dev/donate/" title="Financial Support">💵</a></td>
<td align="center"><a href="https://github.com/iGabyTM"><img src="https://avatars2.githubusercontent.com/u/32105478?s=460&v=4" width="100px;" alt=""/><br /><sub><b>Gabriel Dumitru</b></sub></a><br /><a href="#discord-iGabyTM" title="Discord help">🤝</a></td>
<td align="center"><a href="https://github.com/TauCubed"><img src="https://avatars0.githubusercontent.com/u/35522873?s=460&v=4" width="100px;" alt=""/><br /><sub><b>TauCubed</b></sub></a><br /><a href="#discord-TauCubed" title="Discord help">🤝</a></td>
<td align="center"><a href="https://www.spigotmc.org/members/lonedev.88296"><img src="https://www.spigotmc.org/data/avatars/l/88/88296.jpg?1563463602" width="100px;" alt=""/><br /><sub><b>LoneDev</b></sub></a><br /><a href="https://github.com/tr7zw/Item-NBT-API/commits?author=LoneDev" title="Code">💻</a> <a href="https://www.spigotmc.org/threads/nbt-api.70503/page-7#post-3652832" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://tr7zw.dev/donate/" title="Financial Support">💵</a></td>
<td align="center"><a href="https://www.spigotmc.org/members/gc.25090"><img src="https://www.spigotmc.org/data/avatars/l/25/25090.jpg?1502396477" width="100px;" alt=""/><br /><sub><b>GC.</b></sub></a><br /><a href="https://tr7zw.dev/donate/" title="Financial Support">💵</a></td>
<td align="center"><a href="https://www.spigotmc.org/members/peaches_mlg100.194338/"><img src="https://www.spigotmc.org/data/avatars/l/194/194338.jpg?1561235996" width="100px;" alt=""/><br /><sub><b>Peaches_MLG</b></sub></a><br /><a href="https://tr7zw.dev/donate/" title="Financial Support">💵</a></td>
</tr>
</table>
<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://allcontributors.org) specification.
Contributions of any kind are welcome! Shoot me a message or pullrequest to be added!
![](https://www.yourkit.com/images/yklogo.png)
YourKit supports open source projects with innovative and intelligent tools
for monitoring and profiling Java and .NET applications.
YourKit is the creator of <a href="https://www.yourkit.com/java/profiler/">YourKit Java Profiler</a>,
<a href="https://www.yourkit.com/.net/profiler/">YourKit .NET Profiler</a>,
and <a href="https://www.yourkit.com/youmonitor/">YourKit YouMonitor</a>.
+295
View File
@@ -0,0 +1,295 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import com.github.jengelman.gradle.plugins.shadow.transformers.AppendingTransformer
import org.gradle.api.attributes.Attribute
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.api.tasks.bundling.AbstractArchiveTask
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.jvm.toolchain.JvmVendorSpec
import org.gradle.kotlin.dsl.provideDelegate
import org.gradle.language.jvm.tasks.ProcessResources
/* ------------------------------ Plugins ------------------------------ */
plugins {
id("java") // Import Java plugin.
id("java-library") // Import Java Library plugin.
id("com.diffplug.spotless") version "7.0.4" // Import Spotless plugin.
id("com.gradleup.shadow") version "8.3.9" // Import Shadow plugin.
id("checkstyle") // Import Checkstyle plugin.
eclipse // Import Eclipse plugin.
kotlin("jvm") version "2.1.21" // Import Kotlin JVM plugin.
}
extra["kotlinAttribute"] = Attribute.of("kotlin-tag", Boolean::class.javaObjectType)
val kotlinAttribute: Attribute<Boolean> by rootProject.extra
/* --------------------------- JDK / Kotlin ---------------------------- */
java {
sourceCompatibility = JavaVersion.VERSION_17 // Compile with JDK 17 compatibility.
toolchain { // Select Java toolchain.
languageVersion.set(JavaLanguageVersion.of(17)) // Use JDK 17.
vendor.set(JvmVendorSpec.GRAAL_VM) // Use GraalVM CE.
}
}
kotlin { jvmToolchain(17) }
/* ----------------------------- Metadata ------------------------------ */
group = "de.tr7zw" // Declare bundle identifier.
version = "2.14.1" // Declare plugin version (will be in .jar).
val apiVersion = "1.19" // Declare minecraft server target version.
/* ----------------------------- Resources ----------------------------- */
tasks.named<ProcessResources>("processResources") {
val props = mapOf("version" to version, "apiVersion" to apiVersion)
inputs.properties(props) // Indicates to rerun if version changes.
filesMatching("plugin.yml") { expand(props) }
from("LICENSE") { into("/") } // Bundle licenses into jarfiles.
}
/* ---------------------------- Repos ---------------------------------- */
repositories {
mavenCentral() // Import the Maven Central Maven Repository.
gradlePluginPortal() // Import the Gradle Plugin Portal Maven Repository.
maven { url = uri("https://repo.purpurmc.org/snapshots") } // Import the PurpurMC Maven Repository.
maven { url = uri("https://repo.codemc.org/repository/maven-public/") }
maven { url = uri("https://repo.codemc.org/repository/nms/") }
maven { url = uri("https://libraries.minecraft.net/") }
maven { url = uri("file://${System.getProperty("user.home")}/.m2/repository") }
System.getProperty("SELF_MAVEN_LOCAL_REPO")?.let {
val dir = file(it)
if (dir.isDirectory) {
println("Using SELF_MAVEN_LOCAL_REPO at: $it")
maven { url = uri("file://${dir.absolutePath}") }
} else {
logger.error("TrueOG Bootstrap not found, defaulting to ~/.m2 for mavenLocal()")
mavenLocal()
}
} ?: logger.error("TrueOG Bootstrap not found, defaulting to ~/.m2 for mavenLocal()")
}
/* ---------------------- Java project deps ---------------------------- */
dependencies {
compileOnly("org.purpurmc.purpur:purpur-api:1.19.4-R0.1-SNAPSHOT") // Declare Purpur API version to be packaged.
}
subprojects {
apply(plugin = "java-library")
apply(plugin = "com.gradleup.shadow")
apply(plugin = "checkstyle")
apply(plugin = "com.diffplug.spotless")
apply(plugin = "eclipse")
apply(plugin = "org.jetbrains.kotlin.jvm")
repositories {
mavenCentral()
gradlePluginPortal()
maven { url = uri("https://repo.purpurmc.org/snapshots") }
maven { url = uri("https://repo.codemc.org/repository/maven-public/") }
maven { url = uri("https://repo.codemc.org/repository/nms/") }
maven { url = uri("https://libraries.minecraft.net/") }
maven { url = uri("file://${System.getProperty("user.home")}/.m2/repository") }
System.getProperty("SELF_MAVEN_LOCAL_REPO")?.let {
val dir = file(it)
if (dir.isDirectory) {
println("Using SELF_MAVEN_LOCAL_REPO at: $it")
maven { url = uri("file://${dir.absolutePath}") }
} else {
logger.error("TrueOG Bootstrap not found, defaulting to ~/.m2 for mavenLocal()")
mavenLocal()
}
} ?: logger.error("TrueOG Bootstrap not found, defaulting to ~/.m2 for mavenLocal()")
}
java {
sourceCompatibility = JavaVersion.VERSION_17
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
vendor.set(JvmVendorSpec.GRAAL_VM)
}
withSourcesJar()
withJavadocJar()
}
tasks.withType<ProcessResources>().configureEach {
val props = mapOf("version" to rootProject.version, "apiVersion" to apiVersion)
inputs.properties(props)
filesMatching("plugin.yml") { expand(props) }
from(rootProject.file("LICENSE")) { into("/") }
}
dependencies {
compileOnly("org.purpurmc.purpur:purpur-api:1.19.4-R0.1-SNAPSHOT")
compileOnly("com.mojang:datafixerupper:4.0.26")
compileOnly("com.mojang:authlib:1.5.25")
}
tasks.withType<AbstractArchiveTask>().configureEach {
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
}
tasks.withType<JavaCompile>().configureEach {
options.compilerArgs.add("-parameters")
options.isFork = true
options.compilerArgs.add("-Xlint:deprecation")
options.encoding = "UTF-8"
}
spotless {
java {
eclipse().configFile(rootProject.file("config/formatter/eclipse-java-formatter.xml"))
leadingTabsToSpaces()
removeUnusedImports()
}
kotlinGradle {
ktfmt().kotlinlangStyle().configure { it.setMaxWidth(120) }
target("build.gradle.kts", "settings.gradle.kts")
}
}
checkstyle {
toolVersion = "10.18.1"
configFile = rootProject.file("config/checkstyle/checkstyle.xml")
isIgnoreFailures = true
isShowViolations = true
}
tasks.named("compileJava") { dependsOn("spotlessApply") }
tasks.named("spotlessCheck") { dependsOn("spotlessApply") }
tasks.named<Jar>("jar") { archiveClassifier.set("part") }
}
/* ---------------------- Reproducible jars ---------------------------- */
tasks.withType<AbstractArchiveTask>().configureEach { // Ensure reproducible .jars
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
}
/* ----------------------------- Shadow -------------------------------- */
tasks.shadowJar {
archiveClassifier.set("") // Use empty string instead of null.
minimize()
}
tasks.jar { archiveClassifier.set("part") } // Applies to root jarfile only.
tasks.build { dependsOn(tasks.spotlessApply, tasks.shadowJar) } // Build depends on spotless and shadow.
/* --------------------------- Javac opts ------------------------------- */
tasks.withType<JavaCompile>().configureEach {
options.compilerArgs.add("-parameters") // Enable reflection for java code.
options.isFork = true // Run javac in its own process.
options.compilerArgs.add("-Xlint:deprecation") // Trigger deprecation warning messages.
options.encoding = "UTF-8" // Use UTF-8 file encoding.
}
/* ----------------------------- Auto Formatting ------------------------ */
spotless {
java {
eclipse().configFile("config/formatter/eclipse-java-formatter.xml") // Eclipse java formatting.
leadingTabsToSpaces() // Convert leftover leading tabs to spaces.
removeUnusedImports() // Remove imports that aren't being called.
}
kotlinGradle {
ktfmt().kotlinlangStyle().configure { it.setMaxWidth(120) } // JetBrains Kotlin formatting.
target("build.gradle.kts", "settings.gradle.kts") // Gradle files to format.
}
}
checkstyle {
toolVersion = "10.18.1" // Declare checkstyle version to use.
configFile = file("config/checkstyle/checkstyle.xml") // Point checkstyle to config file.
isIgnoreFailures = true // Don't fail the build if checkstyle does not pass.
isShowViolations = true // Show the violations in any IDE with the checkstyle plugin.
}
tasks.named("compileJava") {
dependsOn("spotlessApply") // Run spotless before compiling with the JDK.
}
tasks.named("spotlessCheck") {
dependsOn("spotlessApply") // Run spotless before checking if spotless ran.
}
/* ------------------------------ Eclipse SHIM ------------------------- */
// This can't be put in eclipse.gradle.kts because Gradle is weird.
subprojects {
apply(plugin = "java-library")
apply(plugin = "eclipse")
eclipse.project.name = "${project.name}-${rootProject.name}"
tasks.withType<Jar>().configureEach { archiveBaseName.set("${project.name}-${rootProject.name}") }
}
/* --------------------------- Module wiring --------------------------- */
project(":item-nbt-api") {
tasks.withType<Jar>().configureEach { archiveBaseName.set("item-nbt-api") }
dependencies {}
tasks.named<ShadowJar>("shadowJar") {
archiveClassifier.set("")
minimize()
transform(AppendingTransformer::class.java) { resource = "LICENSE" }
}
tasks.named("build") { dependsOn("spotlessApply", "shadowJar") }
}
project(":item-nbt-plugin") {
tasks.withType<Jar>().configureEach { archiveBaseName.set("Item-NBT-API") }
dependencies { api(project(":item-nbt-api")) }
tasks.named<ShadowJar>("shadowJar") {
archiveClassifier.set("")
minimize()
relocate("de.tr7zw.changeme.nbtapi", "de.tr7zw.nbtapi")
relocate("javassist", "de.tr7zw.nbtinjector.javassist")
relocate("de.tr7zw.annotations", "de.tr7zw.nbtapi.annotations")
transform(AppendingTransformer::class.java) { resource = "LICENSE" }
dependsOn(project(":item-nbt-api").tasks.named("jar"))
}
val copyJar =
tasks.register<Copy>("copyJar") {
from(tasks.named("shadowJar"))
into(rootProject.layout.projectDirectory.dir("target"))
duplicatesStrategy = DuplicatesStrategy.INCLUDE
}
tasks.named("build") {
dependsOn("spotlessApply", "shadowJar")
finalizedBy(copyJar)
}
plugins.withId("java-library") {
val aggregateJavadoc =
tasks.register<Javadoc>("aggregateJavadoc") {
val srcSets = project.extensions.getByType(SourceSetContainer::class.java)
val thisSrc = srcSets.named("main").get()
val apiSrcSets = project(":item-nbt-api").extensions.getByType(SourceSetContainer::class.java)
val apiSrc = apiSrcSets.named("main").get()
source(thisSrc.allJava)
source(apiSrc.allJava)
classpath = thisSrc.compileClasspath + apiSrc.compileClasspath
isFailOnError = false
}
tasks.register<Jar>("aggregateJavadocJar") {
dependsOn(aggregateJavadoc)
from(aggregateJavadoc.get().destinationDir)
archiveClassifier.set("javadoc")
}
}
}
project(":mappings-parser") {
tasks.withType<Jar>().configureEach { archiveBaseName.set("mappings-parser") }
dependencies { implementation(project(":item-nbt-api")) }
tasks.named<ShadowJar>("shadowJar") {
archiveClassifier.set("")
minimize()
transform(AppendingTransformer::class.java) { resource = "LICENSE" }
dependsOn(project(":item-nbt-api").tasks.named("jar"))
}
tasks.named("build") { dependsOn("spotlessApply", "shadowJar") }
}
+34
View File
@@ -0,0 +1,34 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
<module name="FileTabCharacter">
<property name="eachLine" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="TreeWalker">
<module name="FinalLocalVariable"/>
<module name="AvoidStarImport"/>
<module name="Indentation">
<property name="severity" value="ignore"/>
</module>
</module>
<module name="RegexpSingleline">
<property name="format" value="\borg\.junit\.jupiter\.api\.Assertions\.fail\s*\(\s*&quot;Not yet implemented&quot;\s*\)\s*;"/>
<property name="message" value="Remove placeholder fail() and implement the test."/>
<property name="ignoreCase" value="true"/>
<property name="severity" value="warning"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="(?&lt;!\w)fail\s*\(\s*&quot;Not yet implemented&quot;\s*\)\s*;"/>
<property name="message" value="Remove placeholder fail() and implement the test."/>
<property name="severity" value="warning"/>
</module>
</module>
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="21">
<profile kind="CodeFormatterProfile" name="Java Conventions Spaces" version="21">
<profiles version="23">
<profile kind="CodeFormatterProfile" name="TrueOG Network Formatting" version="23">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
@@ -13,7 +13,7 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="8"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
@@ -52,12 +52,12 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
@@ -69,16 +69,17 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_switch_case_arrow_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="false"/>
@@ -98,13 +99,14 @@
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_permitted_types" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
@@ -116,7 +118,7 @@
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
@@ -145,7 +147,7 @@
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
@@ -156,18 +158,20 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.javadoc_do_not_separate_block_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
@@ -177,7 +181,7 @@
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
@@ -196,6 +200,7 @@
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case_after_arrow" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
@@ -220,13 +225,14 @@
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.keep_switch_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
@@ -234,10 +240,11 @@
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_arrow" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
@@ -246,7 +253,7 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
@@ -258,8 +265,8 @@
<setting id="org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
@@ -274,22 +281,26 @@
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.align_arrows_in_switch_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.align_selector_in_method_invocation_on_expression_first_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.keep_switch_case_with_arrow_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_colon" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
@@ -301,6 +312,7 @@
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_line_comments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
@@ -320,16 +332,17 @@
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_switch_case_with_arrow" value="20"/>
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assertion_message" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
@@ -351,7 +364,7 @@
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="true"/>
@@ -361,11 +374,12 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_permitted_types" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_never"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="next_line_on_wrap"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
@@ -379,7 +393,7 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="true"/>
-16
View File
@@ -1,16 +0,0 @@
# (Item-)NBT-API
Add custom NBT tags to Items/Tiles/Entities without NMS! Modify NBT and store it Files, other NBT or as String in yaml/json/SQL/Redis.
[Server Owner/Developer Wiki](https://github.com/tr7zw/Item-NBT-API/wiki)
### Build/Maven/Sonar Status
[![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)
Discord:[![Discord](https://img.shields.io/discord/342814924310970398?color=%237289DA&label=Discord&logo=discord&logoColor=white)](https://discordapp.com/invite/yk4caxM)
### SpigotMC Status
[![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)
## Getting started
Import the API [using Maven](https://github.com/tr7zw/Item-NBT-API/wiki/Using-Maven), 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/Set-a-skull's-skin-using-NBT-API).
### bStats
[![bStats Stats](https://bstats.org/signatures/bukkit/ItemNBTAPI.svg)](https://bstats.org/plugin/bukkit/ItemNBTAPI)
+151
View File
@@ -0,0 +1,151 @@
/* This is free and unencumbered software released into the public domain */
import org.gradle.plugins.ide.eclipse.model.EclipseModel
import java.nio.file.Files
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.transform.OutputKeys
import javax.xml.transform.TransformerFactory
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult
val kotlinAttribute: Attribute<Boolean> by rootProject.extra
val kotlinPluginProjects = configurations
.getByName("compileClasspath")
.allDependencies
.filterIsInstance<ProjectDependency>()
.filter { it -> it.attributes.getAttribute(kotlinAttribute) != null }
.map { it.path }
kotlinPluginProjects.forEach { evaluationDependsOn(it) }
val ideLibs: Configuration by
configurations.creating {
isCanBeResolved = true
isCanBeConsumed = false
}
configure<EclipseModel> {
project {
name = "Item-NBT-API-Plugin"
}
classpath {
plusConfigurations.add(ideLibs)
}
}
val ideLibDir = layout.buildDirectory.dir("ide-libs")
val hashRegex = Regex("-[0-9a-fA-F]{10}(?=\\.jar$)") // Black magic.
val copyTasks = mutableListOf<TaskProvider<Copy>>()
kotlinPluginProjects.forEach { path ->
val sub = project(path)
val shadowJarProv = sub.tasks.named("shadowJar")
val copyTask =
tasks.register<Copy>("ideCopy${sub.name.replaceFirstChar(Char::titlecase)}") {
dependsOn(shadowJarProv)
from(shadowJarProv)
into(ideLibDir)
rename { it.replace(hashRegex, "") } // Remove git commit hash from jarfile.
}
copyTasks += copyTask
}
/* Ensure the jars exist before .classpath is generated */
tasks.named("eclipseClasspath").configure { dependsOn(copyTasks) }
/* Supply those jars to the ideLibs configuration (after evaluation) */
afterEvaluate { dependencies { add("ideLibs", fileTree(ideLibDir) { include("*.jar") }) } }
val injectIdeLibs =
tasks.register("injectIdeLibs") {
dependsOn("eclipse") // run after all eclipse files are generated
doLast {
val cpFile = file(".classpath")
if (!cpFile.exists()) return@doLast
val jars = fileTree(ideLibDir.get()) { include("*.jar") }.files.sortedBy { it.name }
if (jars.isEmpty()) return@doLast
// Parse DOM
val dbf = DocumentBuilderFactory.newInstance()
val doc = dbf.newDocumentBuilder().parse(cpFile)
val root = doc.documentElement
// Helper to see if an entry already exists
fun exists(path: String): Boolean =
root.getElementsByTagName("classpathentry").let { list ->
(0 until list.length).any { i ->
val n = list.item(i)
val kind = n.attributes?.getNamedItem("kind")?.nodeValue
val p = n.attributes?.getNamedItem("path")?.nodeValue
kind == "lib" && p == path
}
}
// Remove any entry that points to ide-libs dir (folder or jars) to avoid dupes
val toRemove = mutableListOf<org.w3c.dom.Node>()
val list = root.getElementsByTagName("classpathentry")
val dirPath = ideLibDir.get().asFile.absolutePath
for (i in 0 until list.length) {
val n = list.item(i)
val kind = n.attributes?.getNamedItem("kind")?.nodeValue
val p = n.attributes?.getNamedItem("path")?.nodeValue ?: ""
if (kind == "lib" && (p == dirPath || p.startsWith("$dirPath/"))) {
toRemove += n
}
}
toRemove.forEach { root.removeChild(it) }
// Append our jar entries LAST
jars.forEach { f ->
val abs = f.absolutePath
if (!exists(abs)) {
val entry = doc.createElement("classpathentry")
entry.setAttribute("kind", "lib")
entry.setAttribute("path", abs)
root.appendChild(entry)
}
}
// Write back pretty
val tf =
TransformerFactory.newInstance().newTransformer().apply {
setOutputProperty(OutputKeys.INDENT, "yes")
setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "1")
setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no")
setOutputProperty(OutputKeys.ENCODING, "UTF-8")
}
Files.newBufferedWriter(cpFile.toPath()).use { w -> tf.transform(DOMSource(doc), StreamResult(w)) }
}
}
tasks.named("eclipse").configure { finalizedBy(injectIdeLibs) }
val eclipseModel = extensions.getByType<EclipseModel>()
fun Project.addResolvableEclipseConfigs() {
val jarAttr =
objects.named(org.gradle.api.attributes.LibraryElements::class, org.gradle.api.attributes.LibraryElements.JAR)
val apiAttr = objects.named(org.gradle.api.attributes.Usage::class, org.gradle.api.attributes.Usage.JAVA_API)
val compileOnlyRes =
configurations.create("eclipseCompileOnly") {
extendsFrom(configurations.getByName("compileOnly"))
isCanBeResolved = true
isCanBeConsumed = false
attributes.attribute(org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE, apiAttr)
attributes.attribute(org.gradle.api.attributes.LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, jarAttr)
}
val compileOnlyApiRes =
configurations.create("eclipseCompileOnlyApi") {
extendsFrom(configurations.getByName("compileOnlyApi"))
isCanBeResolved = true
isCanBeConsumed = false
attributes.attribute(org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE, apiAttr)
attributes.attribute(org.gradle.api.attributes.LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, jarAttr)
}
eclipseModel.classpath.plusConfigurations.addAll(listOf(compileOnlyRes, compileOnlyApiRes))
}
addResolvableEclipseConfigs()
Binary file not shown.
+7
View File
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored Executable
+251
View File
@@ -0,0 +1,251 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored
+94
View File
@@ -0,0 +1,94 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
-63
View File
@@ -1,63 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.11.1</version>
</parent>
<artifactId>item-nbt-api</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>functional-annotations</artifactId>
<version>0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>clean install javadoc:javadoc</defaultGoal>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>de.tr7zw.annotations</pattern>
<shadedPattern>de.tr7zw.changeme.nbtapi.utils.annotations</shadedPattern>
</relocation>
</relocations>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>LICENSE</resource>
</transformer>
</transformers>
</configuration>
<executions>
<execution>
<id>shade</id>
<goals>
<goal>shade</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -1,7 +1,13 @@
package de.tr7zw.changeme.nbtapi;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.logging.Level;
import javax.annotation.Nullable;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
@@ -9,9 +15,17 @@ import org.bukkit.inventory.ItemStack;
import com.mojang.authlib.GameProfile;
import de.tr7zw.changeme.nbtapi.iface.NBTFileHandle;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteItemNBT;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.changeme.nbtapi.iface.ReadableItemNBT;
import de.tr7zw.changeme.nbtapi.iface.ReadableNBT;
import de.tr7zw.changeme.nbtapi.wrapper.NBTProxy;
import de.tr7zw.changeme.nbtapi.wrapper.ProxyBuilder;
import de.tr7zw.changeme.nbtapi.iface.ReadableNBTList;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
/**
* General utility class for a clean and simple nbt access.
@@ -19,12 +33,87 @@ import de.tr7zw.changeme.nbtapi.iface.ReadableNBT;
* @author tr7zw
*
*/
@SuppressWarnings("deprecation")
public class NBT {
private NBT() {
// No instances of NBT. Utility class
}
/**
* Utility method for shaded versions to preload and check the API during
* onEnable. This method does not throw an exception and instead logs them. Will
* return false if something fundamentally is wrong and the NBTAPI is in a non
* functioning state. The shading plugin then needs to handle this. Note:
* Calling this method during onLoad will cause an failure, so please wait till
* onEnable.
*
* @return true if everything went fine
*/
public static boolean preloadApi() {
try {
// boiled down version of the plugin selfcheck without tests
if (MinecraftVersion.getVersion() == MinecraftVersion.UNKNOWN) {
NbtApiException.confirmedBroken = true;
return false;
}
for (ClassWrapper c : ClassWrapper.values()) {
if (c.isEnabled() && c.getClazz() == null) {
NbtApiException.confirmedBroken = true;
return false;
}
}
for (ReflectionMethod method : ReflectionMethod.values()) {
if (method.isCompatible() && !method.isLoaded()) {
NbtApiException.confirmedBroken = true;
return false;
}
}
// not settings NbtApiException.confirmedBroken = false, as no actual tests were
// done.
// This just means the version was found, and all reflections seem to work.
return true;
} catch (Exception ex) {
NbtApiException.confirmedBroken = true;
MinecraftVersion.getLogger().log(Level.WARNING, "[NBTAPI] Error during the selfcheck!", ex);
return false;
}
}
/**
* Get a read only instance of the items NBT. This method is slightly slower
* than calling NBT.get due to having to create a copy of the ItemStack, but
* allows context free access to the data.
*
* @param item
* @return
*/
public static ReadableNBT readNbt(ItemStack item) {
return new NBTItem(item.clone(), false, true, false);
}
/**
* It takes an ItemStack, and a function that takes a ReadableNBT and returns a
* generic type T. It then returns the result of the function applied to a new
@@ -35,8 +124,33 @@ public class NBT {
* T.
* @return The function is being returned.
*/
public static <T> T get(ItemStack item, Function<ReadableNBT, T> getter) {
return getter.apply(new NBTItem(item));
public static <T> T get(ItemStack item, Function<ReadableItemNBT, T> getter) {
NBTItem nbt = new NBTItem(item, false, true, false);
T ret = getter.apply(nbt);
if (ret instanceof ReadableNBT || ret instanceof ReadableNBTList<?>) {
throw new NbtApiException("Tried returning part of the NBT to outside of the NBT scope!");
}
nbt.setClosed();
return ret;
}
/**
* It takes an ItemStack, and a Consumer that takes a ReadableNBT. Applies the
* Consumer on the NBT of the item
*
* @param item The itemstack you want to get the NBT from
*/
public static void get(ItemStack item, Consumer<ReadableItemNBT> getter) {
NBTItem nbt = new NBTItem(item, false, true, false);
getter.accept(nbt);
nbt.setClosed();
}
/**
@@ -48,7 +162,32 @@ public class NBT {
* @return The NBTEntity class is being returned.
*/
public static <T> T get(Entity entity, Function<ReadableNBT, T> getter) {
return getter.apply(new NBTEntity(entity));
NBTEntity nbt = new NBTEntity(entity, true);
T ret = getter.apply(nbt);
if (ret instanceof ReadableNBT || ret instanceof ReadableNBTList<?>) {
throw new NbtApiException("Tried returning part of the NBT to outside of the NBT scope!");
}
nbt.setClosed();
return ret;
}
/**
* It takes an Entity, and a Consumer that takes a ReadableNBT. Applies the
* Consumer on the NBT of the Entity
*
* @param entity The entity to get the NBT from
*/
public static void get(Entity entity, Consumer<ReadableNBT> getter) {
NBTEntity nbt = new NBTEntity(entity, true);
getter.accept(nbt);
nbt.setClosed();
}
/**
@@ -62,7 +201,32 @@ public class NBT {
* @return The return type is the same as the type of the getter function.
*/
public static <T> T get(BlockState blockState, Function<ReadableNBT, T> getter) {
return getter.apply(new NBTTileEntity(blockState));
NBTTileEntity nbt = new NBTTileEntity(blockState, true);
T ret = getter.apply(nbt);
if (ret instanceof ReadableNBT || ret instanceof ReadableNBTList<?>) {
throw new NbtApiException("Tried returning part of the NBT to outside of the NBT scope!");
}
nbt.setClosed();
return ret;
}
/**
* It takes an BlockEntity, and a Consumer that takes a ReadableNBT. Applies the
* Consumer on the NBT of the BlockEntity
*
* @param blockState The block state of the block you want to get the NBT from.
*/
public static void get(BlockState blockState, Consumer<ReadableNBT> getter) {
NBTTileEntity nbt = new NBTTileEntity(blockState, true);
getter.accept(nbt);
nbt.setClosed();
}
/**
@@ -76,13 +240,22 @@ public class NBT {
* @return The return type is T, which is a generic type.
*/
public static <T> T getPersistentData(Entity entity, Function<ReadableNBT, T> getter) {
return getter.apply(new NBTEntity(entity).getPersistentDataContainer());
T ret = getter.apply(new NBTEntity(entity).getPersistentDataContainer());
if (ret instanceof ReadableNBT || ret instanceof ReadableNBTList<?>) {
throw new NbtApiException("Tried returning part of the NBT to outside of the NBT scope!");
}
return ret;
}
/**
* It takes an block entity and a function that takes a ReadableNBT and returns
* a generic type T, and returns the result of the function, applied to the
* block entities persistent data container
* It takes a block entity and a function that takes a ReadableNBT and returns a
* generic type T, and returns the result of the function, applied to the block
* entities persistent data container
*
* @param blockState The block state of the block you want to get the data from.
* @param getter A function that takes a ReadableNBT and returns a value of
@@ -90,7 +263,16 @@ public class NBT {
* @return The value of the NBT tag.
*/
public static <T> T getPersistentData(BlockState blockState, Function<ReadableNBT, T> getter) {
return getter.apply(new NBTTileEntity(blockState).getPersistentDataContainer());
T ret = getter.apply(new NBTTileEntity(blockState).getPersistentDataContainer());
if (ret instanceof ReadableNBT || ret instanceof ReadableNBTList<?>) {
throw new NbtApiException("Tried returning part of the NBT to outside of the NBT scope!");
}
return ret;
}
/**
@@ -102,10 +284,19 @@ public class NBT {
* @return The return value of the function.
*/
public static <T> T modify(ItemStack item, Function<ReadWriteItemNBT, T> function) {
NBTItem nbti = new NBTItem(item, true);
NBTItem nbti = new NBTItem(item, false, false, true);
T val = function.apply(nbti);
nbti.applyNBT(item);
nbti.finalizeChanges();
if (val instanceof ReadableNBT || val instanceof ReadableNBTList<?>) {
throw new NbtApiException("Tried returning part of the NBT to outside of the NBT scope!");
}
nbti.setClosed();
return val;
}
/**
@@ -116,9 +307,12 @@ public class NBT {
* @param consumer The consumer that will be used to modify the NBT.
*/
public static void modify(ItemStack item, Consumer<ReadWriteItemNBT> consumer) {
NBTItem nbti = new NBTItem(item, true);
NBTItem nbti = new NBTItem(item, false, false, true);
consumer.accept(nbti);
nbti.applyNBT(item);
nbti.finalizeChanges();
nbti.setClosed();
}
/**
@@ -130,7 +324,111 @@ public class NBT {
* @return The return type is the same as the return type of the function.
*/
public static <T> T modify(Entity entity, Function<ReadWriteNBT, T> function) {
return function.apply(new NBTEntity(entity));
NBTEntity nbtEnt = new NBTEntity(entity);
NBTContainer cont = new NBTContainer(nbtEnt.getCompound());
T ret = function.apply(cont);
nbtEnt.setCompound(cont.getCompound());
if (ret instanceof ReadableNBT || ret instanceof ReadableNBTList<?>) {
throw new NbtApiException("Tried returning part of the NBT to outside of the NBT scope!");
}
nbtEnt.setClosed();
return ret;
}
/**
* It takes an ItemStack and a Consumer&lt;ReadWriteNBT&gt;, and then applies
* the Consumer to the ItemStacks Components as NBT. This is for 1.20.5+ only.
* This method is quite expensive, so don't overuse it.
*
* @param item The item you want to modify the components of
* @param consumer The consumer that will be used to modify the components.
*/
public static void modifyComponents(ItemStack item, Consumer<ReadWriteNBT> consumer) {
if (!MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
throw new NbtApiException("This method only works for 1.20.5+!");
}
ReadWriteNBT nbti = NBT.itemStackToNBT(item);
consumer.accept(nbti.getOrCreateCompound("components"));
ItemStack tmp = NBT.itemStackFromNBT(nbti);
item.setItemMeta(tmp.getItemMeta());
}
/**
* It takes an ItemStack and a Consumer&lt;ReadWriteNBT&gt;, and then applies
* the Consumer to the ItemStacks Components as NBT. This is for 1.20.5+ only.
* This method is quite expensive, so don't overuse it.
*
* @param item The item you want to modify the components of
* @param function The consumer that will be used to modify the components.
* @return The return type is the same as the return type of the function.
*/
public static <T> T modifyComponents(ItemStack item, Function<ReadWriteNBT, T> function) {
if (!MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
throw new NbtApiException("This method only works for 1.20.5+!");
}
ReadWriteNBT nbti = NBT.itemStackToNBT(item);
T ret = function.apply(nbti.getOrCreateCompound("components"));
ItemStack tmp = NBT.itemStackFromNBT(nbti);
item.setItemMeta(tmp.getItemMeta());
return ret;
}
/**
* It takes an ItemStack and a Consumer&lt;ReadWriteNBT&gt;, and then applies
* the Consumer to the ItemStacks Components as NBT. This is for 1.20.5+ only.
* This method is quite expensive, try to cache the results/use it smartly.
*
* @param item The item you want to read the components of
* @param consumer The consumer that will be used to read the components.
*/
public static void getComponents(ItemStack item, Consumer<ReadableNBT> consumer) {
if (!MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
throw new NbtApiException("This method only works for 1.20.5+!");
}
ReadWriteNBT nbti = NBT.itemStackToNBT(item);
consumer.accept(nbti.getOrCreateCompound("components"));
}
/**
* It takes an ItemStack and a Consumer&lt;ReadWriteNBT&gt;, and then applies
* the Consumer to the ItemStacks Components as NBT. This is for 1.20.5+ only.
* This method is quite expensive, try to cache the results/use it smartly.
*
* @param item The item you want to read the components of
* @param function The consumer that will be used to read the components.
* @return The return type is the same as the return type of the function.
*/
public static <T> T getComponents(ItemStack item, Function<ReadableNBT, T> function) {
if (!MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
throw new NbtApiException("This method only works for 1.20.5+!");
}
ReadWriteNBT nbti = NBT.itemStackToNBT(item);
return function.apply(nbti.getOrCreateCompound("components"));
}
/**
@@ -141,7 +439,13 @@ public class NBT {
* @param consumer The consumer that will be called with the NBTEntity.
*/
public static void modify(Entity entity, Consumer<ReadWriteNBT> consumer) {
consumer.accept(new NBTEntity(entity));
NBTEntity nbtEnt = new NBTEntity(entity);
NBTContainer cont = new NBTContainer(nbtEnt.getCompound());
consumer.accept(cont);
nbtEnt.setCompound(cont.getCompound());
nbtEnt.setClosed();
}
/**
@@ -154,7 +458,16 @@ public class NBT {
* @return The return type is the same as the return type of the function.
*/
public static <T> T modifyPersistentData(Entity entity, Function<ReadWriteNBT, T> function) {
return function.apply(new NBTEntity(entity).getPersistentDataContainer());
T ret = function.apply(new NBTEntity(entity).getPersistentDataContainer());
if (ret instanceof ReadableNBT || ret instanceof ReadableNBTList<?>) {
throw new NbtApiException("Tried returning part of the NBT to outside of the NBT scope!");
}
return ret;
}
/**
@@ -165,7 +478,9 @@ public class NBT {
* @param consumer The consumer that will be used to modify the persistent data.
*/
public static void modifyPersistentData(Entity entity, Consumer<ReadWriteNBT> consumer) {
consumer.accept(new NBTEntity(entity).getPersistentDataContainer());
}
/**
@@ -177,7 +492,20 @@ public class NBT {
* @return The return type is the same as the return type of the function.
*/
public static <T> T modify(BlockState blockState, Function<ReadWriteNBT, T> function) {
return function.apply(new NBTTileEntity(blockState));
NBTTileEntity blockEnt = new NBTTileEntity(blockState);
NBTContainer cont = new NBTContainer(blockEnt.getCompound());
T ret = function.apply(cont);
blockEnt.setCompound(cont.getCompound());
if (ret instanceof ReadableNBT || ret instanceof ReadableNBTList<?>) {
throw new NbtApiException("Tried returning part of the NBT to outside of the NBT scope!");
}
blockEnt.setClosed();
return ret;
}
/**
@@ -190,7 +518,13 @@ public class NBT {
* takes a ReadWriteNBT and does something with it.
*/
public static void modify(BlockState blockState, Consumer<ReadWriteNBT> consumer) {
consumer.accept(new NBTTileEntity(blockState));
NBTTileEntity blockEnt = new NBTTileEntity(blockState);
NBTContainer cont = new NBTContainer(blockEnt.getCompound());
consumer.accept(cont);
blockEnt.setCompound(cont.getCompound());
blockEnt.setClosed();
}
/**
@@ -203,7 +537,16 @@ public class NBT {
* @return The return type is the same as the return type of the function.
*/
public static <T> T modifyPersistentData(BlockState blockState, Function<ReadWriteNBT, T> function) {
return function.apply(new NBTTileEntity(blockState).getPersistentDataContainer());
T ret = function.apply(new NBTTileEntity(blockState).getPersistentDataContainer());
if (ret instanceof ReadableNBT || ret instanceof ReadableNBTList<?>) {
throw new NbtApiException("Tried returning part of the NBT to outside of the NBT scope!");
}
return ret;
}
/**
@@ -215,7 +558,9 @@ public class NBT {
* takes a ReadWriteNBT and does something with it.
*/
public static void modifyPersistentData(BlockState blockState, Consumer<ReadWriteNBT> consumer) {
consumer.accept(new NBTTileEntity(blockState).getPersistentDataContainer());
}
/**
@@ -225,7 +570,9 @@ public class NBT {
* @return A ReadWriteNBT object.
*/
public static ReadWriteNBT gameProfileToNBT(GameProfile profile) {
return NBTGameProfile.toNBT(profile);
}
/**
@@ -235,7 +582,9 @@ public class NBT {
* @return A GameProfile object.
*/
public static GameProfile gameProfileFromNBT(ReadableNBT compound) {
return NBTGameProfile.fromNBT((NBTCompound) compound);
}
/**
@@ -245,7 +594,9 @@ public class NBT {
* @return A ReadWriteNBT object.
*/
public static ReadWriteNBT itemStackToNBT(ItemStack itemStack) {
return NBTItem.convertItemtoNBT(itemStack);
}
/**
@@ -254,8 +605,11 @@ public class NBT {
* @param compound The NBT tag to convert to an ItemStack
* @return An ItemStack
*/
@Nullable
public static ItemStack itemStackFromNBT(ReadableNBT compound) {
return NBTItem.convertNBTtoItem((NBTCompound) compound);
}
/**
@@ -265,7 +619,9 @@ public class NBT {
* @return An NBTItem object.
*/
public static ReadWriteNBT itemStackArrayToNBT(ItemStack[] itemStacks) {
return NBTItem.convertItemArraytoNBT(itemStacks);
}
/**
@@ -274,8 +630,11 @@ public class NBT {
* @param compound The NBT tag to convert to an ItemStack array.
* @return An array of ItemStacks.
*/
@Nullable
public static ItemStack[] itemStackArrayFromNBT(ReadableNBT compound) {
return NBTItem.convertNBTtoItemArray((NBTCompound) compound);
}
/**
@@ -284,17 +643,244 @@ public class NBT {
* @return A new instance of the NBTContainer class.
*/
public static ReadWriteNBT createNBTObject() {
return new NBTContainer();
}
/**
* It takes a nbt json string, and returns a ReadWriteNBT object
*
* @param nbtString The NBT string to parse.
* @return A new NBTContainer object.
* @return A new ReadWriteNBT object.
*/
public static ReadWriteNBT parseNBT(String nbtString) {
return new NBTContainer(nbtString);
}
/**
* Reads in an NBT stream and returns a ReadWriteNBT object
*
* @param stream The NBT stream to read.
* @return A new ReadWriteNBT object.
*/
public static ReadWriteNBT readNBT(InputStream stream) {
return new NBTContainer(stream);
}
/**
* Helper method for other developers using NMS. Allows to wrap any
* net.minecraft.nbt.CompoundTag to a NBTAPI ReadWriteNBT object.
*
* @param nmsNbtTag Needs to be a valid net.minecraft.nbt.CompoundTag
* @return A new ReadWriteNBT object.
*/
public static ReadWriteNBT wrapNMSTag(Object nmsNbtTag) {
return new NBTContainer(nmsNbtTag);
}
/**
* Creates a NBTFileHandle that uses @param file to store its data. If this file
* exists, the data will be loaded, otherwise a new file gets created.
*
* @param file
* @throws IOException
*/
public static NBTFileHandle getFileHandle(File file) throws IOException {
return new NBTFile(file);
}
/**
* Reads NBT data from the provided file.
* <p>
* Returns an empty tag if the file does not exist.
*
* @param file file to read
* @return ReadWriteNBT of the files data
* @throws IOException exception
*/
public static ReadWriteNBT readFile(File file) throws IOException {
return NBTFile.readFrom(file);
}
/**
* Saves NBT data to the provided file.
* <p>
* Will fully override the file if it already exists.
*
* @param file file
* @param nbt NBT data
* @throws IOException exception
*/
public static void writeFile(File file, ReadWriteNBT nbt) throws IOException {
NBTFile.saveTo(file, (NBTCompound) nbt);
}
/**
* Create a read only proxy class for NBT, given an annotated interface.
*
* @param <T>
* @param item
* @param wrapper
* @return
*/
public static <T extends NBTProxy> T readNbt(ItemStack item, Class<T> wrapper) {
return new ProxyBuilder<>(new NBTItem(item, false, true, false), wrapper).readOnly().build();
}
/**
* Create a read only proxy class for NBT, given an annotated interface.
*
* @param <T>
* @param entity
* @param wrapper
* @return
*/
public static <T extends NBTProxy> T readNbt(Entity entity, Class<T> wrapper) {
return new ProxyBuilder<>(new NBTEntity(entity, true), wrapper).readOnly().build();
}
/**
* Create a read only proxy class for NBT, given an annotated interface.
*
* @param <T>
* @param blockState
* @param wrapper
* @return
*/
public static <T extends NBTProxy> T readNbt(BlockState blockState, Class<T> wrapper) {
return new ProxyBuilder<>(new NBTTileEntity(blockState, true), wrapper).readOnly().build();
}
/**
* It takes an ItemStack, applies a function to its NBT wrapped in a proxy, and
* returns the result of the function
*
* @param item The item you want to
* @param wrapper The target Proxy class
* @param function The function that will be applied to the item.
* @return The return value of the function.
*/
public static <T, X extends NBTProxy> T modify(ItemStack item, Class<X> wrapper, Function<X, T> function) {
NBTItem nbti = new NBTItem(item, false, false, true);
T val = function.apply(new ProxyBuilder<>(nbti, wrapper).build());
nbti.finalizeChanges();
if (val instanceof ReadableNBT || val instanceof ReadableNBTList<?>) {
throw new NbtApiException("Tried returning part of the NBT to outside of the NBT scope!");
}
nbti.setClosed();
return val;
}
/**
* It takes an ItemStack, applies a function to its NBT wrapped in a proxy.
*
* @param item The item you want to modify
* @param wrapper The target Proxy class
* @param consumer The consumer that will be used to modify the NBT.
*/
public static <X extends NBTProxy> void modify(ItemStack item, Class<X> wrapper, Consumer<X> consumer) {
NBTItem nbti = new NBTItem(item, false, false, true);
consumer.accept(new ProxyBuilder<>(nbti, wrapper).build());
nbti.finalizeChanges();
nbti.setClosed();
}
/**
* It takes an entity and a function to modify the entity via the proxy
*
* @param entity The entity to modify
* @param wrapper The target Proxy class
* @param consumer The consumer that will be called with the proxy.
*/
public static <X extends NBTProxy> void modify(Entity entity, Class<X> wrapper, Consumer<X> consumer) {
NBTEntity nbtEnt = new NBTEntity(entity);
NBTContainer cont = new NBTContainer(nbtEnt.getCompound());
consumer.accept(new ProxyBuilder<>(cont, wrapper).build());
nbtEnt.setCompound(cont.getCompound());
cont.setClosed();
}
/**
* It takes an entity and a function to modify the entity via the proxy
*
* @param entity The entity to modify
* @param wrapper The target Proxy class
* @param function The Function that will be called with the proxy.
* @return The return value of the function.
*/
public static <T, X extends NBTProxy> T modify(Entity entity, Class<X> wrapper, Function<X, T> function) {
NBTEntity nbtEnt = new NBTEntity(entity);
NBTContainer cont = new NBTContainer(nbtEnt.getCompound());
T val = function.apply(new ProxyBuilder<>(cont, wrapper).build());
nbtEnt.setCompound(cont.getCompound());
cont.setClosed();
return val;
}
/**
* It takes an block entity and a function to modify the entity via the proxy
*
* @param blockState The blockstate you want to modify
* @param wrapper The target Proxy class
* @param consumer The Consumer that will be called.
*/
public static <X extends NBTProxy> void modify(BlockState blockState, Class<X> wrapper, Consumer<X> consumer) {
NBTTileEntity blockEnt = new NBTTileEntity(blockState);
NBTContainer cont = new NBTContainer(blockEnt.getCompound());
consumer.accept(new ProxyBuilder<>(cont, wrapper).build());
blockEnt.setCompound(cont);
cont.setClosed();
}
/**
* It takes an block entity and a function to modify the entity via the proxy
*
* @param blockState The blockstate you want to modify
* @param wrapper The target Proxy class
* @param function The function that will be called.
* @return The return value of the function.
*/
public static <T, X extends NBTProxy> T modify(BlockState blockState, Class<X> wrapper, Function<X, T> function) {
NBTTileEntity blockEnt = new NBTTileEntity(blockState);
NBTContainer cont = new NBTContainer(blockEnt.getCompound());
T val = function.apply(new ProxyBuilder<>(cont, wrapper).build());
blockEnt.setCompound(cont);
cont.setClosed();
return val;
}
}
@@ -12,7 +12,7 @@ import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
* instead!
*
* - The data is really just on the location. If the block gets
* broken/changed/explodes/moved etc, the data is still on that location!
* broken/changed/exploded/moved etc., the data is still on that location!
*
* @author tr7zw
*
@@ -23,16 +23,23 @@ public class NBTBlock {
private final NBTChunk nbtChunk;
public NBTBlock(Block block) {
this.block = block;
if (!MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_16_R3)) {
throw new NbtApiException("NBTBlock is only working for 1.16.4+!");
}
nbtChunk = new NBTChunk(block.getChunk());
}
public NBTCompound getData() {
return nbtChunk.getPersistentDataContainer().getOrCreateCompound("blocks")
.getOrCreateCompound(block.getX() + "_" + block.getY() + "_" + block.getZ());
}
}
@@ -2,17 +2,17 @@ package de.tr7zw.changeme.nbtapi;
import org.bukkit.Chunk;
import de.tr7zw.annotations.FAUtil;
import de.tr7zw.changeme.nbtapi.utils.CheckUtil;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import de.tr7zw.changeme.nbtapi.utils.annotations.AvailableSince;
import de.tr7zw.changeme.nbtapi.utils.annotations.CheckUtil;
public class NBTChunk {
private final Chunk chunk;
public NBTChunk(Chunk chunk) {
this.chunk = chunk;
}
/**
@@ -21,10 +21,11 @@ public class NBTChunk {
*
* @return NBTCompound containing the data of the PersistentDataAPI
*/
@AvailableSince(version = MinecraftVersion.MC1_16_R3)
public NBTCompound getPersistentDataContainer() {
FAUtil.check(this::getPersistentDataContainer, CheckUtil::isAvaliable);
CheckUtil.assertAvailable(MinecraftVersion.MC1_16_R3);
return new NBTPersistentDataContainer(chunk.getPersistentDataContainer());
}
}
File diff suppressed because it is too large. Load diff
@@ -2,6 +2,7 @@ package de.tr7zw.changeme.nbtapi;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBTCompoundList;
import de.tr7zw.changeme.nbtapi.iface.ReadableNBT;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
@@ -15,7 +16,9 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
public class NBTCompoundList extends NBTList<ReadWriteNBT> implements ReadWriteNBTCompoundList {
protected NBTCompoundList(NBTCompound owner, String name, NBTType type, Object list) {
super(owner, name, type, list);
}
/**
@@ -24,7 +27,9 @@ public class NBTCompoundList extends NBTList<ReadWriteNBT> implements ReadWriteN
* @return The added {@link NBTListCompound}
*/
public NBTListCompound addCompound() {
return (NBTListCompound) addCompound(null);
}
/**
@@ -35,29 +40,55 @@ public class NBTCompoundList extends NBTList<ReadWriteNBT> implements ReadWriteN
* @return
*/
public NBTCompound addCompound(NBTCompound comp) {
if (getParent().isReadOnly()) {
throw new NbtApiException("Tried setting data in read only mode!");
}
try {
Object compound = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) {
ReflectionMethod.LIST_ADD.run(listObject, size(), compound);
} else {
ReflectionMethod.LEGACY_LIST_ADD.run(listObject, compound);
}
getParent().saveCompound();
NBTListCompound listcomp = new NBTListCompound(this, compound);
if (comp != null) {
listcomp.mergeCompound(comp);
}
return listcomp;
} catch (Exception ex) {
throw new NbtApiException(ex);
}
}
public NBTCompound addCompound(ReadWriteNBT comp) {
@Override
public ReadWriteNBT addCompound(ReadableNBT comp) {
if (comp instanceof NBTCompound) {
return addCompound((NBTCompound) comp);
}
return null;
}
/**
@@ -71,45 +102,77 @@ public class NBTCompoundList extends NBTList<ReadWriteNBT> implements ReadWriteN
@Override
@Deprecated
public boolean add(ReadWriteNBT empty) {
return addCompound(empty) != null;
}
@Override
public void add(int index, ReadWriteNBT element) {
if (element != null) {
throw new NbtApiException("You need to pass null! ListCompounds from other lists won't work.");
}
if (getParent().isReadOnly()) {
throw new NbtApiException("Tried setting data in read only mode!");
}
try {
Object compound = ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().newInstance();
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) {
ReflectionMethod.LIST_ADD.run(listObject, index, compound);
} else {
ReflectionMethod.LEGACY_LIST_ADD.run(listObject, compound);
}
super.getParent().saveCompound();
} catch (Exception ex) {
throw new NbtApiException(ex);
}
}
@Override
public NBTListCompound get(int index) {
try {
Object compound = ReflectionMethod.LIST_GET_COMPOUND.run(listObject, index);
return new NBTListCompound(this, compound);
} catch (Exception ex) {
throw new NbtApiException(ex);
}
}
@Override
public NBTListCompound set(int index, ReadWriteNBT element) {
throw new NbtApiException("This method doesn't work in the ListCompound context.");
}
@Override
protected Object asTag(ReadWriteNBT object) {
return null;
}
}
@@ -16,39 +16,58 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
public class NBTContainer extends NBTCompound {
private Object nbt;
private boolean closed;
private boolean readOnly;
/**
* Creates an empty, standalone NBTCompound
*/
@Deprecated
public NBTContainer() {
super(null, null);
nbt = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
}
/**
* Takes in any NMS Compound to wrap it
*
* @param nbt
* @deprecated Use NBT.wrapNMSTag
*/
@Deprecated
public NBTContainer(Object nbt) {
super(null, null);
if (nbt == null) {
throw new NullPointerException("The NBT-Object can't be null!");
nbt = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
}
if (!ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().isAssignableFrom(nbt.getClass())) {
throw new NbtApiException("The object '" + nbt.getClass() + "' is not a valid NBT-Object!");
}
this.nbt = nbt;
}
/**
* Reads in a NBT InputStream
*
* @param inputsteam
* @deprecated Use NBT.readNBT
*/
@Deprecated
public NBTContainer(InputStream inputsteam) {
super(null, null);
this.nbt = NBTReflectionUtil.readNBT(inputsteam);
}
/**
@@ -56,27 +75,69 @@ public class NBTContainer extends NBTCompound {
* {@link NbtApiException} in case something goes wrong.
*
* @param nbtString
* @deprecated Use NBT.parseNBT
*/
@Deprecated
public NBTContainer(String nbtString) {
super(null, null);
if (nbtString == null) {
throw new NullPointerException("The String can't be null!");
}
try {
nbt = ReflectionMethod.PARSE_NBT.run(null, nbtString);
} catch (Exception ex) {
throw new NbtApiException("Unable to parse Malformed Json!", ex);
}
}
@Override
public Object getCompound() {
return nbt;
}
@Override
public void setCompound(Object tag) {
nbt = tag;
}
@Override
protected void setClosed() {
this.closed = true;
}
@Override
protected boolean isClosed() {
return closed;
}
protected boolean isReadOnly() {
return readOnly;
}
protected NBTContainer setReadOnly(boolean readOnly) {
this.readOnly = true;
return this;
}
}
@@ -15,31 +15,48 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
public class NBTDoubleList extends NBTList<Double> {
protected NBTDoubleList(NBTCompound owner, String name, NBTType type, Object list) {
super(owner, name, type, list);
}
@Override
protected Object asTag(Double object) {
try {
Constructor<?> con = ClassWrapper.NMS_NBTTAGDOUBLE.getClazz().getDeclaredConstructor(double.class);
con.setAccessible(true);
return con.newInstance(object);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
| NoSuchMethodException | SecurityException e)
{
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
}
}
@Override
public Double get(int index) {
try {
Object obj = ReflectionMethod.LIST_GET.run(listObject, index);
return Double.valueOf(obj.toString());
} catch (NumberFormatException nf) {
return 0d;
} catch (Exception ex) {
throw new NbtApiException(ex);
}
}
}
@@ -3,10 +3,8 @@ package de.tr7zw.changeme.nbtapi;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import de.tr7zw.annotations.FAUtil;
import de.tr7zw.changeme.nbtapi.utils.CheckUtil;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import de.tr7zw.changeme.nbtapi.utils.annotations.AvailableSince;
import de.tr7zw.changeme.nbtapi.utils.annotations.CheckUtil;
/**
* NBT class to access vanilla tags from Entities. Entities don't support custom
@@ -19,30 +17,108 @@ import de.tr7zw.changeme.nbtapi.utils.annotations.CheckUtil;
public class NBTEntity extends NBTCompound {
private final Entity ent;
private final boolean readonly;
private final Object compound;
private boolean closed = false;
/**
* @param entity Any valid Bukkit Entity
* @param entity Any valid Bukkit Entity
* @param readonly Readonly makes a copy at init, only reading from that copy
*/
public NBTEntity(Entity entity) {
protected NBTEntity(Entity entity, boolean readonly) {
super(null, null);
if (entity == null) {
throw new NullPointerException("Entity can't be null!");
}
this.readonly = readonly;
ent = entity;
if (readonly) {
this.compound = getCompound();
} else {
this.compound = null;
}
}
/**
* Deprecated: Please use the NBT class
*
* @param entity Any valid Bukkit Entity
*/
@Deprecated
public NBTEntity(Entity entity) {
super(null, null);
if (entity == null) {
throw new NullPointerException("Entity can't be null!");
}
this.readonly = false;
this.compound = null;
ent = entity;
}
@Override
protected void setClosed() {
this.closed = true;
}
@Override
protected boolean isClosed() {
return closed;
}
@Override
protected boolean isReadOnly() {
return readonly;
}
@Override
public Object getCompound() {
// this runs before async check, since it's just a copy
if (readonly && compound != null) {
return compound;
}
if (!Bukkit.isPrimaryThread())
throw new NbtApiException("Entity NBT needs to be accessed sync!");
return NBTReflectionUtil.getEntityNBTTagCompound(NBTReflectionUtil.getNMSEntity(ent));
}
@Override
protected void setCompound(Object compound) {
if (readonly) {
throw new NbtApiException("Tried setting data in read only mode!");
}
if (!Bukkit.isPrimaryThread())
throw new NbtApiException("Entity NBT needs to be accessed sync!");
NBTReflectionUtil.setEntityNBTTag(compound, NBTReflectionUtil.getNMSEntity(ent));
}
/**
@@ -51,10 +127,11 @@ public class NBTEntity extends NBTCompound {
*
* @return NBTCompound containing the data of the PersistentDataAPI
*/
@AvailableSince(version = MinecraftVersion.MC1_14_R1)
public NBTCompound getPersistentDataContainer() {
FAUtil.check(this::getPersistentDataContainer, CheckUtil::isAvaliable);
CheckUtil.assertAvailable(MinecraftVersion.MC1_14_R1);
return new NBTPersistentDataContainer(ent.getPersistentDataContainer());
}
}
@@ -4,6 +4,7 @@ import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import de.tr7zw.changeme.nbtapi.iface.NBTFileHandle;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ObjectCreator;
/**
@@ -12,30 +13,41 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ObjectCreator;
* @author tr7zw
*
*/
public class NBTFile extends NBTCompound {
public class NBTFile extends NBTCompound implements NBTFileHandle {
private final File file;
private Object nbt;
/**
* Creates a NBTFile that uses @param file to store it's data. If this file
* Creates a NBTFile that uses @param file to store its data. If this file
* exists, the data will be loaded.
*
* @param file
* @throws IOException
* @deprecated Use NBT.getFileHandle(file)
*/
@Deprecated
public NBTFile(File file) throws IOException {
super(null, null);
if (file == null) {
throw new NullPointerException("File can't be null!");
}
this.file = file;
if (file.exists()) {
nbt = NBTReflectionUtil.readNBT(Files.newInputStream(file.toPath()));
} else {
nbt = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
save();
}
}
/**
@@ -43,30 +55,44 @@ public class NBTFile extends NBTCompound {
*
* @throws IOException
*/
@Override
public void save() throws IOException {
try {
getWriteLock().lock();
saveTo(file, this);
} finally {
getWriteLock().unlock();
}
}
/**
* @return The File used to store the data
*/
@Override
public File getFile() {
return file;
}
@Override
public Object getCompound() {
return nbt;
}
@Override
protected void setCompound(Object compound) {
nbt = compound;
}
/**
@@ -77,11 +103,15 @@ public class NBTFile extends NBTCompound {
* @param file file to read
* @return NBTCompound holding file's nbt data
* @throws IOException exception
* @deprecated Use NBT.readFile(file)
*/
@Deprecated
public static NBTCompound readFrom(File file) throws IOException {
if (!file.exists())
return new NBTContainer();
return new NBTContainer(NBTReflectionUtil.readNBT(Files.newInputStream(file.toPath())));
}
/**
@@ -92,14 +122,21 @@ public class NBTFile extends NBTCompound {
* @param file file
* @param nbt NBT data
* @throws IOException exception
* @deprecated Use NBT.writeFile(file, nbt)
*/
@Deprecated
public static void saveTo(File file, NBTCompound nbt) throws IOException {
if (!file.exists()) {
file.getParentFile().mkdirs();
if (!file.createNewFile())
throw new IOException("Unable to create file at " + file.getAbsolutePath());
}
NBTReflectionUtil.writeNBT(nbt.getCompound(), Files.newOutputStream(file.toPath()));
nbt.writeCompound(Files.newOutputStream(file.toPath()));
}
}
@@ -15,31 +15,48 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
public class NBTFloatList extends NBTList<Float> {
protected NBTFloatList(NBTCompound owner, String name, NBTType type, Object list) {
super(owner, name, type, list);
}
@Override
protected Object asTag(Float object) {
try {
Constructor<?> con = ClassWrapper.NMS_NBTTAGFLOAT.getClazz().getDeclaredConstructor(float.class);
con.setAccessible(true);
return con.newInstance(object);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
| NoSuchMethodException | SecurityException e)
{
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
}
}
@Override
public Float get(int index) {
try {
Object obj = ReflectionMethod.LIST_GET.run(listObject, index);
return Float.valueOf(obj.toString());
} catch (NumberFormatException nf) {
return 0f;
} catch (Exception ex) {
throw new NbtApiException(ex);
}
}
}
@@ -2,6 +2,8 @@ package de.tr7zw.changeme.nbtapi;
import com.mojang.authlib.GameProfile;
import de.tr7zw.changeme.nbtapi.utils.GameprofileUtil;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ObjectCreator;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
@@ -13,9 +15,18 @@ public class NBTGameProfile {
* @param profile
* @return A NBTContainer with all the GameProfile data
*/
@Deprecated
public static NBTCompound toNBT(GameProfile profile) {
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
return (NBTCompound) GameprofileUtil.writeGameProfile(NBT.createNBTObject(), profile);
}
return new NBTContainer(ReflectionMethod.GAMEPROFILE_SERIALIZE.run(null,
ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance(), profile));
}
/**
@@ -24,9 +35,18 @@ public class NBTGameProfile {
* @param compound Has to contain GameProfile data
* @return The reconstructed GameProfile
*/
@Deprecated
public static GameProfile fromNBT(NBTCompound compound) {
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
return GameprofileUtil.readGameProfile(compound);
}
return (GameProfile) ReflectionMethod.GAMEPROFILE_DESERIALIZE.run(null,
NBTReflectionUtil.gettoCompount(compound.getCompound(), compound));
NBTReflectionUtil.getToCompount(compound.getCompound(), compound));
}
}
@@ -17,35 +17,52 @@ public class NBTIntArrayList extends NBTList<int[]> {
private final NBTContainer tmpContainer;
protected NBTIntArrayList(NBTCompound owner, String name, NBTType type, Object list) {
super(owner, name, type, list);
this.tmpContainer = new NBTContainer();
}
@Override
protected Object asTag(int[] object) {
try {
Constructor<?> con = ClassWrapper.NMS_NBTTAGINTARRAY.getClazz().getDeclaredConstructor(int[].class);
con.setAccessible(true);
return con.newInstance(object);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
| NoSuchMethodException | SecurityException e)
{
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
}
}
@Override
public int[] get(int index) {
try {
Object obj = ReflectionMethod.LIST_GET.run(listObject, index);
ReflectionMethod.COMPOUND_SET.run(tmpContainer.getCompound(), "tmp", obj);
int[] val = tmpContainer.getIntArray("tmp");
tmpContainer.removeKey("tmp");
return val;
} catch (NumberFormatException nf) {
return null;
} catch (Exception ex) {
throw new NbtApiException(ex);
}
}
}
@@ -15,31 +15,48 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
public class NBTIntegerList extends NBTList<Integer> {
protected NBTIntegerList(NBTCompound owner, String name, NBTType type, Object list) {
super(owner, name, type, list);
}
@Override
protected Object asTag(Integer object) {
try {
Constructor<?> con = ClassWrapper.NMS_NBTTAGINT.getClazz().getDeclaredConstructor(int.class);
con.setAccessible(true);
return con.newInstance(object);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
| NoSuchMethodException | SecurityException e)
{
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
}
}
@Override
public Integer get(int index) {
try {
Object obj = ReflectionMethod.LIST_GET.run(listObject, index);
return Integer.valueOf(obj.toString());
} catch (NumberFormatException nf) {
return 0;
} catch (Exception ex) {
throw new NbtApiException(ex);
}
}
}
@@ -1,7 +1,10 @@
package de.tr7zw.changeme.nbtapi;
import java.util.Set;
import java.util.function.BiConsumer;
import javax.annotation.Nullable;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@@ -9,6 +12,8 @@ import org.bukkit.inventory.meta.ItemMeta;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteItemNBT;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.changeme.nbtapi.iface.ReadableNBT;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
/**
@@ -21,16 +26,66 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
public class NBTItem extends NBTCompound implements ReadWriteItemNBT {
private ItemStack bukkitItem;
private boolean directApply;
private final boolean directApply;
private final boolean finalizer;
private ItemStack originalSrcStack = null;
private Object cachedCompound = null;
private boolean closed = false;
/**
* Constructor for NBTItems. The ItemStack will be cloned!
* Constructor for NBTItems. The ItemStack will be cloned! Deprecated: Please
* use the NBT class to work with items. It's up to 400% faster and provides
* less ways to mess up code.
*
* @param item
*/
@Deprecated
public NBTItem(ItemStack item) {
this(item, false);
}
/**
* @param item
* @param directApply
* @param readOnly When turned on, no copy of the source item is created.
* Modifying the stack in that case is not valid! Also
* overwrites directApply
*/
protected NBTItem(ItemStack item, boolean directApply, boolean readOnly, boolean finalizer) {
super(null, null, readOnly);
if (item == null || item.getType() == Material.AIR || item.getAmount() <= 0) {
throw new NullPointerException("ItemStack can't be null/air/amount of 0! This is not a NBTAPI bug!");
}
this.finalizer = finalizer;
if (finalizer) {
this.bukkitItem = item;
this.originalSrcStack = item;
this.directApply = false;
} else if (readOnly) {
bukkitItem = item;
this.directApply = false;
} else {
this.directApply = directApply;
bukkitItem = item.clone();
if (directApply) {
this.originalSrcStack = item;
}
}
}
/**
@@ -41,28 +96,166 @@ public class NBTItem extends NBTCompound implements ReadWriteItemNBT {
* @param item
* @param directApply
*/
@Deprecated
public NBTItem(ItemStack item, boolean directApply) {
super(null, null);
if (item == null || item.getType() == Material.AIR || item.getAmount() <= 0) {
throw new NullPointerException("ItemStack can't be null/air/amount of 0! This is not a NBTAPI bug!");
}
this.finalizer = false;
this.directApply = directApply;
bukkitItem = item.clone();
if (directApply) {
this.originalSrcStack = item;
}
}
@Override
public Object getCompound() {
if (closed) {
throw new NbtApiException("Tried using closed NBT data!");
}
if (isReadOnly() && (cachedCompound != null
|| ClassWrapper.CRAFT_ITEMSTACK.getClazz().isAssignableFrom(bukkitItem.getClass())))
{
if (cachedCompound == null) {
cachedCompound = NBTReflectionUtil
.getItemRootNBTTagCompound(NBTReflectionUtil.getCraftItemHandle(bukkitItem));
}
return cachedCompound;
}
if (finalizer) {
if (cachedCompound == null) {
updateCachedCompound();
}
return cachedCompound;
}
return NBTReflectionUtil.getItemRootNBTTagCompound(ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, bukkitItem));
}
private void updateCachedCompound() {
if (finalizer) {
cachedCompound = NBTReflectionUtil
.getItemRootNBTTagCompound(ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, bukkitItem));
}
}
protected void finalizeChanges() {
if (!finalizer || cachedCompound == null) {
return;
}
// There was data, but not anymore, delete the tag from the itemstack
if (NBTReflectionUtil.getKeys(this).isEmpty()) {
cachedCompound = null;
}
if (ClassWrapper.CRAFT_ITEMSTACK.getClazz().isAssignableFrom(originalSrcStack.getClass())) {
Object nmsStack = NBTReflectionUtil.getCraftItemHandle(originalSrcStack);
NBTReflectionUtil.setItemStackCompound(nmsStack, cachedCompound);
bukkitItem = originalSrcStack;
} else {
Object stack = ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, bukkitItem);
NBTReflectionUtil.setItemStackCompound(stack, cachedCompound);
bukkitItem = (ItemStack) ReflectionMethod.ITEMSTACK_BUKKITMIRROR.run(null, stack);
originalSrcStack.setItemMeta(bukkitItem.getItemMeta());
}
}
@Override
protected void setClosed() {
this.closed = true;
}
@Override
protected boolean isClosed() {
return closed;
}
@SuppressWarnings("unchecked")
@Override
protected void setCompound(Object compound) {
Object stack = ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, bukkitItem);
ReflectionMethod.ITEMSTACK_SET_TAG.run(stack, compound);
bukkitItem = (ItemStack) ReflectionMethod.ITEMSTACK_BUKKITMIRROR.run(null, stack);
if (isReadOnly()) {
throw new NbtApiException("Tried setting data in read only mode!");
}
if (closed) {
throw new NbtApiException("Tried using closed NBT data!");
}
if (finalizer) {
cachedCompound = compound;
return;
}
if (compound != null && ((Set<String>) ReflectionMethod.COMPOUND_GET_KEYS.run(compound)).isEmpty()) {
compound = null;
}
if (ClassWrapper.CRAFT_ITEMSTACK.getClazz().isAssignableFrom(bukkitItem.getClass())) {
Object nmsStack = NBTReflectionUtil.getCraftItemHandle(bukkitItem);
NBTReflectionUtil.setItemStackCompound(nmsStack, compound);
} else {
Object stack = ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, bukkitItem);
NBTReflectionUtil.setItemStackCompound(stack, compound);
bukkitItem = (ItemStack) ReflectionMethod.ITEMSTACK_BUKKITMIRROR.run(null, stack);
}
}
/**
@@ -74,13 +267,19 @@ public class NBTItem extends NBTCompound implements ReadWriteItemNBT {
*
* @param item ItemStack that should get the new NBT data
*/
@Deprecated
public void applyNBT(ItemStack item) {
if (item == null || item.getType() == Material.AIR) {
throw new NullPointerException("ItemStack can't be null/Air! This is not a NBTAPI bug!");
}
NBTItem nbti = new NBTItem(new ItemStack(item.getType()));
nbti.mergeCompound(this);
item.setItemMeta(nbti.getItem().getItemMeta());
}
/**
@@ -88,10 +287,13 @@ public class NBTItem extends NBTCompound implements ReadWriteItemNBT {
*
* @param item ItemStack that should get the new NBT data
*/
@Deprecated
public void mergeNBT(ItemStack item) {
NBTItem nbti = new NBTItem(item);
nbti.mergeCompound(this);
item.setItemMeta(nbti.getItem().getItemMeta());
}
/**
@@ -99,14 +301,32 @@ public class NBTItem extends NBTCompound implements ReadWriteItemNBT {
*
* @param item ItemStack that should get the new NBT data
*/
@Deprecated
public void mergeCustomNBT(ItemStack item) {
if (item == null || item.getType() == Material.AIR) {
throw new NullPointerException("ItemStack can't be null/Air!");
}
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
// 1.20.5+ doesn't have any vanilla tags
NBT.modify(item, nbt -> {
nbt.mergeCompound(this);
});
return;
}
ItemMeta meta = item.getItemMeta();
NBTReflectionUtil.getUnhandledNBTTags(meta)
.putAll(NBTReflectionUtil.getUnhandledNBTTags(bukkitItem.getItemMeta()));
item.setItemMeta(meta);
}
/**
@@ -114,38 +334,69 @@ public class NBTItem extends NBTCompound implements ReadWriteItemNBT {
*
* @return true when custom tags are present
*/
@Deprecated
public boolean hasCustomNbtData() {
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
// 1.20.5+ doesn't have any vanilla tags
return hasNBTData();
}
finalizeChanges();
ItemMeta meta = bukkitItem.getItemMeta();
return !NBTReflectionUtil.getUnhandledNBTTags(meta).isEmpty();
}
/**
* Remove all custom (non-vanilla) NBT tags from the NBTItem.
*/
@Deprecated
public void clearCustomNBT() {
finalizeChanges();
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
// 1.20.5+ doesn't have any vanilla tags
setCompound(null);
return;
}
ItemMeta meta = bukkitItem.getItemMeta();
NBTReflectionUtil.getUnhandledNBTTags(meta).clear();
bukkitItem.setItemMeta(meta);
updateCachedCompound();
}
/**
* @return The modified ItemStack
*/
public ItemStack getItem() {
return bukkitItem;
}
protected void setItem(ItemStack item) {
bukkitItem = item;
}
/**
* This may return true even when the NBT is empty.
* Returns true if the item has NBT data. This needs to be checked before
* calling methods like remove, otherwise the value might be wrong!
*
* @return Does the ItemStack have a NBTCompound.
*/
public boolean hasNBTData() {
return getCompound() != null;
}
/**
@@ -159,12 +410,25 @@ public class NBTItem extends NBTCompound implements ReadWriteItemNBT {
* @param handler
*/
public void modifyMeta(BiConsumer<ReadableNBT, ItemMeta> handler) {
finalizeChanges();
ItemMeta meta = bukkitItem.getItemMeta();
handler.accept(this, meta);
handler.accept(new NBTContainer(getResolvedObject()).setReadOnly(true), meta);
bukkitItem.setItemMeta(meta);
updateCachedCompound();
if (directApply) {
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
throw new NbtApiException(
"Direct apply mode meta changes don't work anymore in 1.20.5+. Please switch to the modern NBT.modify sytnax!");
}
applyNBT(originalSrcStack);
}
}
/**
@@ -178,13 +442,19 @@ public class NBTItem extends NBTCompound implements ReadWriteItemNBT {
* @param handler
*/
public <T extends ItemMeta> void modifyMeta(Class<T> type, BiConsumer<ReadableNBT, T> handler) {
finalizeChanges();
@SuppressWarnings("unchecked")
T meta = (T) bukkitItem.getItemMeta();
handler.accept(this, meta);
handler.accept(new NBTContainer(getResolvedObject()).setReadOnly(true), meta);
bukkitItem.setItemMeta(meta);
updateCachedCompound();
if (directApply) {
applyNBT(originalSrcStack);
}
}
/**
@@ -194,8 +464,11 @@ public class NBTItem extends NBTCompound implements ReadWriteItemNBT {
* @param item
* @return Standalone {@link NBTContainer} with the Item's data
*/
@Deprecated
public static NBTContainer convertItemtoNBT(ItemStack item) {
return NBTReflectionUtil.convertNMSItemtoNBTCompound(ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, item));
}
/**
@@ -205,39 +478,52 @@ public class NBTItem extends NBTCompound implements ReadWriteItemNBT {
* @param comp
* @return ItemStack using the {@link NBTCompound}'s data
*/
@Nullable
@Deprecated
public static ItemStack convertNBTtoItem(NBTCompound comp) {
return (ItemStack) ReflectionMethod.ITEMSTACK_BUKKITMIRROR.run(null,
NBTReflectionUtil.convertNBTCompoundtoNMSItem(comp));
}
/**
* Helper method that converts {@link ItemStack}[] to {@link NBTContainer} with
* all it data like Material, Damage, Amount and Tags. This is a custom
* all its data like Material, Damage, Amount and Tags. This is a custom
* implementation and won't work with vanilla code(Shulker content etc).
*
* @param items
* @return Standalone {@link NBTContainer} with the Item's data
*/
@Deprecated
public static NBTContainer convertItemArraytoNBT(ItemStack[] items) {
NBTContainer container = new NBTContainer();
container.setInteger("size", items.length);
NBTCompoundList list = container.getCompoundList("items");
for (int i = 0; i < items.length; i++) {
ItemStack item = items[i];
if (item == null || item.getType() == Material.AIR) {
continue;
}
NBTListCompound entry = list.addCompound();
entry.setInteger("Slot", i);
entry.mergeCompound(convertItemtoNBT(item));
}
return container;
}
/**
* Helper method to do the inverse of "convertItemArraytoNBT". Creates an
* {@link ItemStack}[] using the {@link NBTCompound}. This is a custom
* implementation and won't work with vanilla code(Shulker content etc).
* implementation and won't work with vanilla code (Shulker content, etc.).
*
* Will return null for invalid data. Empty slots in the array are filled with
* AIR Stacks!
@@ -245,32 +531,54 @@ public class NBTItem extends NBTCompound implements ReadWriteItemNBT {
* @param comp
* @return ItemStack[] using the {@link NBTCompound}'s data
*/
@Nullable
@Deprecated
public static ItemStack[] convertNBTtoItemArray(NBTCompound comp) {
if (!comp.hasTag("size")) {
return null;
}
ItemStack[] rebuild = new ItemStack[comp.getInteger("size")];
for (int i = 0; i < rebuild.length; i++) { // not using Arrays.fill, since then it's all the same instance
rebuild[i] = new ItemStack(Material.AIR);
}
if (!comp.hasTag("items")) {
return rebuild;
}
NBTCompoundList list = comp.getCompoundList("items");
for (ReadWriteNBT lcomp : list) {
if (lcomp instanceof NBTCompound) {
int slot = lcomp.getInteger("Slot");
rebuild[slot] = convertNBTtoItem((NBTCompound) lcomp);
}
}
return rebuild;
}
@Override
protected void saveCompound() {
if (directApply) {
applyNBT(originalSrcStack);
}
}
}
@@ -28,107 +28,195 @@ public abstract class NBTList<T> implements List<T>, ReadWriteNBTList<T> {
protected Object listObject;
protected NBTList(NBTCompound owner, String name, NBTType type, Object list) {
parent = owner;
listName = name;
this.type = type;
this.listObject = list;
}
/**
* @return Name of this list-compound
*/
public String getName() {
return listName;
}
/**
* @return The Compound's parent Object
*/
public NBTCompound getParent() {
return parent;
}
private void validateClosed() {
if (parent.isClosed()) {
throw new NbtApiException("Tried using closed NBT data!");
}
}
private void validateWritable() {
if (getParent().isReadOnly()) {
throw new NbtApiException("Tried setting data in read only mode!");
}
}
protected void save() {
validateClosed();
parent.set(listName, listObject);
}
protected abstract Object asTag(T object);
@Override
public boolean add(T element) {
validateClosed();
validateWritable();
try {
parent.getWriteLock().lock();
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) {
ReflectionMethod.LIST_ADD.run(listObject, size(), asTag(element));
} else {
ReflectionMethod.LEGACY_LIST_ADD.run(listObject, asTag(element));
}
save();
return true;
} catch (Exception ex) {
throw new NbtApiException(ex);
} finally {
parent.getWriteLock().unlock();
}
}
@Override
public void add(int index, T element) {
validateClosed();
validateWritable();
try {
parent.getWriteLock().lock();
if (MinecraftVersion.getVersion().getVersionId() >= MinecraftVersion.MC1_14_R1.getVersionId()) {
ReflectionMethod.LIST_ADD.run(listObject, index, asTag(element));
} else {
ReflectionMethod.LEGACY_LIST_ADD.run(listObject, asTag(element));
}
save();
} catch (Exception ex) {
throw new NbtApiException(ex);
} finally {
parent.getWriteLock().unlock();
}
}
@Override
public T set(int index, T element) {
validateClosed();
validateWritable();
try {
parent.getWriteLock().lock();
T prev = get(index);
ReflectionMethod.LIST_SET.run(listObject, index, asTag(element));
save();
return prev;
} catch (Exception ex) {
throw new NbtApiException(ex);
} finally {
parent.getWriteLock().unlock();
}
}
@Override
public T remove(int i) {
validateClosed();
validateWritable();
try {
parent.getWriteLock().lock();
T old = get(i);
ReflectionMethod.LIST_REMOVE_KEY.run(listObject, i);
save();
return old;
} catch (Exception ex) {
throw new NbtApiException(ex);
} finally {
parent.getWriteLock().unlock();
}
}
@Override
public int size() {
validateClosed();
try {
parent.getReadLock().lock();
return (int) ReflectionMethod.LIST_SIZE.run(listObject);
} catch (Exception ex) {
throw new NbtApiException(ex);
} finally {
parent.getReadLock().unlock();
}
}
/**
@@ -136,186 +224,300 @@ public abstract class NBTList<T> implements List<T>, ReadWriteNBTList<T> {
*/
@Override
public NBTType getType() {
return type;
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public void clear() {
while (!isEmpty()) {
remove(0);
}
}
@Override
public boolean contains(Object o) {
validateClosed();
try {
parent.getReadLock().lock();
for (int i = 0; i < size(); i++) {
if (o.equals(get(i)))
return true;
}
return false;
} finally {
parent.getReadLock().unlock();
}
}
@Override
public int indexOf(Object o) {
validateClosed();
try {
parent.getReadLock().lock();
for (int i = 0; i < size(); i++) {
if (o.equals(get(i)))
return i;
}
return -1;
} finally {
parent.getReadLock().unlock();
}
}
@Override
public boolean addAll(Collection<? extends T> c) {
validateClosed();
try {
parent.getWriteLock().lock();
int size = size();
for (T ele : c) {
add(ele);
}
return size != size();
} finally {
parent.getWriteLock().unlock();
}
}
@Override
public boolean addAll(int index, Collection<? extends T> c) {
validateClosed();
try {
parent.getWriteLock().lock();
int size = size();
for (T ele : c) {
add(index++, ele);
}
return size != size();
} finally {
parent.getWriteLock().unlock();
}
}
@Override
public boolean containsAll(Collection<?> c) {
validateClosed();
try {
parent.getReadLock().lock();
for (Object ele : c) {
if (!contains(ele))
return false;
}
return true;
} finally {
parent.getReadLock().unlock();
}
}
@Override
public int lastIndexOf(Object o) {
validateClosed();
try {
parent.getReadLock().lock();
int index = -1;
for (int i = 0; i < size(); i++) {
if (o.equals(get(i)))
index = i;
}
return index;
} finally {
parent.getReadLock().unlock();
}
}
@Override
public boolean removeAll(Collection<?> c) {
validateClosed();
try {
parent.getWriteLock().lock();
int size = size();
for (Object obj : c) {
remove(obj);
}
return size != size();
} finally {
parent.getWriteLock().unlock();
}
}
@Override
public boolean retainAll(Collection<?> c) {
validateClosed();
try {
parent.getWriteLock().lock();
int size = size();
for (Object obj : c) {
for (int i = 0; i < size(); i++) {
if (!obj.equals(get(i))) {
remove(i--);
}
}
}
return size != size();
} finally {
parent.getWriteLock().unlock();
}
}
@Override
public boolean remove(Object o) {
validateClosed();
try {
parent.getWriteLock().lock();
int size = size();
int id = -1;
while ((id = indexOf(o)) != -1) {
remove(id);
}
return size != size();
} finally {
parent.getWriteLock().unlock();
}
}
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
private int index = -1;
@Override
public boolean hasNext() {
return size() > index + 1;
}
@Override
public T next() {
if (!hasNext())
throw new NoSuchElementException();
return get(++index);
}
@Override
public void remove() {
NBTList.this.remove(index);
index--;
}
};
}
@Override
public ListIterator<T> listIterator() {
return listIterator(0);
}
@Override
public ListIterator<T> listIterator(int startIndex) {
final NBTList<T> list = this;
return new ListIterator<T>() {
@@ -323,117 +525,174 @@ public abstract class NBTList<T> implements List<T>, ReadWriteNBTList<T> {
@Override
public void add(T e) {
list.add(index, e);
}
@Override
public boolean hasNext() {
return size() > index + 1;
}
@Override
public boolean hasPrevious() {
return index >= 0 && index <= size();
}
@Override
public T next() {
if (!hasNext())
throw new NoSuchElementException();
return get(++index);
}
@Override
public int nextIndex() {
return index + 1;
}
@Override
public T previous() {
if (!hasPrevious())
throw new NoSuchElementException("Id: " + (index - 1));
return get(index--);
}
@Override
public int previousIndex() {
return index - 1;
}
@Override
public void remove() {
list.remove(index);
index--;
}
@Override
public void set(T e) {
list.set(index, e);
}
};
}
@Override
public Object[] toArray() {
validateClosed();
try {
parent.getReadLock().lock();
Object[] ar = new Object[size()];
for (int i = 0; i < size(); i++)
ar[i] = get(i);
return ar;
} finally {
parent.getReadLock().unlock();
}
}
@SuppressWarnings("unchecked")
@Override
public <E> E[] toArray(E[] a) {
validateClosed();
try {
parent.getReadLock().lock();
E[] ar = Arrays.copyOf(a, size());
Arrays.fill(ar, null);
Class<?> arrayclass = a.getClass().getComponentType();
for (int i = 0; i < size(); i++) {
T obj = get(i);
if (arrayclass.isInstance(obj)) {
ar[i] = (E) get(i);
} else {
throw new ArrayStoreException("The array does not match the objects stored in the List.");
}
}
return ar;
} finally {
parent.getReadLock().unlock();
}
}
@Override
public List<T> subList(int fromIndex, int toIndex) {
validateClosed();
try {
parent.getReadLock().lock();
ArrayList<T> list = new ArrayList<>();
for (int i = fromIndex; i < toIndex; i++)
list.add(get(i));
return list;
} finally {
parent.getReadLock().unlock();
}
}
@Override
public boolean removeIf(Predicate<? super T> filter) {
return List.super.removeIf(filter);
}
@Override
public String toString() {
validateClosed();
try {
parent.getReadLock().lock();
return listObject.toString();
} finally {
parent.getReadLock().unlock();
}
}
}
@@ -15,28 +15,70 @@ public class NBTListCompound extends NBTCompound {
private Object compound;
protected NBTListCompound(NBTList<?> parent, Object obj) {
super(null, null);
owner = parent;
compound = obj;
}
public NBTList<?> getListParent() {
return owner;
}
@Override
protected boolean isClosed() {
return owner.getParent().isClosed();
}
@Override
protected boolean isReadOnly() {
return owner.getParent().isReadOnly();
}
@Override
public Object getCompound() {
if (isClosed()) {
throw new NbtApiException("Tried using closed NBT data!");
}
return compound;
}
@Override
protected void setCompound(Object compound) {
if (isClosed()) {
throw new NbtApiException("Tried using closed NBT data!");
}
if (isReadOnly()) {
throw new NbtApiException("Tried setting data in read only mode!");
}
this.compound = compound;
}
@Override
protected void saveCompound() {
owner.save();
}
}
@@ -15,31 +15,48 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
public class NBTLongList extends NBTList<Long> {
protected NBTLongList(NBTCompound owner, String name, NBTType type, Object list) {
super(owner, name, type, list);
}
@Override
protected Object asTag(Long object) {
try {
Constructor<?> con = ClassWrapper.NMS_NBTTAGLONG.getClazz().getDeclaredConstructor(long.class);
con.setAccessible(true);
return con.newInstance(object);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
| NoSuchMethodException | SecurityException e)
{
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
}
}
@Override
public Long get(int index) {
try {
Object obj = ReflectionMethod.LIST_GET.run(listObject, index);
return Long.valueOf(obj.toString().replace("L", ""));
} catch (NumberFormatException nf) {
return 0l;
} catch (Exception ex) {
throw new NbtApiException(ex);
}
}
}
@@ -11,22 +11,28 @@ public class NBTPersistentDataContainer extends NBTCompound {
private final PersistentDataContainer container;
public NBTPersistentDataContainer(PersistentDataContainer container) {
super(null, null);
this.container = container;
}
@Override
public Object getCompound() {
return ReflectionMethod.CRAFT_PERSISTENT_DATA_CONTAINER_TO_TAG.run(container);
}
@Override
protected void setCompound(Object compound) {
@SuppressWarnings("unchecked")
Map<Object, Object> map = (Map<Object, Object>) ReflectionMethod.CRAFT_PERSISTENT_DATA_CONTAINER_GET_MAP
.run(container);
map.clear();
ReflectionMethod.CRAFT_PERSISTENT_DATA_CONTAINER_PUT_ALL.run(container, compound);
}
}
File diff suppressed because it is too large. Load diff
@@ -15,28 +15,43 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
public class NBTStringList extends NBTList<String> {
protected NBTStringList(NBTCompound owner, String name, NBTType type, Object list) {
super(owner, name, type, list);
}
@Override
public String get(int index) {
try {
return (String) ReflectionMethod.LIST_GET_STRING.run(listObject, index);
} catch (Exception ex) {
throw new NbtApiException(ex);
}
}
@Override
protected Object asTag(String object) {
try {
Constructor<?> con = ClassWrapper.NMS_NBTTAGSTRING.getClazz().getDeclaredConstructor(String.class);
con.setAccessible(true);
return con.newInstance(object);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
| NoSuchMethodException | SecurityException e)
{
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
}
}
}
@@ -3,10 +3,8 @@ package de.tr7zw.changeme.nbtapi;
import org.bukkit.Bukkit;
import org.bukkit.block.BlockState;
import de.tr7zw.annotations.FAUtil;
import de.tr7zw.changeme.nbtapi.utils.CheckUtil;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import de.tr7zw.changeme.nbtapi.utils.annotations.AvailableSince;
import de.tr7zw.changeme.nbtapi.utils.annotations.CheckUtil;
/**
* NBT class to access vanilla tags from TileEntities. TileEntities don't
@@ -20,30 +18,108 @@ import de.tr7zw.changeme.nbtapi.utils.annotations.CheckUtil;
public class NBTTileEntity extends NBTCompound {
private final BlockState tile;
private final boolean readonly;
private final Object compound;
private boolean closed = false;
/**
* @param tile BlockState from any TileEntity
* @param tile BlockState from any TileEntity
* @param readonly Readonly makes a copy at init, only reading from that copy
*/
public NBTTileEntity(BlockState tile) {
protected NBTTileEntity(BlockState tile, boolean readonly) {
super(null, null);
if (tile == null || (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_8_R3) && !tile.isPlaced())) {
throw new NullPointerException("Tile can't be null/not placed!");
}
this.tile = tile;
this.readonly = readonly;
if (readonly) {
this.compound = getCompound();
} else {
this.compound = null;
}
}
/**
* Deprecated: Please use the NBT class
*
* @param tile BlockState from any TileEntity
*/
@Deprecated
public NBTTileEntity(BlockState tile) {
super(null, null);
if (tile == null || (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_8_R3) && !tile.isPlaced())) {
throw new NullPointerException("Tile can't be null/not placed!");
}
this.readonly = false;
this.compound = null;
this.tile = tile;
}
@Override
protected void setClosed() {
this.closed = true;
}
@Override
protected boolean isClosed() {
return closed;
}
@Override
protected boolean isReadOnly() {
return readonly;
}
@Override
public Object getCompound() {
// this runs before async check, since it's just a copy
if (readonly && compound != null) {
return compound;
}
if (!Bukkit.isPrimaryThread())
throw new NbtApiException("BlockEntity NBT needs to be accessed sync!");
return NBTReflectionUtil.getTileEntityNBTTagCompound(tile);
}
@Override
protected void setCompound(Object compound) {
if (readonly) {
throw new NbtApiException("Tried setting data in read only mode!");
}
if (!Bukkit.isPrimaryThread())
throw new NbtApiException("BlockEntity NBT needs to be accessed sync!");
NBTReflectionUtil.setTileEntityNBTTagCompound(tile, compound);
}
/**
@@ -52,18 +128,23 @@ public class NBTTileEntity extends NBTCompound {
*
* @return NBTCompound containing the data of the PersistentDataAPI
*/
@AvailableSince(version = MinecraftVersion.MC1_14_R1)
public NBTCompound getPersistentDataContainer() {
FAUtil.check(this::getPersistentDataContainer, CheckUtil::isAvaliable);
CheckUtil.assertAvailable(MinecraftVersion.MC1_14_R1);
if (hasTag("PublicBukkitValues")) {
return getCompound("PublicBukkitValues");
} else {
NBTContainer container = new NBTContainer();
container.addCompound("PublicBukkitValues").setString("__nbtapi",
"Marker to make the PersistentDataContainer have content");
mergeCompound(container);
return getCompound("PublicBukkitValues");
}
}
}
@@ -8,11 +8,14 @@ package de.tr7zw.changeme.nbtapi;
*/
@SuppressWarnings("javadoc")
public enum NBTType {
NBTTagEnd(0), NBTTagByte(1), NBTTagShort(2), NBTTagInt(3), NBTTagLong(4), NBTTagFloat(5), NBTTagDouble(6),
NBTTagByteArray(7), NBTTagIntArray(11), NBTTagString(8), NBTTagList(9), NBTTagCompound(10);
NBTTagByteArray(7), NBTTagString(8), NBTTagList(9), NBTTagCompound(10), NBTTagIntArray(11), NBTTagLongArray(12);
NBTType(int i) {
id = i;
}
private final int id;
@@ -21,7 +24,9 @@ public enum NBTType {
* @return Id used by Minecraft internally
*/
public int getId() {
return id;
}
/**
@@ -29,10 +34,12 @@ public enum NBTType {
* @return Enum representing the id, NBTTagEnd for invalide ids
*/
public static NBTType valueOf(int id) {
for (NBTType t : values())
if (t.getId() == id)
return t;
return NBTType.NBTTagEnd;
}
}
@@ -19,35 +19,52 @@ public class NBTUUIDList extends NBTList<UUID> {
private final NBTContainer tmpContainer;
protected NBTUUIDList(NBTCompound owner, String name, NBTType type, Object list) {
super(owner, name, type, list);
this.tmpContainer = new NBTContainer();
}
@Override
protected Object asTag(UUID object) {
try {
Constructor<?> con = ClassWrapper.NMS_NBTTAGINTARRAY.getClazz().getDeclaredConstructor(int[].class);
con.setAccessible(true);
return con.newInstance(UUIDUtil.uuidToIntArray(object));
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
| NoSuchMethodException | SecurityException e)
{
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
}
}
@Override
public UUID get(int index) {
try {
Object obj = ReflectionMethod.LIST_GET.run(listObject, index);
ReflectionMethod.COMPOUND_SET.run(tmpContainer.getCompound(), "tmp", obj);
int[] val = tmpContainer.getIntArray("tmp");
tmpContainer.removeKey("tmp");
return UUIDUtil.uuidFromIntArray(val);
} catch (NumberFormatException nf) {
return null;
} catch (Exception ex) {
throw new NbtApiException(ex);
}
}
}
@@ -26,17 +26,9 @@ public class NbtApiException extends RuntimeException {
*
*/
public NbtApiException() {
super();
}
/**
* @param message
* @param cause
* @param enableSuppression
* @param writableStackTrace
*/
public NbtApiException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(generateMessage(message), cause, enableSuppression, writableStackTrace);
super();
}
/**
@@ -44,35 +36,47 @@ public class NbtApiException extends RuntimeException {
* @param cause
*/
public NbtApiException(String message, Throwable cause) {
super(generateMessage(message), cause);
}
/**
* @param message
*/
public NbtApiException(String message) {
super(generateMessage(message));
}
/**
* @param cause
*/
public NbtApiException(Throwable cause) {
super(generateMessage(cause == null ? null : cause.toString()), cause);
}
private static String generateMessage(String message) {
if (message == null)
return null;
if (confirmedBroken == null) {
return "[?]" + message;
return "[?][" + MinecraftVersion.getNBTAPIVersion() + "]" + message;
} else if (confirmedBroken == false) {
return "[Selfchecked]" + message;
return "[Selfchecked][" + MinecraftVersion.getNBTAPIVersion() + "]" + message;
}
return "[" + MinecraftVersion.getVersion()
return "[" + MinecraftVersion.getVersion() + "][" + MinecraftVersion.getNBTAPIVersion()
+ "]There were errors detected during the server self-check! Please, make sure that NBT-API is up to date. Error message: "
+ message;
}
}
@@ -0,0 +1,116 @@
package de.tr7zw.changeme.nbtapi.handler;
import org.bukkit.inventory.ItemStack;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.iface.NBTHandler;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.changeme.nbtapi.iface.ReadableNBT;
public class NBTHandlers {
public static final NBTHandler<ItemStack> ITEM_STACK = new NBTHandler<ItemStack>() {
@Override
public boolean fuzzyMatch(Object obj) {
return obj instanceof ItemStack;
}
@Override
public void set(ReadWriteNBT nbt, String key, ItemStack value) {
nbt.removeKey(key);
ReadWriteNBT tag = nbt.getOrCreateCompound(key);
tag.mergeCompound(NBT.itemStackToNBT(value));
}
@Override
public ItemStack get(ReadableNBT nbt, String key) {
ReadableNBT tag = nbt.getCompound(key);
if (tag != null) {
return NBT.itemStackFromNBT(tag);
}
return null;
}
};
public static final NBTHandler<ReadableNBT> STORE_READABLE_TAG = new NBTHandler<ReadableNBT>() {
@Override
public boolean fuzzyMatch(Object obj) {
return obj instanceof ReadableNBT;
}
@Override
public void set(ReadWriteNBT nbt, String key, ReadableNBT value) {
nbt.removeKey(key);
nbt.getOrCreateCompound(key).mergeCompound(value);
}
@Override
public ReadableNBT get(ReadableNBT nbt, String key) {
ReadableNBT tag = nbt.getCompound(key);
if (tag != null) {
ReadWriteNBT value = NBT.createNBTObject();
value.mergeCompound(tag);
return value;
}
return null;
}
};
public static final NBTHandler<ReadWriteNBT> STORE_READWRITE_TAG = new NBTHandler<ReadWriteNBT>() {
@Override
public boolean fuzzyMatch(Object obj) {
return obj instanceof ReadWriteNBT;
}
@Override
public void set(ReadWriteNBT nbt, String key, ReadWriteNBT value) {
nbt.removeKey(key);
nbt.getOrCreateCompound(key).mergeCompound(value);
}
@Override
public ReadWriteNBT get(ReadableNBT nbt, String key) {
ReadableNBT tag = nbt.getCompound(key);
if (tag != null) {
ReadWriteNBT value = NBT.createNBTObject();
value.mergeCompound(tag);
return value;
}
return null;
}
};
}
@@ -0,0 +1,20 @@
package de.tr7zw.changeme.nbtapi.iface;
import java.io.File;
import java.io.IOException;
public interface NBTFileHandle extends ReadWriteNBT {
/**
* Saves the data to the file
*
* @throws IOException
*/
void save() throws IOException;
/**
* @return The File used to store the data
*/
File getFile();
}
@@ -0,0 +1,17 @@
package de.tr7zw.changeme.nbtapi.iface;
import javax.annotation.Nonnull;
public interface NBTHandler<T> {
public default boolean fuzzyMatch(Object obj) {
return false;
}
public void set(@Nonnull ReadWriteNBT nbt, @Nonnull String key, @Nonnull T value);
public T get(@Nonnull ReadableNBT nbt, @Nonnull String key);
}
@@ -7,7 +7,7 @@ import org.bukkit.inventory.meta.ItemMeta;
import de.tr7zw.changeme.nbtapi.NBTItem;
public interface ReadWriteItemNBT extends ReadWriteNBT {
public interface ReadWriteItemNBT extends ReadWriteNBT, ReadableItemNBT {
/**
* True, if the item has any tags now known for this item type.
@@ -2,6 +2,8 @@ package de.tr7zw.changeme.nbtapi.iface;
import java.util.UUID;
import javax.annotation.Nullable;
import org.bukkit.inventory.ItemStack;
public interface ReadWriteNBT extends ReadableNBT {
@@ -86,6 +88,16 @@ public interface ReadWriteNBT extends ReadableNBT {
*/
void setIntArray(String key, int[] value);
/**
* Setter
*
* Requires 1.16+
*
* @param key
* @param value
*/
void setLongArray(String key, long[] value);
/**
* Setter
*
@@ -129,7 +141,34 @@ public interface ReadWriteNBT extends ReadableNBT {
* @param name
* @return
*/
ReadableNBT getOrCreateCompound(String name);
ReadWriteNBT getOrCreateCompound(String name);
/**
* @param name
* @return The Compound instance or null
*/
@Nullable
ReadWriteNBT getCompound(String name);
/**
* Returns the resolved and creates compounds as required.
* <p>
*
* @param key Path key, seperated by '.'. For example: "foo.bar.baz". Dots can
* be escaped with a backslash.
* @return The resolved compound.
*/
ReadWriteNBT resolveOrCreateCompound(String key);
/**
* Set an Object to a key via the provided handler.
*
* @param <T>
* @param key
* @param value
* @param handler
*/
<T> void set(String key, T value, NBTHandler<T> handler);
/**
* Set a key to the given Enum value. It gets stored as a String. Passing null
@@ -165,6 +204,10 @@ public interface ReadWriteNBT extends ReadableNBT {
@Override
ReadWriteNBTCompoundList getCompoundList(String name);
@Override
@Nullable
ReadWriteNBT resolveCompound(String key);
/**
* Remove all keys from this compound
*/
@@ -11,6 +11,15 @@ public interface ReadWriteNBTCompoundList extends ReadableNBTList<ReadWriteNBT>
*/
ReadWriteNBT addCompound();
/**
* Adds a copy of the Compound to the end of the List and returns it. When null
* is given, a new Compound will be created
*
* @param comp
* @return
*/
ReadWriteNBT addCompound(ReadableNBT comp);
/**
* Removes the element at the specified position in this list
*
@@ -0,0 +1,12 @@
package de.tr7zw.changeme.nbtapi.iface;
public interface ReadableItemNBT extends ReadableNBT {
/**
* Returns true if the item has NBT data.
*
* @return Does the ItemStack have a NBTCompound.
*/
public boolean hasNBTData();
}
@@ -4,6 +4,8 @@ import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;
import javax.annotation.Nullable;
import org.bukkit.inventory.ItemStack;
import de.tr7zw.changeme.nbtapi.NBTType;
@@ -84,6 +86,7 @@ public interface ReadableNBT {
* @param key The key to use to retrieve the value.
* @return A byte array.
*/
@Nullable
byte[] getByteArray(String key);
/**
@@ -93,8 +96,21 @@ public interface ReadableNBT {
* @param key The key of the value you want to get.
* @return An array of integers.
*/
@Nullable
int[] getIntArray(String key);
/**
* Returns the value associated with the given key as an array of longs, or null
* if the key does not exist.
*
* Requires 1.16+
*
* @param key The key of the value you want to get.
* @return An array of integers.
*/
@Nullable
long[] getLongArray(String key);
/**
* Returns the value associated with the given key, or false if the key is not
* found.
@@ -111,6 +127,7 @@ public interface ReadableNBT {
* @param key The key of the itemstack you want to get.
* @return An ItemStack
*/
@Nullable
ItemStack getItemStack(String key);
/**
@@ -121,6 +138,7 @@ public interface ReadableNBT {
* @return The stored {@link ItemStack} array, or null if stored data wasn't
* found
*/
@Nullable
ItemStack[] getItemStackArray(String key);
/**
@@ -129,14 +147,30 @@ public interface ReadableNBT {
* @param key The key to get the value from
* @return A UUID object.
*/
@Nullable
UUID getUUID(String key);
/**
* Checks whether the provided key exists
*
* @param key String key
* @return true, if the key is set
*/
boolean hasTag(String key);
/**
* Checks whether the provided key exists and has the specified type
*
* @param key String key
* @param type nbt tag type
* @return whether the key is set and has the specified type
*/
default boolean hasTag(String key, NBTType type) {
return hasTag(key) && getType(key) == type;
}
/**
* @return Set of all stored Keys
*/
@@ -146,6 +180,7 @@ public interface ReadableNBT {
* @param name
* @return The Compound instance or null
*/
@Nullable
ReadableNBT getCompound(String name);
/**
@@ -196,6 +231,7 @@ public interface ReadableNBT {
* @param name
* @return
*/
@Nullable
NBTType getListType(String name);
/**
@@ -208,8 +244,8 @@ public interface ReadableNBT {
* Returns the stored value if exists, or provided value otherwise.
* <p>
* Supported types:
* {@code byte/Byte, short/Short, int/Integer, long/Long, float/Float, double/Double, byte[], int[]},
* {@link String}, {@link UUID}
* {@code Boolean, Byte, Short, Integer, Long, Float, Double, byte[], int[], long[]},
* {@link String}, {@link UUID}, and {@link Enum}
*
* @param key key
* @param defaultValue default non-null value
@@ -222,16 +258,69 @@ public interface ReadableNBT {
* Returns the stored value if exists, or null.
* <p>
* Supported types:
* {@code Byte, Short, Integer, Long, Float, Double, byte[], int[]},
* {@link String}, {@link UUID}
* {@code Boolean, Byte, Short, Integer, Long, Float, Double, byte[], int[], long[]},
* {@link String}, {@link UUID}, and {@link Enum}
*
* @param key key
* @param type data type
* @param <T> value type
* @return Stored or provided value
*/
@Nullable
<T> T getOrNull(String key, Class<?> type);
/**
* Returns the resolved value if exists, or null.
* <p>
* Supported types:
* {@code Boolean, Byte, Short, Integer, Long, Float, Double, byte[], int[], long[]},
* {@link String}, {@link UUID}, and {@link Enum}
*
* @param key Path key, seperated by '.'. For example: "foo.bar.baz". Dots can
* be escaped with a backslash.
* @param type data type
* @param <T> value type
* @return resolved or provided value
*/
@Nullable
<T> T resolveOrNull(String key, Class<?> type);
/**
* Returns the resolved value if exists, or provided value otherwise.
* <p>
* Supported types:
* {@code Boolean, Byte, Short, Integer, Long, Float, Double, byte[], int[], long[]},
* {@link String}, {@link UUID}, and {@link Enum}
*
* @param key Path key, seperated by '.'. For example: "foo.bar.baz".
* Dots can be escaped with a backslash.
* @param defaultValue default non-null value
* @param <T> value type
* @return resolved or provided value
*/
<T> T resolveOrDefault(String key, T defaultValue);
/**
* Returns the resolved Compound if exists, or null.
* <p>
*
* @param key Path key, seperated by '.'. For example: "foo.bar.baz". Dots can
* be escaped with a backslash.
* @return The resolved value if exists, or null.
*/
@Nullable
ReadableNBT resolveCompound(String key);
/**
* Get the object at the specified key via the handler.
*
* @param <T>
* @param key
* @param handler
* @return
*/
<T> T get(String key, NBTHandler<T> handler);
/**
* Get an Enum value that has been set via setEnum or setString(key,
* value.name()). Passing null/invalid keys will return null.
@@ -241,6 +330,7 @@ public interface ReadableNBT {
* @param type
* @return
*/
@Nullable
<E extends Enum<E>> E getEnum(String key, Class<E> type);
/**
@@ -109,9 +109,11 @@ public interface ReadableNBTList<T> extends Iterable<T> {
* @return A list of the elements in the stream.
*/
default List<T> toListCopy() {
List<T> list = new ArrayList<>();
iterator().forEachRemaining(list::add);
return list;
}
}
@@ -1,412 +0,0 @@
package de.tr7zw.changeme.nbtapi.utils;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.ServicePriority;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.logging.Level;
import java.util.zip.GZIPOutputStream;
import static de.tr7zw.changeme.nbtapi.utils.MinecraftVersion.getLogger;
/**
* bStats collects some data for plugin authors.
* <p>
* Check out https://bStats.org/ to learn more about bStats!
*
* This class is modified by tr7zw to work when the api is shaded into other
* peoples plugins.
*/
public class ApiMetricsLite {
private static final String PLUGINNAME = "ItemNBTAPI"; // DO NOT CHANGE THE NAME! else it won't link the data on
// bStats
// The version of this bStats class
public static final int B_STATS_VERSION = 1;
// The version of the NBT-Api bStats
public static final int NBT_BSTATS_VERSION = 1;
// The url to which the data is sent
private static final String URL = "https://bStats.org/submitData/bukkit";
// Is bStats enabled on this server?
private boolean enabled;
// Should failed requests be logged?
private static boolean logFailedRequests;
// Should the sent data be logged?
private static boolean logSentData;
// Should the response text be logged?
private static boolean logResponseStatusText;
// The uuid of the server
private static String serverUUID;
// The plugin
private Plugin plugin;
/**
* Class constructor.
*
*/
public ApiMetricsLite() {
// The register method just uses any enabled plugin it can find to register.
// This *shouldn't* cause any problems, since the plugin isn't used any other
// way.
// Register our service
for (Plugin plug : Bukkit.getPluginManager().getPlugins()) {
plugin = plug;
if (plugin != null)
break;
}
if (plugin == null) {
return;// Didn't find any plugin that could work
}
// Get the config file
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
File configFile = new File(bStatsFolder, "config.yml");
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
// Check if the config file exists
if (!config.isSet("serverUuid")) {
// Add default values
config.addDefault("enabled", true);
// Every server gets it's unique random id.
config.addDefault("serverUuid", UUID.randomUUID().toString());
// Should failed request be logged?
config.addDefault("logFailedRequests", false);
// Should the sent data be logged?
config.addDefault("logSentData", false);
// Should the response text be logged?
config.addDefault("logResponseStatusText", false);
// Inform the server owners about bStats
config.options().header(
"bStats collects some data for plugin authors like how many servers are using their plugins.\n"
+ "To honor their work, you should not disable it.\n"
+ "This has nearly no effect on the server performance!\n"
+ "Check out https://bStats.org/ to learn more :)")
.copyDefaults(true);
try {
config.save(configFile);
} catch (IOException ignored) {
}
}
// Load the data
serverUUID = config.getString("serverUuid");
logFailedRequests = config.getBoolean("logFailedRequests", false);
enabled = config.getBoolean("enabled", true);
logSentData = config.getBoolean("logSentData", false);
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
if (enabled) {
boolean found = false;
// Search for all other bStats Metrics classes to see if we are the first one
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
try {
service.getField("NBT_BSTATS_VERSION"); // Create only one instance of the nbt-api bstats.
return;
} catch (NoSuchFieldException ignored) {
}
try {
service.getField("B_STATS_VERSION"); // Our identifier :)
found = true; // We aren't the first
break;
} catch (NoSuchFieldException ignored) {
}
}
boolean fFound = found;
// Register our service
if (Bukkit.isPrimaryThread()) {
Bukkit.getServicesManager().register(ApiMetricsLite.class, this, plugin, ServicePriority.Normal);
if (!fFound) {
getLogger()
.info("[NBTAPI] Using the plugin '" + plugin.getName() + "' to create a bStats instance!");
// We are the first!
startSubmitting();
}
} else {
Bukkit.getScheduler().runTask(plugin, () -> {
Bukkit.getServicesManager().register(ApiMetricsLite.class, this, plugin, ServicePriority.Normal);
if (!fFound) {
getLogger().info(
"[NBTAPI] Using the plugin '" + plugin.getName() + "' to create a bStats instance!");
// We are the first!
startSubmitting();
}
});
}
}
}
/**
* Checks if bStats is enabled.
*
* @return Whether bStats is enabled or not.
*/
public boolean isEnabled() {
return enabled;
}
/**
* Starts the Scheduler which submits our data every 30 minutes.
*/
private void startSubmitting() {
final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
if (!plugin.isEnabled()) { // Plugin was disabled
timer.cancel();
return;
}
// Nevertheless we want our code to run in the Bukkit main thread, so we have to
// use the Bukkit scheduler
// Don't be afraid! The connection to the bStats server is still async, only the
// stats collection is sync ;)
Bukkit.getScheduler().runTask(plugin, () -> submitData());
}
}, 1000l * 60l * 5l, 1000l * 60l * 30l);
// Submit the data every 30 minutes, first time after 5 minutes to give other
// plugins enough time to start
// WARNING: Changing the frequency has no effect but your plugin WILL be
// blocked/deleted!
// WARNING: Just don't do it!
}
/**
* Gets the plugin specific data. This method is called using Reflection.
*
* @return The plugin specific data.
*/
public JsonObject getPluginData() {
JsonObject data = new JsonObject();
data.addProperty("pluginName", PLUGINNAME); // Append the name of the plugin
data.addProperty("pluginVersion", MinecraftVersion.VERSION); // Append the version of the plugin
data.add("customCharts", new JsonArray());
return data;
}
/**
* Gets the server specific data.
*
* @return The server specific data.
*/
private JsonObject getServerData() {
// Minecraft specific data
int playerAmount;
try {
// Around MC 1.8 the return type was changed to a collection from an array,
// This fixes java.lang.NoSuchMethodError:
// org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class)
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
} catch (Exception e) {
playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed
}
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
String bukkitVersion = Bukkit.getVersion();
String bukkitName = Bukkit.getName();
// OS/Java specific data
String javaVersion = System.getProperty("java.version");
String osName = System.getProperty("os.name");
String osArch = System.getProperty("os.arch");
String osVersion = System.getProperty("os.version");
int coreCount = Runtime.getRuntime().availableProcessors();
JsonObject data = new JsonObject();
data.addProperty("serverUUID", serverUUID);
data.addProperty("playerAmount", playerAmount);
data.addProperty("onlineMode", onlineMode);
data.addProperty("bukkitVersion", bukkitVersion);
data.addProperty("bukkitName", bukkitName);
data.addProperty("javaVersion", javaVersion);
data.addProperty("osName", osName);
data.addProperty("osArch", osArch);
data.addProperty("osVersion", osVersion);
data.addProperty("coreCount", coreCount);
return data;
}
/**
* Collects the data and sends it afterwards.
*/
private void submitData() {
final JsonObject data = getServerData();
JsonArray pluginData = new JsonArray();
// Search for all other bStats Metrics classes to get their plugin data
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
try {
service.getField("B_STATS_VERSION"); // Our identifier :)
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
try {
Object plugin = provider.getService().getMethod("getPluginData").invoke(provider.getProvider());
if (plugin instanceof JsonObject) {
pluginData.add((JsonObject) plugin);
} else { // old bstats version compatibility
try {
Class<?> jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject");
if (plugin.getClass().isAssignableFrom(jsonObjectJsonSimple)) {
Method jsonStringGetter = jsonObjectJsonSimple.getDeclaredMethod("toJSONString");
jsonStringGetter.setAccessible(true);
String jsonString = (String) jsonStringGetter.invoke(plugin);
JsonObject object = new JsonParser().parse(jsonString).getAsJsonObject();
pluginData.add(object);
}
} catch (ClassNotFoundException e) {
// minecraft version 1.14+
if (logFailedRequests) {
getLogger().log(Level.WARNING,
"[NBTAPI][BSTATS] Encountered exception while posting request!", e);
// Not using the plugins logger since the plugin isn't the plugin containing the
// NBT-Api most of the time
// this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception
// ", e);
}
continue; // continue looping since we cannot do any other thing.
}
}
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException
| InvocationTargetException ignored) {
}
}
} catch (NoSuchFieldException ignored) {
}
}
data.add("plugins", pluginData);
// Create a new thread for the connection to the bStats server
new Thread(new Runnable() {
@Override
public void run() {
try {
// Send the data
sendData(plugin, data);
} catch (Exception e) {
// Something went wrong! :(
if (logFailedRequests) {
getLogger().log(Level.WARNING,
"[NBTAPI][BSTATS] Could not submit plugin stats of " + plugin.getName(), e);
// Not using the plugins logger since the plugin isn't the plugin containing the
// NBT-Api most of the time
// plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " +
// plugin.getName(), e);
}
}
}
}).start();
}
/**
* Sends the data to the bStats server.
*
* @param plugin Any plugin. It's just used to get a logger instance.
* @param data The data to send.
* @throws Exception If the request failed.
*/
private static void sendData(Plugin plugin, JsonObject data) throws Exception {
if (data == null) {
throw new IllegalArgumentException("Data cannot be null!");
}
if (Bukkit.isPrimaryThread()) {
throw new IllegalAccessException("This method must not be called from the main thread!");
}
if (logSentData) {
MinecraftVersion.getLogger().info("[NBTAPI][BSTATS] Sending data to bStats: " + data.toString());
// Not using the plugins logger since the plugin isn't the plugin containing the
// NBT-Api most of the time
// plugin.getLogger().info("Sending data to bStats: " + data.toString());
}
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
// Compress the data to save bandwidth
byte[] compressedData = compress(data.toString());
// Add headers
connection.setRequestMethod("POST");
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
// Send data
connection.setDoOutput(true);
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.write(compressedData);
outputStream.flush();
outputStream.close();
InputStream inputStream = connection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder builder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
builder.append(line);
}
bufferedReader.close();
if (logResponseStatusText) {
getLogger().info("[NBTAPI][BSTATS] Sent data to bStats and received response: " + builder.toString());
// Not using the plugins logger since the plugin isn't the plugin containing the
// NBT-Api most of the time
// plugin.getLogger().info("Sent data to bStats and received response: " +
// builder.toString());
}
}
/**
* Gzips the given String.
*
* @param str The string to gzip.
* @return The gzipped String.
* @throws IOException If the compression failed.
*/
private static byte[] compress(final String str) throws IOException {
if (str == null) {
return new byte[0];
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
gzip.write(str.getBytes(StandardCharsets.UTF_8));
gzip.close();
return outputStream.toByteArray();
}
}
@@ -0,0 +1,20 @@
package de.tr7zw.changeme.nbtapi.utils;
import de.tr7zw.changeme.nbtapi.NbtApiException;
public class CheckUtil {
private CheckUtil() {
// util
}
public static void assertAvailable(MinecraftVersion version) {
if (!MinecraftVersion.isAtLeastVersion(version))
throw new NbtApiException(
"This Method is only avaliable for the version " + version.name() + " and above!");
}
}
@@ -0,0 +1,129 @@
package de.tr7zw.changeme.nbtapi.utils;
import com.mojang.datafixers.DSL.TypeReference;
import com.mojang.datafixers.DataFixer;
import com.mojang.serialization.Dynamic;
import com.mojang.serialization.DynamicOps;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTContainer;
import de.tr7zw.changeme.nbtapi.NBTReflectionUtil;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.MojangToMapping;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
public class DataFixerUtil {
// these values can be found in DetectedVersion inside mc
// Finding pre 1.12.2 values is left as an exercise for the reader,
// as DetectedVersion is not a thing there
public static final int VERSION1_12_2 = 1343;
public static final int VERSION1_16_5 = 2586;
public static final int VERSION1_17_1 = 2730;
public static final int VERSION1_18_2 = 2975;
public static final int VERSION1_19_2 = 3120;
public static final int VERSION1_19_4 = 3337;
public static final int VERSION1_20_1 = 3465;
public static final int VERSION1_20_2 = 3578;
public static final int VERSION1_20_4 = 3700;
public static final int VERSION1_20_5 = 3837;
public static final int VERSION1_21 = 3953;
public static final int VERSION1_21_2 = 4080;
public static final int VERSION1_21_3 = 4189;
@SuppressWarnings("unchecked")
public static Object fixUpRawItemData(Object nbt, int fromVersion, int toVersion)
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException
{
DataFixer dataFixer = (DataFixer) ReflectionMethod.GET_DATAFIXER.run(null);
TypeReference itemStackReference = (TypeReference) ClassWrapper.NMS_REFERENCES.getClazz()
.getField(MojangToMapping.getMapping().get("net.minecraft.util.datafix.fixes.References#ITEM_STACK"))
.get(null);
DynamicOps<Object> nbtOps = (DynamicOps<Object>) ClassWrapper.NMS_NBTOPS.getClazz()
.getField(MojangToMapping.getMapping().get("net.minecraft.nbt.NbtOps#INSTANCE")).get(null);
Dynamic<Object> fixed = dataFixer.update(itemStackReference, new Dynamic<Object>(nbtOps, nbt), fromVersion,
toVersion);
return fixed.getValue();
}
public static ReadWriteNBT fixUpItemData(ReadWriteNBT nbt, int fromVersion, int toVersion)
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException
{
return new NBTContainer(fixUpRawItemData(
NBTReflectionUtil.getToCompount(((NBTCompound) nbt).getCompound(), ((NBTCompound) nbt)), fromVersion,
toVersion));
}
/**
* This method will return the closest or exact version number of the current
* server. Only contains versions people will reasonably use and will fail with
* an exception, when the target version is before 1.12.2. (Assuming no one will
* update 1.8 items to 1.11, if so, provide the version numbers to the converter
* method directly)
*
* @return
*/
public static int getCurrentVersion() {
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R3)) {
return VERSION1_21_3;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R2)) {
return VERSION1_21_2;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_21_R1)) {
return VERSION1_21;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
return VERSION1_20_5;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R3)) {
return VERSION1_20_4;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R1)) {
return VERSION1_20_1;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_19_R3)) {
return VERSION1_19_4;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_19_R1)) {
return VERSION1_19_2;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_18_R1)) {
return VERSION1_18_2;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_17_R1)) {
return VERSION1_17_1;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_16_R1)) {
return VERSION1_16_5;
} else if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_12_R1)) {
return VERSION1_12_2;
}
throw new NbtApiException(
"Trying to update data *to* a version before 1.12.2? Something is probably going wrong, contact the plugin author.");
}
}
@@ -0,0 +1,117 @@
package de.tr7zw.changeme.nbtapi.utils;
import java.util.UUID;
import javax.annotation.Nullable;
import com.mojang.authlib.GameProfile;
import de.tr7zw.changeme.nbtapi.NBTType;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBTCompoundList;
import de.tr7zw.changeme.nbtapi.iface.ReadableNBT;
import de.tr7zw.changeme.nbtapi.iface.ReadableNBTList;
public class GameprofileUtil {
@Nullable
public static GameProfile readGameProfile(ReadableNBT arg) {
String string = null;
UUID uUID = null;
if (arg.hasTag("Name") && arg.getType("Name") == NBTType.NBTTagString) {
string = arg.getString("Name");
}
if (arg.hasTag("Id") && arg.getType("Id") == NBTType.NBTTagIntArray && arg.getIntArray("Id").length == 4) {
uUID = arg.getUUID("Id");
}
try {
GameProfile gameProfile = new GameProfile(uUID, string);
if (arg.hasTag("Properties") && arg.getType("Properties") == NBTType.NBTTagCompound) {
ReadableNBT compoundTag = arg.getCompound("Properties");
for (String string2 : compoundTag.getKeys()) {
ReadableNBTList<ReadWriteNBT> listTag = compoundTag.getCompoundList(string);
for (int i = 0; i < listTag.size(); ++i) {
ReadableNBT compoundTag2 = listTag.get(i);
String string3 = compoundTag2.getString("Value");
if (compoundTag2.hasTag("Signature")
&& compoundTag2.getType("Signature") == NBTType.NBTTagString)
{
gameProfile.getProperties().put(string2, new com.mojang.authlib.properties.Property(string2,
string3, compoundTag2.getString("Signature")));
} else {
gameProfile.getProperties().put(string2,
new com.mojang.authlib.properties.Property(string2, string3));
}
}
}
}
return gameProfile;
} catch (Throwable var11) {
return null;
}
}
public static ReadWriteNBT writeGameProfile(ReadWriteNBT arg, GameProfile gameProfile) {
if (!(gameProfile.getName() == null || gameProfile.getName().isEmpty())) {
arg.setString("Name", gameProfile.getName());
}
if (gameProfile.getId() != null) {
arg.setUUID("Id", gameProfile.getId());
}
if (!gameProfile.getProperties().isEmpty()) {
ReadWriteNBT compoundTag = arg.getOrCreateCompound("Properties");
for (String string : gameProfile.getProperties().keySet()) {
ReadWriteNBTCompoundList list = compoundTag.getCompoundList(string);
for (com.mojang.authlib.properties.Property property : gameProfile.getProperties().get(string)) {
ReadWriteNBT tag = list.addCompound();
tag.setString("Value", property.getValue());
if (property.hasSignature()) {
tag.setString("Signature", property.getSignature());
}
}
}
}
return arg;
}
}
@@ -32,11 +32,15 @@ public class GsonWrapper {
* @return Json, representing the Object
*/
public static String getString(Object obj) {
return gson.toJson(obj);
}
public static void overwriteGsonInstance(Gson replacement) {
gson = replacement;
}
/**
@@ -47,16 +51,24 @@ public class GsonWrapper {
* @return Object that got created, or null if the json is null
*/
public static <T> T deserializeJson(String json, Class<T> type) {
try {
if (json == null) {
return null;
}
T obj = gson.fromJson(json, type);
return type.cast(obj);
} catch (Exception ex) {
throw new NbtApiException("Error while converting json to " + type.getName(), ex);
}
}
}
File diff suppressed because it is too large. Load diff
@@ -1,9 +1,13 @@
package de.tr7zw.changeme.nbtapi.utils;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
/**
* This class acts as the "Brain" of the NBTApi. It contains the main logger for
@@ -15,43 +19,74 @@ import org.bukkit.Bukkit;
*/
@SuppressWarnings("javadoc")
public enum MinecraftVersion {
UNKNOWN(Integer.MAX_VALUE), // Use the newest known mappings
MC1_7_R4(174), MC1_8_R3(183), MC1_9_R1(191), MC1_9_R2(192), MC1_10_R1(1101), MC1_11_R1(1111), MC1_12_R1(1121),
MC1_13_R1(1131), MC1_13_R2(1132), MC1_14_R1(1141), MC1_15_R1(1151), MC1_16_R1(1161), MC1_16_R2(1162),
MC1_16_R3(1163), MC1_17_R1(1171), MC1_18_R1(1181, true), MC1_18_R2(1182, true), MC1_19_R1(1191, true),
MC1_19_R2(1192, true);
MC1_19_R2(1192, true), MC1_19_R3(1193, true), MC1_20_R1(1201, true), MC1_20_R2(1202, true), MC1_20_R3(1203, true),
MC1_20_R4(1204, true), MC1_21_R1(1211, true), MC1_21_R2(1212, true), MC1_21_R3(1213, true);
private static MinecraftVersion version;
private static Boolean hasGsonSupport;
private static Boolean isForgePresent;
private static Boolean isFoliaPresent;
private static boolean bStatsDisabled = false;
private static boolean disablePackageWarning = false;
private static boolean updateCheckDisabled = false;
/**
* Logger used by the api
*/
private static Logger logger = Logger.getLogger("NBTAPI");
// NBT-API Version
protected static final String VERSION = "2.11.1";
protected static final String VERSION = "2.14.1";
private final int versionId;
private final boolean mojangMapping;
// TODO: not nice
@SuppressWarnings("serial")
private static final Map<String, MinecraftVersion> VERSION_TO_REVISION = new HashMap<String, MinecraftVersion>() {
{
this.put("1.20", MC1_20_R1);
this.put("1.20.1", MC1_20_R1);
this.put("1.20.2", MC1_20_R2);
this.put("1.20.3", MC1_20_R3);
this.put("1.20.4", MC1_20_R3);
this.put("1.20.5", MC1_20_R4);
this.put("1.20.6", MC1_20_R4);
this.put("1.21", MC1_21_R1);
this.put("1.21.1", MC1_21_R1);
this.put("1.21.2", MC1_21_R2);
this.put("1.21.3", MC1_21_R2);
this.put("1.21.4", MC1_21_R3);
}
};
MinecraftVersion(int versionId) {
this(versionId, false);
}
MinecraftVersion(int versionId, boolean mojangMapping) {
this.versionId = versionId;
this.mojangMapping = mojangMapping;
}
/**
* @return A simple comparable Integer, representing the version.
*/
public int getVersionId() {
return versionId;
}
/**
@@ -59,7 +94,9 @@ public enum MinecraftVersion {
* internally
*/
public boolean isMojangMapping() {
return mojangMapping;
}
/**
@@ -69,10 +106,22 @@ public enum MinecraftVersion {
* @return
*/
public String getPackageName() {
if (this == UNKNOWN) {
return Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
try {
return Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
} catch (Exception ex) {
// ignore, paper without remap, will fail
}
}
return this.name().replace("MC", "v");
}
/**
@@ -82,7 +131,9 @@ public enum MinecraftVersion {
* @return
*/
public static boolean isAtLeastVersion(MinecraftVersion version) {
return getVersion().getVersionId() >= version.getVersionId();
}
/**
@@ -92,7 +143,9 @@ public enum MinecraftVersion {
* @return
*/
public static boolean isNewerThan(MinecraftVersion version) {
return getVersion().getVersionId() > version.getVersionId();
}
/**
@@ -102,48 +155,91 @@ public enum MinecraftVersion {
* @return The enum for the MinecraftVersion this server is running
*/
public static MinecraftVersion getVersion() {
if (version != null) {
return version;
}
final String ver = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
logger.info("[NBTAPI] Found Spigot: " + ver + "! Trying to find NMS support");
try {
final String ver = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
logger.info("[NBTAPI] Found Minecraft: " + ver + "! Trying to find NMS support");
version = MinecraftVersion.valueOf(ver.replace("v", "MC"));
} catch (IllegalArgumentException ex) {
version = MinecraftVersion.UNKNOWN;
} catch (Exception ex) {
logger.info("[NBTAPI] Found Minecraft: " + Bukkit.getServer().getBukkitVersion().split("-")[0]
+ "! Trying to find NMS support");
version = VERSION_TO_REVISION.getOrDefault(Bukkit.getServer().getBukkitVersion().split("-")[0],
MinecraftVersion.UNKNOWN);
}
if (version != UNKNOWN) {
logger.info("[NBTAPI] NMS support '" + version.name() + "' loaded!");
} else {
logger.warning("[NBTAPI] This Server-Version(" + ver + ") is not supported by this NBT-API Version("
+ VERSION + ") located at " + MinecraftVersion.class.getName()
logger.warning("[NBTAPI] This Server-Version(" + Bukkit.getServer().getBukkitVersion()
+ ") is not supported by this NBT-API Version(" + VERSION + ") located in "
+ VersionChecker.getPlugin()
+ ". The NBT-API will try to work as good as it can! Some functions may not work!");
}
init();
return version;
}
public static String getNBTAPIVersion() {
return VERSION;
}
private static void init() {
try {
if (hasGsonSupport() && !bStatsDisabled)
new ApiMetricsLite();
if (hasGsonSupport() && !bStatsDisabled) {
Plugin plugin = Bukkit.getPluginManager().getPlugin(VersionChecker.getPlugin());
if (plugin != null && plugin instanceof JavaPlugin) {
getLogger()
.info("[NBTAPI] Using the plugin '" + plugin.getName() + "' to create a bStats instance!");
new Metrics((JavaPlugin) plugin, 1058);
} else if (plugin == null) {
getLogger().info("[NBTAPI] Unable to create a bStats instance!!");
}
}
} catch (Exception ex) {
logger.log(Level.WARNING, "[NBTAPI] Error enabling Metrics!", ex);
}
if (hasGsonSupport() && !updateCheckDisabled)
new Thread(() -> {
try {
VersionChecker.checkForUpdates();
} catch (Exception ex) {
logger.log(Level.WARNING, "[NBTAPI] Error while checking for updates! Error: " + ex.getMessage());
}
}).start();
// Maven's Relocate is clever and changes strings, too. So we have to use this
// little "trick" ... :D (from bStats)
final String defaultPackage = new String(new byte[] { 'd', 'e', '.', 't', 'r', '7', 'z', 'w', '.', 'c', 'h',
'a', 'n', 'g', 'e', 'm', 'e', '.', 'n', 'b', 't', 'a', 'p', 'i', '.', 'u', 't', 'i', 'l', 's' });
final String defaultPackage = new String(
new byte[]
{ 'd', 'e', '.', 't', 'r', '7', 'z', 'w', '.', 'c', 'h', 'a', 'n', 'g', 'e', 'm', 'e', '.', 'n', 'b',
't', 'a', 'p', 'i', '.', 'u', 't', 'i', 'l', 's' });
final String reservedPackage = new String(
new byte[]
{ 'd', 'e', '.', 't', 'r', '7', 'z', 'w', '.', 'n', 'b', 't', 'a', 'p', 'i', '.', 'u', 't', 'i', 'l',
's' });
if (!disablePackageWarning && MinecraftVersion.class.getPackage().getName().equals(defaultPackage)) {
logger.warning(
"#########################################- NBTAPI -#########################################");
logger.warning(
@@ -155,42 +251,127 @@ public enum MinecraftVersion {
logger.warning("please check your plugins and contact their developer, so they can fix this issue.");
logger.warning(
"#########################################- NBTAPI -#########################################");
}
if (!disablePackageWarning && !"NBTAPI".equals(VersionChecker.getPlugin())
&& !"Item-NBT-API".equals(VersionChecker.getPlugin()))
{ // we are not the nbtapi, check
// for common shading errors
if (!"de.tr7zw.nbtapi.utils".equals(reservedPackage)) {
logger.warning(
"#########################################- NBTAPI -#########################################");
logger.warning(
"The NBT-API inside " + VersionChecker.getPlugin() + " is the plugin version, not the API!");
logger.warning(
"The plugin itself should never be shaded! Remove the `-plugin` from the dependency and fix your shading setup.");
logger.warning(
"For more info check: https://github.com/tr7zw/Item-NBT-API/wiki/Using-Maven#option-2-shading-the-nbt-api-into-your-plugin");
logger.warning(
"#########################################- NBTAPI -#########################################");
return; // don't also print the second error
}
if (MinecraftVersion.class.getPackage().getName().equals("de.tr7zw.nbtapi.utils")) {
logger.warning(
"#########################################- NBTAPI -#########################################");
logger.warning(
"The NBT-API inside " + VersionChecker.getPlugin() + " is located at 'de.tr7zw.nbtapi.utils'!");
logger.warning(
"This package name is reserved for the official NBTAPI plugin, and not intended to be used for shading!");
logger.warning("Please change the relocate to something else. For example: com.example.util.nbtapi");
logger.warning(
"#########################################- NBTAPI -#########################################");
}
}
}
/**
* @return True, if Gson is usable
*/
public static boolean hasGsonSupport() {
if (hasGsonSupport != null) {
return hasGsonSupport;
}
try {
logger.info("[NBTAPI] Found Gson: " + Class.forName("com.google.gson.Gson"));
Class.forName("com.google.gson.Gson");
hasGsonSupport = true;
} catch (Exception ex) {
logger.info("[NBTAPI] Gson not found! This will not allow the usage of some methods!");
hasGsonSupport = false;
}
return hasGsonSupport;
}
/**
* @return True, if Forge is present
*/
public static boolean isForgePresent() {
if (isForgePresent != null) {
return isForgePresent;
}
try {
logger.info("[NBTAPI] Found Forge: "
+ (getVersion() == MinecraftVersion.MC1_7_R4 ? Class.forName("cpw.mods.fml.common.Loader")
: Class.forName("net.minecraftforge.fml.common.Loader")));
isForgePresent = true;
} catch (Exception ex) {
isForgePresent = false;
}
return isForgePresent;
}
/**
* @return True, if Folia is present
*/
public static boolean isFoliaPresent() {
if (isFoliaPresent != null) {
return isFoliaPresent;
}
try {
logger.info("[NBTAPI] Found Folia: " + Class.forName("io.papermc.paper.threadedregions.RegionizedServer"));
isFoliaPresent = true;
} catch (Exception ex) {
isFoliaPresent = false;
}
return isFoliaPresent;
}
/**
@@ -199,15 +380,9 @@ public enum MinecraftVersion {
* and helps the NBT-Api developer to see api's demand.
*/
public static void disableBStats() {
bStatsDisabled = true;
}
/**
* Disables the update check. Uses Spiget to get the current version and prints
* a warning when outdated.
*/
public static void disableUpdateCheck() {
updateCheckDisabled = true;
bStatsDisabled = true;
}
/**
@@ -217,14 +392,18 @@ public enum MinecraftVersion {
* Spigotmc.
*/
public static void disablePackageWarning() {
disablePackageWarning = true;
}
/**
* @return Logger used by the NBT-API
*/
public static Logger getLogger() {
return logger;
}
/**
@@ -233,9 +412,11 @@ public enum MinecraftVersion {
* @param logger The new logger(can not be null!)
*/
public static void replaceLogger(Logger logger) {
if (logger == null)
throw new NullPointerException("Logger can not be null!");
MinecraftVersion.logger = logger;
}
}
@@ -0,0 +1,47 @@
package de.tr7zw.changeme.nbtapi.utils;
import java.util.Optional;
import org.bukkit.inventory.ItemStack;
import com.google.gson.JsonElement;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.JsonOps;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.MojangToMapping;
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
public class NBTJsonUtil {
/**
* 1.20.3+ only. Used to convert items into Json, used in Chat Hover Components.
*
* @param itemStack
* @return
* @throws NbtApiException
*/
@SuppressWarnings("unchecked")
public static JsonElement itemStackToJson(ItemStack itemStack) {
try {
Codec<Object> itemStackCodec = (Codec<Object>) ClassWrapper.NMS_ITEMSTACK.getClazz()
.getField(MojangToMapping.getMapping().get("net.minecraft.world.item.ItemStack#CODEC")).get(null);
Object stack = ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, itemStack);
DataResult<JsonElement> result = itemStackCodec.encode(stack, JsonOps.INSTANCE,
JsonOps.INSTANCE.emptyMap());
Optional<JsonElement> opt = (Optional<JsonElement>) result.getClass().getMethod("result").invoke(result);
return opt.orElse(null);
} catch (Exception ex) {
throw new NbtApiException("Error trying to get Json of an ItemStack.", ex);
}
}
}
@@ -0,0 +1,79 @@
package de.tr7zw.changeme.nbtapi.utils;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class PathUtil {
private static final Pattern pattern = Pattern.compile("[^\\\\](\\.)");
private static final Pattern indexPattern = Pattern.compile(".*\\[(-?[0-9]+)\\]");
public static List<PathSegment> splitPath(String path) {
List<PathSegment> list = new ArrayList<>();
Matcher matcher = pattern.matcher(path);
int startIndex = 0;
while (matcher.find(startIndex)) {
list.add(new PathSegment(path.substring(startIndex, matcher.end() - 1).replace("\\.", ".")));
startIndex = matcher.end();
}
list.add(new PathSegment(path.substring(startIndex).replace("\\.", ".")));
return list;
}
public static class PathSegment {
private final String path;
private final Integer index;
private PathSegment(String path) {
Matcher matcher = indexPattern.matcher(path);
if (matcher.find()) {
this.path = path.substring(0, path.indexOf("["));
this.index = Integer.parseInt(matcher.group(1));
} else {
this.path = path;
this.index = null;
}
}
public String getPath() {
return path;
}
public int getIndex() {
return index;
}
public boolean hasIndex() {
return index != null;
}
@Override
public String toString() {
return "PathSegment [path=" + path + ", index=" + index + "]";
}
}
}
@@ -11,43 +11,66 @@ public final class ReflectionUtil {
private static Field field_modifiers;
static {
try {
field_modifiers = Field.class.getDeclaredField("modifiers");
field_modifiers.setAccessible(true);
} catch (NoSuchFieldException ex) {
try {
// This hacky workaround is for newer jdk versions 11+?
Method fieldGetter = Class.class.getDeclaredMethod("getDeclaredFields0", boolean.class);
fieldGetter.setAccessible(true);
Field[] fields = (Field[]) fieldGetter.invoke(Field.class, false);
for (Field f : fields)
if (f.getName().equals("modifiers")) {
field_modifiers = f;
field_modifiers.setAccessible(true);
break;
}
} catch (Exception e) {
throw new NbtApiException(e);
}
}
if (field_modifiers == null) {
throw new NbtApiException("Unable to init the modifiers Field.");
}
}
public static Field makeNonFinal(Field field) throws IllegalArgumentException, IllegalAccessException {
int mods = field.getModifiers();
if (Modifier.isFinal(mods)) {
field_modifiers.set(field, mods & ~Modifier.FINAL);
}
return field;
}
public static void setFinal(Object obj, Field field, Object newValue)
throws IllegalArgumentException, IllegalAccessException {
throws IllegalArgumentException, IllegalAccessException
{
field.setAccessible(true);
field = makeNonFinal(field);
field.set(obj, newValue);
}
}
@@ -5,18 +5,24 @@ import java.util.UUID;
public class UUIDUtil {
public static UUID uuidFromIntArray(int[] is) {
return new UUID((long) is[0] << 32 | (long) is[1] & 4294967295L,
(long) is[2] << 32 | (long) is[3] & 4294967295L);
}
public static int[] uuidToIntArray(UUID uUID) {
long l = uUID.getMostSignificantBits();
long m = uUID.getLeastSignificantBits();
return leastMostToIntArray(l, m);
}
private static int[] leastMostToIntArray(long l, long m) {
return new int[] { (int) (l >> 32), (int) l, (int) (m >> 32), (int) m };
}
}
@@ -1,108 +1,42 @@
package de.tr7zw.changeme.nbtapi.utils;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.logging.Level;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.bukkit.configuration.file.YamlConfiguration;
import de.tr7zw.changeme.nbtapi.NBTItem;
/**
* This class uses the Spiget API to check for updates
* This class checks plugin identity for logging purposes
*
*/
public class VersionChecker {
private static final String USER_AGENT = "nbt-api Version check";
private static final String REQUEST_URL = "https://api.spiget.org/v2/resources/7939/versions?size=100";
public static boolean hideOk = false;
protected static void checkForUpdates() throws Exception {
URL url = new URL(REQUEST_URL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.addRequestProperty("User-Agent", USER_AGENT);// Set
// User-Agent
protected static String getPlugin() {
// If you're not sure if the request will be successful,
// you need to check the response code and use #getErrorStream if it
// returned an error code
InputStream inputStream = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
ClassLoader classLoader = VersionChecker.class.getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("plugin.yml");
// This could be either a JsonArray or JsonObject
JsonElement element = new JsonParser().parse(reader);
if (element.isJsonArray()) {
// Is JsonArray
JsonArray updates = (JsonArray) element;
JsonObject latest = (JsonObject) updates.get(updates.size() - 1);
int versionDifference = getVersionDifference(latest.get("name").getAsString());
if (versionDifference == -1) { // Outdated
MinecraftVersion.getLogger().log(Level.WARNING,
"[NBTAPI] The NBT-API located at '" + NBTItem.class.getPackage() + "' seems to be outdated!");
MinecraftVersion.getLogger().log(Level.WARNING, "[NBTAPI] Current Version: '" + MinecraftVersion.VERSION
+ "' Newest Version: " + latest.get("name").getAsString() + "'");
MinecraftVersion.getLogger().log(Level.WARNING,
"[NBTAPI] Please update the NBTAPI or the plugin that contains the api(nag the mod author when the newest release has an old version, not the NBTAPI dev)!");
if (inputStream != null) {
} else if (versionDifference == 0) {
if (!hideOk)
MinecraftVersion.getLogger().log(Level.INFO, "[NBTAPI] The NBT-API seems to be up-to-date!");
} else if (versionDifference == 1) {
MinecraftVersion.getLogger().log(Level.INFO, "[NBTAPI] The NBT-API at '" + NBTItem.class.getPackage()
+ "' seems to be a future Version, not yet released on Spigot/CurseForge! This is not an error!");
MinecraftVersion.getLogger().log(Level.INFO, "[NBTAPI] Current Version: '" + MinecraftVersion.VERSION
+ "' Newest Version: " + latest.get("name").getAsString() + "'");
try (InputStreamReader reader = new InputStreamReader(inputStream)) {
YamlConfiguration pluginYml = YamlConfiguration.loadConfiguration(reader);
return pluginYml.getString("name");
} catch (IOException e) {
// ignored
}
} else {
// wut?!
MinecraftVersion.getLogger().log(Level.WARNING,
"[NBTAPI] Error when looking for Updates! Got non Json Array: '" + element.toString() + "'");
}
}
// -1 = we are outdated
// 0 = up to date
// 1 = using a future version
// This method is only able to compare the Format 0.0.0(-SNAPSHOT)
private static int getVersionDifference(String version) {
String current = MinecraftVersion.VERSION;
if (current.equals(version))
return 0;
String pattern = "\\.";
if (current.split(pattern).length != 3 || version.split(pattern).length != 3)
return -1;
int curMaj = Integer.parseInt(current.split(pattern)[0]);
int curMin = Integer.parseInt(current.split(pattern)[1]);
String curPatch = current.split(pattern)[2];
int relMaj = Integer.parseInt(version.split(pattern)[0]);
int relMin = Integer.parseInt(version.split(pattern)[1]);
String relPatch = version.split(pattern)[2];
if (curMaj < relMaj)
return -1;
if (curMaj > relMaj)
return 1;
if (curMin < relMin)
return -1;
if (curMin > relMin)
return 1;
int curPatchN = Integer.parseInt(curPatch.split("-")[0]);
int relPatchN = Integer.parseInt(relPatch.split("-")[0]);
if (curPatchN < relPatchN)
return -1;
if (curPatchN > relPatchN)
return 1;
if (!relPatch.contains("-") && curPatch.contains("-"))
return -1; // Release has no - but we do = We use a Snapshot of the
// release
if (relPatch.contains("-") && curPatch.contains("-"))
return 0; // Release and cur are Snapshots/alpha/beta
return 1;
}
return NBTItem.class.getPackage().getName();
}
}
@@ -1,17 +0,0 @@
package de.tr7zw.changeme.nbtapi.utils.annotations;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
@Retention(RUNTIME)
@Target({ METHOD })
public @interface AvailableSince {
MinecraftVersion version();
}
@@ -1,18 +0,0 @@
package de.tr7zw.changeme.nbtapi.utils.annotations;
import java.lang.reflect.Method;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
public class CheckUtil {
public static boolean isAvaliable(Method method) {
if (MinecraftVersion.getVersion().getVersionId() < method.getAnnotation(AvailableSince.class).version()
.getVersionId())
throw new NbtApiException("The Method '" + method.getName() + "' is only avaliable for the Versions "
+ method.getAnnotation(AvailableSince.class).version() + "+, but still got called!");
return true;
}
}
@@ -4,6 +4,8 @@ import static de.tr7zw.changeme.nbtapi.utils.MinecraftVersion.getLogger;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
/**
@@ -14,10 +16,12 @@ import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
*/
@SuppressWarnings("javadoc")
public enum ClassWrapper {
CRAFT_ITEMSTACK(PackageWrapper.CRAFTBUKKIT, "inventory.CraftItemStack", null, null),
CRAFT_METAITEM(PackageWrapper.CRAFTBUKKIT, "inventory.CraftMetaItem", null, null),
CRAFT_ENTITY(PackageWrapper.CRAFTBUKKIT, "entity.CraftEntity", null, null),
CRAFT_WORLD(PackageWrapper.CRAFTBUKKIT, "CraftWorld", null, null),
CRAFT_SERVER(PackageWrapper.CRAFTBUKKIT, "CraftServer", null, null),
CRAFT_PERSISTENTDATACONTAINER(PackageWrapper.CRAFTBUKKIT, "persistence.CraftPersistentDataContainer",
MinecraftVersion.MC1_14_R1, null),
NMS_NBTBASE(PackageWrapper.NMS, "NBTBase", null, null, "net.minecraft.nbt", "net.minecraft.nbt.Tag"),
@@ -62,6 +66,26 @@ public enum ClassWrapper {
"net.minecraft.nbt.NbtUtils"),
NMS_IBLOCKDATA(PackageWrapper.NMS, "IBlockData", MinecraftVersion.MC1_8_R3, null,
"net.minecraft.world.level.block.state", "net.minecraft.world.level.block.state.BlockState"),
NMS_NBTACCOUNTER(PackageWrapper.NMS, "NBTReadLimiter", MinecraftVersion.MC1_20_R3, null, "net.minecraft.nbt",
"net.minecraft.nbt.NbtAccounter"),
NMS_CUSTOMDATA(PackageWrapper.NMS, "CustomData", MinecraftVersion.MC1_20_R4, null,
"net.minecraft.world.item.component", "net.minecraft.world.item.component.CustomData"),
NMS_DATACOMPONENTTYPE(PackageWrapper.NMS, "DataComponentType", MinecraftVersion.MC1_20_R4, null,
"net.minecraft.core.component", "net.minecraft.core.component.DataComponentType"),
NMS_DATACOMPONENTS(PackageWrapper.NMS, "DataComponents", MinecraftVersion.MC1_20_R4, null,
"net.minecraft.core.component", "net.minecraft.core.component.DataComponents"),
NMS_DATACOMPONENTHOLDER(PackageWrapper.NMS, "DataComponentHolder", MinecraftVersion.MC1_20_R4, null,
"net.minecraft.core.component", "net.minecraft.core.component.DataComponentHolder"),
NMS_PROVIDER(PackageWrapper.NMS, "HolderLookup$a", MinecraftVersion.MC1_20_R4, null, "net.minecraft.core",
"net.minecraft.core.HolderLookup$Provider"),
NMS_SERVER(PackageWrapper.NMS, "MinecraftServer", MinecraftVersion.MC1_20_R4, null, "net.minecraft.server",
"net.minecraft.server.MinecraftServer"),
NMS_DATAFIXERS(PackageWrapper.NMS, "DataConverterRegistry", MinecraftVersion.MC1_20_R4, null,
"net.minecraft.util.datafix", "net.minecraft.util.datafix.DataFixers"),
NMS_REFERENCES(PackageWrapper.NMS, "DataConverterTypes", MinecraftVersion.MC1_20_R4, null,
"net.minecraft.util.datafix.fixes", "net.minecraft.util.datafix.fixes.References"),
NMS_NBTOPS(PackageWrapper.NMS, "DynamicOpsNBT", MinecraftVersion.MC1_20_R4, null, "net.minecraft.nbt",
"net.minecraft.nbt.NbtOps"),
GAMEPROFILE(PackageWrapper.NONE, "com.mojang.authlib.GameProfile", MinecraftVersion.MC1_8_R3, null);
private Class<?> clazz;
@@ -69,55 +93,106 @@ public enum ClassWrapper {
private final String mojangName;
ClassWrapper(PackageWrapper packageId, String clazzName, MinecraftVersion from, MinecraftVersion to) {
this(packageId, clazzName, from, to, null, null);
}
ClassWrapper(PackageWrapper packageId, String clazzName, MinecraftVersion from, MinecraftVersion to,
String mojangMap, String mojangName) {
String mojangMap, String mojangName)
{
this.mojangName = mojangName;
if (from != null && MinecraftVersion.getVersion().getVersionId() < from.getVersionId()) {
return;
}
if (to != null && MinecraftVersion.getVersion().getVersionId() > to.getVersionId()) {
return;
}
enabled = true;
try {
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_18_R1) && mojangName != null) {
// check for Mojmapped enviroment
try {
clazz = Class.forName(mojangName);
return;
} catch (ClassNotFoundException ex) {
// ignored, not mojang mapped
}
}
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_17_R1) && mojangMap != null) {
clazz = Class.forName(mojangMap + "." + clazzName);
} else if (packageId == PackageWrapper.NONE) {
clazz = Class.forName(clazzName);
} else if (MinecraftVersion.isForgePresent() && MinecraftVersion.getVersion() == MinecraftVersion.MC1_7_R4
&& Forge1710Mappings.getClassMappings().get(this.name()) != null) {
&& Forge1710Mappings.getClassMappings().get(this.name()) != null)
{
clazz = Class.forName(clazzName = Forge1710Mappings.getClassMappings().get(this.name()));
} else if (packageId == PackageWrapper.CRAFTBUKKIT) {
// this also works for un-remapped Paper 1.20+
clazz = Class.forName(Bukkit.getServer().getClass().getPackage().getName() + "." + clazzName);
} else {
// fallback for old versions pre mojmap and in the nms package
String version = MinecraftVersion.getVersion().getPackageName();
clazz = Class.forName(packageId.getUri() + "." + version + "." + clazzName);
}
} catch (Throwable ex) {
getLogger().log(Level.WARNING, "[NBTAPI] Error while trying to resolve the class '" + clazzName + "'!", ex);
}
}
/**
* @return The wrapped class
*/
public Class<?> getClazz() {
return clazz;
}
/**
* @return Is this class available in this Version
*/
public boolean isEnabled() {
return enabled;
}
/**
* @return Package+Class name used by Mojang
*/
public String getMojangName() {
return mojangName;
}
}
@@ -19,6 +19,7 @@ public class Forge1710Mappings {
private static Method crucible_toString;
static {
// Fields
classMap.put("NMS_NBTBASE", "net.minecraft.nbt.NBTBase");
classMap.put("NMS_NBTTAGSTRING", "net.minecraft.nbt.NBTTagString");
@@ -95,32 +96,47 @@ public class Forge1710Mappings {
// Crucible
try {
crucible_toString = Class.forName("net.minecraft.nbt.NBTTagCompound")
.getDeclaredMethod("crucible_toString");
} catch (Exception e) {
e.printStackTrace();
}
}
public static Map<String, String> getClassMappings() {
return classMap;
}
public static Map<String, String> getMethodMapping() {
return methodMap;
}
public static String toString(Object nbtTagCompound) {
if (crucible_toString == null)
throw new NbtApiException("Method not loaded! 'Forge1710Mappings.crucible_toString' ");
try {
return (String) crucible_toString.invoke(nbtTagCompound);
} catch (Exception ex) {
throw new NbtApiException(
"Error while calling the method 'crucible_toString', from Forge1710Mappings. Passed Class: "
+ Forge1710Mappings.class,
ex);
}
}
}
@@ -3,10 +3,12 @@ package de.tr7zw.changeme.nbtapi.utils.nmsmappings;
import java.util.HashMap;
import java.util.Map;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
/**
* Temporary solution to hold Mojang to unmapped Spigot mappings.
* Temporary solution to hold Mojang to unmapped Spigot mappings. Note years
* later: nothing is more permanent than a temporary solution.
*
* @author tr7zw
*
@@ -17,6 +19,7 @@ public class MojangToMapping {
private static Map<String, String> MC1_18R1 = new HashMap<String, String>() {
{
put("net.minecraft.nbt.CompoundTag#contains(java.lang.String)", "e");
put("net.minecraft.nbt.CompoundTag#getCompound(java.lang.String)", "p");
put("net.minecraft.nbt.CompoundTag#getList(java.lang.String,int)", "c");
@@ -28,10 +31,12 @@ public class MojangToMapping {
put("net.minecraft.nbt.CompoundTag#getIntArray(java.lang.String)", "n");
put("net.minecraft.nbt.CompoundTag#remove(java.lang.String)", "r");
put("net.minecraft.nbt.CompoundTag#get(java.lang.String)", "c");
put("net.minecraft.nbt.CompoundTag#put(java.lang.String,net.minecraft.nbt.Tag)", "a");
put("net.minecraft.nbt.CompoundTag#merge(net.minecraft.nbt.CompoundTag)", "a");
put("net.minecraft.nbt.CompoundTag#putBoolean(java.lang.String,boolean)", "a");
put("net.minecraft.nbt.CompoundTag#getTagType(java.lang.String)", "d");
put("net.minecraft.nbt.CompoundTag#putLong(java.lang.String,long)", "a");
put("net.minecraft.nbt.CompoundTag#putLongArray(java.lang.String,long[])", "a");
put("net.minecraft.nbt.CompoundTag#getLongArray(java.lang.String)", "o");
put("net.minecraft.nbt.CompoundTag#getString(java.lang.String)", "l");
put("net.minecraft.nbt.CompoundTag#getInt(java.lang.String)", "h");
put("net.minecraft.nbt.CompoundTag#putString(java.lang.String,java.lang.String)", "a");
@@ -41,7 +46,6 @@ public class MojangToMapping {
put("net.minecraft.nbt.CompoundTag#getShort(java.lang.String)", "g");
put("net.minecraft.nbt.CompoundTag#putByte(java.lang.String,byte)", "a");
put("net.minecraft.nbt.CompoundTag#getAllKeys()", "d");
put("net.minecraft.nbt.CompoundTag#getAllKeys()", "d");
put("net.minecraft.nbt.CompoundTag#putUUID(java.lang.String,java.util.UUID)", "a");
put("net.minecraft.nbt.CompoundTag#putShort(java.lang.String,short)", "a");
put("net.minecraft.nbt.CompoundTag#getLong(java.lang.String)", "i");
@@ -72,6 +76,7 @@ public class MojangToMapping {
put("net.minecraft.world.level.block.entity.BlockEntity#getBlockState()", "q");
put("net.minecraft.world.level.block.entity.BlockEntity#load(net.minecraft.nbt.CompoundTag)", "a");
put("net.minecraft.server.level.ServerLevel#getBlockEntity(net.minecraft.core.BlockPos)", "c_");
}
};
@@ -80,19 +85,24 @@ public class MojangToMapping {
private static Map<String, String> MC1_18R2 = new HashMap<String, String>() {
{
putAll(MC1_18R1);
put("net.minecraft.world.item.ItemStack#getTag()", "t");
}
};
@SuppressWarnings("serial")
private static Map<String, String> MC1_19R1 = new HashMap<String, String>() {
{
putAll(MC1_18R2);
put("net.minecraft.world.item.ItemStack#getTag()", "u");
}
};
@@ -101,27 +111,172 @@ public class MojangToMapping {
private static Map<String, String> MC1_19R2 = new HashMap<String, String>() {
{
putAll(MC1_19R1);
put("net.minecraft.nbt.CompoundTag#getAllKeys()", "e");
}
};
@SuppressWarnings("serial")
private static Map<String, String> MC1_20R1 = new HashMap<String, String>() {
{
putAll(MC1_19R2);
put("net.minecraft.world.entity.Entity#getEncodeId()", "br");
put("net.minecraft.world.item.ItemStack#getTag()", "v");
}
};
@SuppressWarnings("serial")
private static Map<String, String> MC1_20R2 = new HashMap<String, String>() {
{
putAll(MC1_20R1);
put("net.minecraft.world.entity.Entity#getEncodeId()", "bu");
}
};
@SuppressWarnings("serial")
private static Map<String, String> MC1_20R3 = new HashMap<String, String>() {
{
putAll(MC1_20R2);
put("net.minecraft.nbt.NbtIo#readCompressed(java.io.InputStream,net.minecraft.nbt.NbtAccounter)", "a");
put("net.minecraft.nbt.NbtAccounter#unlimitedHeap()", "a");
put("net.minecraft.world.entity.Entity#getEncodeId()", "bw");
put("net.minecraft.world.level.block.entity.BlockEntity#saveWithId()", "p");
put("net.minecraft.world.level.block.entity.BlockEntity#getBlockState()", "r");
put("net.minecraft.world.item.ItemStack#CODEC", "a");
}
};
@SuppressWarnings("serial")
private static Map<String, String> MC1_20R4 = new HashMap<String, String>() {
{
putAll(MC1_20R3);
put("net.minecraft.world.entity.Entity#getEncodeId()", "bC");
put("net.minecraft.world.level.block.entity.BlockEntity#getBlockState()", "n");
put("net.minecraft.core.component.DataComponents#CUSTOM_DATA", "b");
put("net.minecraft.core.component.DataComponentHolder#get(net.minecraft.core.component.DataComponentType)",
"a");
put("net.minecraft.world.item.component.CustomData#copyTag()", "c");
put("net.minecraft.world.item.ItemStack#set(net.minecraft.core.component.DataComponentType,java.lang.Object)",
"b");
put("net.minecraft.world.item.ItemStack#save(net.minecraft.core.HolderLookup$Provider)", "a");
put("net.minecraft.server.MinecraftServer#registryAccess()", "bc");
put("net.minecraft.world.item.ItemStack#parseOptional(net.minecraft.core.HolderLookup$Provider,net.minecraft.nbt.CompoundTag)",
"a");
put("net.minecraft.world.level.block.entity.BlockEntity#saveWithId(net.minecraft.core.HolderLookup$Provider)",
"c");
put("net.minecraft.world.level.block.entity.BlockEntity#loadWithComponents(net.minecraft.nbt.CompoundTag,net.minecraft.core.HolderLookup$Provider)",
"c");
put("net.minecraft.util.datafix.DataFixers#getDataFixer()", "a");
put("net.minecraft.util.datafix.fixes.References#ITEM_STACK", "t");
put("net.minecraft.nbt.NbtOps#INSTANCE", "a");
put("net.minecraft.world.item.ItemStack#CODEC", "b");
}
};
@SuppressWarnings("serial")
private static Map<String, String> MC1_21R1 = new HashMap<String, String>() {
{
putAll(MC1_20R4);
put("net.minecraft.world.entity.Entity#getEncodeId()", "bD");
}
};
@SuppressWarnings("serial")
private static Map<String, String> MC1_21R2 = new HashMap<String, String>() {
{
putAll(MC1_21R1);
put("net.minecraft.server.MinecraftServer#registryAccess()", "ba");
put("net.minecraft.world.entity.Entity#getEncodeId()", "bK");
put("net.minecraft.world.level.block.entity.BlockEntity#getBlockState()", "m");
put("net.minecraft.world.item.ItemStack#CODEC", "a");
}
};
@SuppressWarnings("serial")
private static Map<String, String> MC1_21R3 = new HashMap<String, String>() {
{
putAll(MC1_21R2);
put("net.minecraft.world.item.component.CustomData#copyTag()", "d");
}
};
public static Map<String, String> getMapping() {
switch (MinecraftVersion.getVersion()) {
case MC1_19_R2:
return MC1_19R2;
case MC1_19_R1:
return MC1_19R1;
case MC1_18_R2:
return MC1_18R2;
case MC1_18_R1:
return MC1_18R1;
default:
return MC1_19R2;// throw new NbtApiException("This version of the NBTAPI is not compatible with
// this server version!");
case MC1_21_R3:
return MC1_21R3;
case MC1_21_R2:
return MC1_21R2;
case MC1_21_R1:
return MC1_21R1;
case MC1_20_R4:
return MC1_20R4;
case MC1_20_R3:
return MC1_20R3;
case MC1_20_R2:
return MC1_20R2;
case MC1_20_R1:
return MC1_20R1;
case MC1_19_R3:
return MC1_19R2;
case MC1_19_R2:
return MC1_19R2;
case MC1_19_R1:
return MC1_19R1;
case MC1_18_R2:
return MC1_18R2;
case MC1_18_R1:
return MC1_18R1;
case UNKNOWN:
return MC1_20R2; // assume it's a future version, so try the latest known mappings
default:
// this should never happen, unless a version is forgotten here(like 1.19R3
// which uses the 1.19R2 mappings)
throw new NbtApiException(
"No fitting mapping found for version " + MinecraftVersion.getVersion() + ". This is a bug!");
}
}
}
@@ -16,15 +16,19 @@ import static de.tr7zw.changeme.nbtapi.utils.MinecraftVersion.getLogger;
*/
@SuppressWarnings("javadoc")
public enum ObjectCreator {
NMS_NBTTAGCOMPOUND(null, null, ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()),
NMS_CUSTOMDATA(MinecraftVersion.MC1_20_R4, null, ClassWrapper.NMS_CUSTOMDATA.getClazz(),
ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()),
NMS_BLOCKPOSITION(null, null, ClassWrapper.NMS_BLOCKPOSITION.getClazz(), int.class, int.class, int.class),
NMS_COMPOUNDFROMITEM(MinecraftVersion.MC1_11_R1, null, ClassWrapper.NMS_ITEMSTACK.getClazz(),
NMS_COMPOUNDFROMITEM(MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_20_R3, ClassWrapper.NMS_ITEMSTACK.getClazz(),
ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()),;
private Constructor<?> construct;
private Class<?> targetClass;
ObjectCreator(MinecraftVersion from, MinecraftVersion to, Class<?> clazz, Class<?>... args) {
if (clazz == null)
return;
if (from != null && MinecraftVersion.getVersion().getVersionId() < from.getVersionId())
@@ -32,12 +36,17 @@ public enum ObjectCreator {
if (to != null && MinecraftVersion.getVersion().getVersionId() > to.getVersionId())
return;
try {
this.targetClass = clazz;
construct = clazz.getDeclaredConstructor(args);
construct.setAccessible(true);
} catch (Exception ex) {
getLogger().log(Level.SEVERE, "Unable to find the constructor for the class '" + clazz.getName() + "'", ex);
}
}
/**
@@ -47,11 +56,17 @@ public enum ObjectCreator {
* @return Object created
*/
public Object getInstance(Object... args) {
try {
return construct.newInstance(args);
} catch (Exception ex) {
throw new NbtApiException("Exception while creating a new instance of '" + targetClass + "'", ex);
}
}
}
@@ -8,23 +8,29 @@ package de.tr7zw.changeme.nbtapi.utils.nmsmappings;
*/
@SuppressWarnings("javadoc")
public enum PackageWrapper {
NMS(new String(new byte[] { 'n', 'e', 't', '.', 'm', 'i', 'n', 'e', 'c', 'r', 'a', 'f', 't', '.', 's', 'e', 'r',
'v', 'e', 'r' })),
CRAFTBUKKIT(new String(new byte[] { 'o', 'r', 'g', '.', 'b', 'u', 'k', 'k', 'i', 't', '.', 'c', 'r', 'a', 'f', 't',
'b', 'u', 'k', 'k', 'i', 't' })),
NMS(new String(
new byte[]
{ 'n', 'e', 't', '.', 'm', 'i', 'n', 'e', 'c', 'r', 'a', 'f', 't', '.', 's', 'e', 'r', 'v', 'e', 'r' })),
CRAFTBUKKIT(new String(new byte[]
{ 'o', 'r', 'g', '.', 'b', 'u', 'k', 'k', 'i', 't', '.', 'c', 'r', 'a', 'f', 't', 'b', 'u', 'k', 'k', 'i', 't' })),
NONE("");
private final String uri;
private PackageWrapper(String uri) {
this.uri = uri;
}
/**
* @return The Uri for that package
*/
public String getUri() {
return uri;
}
}
@@ -5,7 +5,6 @@ import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.UUID;
import org.bukkit.inventory.ItemStack;
import de.tr7zw.changeme.nbtapi.NbtApiException;
@@ -21,109 +20,121 @@ import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
@SuppressWarnings("javadoc")
public enum ReflectionMethod {
COMPOUND_SET_FLOAT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class, float.class },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setFloat"),
COMPOUND_SET_FLOAT(
ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class, float.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setFloat"),
new Since(MinecraftVersion.MC1_18_R1, "putFloat(java.lang.String,float)")),
COMPOUND_SET_STRING(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class, String.class },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setString"),
COMPOUND_SET_STRING(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class, String.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setString"),
new Since(MinecraftVersion.MC1_18_R1, "putString(java.lang.String,java.lang.String)")),
COMPOUND_SET_INT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class, int.class },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setInt"),
COMPOUND_SET_INT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class, int.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setInt"),
new Since(MinecraftVersion.MC1_18_R1, "putInt(java.lang.String,int)")),
COMPOUND_SET_BYTEARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class, byte[].class },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setByteArray"),
COMPOUND_SET_BYTEARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class, byte[].class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setByteArray"),
new Since(MinecraftVersion.MC1_18_R1, "putByteArray(java.lang.String,byte[])")),
COMPOUND_SET_INTARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class, int[].class },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setIntArray"),
COMPOUND_SET_INTARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class, int[].class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setIntArray"),
new Since(MinecraftVersion.MC1_18_R1, "putIntArray(java.lang.String,int[])")),
COMPOUND_SET_LONG(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class, long.class },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setLong"),
COMPOUND_SET_LONGARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class, long[].class }, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "a"),
new Since(MinecraftVersion.MC1_18_R1, "putLongArray(java.lang.String,long[])")),
COMPOUND_SET_LONG(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class, long.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setLong"),
new Since(MinecraftVersion.MC1_18_R1, "putLong(java.lang.String,long)")),
COMPOUND_SET_SHORT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class, short.class },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setShort"),
COMPOUND_SET_SHORT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class, short.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setShort"),
new Since(MinecraftVersion.MC1_18_R1, "putShort(java.lang.String,short)")),
COMPOUND_SET_BYTE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class, byte.class },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setByte"),
COMPOUND_SET_BYTE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class, byte.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setByte"),
new Since(MinecraftVersion.MC1_18_R1, "putByte(java.lang.String,byte)")),
COMPOUND_SET_DOUBLE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class, double.class },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setDouble"),
COMPOUND_SET_DOUBLE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class, double.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setDouble"),
new Since(MinecraftVersion.MC1_18_R1, "putDouble(java.lang.String,double)")),
COMPOUND_SET_BOOLEAN(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class, boolean.class },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setBoolean"),
COMPOUND_SET_BOOLEAN(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class, boolean.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setBoolean"),
new Since(MinecraftVersion.MC1_18_R1, "putBoolean(java.lang.String,boolean)")),
COMPOUND_SET_UUID(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class, UUID.class },
MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "a"),
COMPOUND_SET_UUID(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class, UUID.class }, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "a"),
new Since(MinecraftVersion.MC1_18_R1, "putUUID(java.lang.String,java.util.UUID)")),
COMPOUND_MERGE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a"),
COMPOUND_MERGE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_8_R3,
new Since(MinecraftVersion.MC1_8_R3, "a"),
new Since(MinecraftVersion.MC1_18_R1, "merge(net.minecraft.nbt.CompoundTag)")),
COMPOUND_SET(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class, ClassWrapper.NMS_NBTBASE.getClazz() }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "set"),
new Since(MinecraftVersion.MC1_18_R1, "put(java.lang.String,net.minecraft.nbt.Tag)")),
COMPOUND_SET(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class, ClassWrapper.NMS_NBTBASE.getClazz() },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "set"),
new Since(MinecraftVersion.MC1_18_R1, "put(java.lang.String,net.minecraft.nbt.Tag)")),
COMPOUND_GET(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "get"),
COMPOUND_GET(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "get"),
new Since(MinecraftVersion.MC1_18_R1, "get(java.lang.String)")),
COMPOUND_GET_LIST(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class, int.class },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getList"),
COMPOUND_GET_LIST(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class, int.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getList"),
new Since(MinecraftVersion.MC1_18_R1, "getList(java.lang.String,int)")),
// Only needed for 1.7.10 getType
COMPOUND_OWN_TYPE(ClassWrapper.NMS_NBTBASE, new Class[] {}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getTypeId")),
COMPOUND_GET_FLOAT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getFloat"),
COMPOUND_GET_FLOAT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getFloat"),
new Since(MinecraftVersion.MC1_18_R1, "getFloat(java.lang.String)")),
COMPOUND_GET_STRING(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getString"),
COMPOUND_GET_STRING(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getString"),
new Since(MinecraftVersion.MC1_18_R1, "getString(java.lang.String)")),
COMPOUND_GET_INT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getInt"),
COMPOUND_GET_INT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getInt"),
new Since(MinecraftVersion.MC1_18_R1, "getInt(java.lang.String)")),
COMPOUND_GET_BYTEARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getByteArray"),
COMPOUND_GET_BYTEARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getByteArray"),
new Since(MinecraftVersion.MC1_18_R1, "getByteArray(java.lang.String)")),
COMPOUND_GET_INTARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getIntArray"),
COMPOUND_GET_INTARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getIntArray"),
new Since(MinecraftVersion.MC1_18_R1, "getIntArray(java.lang.String)")),
COMPOUND_GET_LONG(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getLong"),
COMPOUND_GET_LONGARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class }, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "getLongArray"),
new Since(MinecraftVersion.MC1_18_R1, "getLongArray(java.lang.String)")),
COMPOUND_GET_LONG(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getLong"),
new Since(MinecraftVersion.MC1_18_R1, "getLong(java.lang.String)")),
COMPOUND_GET_SHORT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getShort"),
COMPOUND_GET_SHORT(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getShort"),
new Since(MinecraftVersion.MC1_18_R1, "getShort(java.lang.String)")),
COMPOUND_GET_BYTE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getByte"),
COMPOUND_GET_BYTE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getByte"),
new Since(MinecraftVersion.MC1_18_R1, "getByte(java.lang.String)")),
COMPOUND_GET_DOUBLE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getDouble"),
COMPOUND_GET_DOUBLE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getDouble"),
new Since(MinecraftVersion.MC1_18_R1, "getDouble(java.lang.String)")),
COMPOUND_GET_BOOLEAN(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getBoolean"),
COMPOUND_GET_BOOLEAN(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getBoolean"),
new Since(MinecraftVersion.MC1_18_R1, "getBoolean(java.lang.String)")),
COMPOUND_GET_UUID(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_16_R1,
new Since(MinecraftVersion.MC1_16_R1, "a"),
COMPOUND_GET_UUID(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class }, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "a"),
new Since(MinecraftVersion.MC1_18_R1, "getUUID(java.lang.String)")),
COMPOUND_GET_COMPOUND(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getCompound"),
COMPOUND_GET_COMPOUND(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getCompound"),
new Since(MinecraftVersion.MC1_18_R1, "getCompound(java.lang.String)")),
NMSITEM_GETTAG(ClassWrapper.NMS_ITEMSTACK, new Class[] {}, MinecraftVersion.MC1_7_R4,
NMSITEM_GETTAG(ClassWrapper.NMS_ITEMSTACK, new Class[] {}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_20_R3,
new Since(MinecraftVersion.MC1_7_R4, "getTag"), new Since(MinecraftVersion.MC1_18_R1, "getTag()")),
NMSITEM_SAVE(ClassWrapper.NMS_ITEMSTACK, new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "save"),
NMSITEM_SAVE(ClassWrapper.NMS_ITEMSTACK, new Class[]
{ ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_20_R3,
new Since(MinecraftVersion.MC1_7_R4, "save"),
new Since(MinecraftVersion.MC1_18_R1, "save(net.minecraft.nbt.CompoundTag)")),
NMSITEM_CREATESTACK(ClassWrapper.NMS_ITEMSTACK, new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_10_R1, new Since(MinecraftVersion.MC1_7_R4, "createStack")),
NMSITEM_CREATESTACK(ClassWrapper.NMS_ITEMSTACK, new Class[]
{ ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_10_R1,
new Since(MinecraftVersion.MC1_7_R4, "createStack")),
COMPOUND_REMOVE_KEY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "remove"),
COMPOUND_REMOVE_KEY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "remove"),
new Since(MinecraftVersion.MC1_18_R1, "remove(java.lang.String)")),
COMPOUND_HAS_KEY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "hasKey"),
COMPOUND_HAS_KEY(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "hasKey"),
new Since(MinecraftVersion.MC1_18_R1, "contains(java.lang.String)")),
COMPOUND_GET_TYPE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] { String.class }, MinecraftVersion.MC1_8_R3,
new Since(MinecraftVersion.MC1_8_R3, "b"), new Since(MinecraftVersion.MC1_9_R1, "d"),
new Since(MinecraftVersion.MC1_15_R1, "e"), new Since(MinecraftVersion.MC1_16_R1, "d"),
COMPOUND_GET_TYPE(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[]
{ String.class }, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "b"),
new Since(MinecraftVersion.MC1_9_R1, "d"), new Since(MinecraftVersion.MC1_15_R1, "e"),
new Since(MinecraftVersion.MC1_16_R1, "d"),
new Since(MinecraftVersion.MC1_18_R1, "getTagType(java.lang.String)")),
COMPOUND_GET_KEYS(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] {}, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "c"), new Since(MinecraftVersion.MC1_13_R1, "getKeys"),
@@ -132,86 +143,90 @@ public enum ReflectionMethod {
LISTCOMPOUND_GET_KEYS(ClassWrapper.NMS_NBTTAGCOMPOUND, new Class[] {}, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "c"), new Since(MinecraftVersion.MC1_13_R1, "getKeys"),
new Since(MinecraftVersion.MC1_18_R1, "getAllKeys()")),
LIST_REMOVE_KEY(ClassWrapper.NMS_NBTTAGLIST, new Class[] { int.class }, MinecraftVersion.MC1_8_R3,
new Since(MinecraftVersion.MC1_8_R3, "a"), new Since(MinecraftVersion.MC1_9_R1, "remove"),
new Since(MinecraftVersion.MC1_18_R1, "remove(int)")),
LIST_REMOVE_KEY(ClassWrapper.NMS_NBTTAGLIST, new Class[]
{ int.class }, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a"),
new Since(MinecraftVersion.MC1_9_R1, "remove"), new Since(MinecraftVersion.MC1_18_R1, "remove(int)")),
LIST_SIZE(ClassWrapper.NMS_NBTTAGLIST, new Class[] {}, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "size"), new Since(MinecraftVersion.MC1_18_R1, "size()")),
LIST_SET(ClassWrapper.NMS_NBTTAGLIST, new Class[] { int.class, ClassWrapper.NMS_NBTBASE.getClazz() },
MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a"),
new Since(MinecraftVersion.MC1_13_R1, "set"),
LIST_SET(ClassWrapper.NMS_NBTTAGLIST, new Class[]
{ int.class, ClassWrapper.NMS_NBTBASE.getClazz() }, MinecraftVersion.MC1_8_R3,
new Since(MinecraftVersion.MC1_8_R3, "a"), new Since(MinecraftVersion.MC1_13_R1, "set"),
new Since(MinecraftVersion.MC1_18_R1, "setTag(int,net.minecraft.nbt.Tag)")),
LEGACY_LIST_ADD(ClassWrapper.NMS_NBTTAGLIST, new Class[] { ClassWrapper.NMS_NBTBASE.getClazz() },
MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_13_R2, new Since(MinecraftVersion.MC1_7_R4, "add")),
LIST_ADD(ClassWrapper.NMS_NBTTAGLIST, new Class[] { int.class, ClassWrapper.NMS_NBTBASE.getClazz() },
MinecraftVersion.MC1_14_R1, new Since(MinecraftVersion.MC1_14_R1, "add"),
LEGACY_LIST_ADD(ClassWrapper.NMS_NBTTAGLIST, new Class[]
{ ClassWrapper.NMS_NBTBASE.getClazz() }, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_13_R2,
new Since(MinecraftVersion.MC1_7_R4, "add")),
LIST_ADD(ClassWrapper.NMS_NBTTAGLIST, new Class[]
{ int.class, ClassWrapper.NMS_NBTBASE.getClazz() }, MinecraftVersion.MC1_14_R1,
new Since(MinecraftVersion.MC1_14_R1, "add"),
new Since(MinecraftVersion.MC1_18_R1, "addTag(int,net.minecraft.nbt.Tag)")),
LIST_GET_STRING(ClassWrapper.NMS_NBTTAGLIST, new Class[] { int.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getString"), new Since(MinecraftVersion.MC1_18_R1, "getString(int)")),
LIST_GET_COMPOUND(ClassWrapper.NMS_NBTTAGLIST, new Class[] { int.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "get"), new Since(MinecraftVersion.MC1_18_R1, "getCompound(int)")),
LIST_GET(ClassWrapper.NMS_NBTTAGLIST, new Class[] { int.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "get"), new Since(MinecraftVersion.MC1_8_R3, "g"),
new Since(MinecraftVersion.MC1_9_R1, "h"), new Since(MinecraftVersion.MC1_12_R1, "i"),
new Since(MinecraftVersion.MC1_13_R1, "get"), new Since(MinecraftVersion.MC1_18_R1, "get(int)")),
LIST_GET_STRING(ClassWrapper.NMS_NBTTAGLIST, new Class[]
{ int.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getString"),
new Since(MinecraftVersion.MC1_18_R1, "getString(int)")),
LIST_GET_COMPOUND(ClassWrapper.NMS_NBTTAGLIST, new Class[]
{ int.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "get"),
new Since(MinecraftVersion.MC1_18_R1, "getCompound(int)")),
LIST_GET(ClassWrapper.NMS_NBTTAGLIST, new Class[]
{ int.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "get"),
new Since(MinecraftVersion.MC1_8_R3, "g"), new Since(MinecraftVersion.MC1_9_R1, "h"),
new Since(MinecraftVersion.MC1_12_R1, "i"), new Since(MinecraftVersion.MC1_13_R1, "get"),
new Since(MinecraftVersion.MC1_18_R1, "get(int)")),
ITEMSTACK_SET_TAG(ClassWrapper.NMS_ITEMSTACK, new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setTag"),
ITEMSTACK_SET_TAG(ClassWrapper.NMS_ITEMSTACK, new Class[]
{ ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_20_R3,
new Since(MinecraftVersion.MC1_7_R4, "setTag"),
new Since(MinecraftVersion.MC1_18_R1, "setTag(net.minecraft.nbt.CompoundTag)")),
ITEMSTACK_NMSCOPY(ClassWrapper.CRAFT_ITEMSTACK, new Class[] { ItemStack.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "asNMSCopy")),
ITEMSTACK_BUKKITMIRROR(ClassWrapper.CRAFT_ITEMSTACK, new Class[] { ClassWrapper.NMS_ITEMSTACK.getClazz() },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "asCraftMirror")),
ITEMSTACK_NMSCOPY(ClassWrapper.CRAFT_ITEMSTACK, new Class[]
{ ItemStack.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "asNMSCopy")),
ITEMSTACK_BUKKITMIRROR(ClassWrapper.CRAFT_ITEMSTACK, new Class[]
{ ClassWrapper.NMS_ITEMSTACK.getClazz() }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "asCraftMirror")),
CRAFT_WORLD_GET_HANDLE(ClassWrapper.CRAFT_WORLD, new Class[] {}, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getHandle")),
NMS_WORLD_GET_TILEENTITY(ClassWrapper.NMS_WORLDSERVER, new Class[] { ClassWrapper.NMS_BLOCKPOSITION.getClazz() },
MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "getTileEntity"),
NMS_WORLD_GET_TILEENTITY(ClassWrapper.NMS_WORLDSERVER, new Class[]
{ ClassWrapper.NMS_BLOCKPOSITION.getClazz() }, MinecraftVersion.MC1_8_R3,
new Since(MinecraftVersion.MC1_8_R3, "getTileEntity"),
new Since(MinecraftVersion.MC1_18_R1, "getBlockEntity(net.minecraft.core.BlockPos)")),
NMS_WORLD_SET_TILEENTITY(ClassWrapper.NMS_WORLDSERVER,
new Class[] { ClassWrapper.NMS_BLOCKPOSITION.getClazz(), ClassWrapper.NMS_TILEENTITY.getClazz() },
MinecraftVersion.MC1_8_R3, MinecraftVersion.MC1_16_R3,
new Since(MinecraftVersion.MC1_8_R3, "setTileEntity")),
NMS_WORLD_REMOVE_TILEENTITY(ClassWrapper.NMS_WORLDSERVER, new Class[] { ClassWrapper.NMS_BLOCKPOSITION.getClazz() },
MinecraftVersion.MC1_8_R3, MinecraftVersion.MC1_17_R1, new Since(MinecraftVersion.MC1_8_R3, "t"),
new Since(MinecraftVersion.MC1_9_R1, "s"), new Since(MinecraftVersion.MC1_13_R1, "n"),
new Since(MinecraftVersion.MC1_14_R1, "removeTileEntity")),
NMS_WORLD_REMOVE_TILEENTITY(ClassWrapper.NMS_WORLDSERVER, new Class[]
{ ClassWrapper.NMS_BLOCKPOSITION.getClazz() }, MinecraftVersion.MC1_8_R3, MinecraftVersion.MC1_17_R1,
new Since(MinecraftVersion.MC1_8_R3, "t"), new Since(MinecraftVersion.MC1_9_R1, "s"),
new Since(MinecraftVersion.MC1_13_R1, "n"), new Since(MinecraftVersion.MC1_14_R1, "removeTileEntity")),
NMS_WORLD_GET_TILEENTITY_1_7_10(ClassWrapper.NMS_WORLDSERVER, new Class[] { int.class, int.class, int.class },
MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_7_R4,
NMS_WORLD_GET_TILEENTITY_1_7_10(ClassWrapper.NMS_WORLDSERVER, new Class[]
{ int.class, int.class, int.class }, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getTileEntity")),
// FIXME: No Spigot mapping!
TILEENTITY_LOAD_LEGACY191(ClassWrapper.NMS_TILEENTITY,
new Class[] { ClassWrapper.NMS_MINECRAFTSERVER.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
TILEENTITY_LOAD_LEGACY191(ClassWrapper.NMS_TILEENTITY, new Class[]
{ ClassWrapper.NMS_MINECRAFTSERVER.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
MinecraftVersion.MC1_9_R1, MinecraftVersion.MC1_9_R1, new Since(MinecraftVersion.MC1_9_R1, "a")),
// FIXME: No Spigot mapping!
TILEENTITY_LOAD_LEGACY183(ClassWrapper.NMS_TILEENTITY, new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
MinecraftVersion.MC1_8_R3, MinecraftVersion.MC1_9_R2, new Since(MinecraftVersion.MC1_8_R3, "c"),
new Since(MinecraftVersion.MC1_9_R1, "a"), new Since(MinecraftVersion.MC1_9_R2, "c")),
TILEENTITY_LOAD_LEGACY1121(ClassWrapper.NMS_TILEENTITY,
new Class[] { ClassWrapper.NMS_WORLD.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
MinecraftVersion.MC1_10_R1, MinecraftVersion.MC1_12_R1, new Since(MinecraftVersion.MC1_10_R1, "a"),
TILEENTITY_LOAD_LEGACY183(ClassWrapper.NMS_TILEENTITY, new Class[]
{ ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_8_R3, MinecraftVersion.MC1_9_R2,
new Since(MinecraftVersion.MC1_8_R3, "c"), new Since(MinecraftVersion.MC1_9_R1, "a"),
new Since(MinecraftVersion.MC1_9_R2, "c")),
TILEENTITY_LOAD_LEGACY1121(ClassWrapper.NMS_TILEENTITY, new Class[]
{ ClassWrapper.NMS_WORLD.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_10_R1,
MinecraftVersion.MC1_12_R1, new Since(MinecraftVersion.MC1_10_R1, "a"),
new Since(MinecraftVersion.MC1_12_R1, "create")),
TILEENTITY_LOAD_LEGACY1151(ClassWrapper.NMS_TILEENTITY, new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
MinecraftVersion.MC1_13_R1, MinecraftVersion.MC1_15_R1, new Since(MinecraftVersion.MC1_12_R1, "create")),
TILEENTITY_LOAD(ClassWrapper.NMS_TILEENTITY,
new Class[] { ClassWrapper.NMS_IBLOCKDATA.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
MinecraftVersion.MC1_16_R1, MinecraftVersion.MC1_16_R3, new Since(MinecraftVersion.MC1_16_R1, "create")),
TILEENTITY_LOAD_LEGACY1151(ClassWrapper.NMS_TILEENTITY, new Class[]
{ ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_13_R1, MinecraftVersion.MC1_15_R1,
new Since(MinecraftVersion.MC1_12_R1, "create")),
TILEENTITY_LOAD(ClassWrapper.NMS_TILEENTITY, new Class[]
{ ClassWrapper.NMS_IBLOCKDATA.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_16_R1,
MinecraftVersion.MC1_16_R3, new Since(MinecraftVersion.MC1_16_R1, "create")),
TILEENTITY_GET_NBT(ClassWrapper.NMS_TILEENTITY, new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_17_R1, new Since(MinecraftVersion.MC1_7_R4, "b"),
new Since(MinecraftVersion.MC1_9_R1, "save")),
TILEENTITY_GET_NBT(ClassWrapper.NMS_TILEENTITY, new Class[]
{ ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_17_R1,
new Since(MinecraftVersion.MC1_7_R4, "b"), new Since(MinecraftVersion.MC1_9_R1, "save")),
TILEENTITY_GET_NBT_1181(ClassWrapper.NMS_TILEENTITY, new Class[] {}, MinecraftVersion.MC1_18_R1,
new Since(MinecraftVersion.MC1_18_R1, "saveWithId()")),
TILEENTITY_SET_NBT_LEGACY1151(ClassWrapper.NMS_TILEENTITY,
new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_7_R4,
MinecraftVersion.MC1_15_R1, new Since(MinecraftVersion.MC1_7_R4, "a"),
new Since(MinecraftVersion.MC1_12_R1, "load")),
TILEENTITY_SET_NBT_LEGACY1161(ClassWrapper.NMS_TILEENTITY,
new Class[] { ClassWrapper.NMS_IBLOCKDATA.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
MinecraftVersion.MC1_16_R1, MinecraftVersion.MC1_16_R3, new Since(MinecraftVersion.MC1_16_R1, "load")),
TILEENTITY_SET_NBT(ClassWrapper.NMS_TILEENTITY, new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
MinecraftVersion.MC1_17_R1, new Since(MinecraftVersion.MC1_16_R1, "load"),
MinecraftVersion.MC1_20_R3, new Since(MinecraftVersion.MC1_18_R1, "saveWithId()")),
TILEENTITY_SET_NBT_LEGACY1151(ClassWrapper.NMS_TILEENTITY, new Class[]
{ ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_15_R1,
new Since(MinecraftVersion.MC1_7_R4, "a"), new Since(MinecraftVersion.MC1_12_R1, "load")),
TILEENTITY_SET_NBT_LEGACY1161(ClassWrapper.NMS_TILEENTITY, new Class[]
{ ClassWrapper.NMS_IBLOCKDATA.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_16_R1,
MinecraftVersion.MC1_16_R3, new Since(MinecraftVersion.MC1_16_R1, "load")),
TILEENTITY_SET_NBT(ClassWrapper.NMS_TILEENTITY, new Class[]
{ ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_17_R1, MinecraftVersion.MC1_20_R4,
new Since(MinecraftVersion.MC1_16_R1, "load"),
new Since(MinecraftVersion.MC1_18_R1, "load(net.minecraft.nbt.CompoundTag)")),
TILEENTITY_GET_BLOCKDATA(ClassWrapper.NMS_TILEENTITY, new Class[] {}, MinecraftVersion.MC1_16_R1,
new Since(MinecraftVersion.MC1_16_R1, "getBlock"),
@@ -219,53 +234,66 @@ public enum ReflectionMethod {
CRAFT_ENTITY_GET_HANDLE(ClassWrapper.CRAFT_ENTITY, new Class[] {}, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "getHandle")),
NMS_ENTITY_SET_NBT(ClassWrapper.NMS_ENTITY, new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "f"),
new Since(MinecraftVersion.MC1_16_R1, "load"),
NMS_ENTITY_SET_NBT(ClassWrapper.NMS_ENTITY, new Class[]
{ ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "f"), new Since(MinecraftVersion.MC1_16_R1, "load"),
new Since(MinecraftVersion.MC1_18_R1, "load(net.minecraft.nbt.CompoundTag)")),
NMS_ENTITY_GET_NBT(ClassWrapper.NMS_ENTITY, new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "e"),
new Since(MinecraftVersion.MC1_12_R1, "save"),
NMS_ENTITY_GET_NBT(ClassWrapper.NMS_ENTITY, new Class[]
{ ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "e"), new Since(MinecraftVersion.MC1_12_R1, "save"),
new Since(MinecraftVersion.MC1_18_R1, "saveWithoutId(net.minecraft.nbt.CompoundTag)")),
NMS_ENTITY_GETSAVEID(ClassWrapper.NMS_ENTITY, new Class[] {}, MinecraftVersion.MC1_14_R1,
new Since(MinecraftVersion.MC1_14_R1, "getSaveID"), new Since(MinecraftVersion.MC1_18_R1, "getEncodeId()")),
NBTFILE_READ(ClassWrapper.NMS_NBTCOMPRESSEDSTREAMTOOLS, new Class[] { InputStream.class },
MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "a"),
NBTFILE_READ(ClassWrapper.NMS_NBTCOMPRESSEDSTREAMTOOLS, new Class[]
{ InputStream.class }, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_20_R2,
new Since(MinecraftVersion.MC1_7_R4, "a"),
new Since(MinecraftVersion.MC1_18_R1, "readCompressed(java.io.InputStream)")),
NBTFILE_WRITE(ClassWrapper.NMS_NBTCOMPRESSEDSTREAMTOOLS,
new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), OutputStream.class }, MinecraftVersion.MC1_7_R4,
NBTFILE_READV2(ClassWrapper.NMS_NBTCOMPRESSEDSTREAMTOOLS, new Class[]
{ InputStream.class, ClassWrapper.NMS_NBTACCOUNTER.getClazz() }, MinecraftVersion.MC1_20_R3,
new Since(MinecraftVersion.MC1_20_R3,
"readCompressed(java.io.InputStream,net.minecraft.nbt.NbtAccounter)")),
NBTACCOUNTER_CREATE_UNLIMITED(ClassWrapper.NMS_NBTACCOUNTER, new Class[] {}, MinecraftVersion.MC1_20_R3,
new Since(MinecraftVersion.MC1_20_R3, "unlimitedHeap()")),
NBTFILE_WRITE(ClassWrapper.NMS_NBTCOMPRESSEDSTREAMTOOLS, new Class[]
{ ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), OutputStream.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "a"),
new Since(MinecraftVersion.MC1_18_R1,
"writeCompressed(net.minecraft.nbt.CompoundTag,java.io.OutputStream)")),
PARSE_NBT(ClassWrapper.NMS_MOJANGSONPARSER, new Class[] { String.class }, MinecraftVersion.MC1_7_R4,
new Since(MinecraftVersion.MC1_7_R4, "parse"),
PARSE_NBT(ClassWrapper.NMS_MOJANGSONPARSER, new Class[]
{ String.class }, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "parse"),
new Since(MinecraftVersion.MC1_18_R1, "parseTag(java.lang.String)")),
REGISTRY_KEYSET(ClassWrapper.NMS_REGISTRYSIMPLE, new Class[] {}, MinecraftVersion.MC1_11_R1,
MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "keySet")),
REGISTRY_GET(ClassWrapper.NMS_REGISTRYSIMPLE, new Class[] { Object.class }, MinecraftVersion.MC1_11_R1,
MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "get")),
// FIXME: No Spigot mapping!
REGISTRY_SET(ClassWrapper.NMS_REGISTRYSIMPLE, new Class[] { Object.class, Object.class },
MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "a")),
// FIXME: No Spigot mapping!
REGISTRY_GET_INVERSE(ClassWrapper.NMS_REGISTRYMATERIALS, new Class[] { Object.class }, MinecraftVersion.MC1_11_R1,
MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "b")),
REGISTRY_GET(ClassWrapper.NMS_REGISTRYSIMPLE, new Class[]
{ Object.class }, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1,
new Since(MinecraftVersion.MC1_11_R1, "get")),
REGISTRY_SET(ClassWrapper.NMS_REGISTRYSIMPLE, new Class[]
{ Object.class, Object.class }, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1,
new Since(MinecraftVersion.MC1_11_R1, "a")),
REGISTRY_GET_INVERSE(ClassWrapper.NMS_REGISTRYMATERIALS, new Class[]
{ Object.class }, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1,
new Since(MinecraftVersion.MC1_11_R1, "b")),
REGISTRYMATERIALS_KEYSET(ClassWrapper.NMS_REGISTRYMATERIALS, new Class[] {}, MinecraftVersion.MC1_13_R1,
MinecraftVersion.MC1_17_R1, new Since(MinecraftVersion.MC1_13_R1, "keySet")),
REGISTRYMATERIALS_GET(ClassWrapper.NMS_REGISTRYMATERIALS, new Class[] { ClassWrapper.NMS_MINECRAFTKEY.getClazz() },
MinecraftVersion.MC1_13_R1, MinecraftVersion.MC1_17_R1, new Since(MinecraftVersion.MC1_13_R1, "get")),
REGISTRYMATERIALS_GETKEY(ClassWrapper.NMS_REGISTRYMATERIALS, new Class[] { Object.class },
MinecraftVersion.MC1_13_R2, MinecraftVersion.MC1_17_R1, new Since(MinecraftVersion.MC1_13_R2, "getKey")),
REGISTRYMATERIALS_GET(ClassWrapper.NMS_REGISTRYMATERIALS, new Class[]
{ ClassWrapper.NMS_MINECRAFTKEY.getClazz() }, MinecraftVersion.MC1_13_R1, MinecraftVersion.MC1_17_R1,
new Since(MinecraftVersion.MC1_13_R1, "get")),
REGISTRYMATERIALS_GETKEY(ClassWrapper.NMS_REGISTRYMATERIALS, new Class[]
{ Object.class }, MinecraftVersion.MC1_13_R2, MinecraftVersion.MC1_17_R1,
new Since(MinecraftVersion.MC1_13_R2, "getKey")),
GAMEPROFILE_DESERIALIZE(ClassWrapper.NMS_GAMEPROFILESERIALIZER,
new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_7_R4,
GAMEPROFILE_DESERIALIZE(ClassWrapper.NMS_GAMEPROFILESERIALIZER, new Class[]
{ ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_20_R3,
new Since(MinecraftVersion.MC1_7_R4, "deserialize"),
new Since(MinecraftVersion.MC1_18_R1, "readGameProfile(net.minecraft.nbt.CompoundTag)")),
GAMEPROFILE_SERIALIZE(ClassWrapper.NMS_GAMEPROFILESERIALIZER,
new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), ClassWrapper.GAMEPROFILE.getClazz() },
MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "serialize"),
GAMEPROFILE_SERIALIZE(ClassWrapper.NMS_GAMEPROFILESERIALIZER, new Class[]
{ ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), ClassWrapper.GAMEPROFILE.getClazz() }, MinecraftVersion.MC1_8_R3,
MinecraftVersion.MC1_20_R3, new Since(MinecraftVersion.MC1_8_R3, "serialize"),
new Since(MinecraftVersion.MC1_18_R1,
"writeGameProfile(net.minecraft.nbt.CompoundTag,com.mojang.authlib.GameProfile)")),
@@ -273,9 +301,39 @@ public enum ReflectionMethod {
MinecraftVersion.MC1_14_R1, new Since(MinecraftVersion.MC1_14_R1, "toTagCompound")),
CRAFT_PERSISTENT_DATA_CONTAINER_GET_MAP(ClassWrapper.CRAFT_PERSISTENTDATACONTAINER, new Class[] {},
MinecraftVersion.MC1_14_R1, new Since(MinecraftVersion.MC1_14_R1, "getRaw")),
CRAFT_PERSISTENT_DATA_CONTAINER_PUT_ALL(ClassWrapper.CRAFT_PERSISTENTDATACONTAINER,
new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_14_R1,
new Since(MinecraftVersion.MC1_14_R1, "putAll")),;
CRAFT_PERSISTENT_DATA_CONTAINER_PUT_ALL(ClassWrapper.CRAFT_PERSISTENTDATACONTAINER, new Class[]
{ ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_14_R1,
new Since(MinecraftVersion.MC1_14_R1, "putAll")),
// 1.20.5+ Stuff
NMSDATACOMPONENTHOLDER_GET(ClassWrapper.NMS_DATACOMPONENTHOLDER, new Class[]
{ ClassWrapper.NMS_DATACOMPONENTTYPE.getClazz() }, MinecraftVersion.MC1_20_R4,
new Since(MinecraftVersion.MC1_20_R4, "get(net.minecraft.core.component.DataComponentType)")),
NMSCUSTOMDATA_GETCOPY(ClassWrapper.NMS_CUSTOMDATA, new Class[] {}, MinecraftVersion.MC1_20_R4,
new Since(MinecraftVersion.MC1_20_R4, "copyTag()")),
NMSITEM_SET(ClassWrapper.NMS_ITEMSTACK, new Class[]
{ ClassWrapper.NMS_DATACOMPONENTTYPE.getClazz(), Object.class }, MinecraftVersion.MC1_20_R4,
new Since(MinecraftVersion.MC1_20_R4,
"set(net.minecraft.core.component.DataComponentType,java.lang.Object)")),
NMSITEM_SAVE_MODERN(ClassWrapper.NMS_ITEMSTACK, new Class[]
{ ClassWrapper.NMS_PROVIDER.getClazz() }, MinecraftVersion.MC1_20_R4,
new Since(MinecraftVersion.MC1_20_R4, "save(net.minecraft.core.HolderLookup$Provider)")),
NMSITEM_LOAD(ClassWrapper.NMS_ITEMSTACK, new Class[]
{ ClassWrapper.NMS_PROVIDER.getClazz(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_20_R4,
new Since(MinecraftVersion.MC1_20_R4,
"parseOptional(net.minecraft.core.HolderLookup$Provider,net.minecraft.nbt.CompoundTag)")),
NMSSERVER_GETREGISTRYACCESS(ClassWrapper.NMS_SERVER, new Class[] {}, MinecraftVersion.MC1_20_R4,
new Since(MinecraftVersion.MC1_20_R4, "registryAccess()")),
NMSSERVER_GETSERVER(ClassWrapper.CRAFT_SERVER, new Class[] {}, MinecraftVersion.MC1_20_R4,
new Since(MinecraftVersion.MC1_20_R4, "getServer()")),
TILEENTITY_GET_NBT_1205(ClassWrapper.NMS_TILEENTITY, new Class[]
{ ClassWrapper.NMS_PROVIDER.getClazz() }, MinecraftVersion.MC1_20_R4,
new Since(MinecraftVersion.MC1_20_R4, "saveWithId(net.minecraft.core.HolderLookup$Provider)")),
TILEENTITY_SET_NBT_1205(ClassWrapper.NMS_TILEENTITY, new Class[]
{ ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), ClassWrapper.NMS_PROVIDER.getClazz() }, MinecraftVersion.MC1_20_R4,
new Since(MinecraftVersion.MC1_20_R4,
"loadWithComponents(net.minecraft.nbt.CompoundTag,net.minecraft.core.HolderLookup$Provider)")),
GET_DATAFIXER(ClassWrapper.NMS_DATAFIXERS, new Class[] {}, MinecraftVersion.MC1_20_R4,
new Since(MinecraftVersion.MC1_20_R4, "getDataFixer()")),;
private MinecraftVersion removedAfter;
private Since targetVersion;
@@ -286,7 +344,9 @@ public enum ReflectionMethod {
private ClassWrapper parentClassWrapper;
ReflectionMethod(ClassWrapper targetClass, Class<?>[] args, MinecraftVersion addedSince,
MinecraftVersion removedAfter, Since... methodnames) {
MinecraftVersion removedAfter, Since... methodnames)
{
this.removedAfter = removedAfter;
this.parentClassWrapper = targetClass;
// Special Case for Modded 1.7.10
@@ -300,25 +360,52 @@ public enum ReflectionMethod {
MinecraftVersion server = MinecraftVersion.getVersion();
Since target = methodnames[0];
for (Since s : methodnames) {
if (s.version.getVersionId() <= server.getVersionId()
&& target.version.getVersionId() < s.version.getVersionId())
target = s;
}
targetVersion = target;
String targetMethodName = targetVersion.name;
try {
if (MinecraftVersion.isForgePresent() && MinecraftVersion.getVersion() == MinecraftVersion.MC1_7_R4) {
targetMethodName = Forge1710Mappings.getMethodMapping().getOrDefault(this.name(), targetMethodName);
} else if (targetVersion.version.isMojangMapping()) {
try {
// check for mojang mapped method
String name = targetVersion.name.split("\\(")[0];
method = targetClass.getClazz().getMethod(name, args);
method.setAccessible(true);
loaded = true;
methodName = name;
return;
} catch (NoSuchMethodException ignore) {
// not mojang mapped
}
targetMethodName = MojangToMapping.getMapping().getOrDefault(
targetClass.getMojangName() + "#" + targetVersion.name, "Unmapped" + targetVersion.name);
}
method = targetClass.getClazz().getDeclaredMethod(targetMethodName, args);
method.setAccessible(true);
loaded = true;
methodName = targetVersion.name;
} catch (NullPointerException | NoSuchMethodException | SecurityException ex) {
try {
if (targetVersion.version.isMojangMapping())
targetMethodName = MojangToMapping.getMapping().getOrDefault(
targetClass.getMojangName() + "#" + targetVersion.name, "Unmapped" + targetVersion.name);
@@ -326,19 +413,26 @@ public enum ReflectionMethod {
method.setAccessible(true);
loaded = true;
methodName = targetVersion.name;
} catch (NullPointerException | NoSuchMethodException | SecurityException ex2) {
MinecraftVersion.getLogger()
.warning("[NBTAPI] Unable to find the method '" + targetMethodName + "' in '"
+ (targetClass.getClazz() == null ? targetClass.getMojangName()
: targetClass.getClazz().getSimpleName())
+ "' Args: " + Arrays.toString(args) + " Enum: " + this); // NOSONAR This gets loaded
// before the logger is loaded
}
}
}
ReflectionMethod(ClassWrapper targetClass, Class<?>[] args, MinecraftVersion addedSince, Since... methodnames) {
this(targetClass, args, addedSince, null, methodnames);
}
/**
@@ -349,56 +443,77 @@ public enum ReflectionMethod {
* @return Value returned by the method
*/
public Object run(Object target, Object... args) {
if (method == null)
throw new NbtApiException("Method not loaded! '" + this + "'");
try {
return method.invoke(target, args);
} catch (Exception ex) {
throw new NbtApiException("Error while calling the method '" + methodName + "', loaded: " + loaded
+ ", Enum: " + this + ", Passed Class: " + (target == null ? "null" : target.getClass()), ex);
+ ", Enum: " + this + ", Passed Class: " + (target == null ? "null" : target.getClass()) + " Args: "
+ (args == null ? "null" : Arrays.toString(args)), ex);
}
}
/**
* @return The MethodName, used in this Minecraft Version
*/
public String getMethodName() {
return methodName;
}
/**
* @return Has this method been linked
*/
public boolean isLoaded() {
return loaded;
}
/**
* @return Is this method available in this Minecraft Version
*/
public boolean isCompatible() {
return compatible;
}
public Since getSelectedVersionInfo() {
return targetVersion;
}
/**
* @return Get Wrapper of the parent class
*/
public ClassWrapper getParentClassWrapper() {
return parentClassWrapper;
}
public static class Since {
public final MinecraftVersion version;
public final String name;
public Since(MinecraftVersion version, String name) {
this.version = version;
this.name = name;
}
}
}
@@ -0,0 +1,67 @@
package de.tr7zw.changeme.nbtapi.wrapper;
import java.util.function.UnaryOperator;
public enum Casing {
camelCase(s -> {
if (s.length() < 2) {
return s.toLowerCase();
}
return Character.toLowerCase(s.charAt(0)) + s.substring(1);
}), snake_case(s -> {
StringBuilder result = new StringBuilder();
// Convert the first letter to lowercase
result.append(Character.toLowerCase(s.charAt(0)));
// Iterate through the rest of the string
for (int i = 1; i < s.length(); i++) {
char currentChar = s.charAt(i);
// Convert uppercase letters to lowercase and add underscore
if (Character.isUpperCase(currentChar)) {
result.append('_').append(Character.toLowerCase(currentChar));
} else {
result.append(currentChar);
}
}
return result.toString();
}), PascalCase(s -> {
if (s.length() < 2) {
return s.toUpperCase();
}
return Character.toUpperCase(s.charAt(0)) + s.substring(1);
}), lowercase(String::toLowerCase), UPPERCASE(String::toUpperCase);
private UnaryOperator<String> convert;
Casing(UnaryOperator<String> function) {
this.convert = function;
}
public String convertString(String str) {
return convert.apply(str);
}
}
@@ -0,0 +1,75 @@
package de.tr7zw.changeme.nbtapi.wrapper;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import de.tr7zw.changeme.nbtapi.NbtApiException;
class DefaultMethodInvoker {
private static Method invokeDefaultMethod;
static {
try {
invokeDefaultMethod = InvocationHandler.class.getDeclaredMethod("invokeDefault",
new Class[]
{ Object.class, Method.class, Object[].class });
invokeDefaultMethod.setAccessible(true);
} catch (NoSuchMethodException | SecurityException e) {
// we are in java 8, use the fallback
}
}
/**
* Using reflections to access reflections, since some are still on java 8.
*
* @param target
* @param method
* @param args
* @return
*/
public static Object invokeDefault(Class<?> srcInt, Object target, Method method, Object[] args) {
if (invokeDefaultMethod != null) { // java 9+
try {
return invokeDefaultMethod.invoke(null, target, method, args);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new NbtApiException("Error while trying to invoke a default method for Java 9+. " + target + " "
+ method + " " + Arrays.toString(args), e);
}
} else {
try {
Constructor<Lookup> constructor = Lookup.class.getDeclaredConstructor(Class.class);
constructor.setAccessible(true);
return constructor.newInstance(srcInt).in(srcInt).unreflectSpecial(method, srcInt).bindTo(target)
.invokeWithArguments(args);
} catch (Throwable e) {
throw new NbtApiException("Error while trying to invoke a default method for Java 8. " + target + " "
+ method + " " + Arrays.toString(args), e);
}
}
}
}
@@ -0,0 +1,43 @@
package de.tr7zw.changeme.nbtapi.wrapper;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import de.tr7zw.changeme.nbtapi.iface.NBTHandler;
public interface NBTProxy {
final Map<Class<?>, NBTHandler<Object>> handlers = new HashMap<>();
public default void init() {
}
public default Casing getCasing() {
return Casing.PascalCase;
}
@SuppressWarnings("unchecked")
public default <T> NBTHandler<T> getHandler(Class<T> clazz) {
return (NBTHandler<T>) handlers.get(clazz);
}
public default Collection<NBTHandler<Object>> getHandlers() {
return handlers.values();
}
@SuppressWarnings("unchecked")
public default <T> void registerHandler(Class<T> clazz, NBTHandler<T> handler) {
handlers.put(clazz, (NBTHandler<Object>) handler);
}
}
@@ -0,0 +1,21 @@
package de.tr7zw.changeme.nbtapi.wrapper;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(METHOD)
public @interface NBTTarget {
public String value();
public Type type() default Type.AUTOMATIC;
public enum Type {
AUTOMATIC, GET, SET, HAS
}
}
@@ -0,0 +1,125 @@
package de.tr7zw.changeme.nbtapi.wrapper;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBTCompoundList;
class ProxiedList<E extends NBTProxy> implements ProxyList<E> {
private final ReadWriteNBTCompoundList nbt;
private final Class<E> proxy;
public ProxiedList(ReadWriteNBTCompoundList nbt, Class<E> proxyClass) {
this.nbt = nbt;
this.proxy = proxyClass;
}
@Override
public E get(int index) {
ReadWriteNBT tag = nbt.get(index);
return new ProxyBuilder<E>(tag, proxy).build();
}
@Override
public int size() {
return nbt.size();
}
@Override
public void remove(int index) {
nbt.remove(index);
}
@Override
public Iterator<E> iterator() {
return new Itr();
}
@Override
public E addCompound() {
ReadWriteNBT tag = nbt.addCompound();
return new ProxyBuilder<E>(tag, proxy).build();
}
@Override
public boolean isEmpty() {
return nbt.isEmpty();
}
private class Itr implements Iterator<E> {
/**
* Index of element to be returned by subsequent call to next.
*/
int cursor = 0;
/**
* Index of element returned by most recent call to next or previous. Reset to
* -1 if this element is deleted by a call to remove.
*/
int lastRet = -1;
public boolean hasNext() {
return cursor != size();
}
public E next() {
try {
int i = cursor;
E next = get(i);
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
throw new NoSuchElementException();
}
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
try {
ProxiedList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
}
}
@@ -0,0 +1,340 @@
package de.tr7zw.changeme.nbtapi.wrapper;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import de.tr7zw.changeme.nbtapi.NBTType;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.NBTHandler;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.changeme.nbtapi.wrapper.NBTTarget.Type;
public class ProxyBuilder<T extends NBTProxy> implements InvocationHandler {
private static final Map<Method, Function<Arguments, Object>> METHOD_CACHE = new ConcurrentHashMap<>();
private final Class<T> target;
private final ReadWriteNBT nbt;
private boolean readOnly;
public ProxyBuilder(ReadWriteNBT nbt, Class<T> target) {
if (!target.isInterface()) {
throw new NbtApiException("A proxy can only be built from an interface! Check the wiki for examples.");
}
this.target = target;
this.nbt = nbt;
}
public ProxyBuilder<T> readOnly() {
this.readOnly = true;
return this;
}
@SuppressWarnings("unchecked")
public T build() {
T inst = (T) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] { target }, this);
inst.init();
return inst;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
METHOD_CACHE.computeIfAbsent(method, m -> ProxyBuilder.createFunction((NBTProxy) proxy, m));
return METHOD_CACHE.get(method).apply(new Arguments(target, (NBTProxy) proxy, readOnly, nbt, args));
}
private static class Arguments {
Class<?> target;
NBTProxy proxy;
ReadWriteNBT nbt;
Object[] args;
boolean readOnly;
public Arguments(Class<?> target, NBTProxy proxy, boolean readOnly, ReadWriteNBT nbt, Object[] args) {
this.target = target;
this.proxy = proxy;
this.nbt = nbt;
this.args = args;
this.readOnly = readOnly;
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private static Function<Arguments, Object> createFunction(NBTProxy proxy, Method method) {
if ("toString".equals(method.getName()) && method.getParameterCount() == 0
&& method.getReturnType() == String.class)
{
return (arguments) -> arguments.nbt.toString();
}
if (method.isDefault()) {
return (arguments) -> DefaultMethodInvoker.invokeDefault(arguments.target, arguments.proxy, method,
arguments.args);
}
Type action = getAction(method);
if (action == Type.SET) {
String fieldName = getNBTName(proxy.getCasing(), method);
return (arguments) -> {
if (arguments.readOnly) {
throw new NbtApiException("Tried calling a set method on a read only object.");
}
return setNBT(arguments.nbt, arguments.proxy, fieldName, arguments.args[0]);
};
}
if (action == Type.GET) {
Class<?> retType = method.getReturnType();
String fieldName = getNBTName(proxy.getCasing(), method);
// Allow stacking of proxies
if (retType.isInterface() && NBTProxy.class.isAssignableFrom(retType)) {
return (arguments) -> {
if (arguments.nbt.hasTag(fieldName) && arguments.nbt.getType(fieldName) != NBTType.NBTTagCompound) {
throw new NbtApiException("Tried getting a '" + retType + "' proxy from the field '" + fieldName
+ "', but it's not a TagCompound!");
}
return new ProxyBuilder<NBTProxy>(arguments.nbt.getOrCreateCompound(fieldName),
(Class<NBTProxy>) retType).build();
};
}
if (retType == ProxyList.class) {
Class<?> parameterType = (Class<?>) ((ParameterizedType) method.getGenericReturnType())
.getActualTypeArguments()[0];
if (parameterType != null && parameterType.isInterface()
&& NBTProxy.class.isAssignableFrom(parameterType))
{
return (arguments) -> {
return new ProxiedList(arguments.nbt.getCompoundList(fieldName), parameterType);
};
}
}
NBTHandler<Object> handler = (NBTHandler<Object>) proxy.getHandler(retType);
if (handler != null) {
return (arguments) -> handler.get(arguments.nbt, fieldName);
}
return (arguments) -> arguments.nbt.getOrNull(fieldName, retType);
}
if (action == Type.HAS) {
String fieldName = getNBTName(proxy.getCasing(), method);
return (arguments) -> arguments.nbt.hasTag(fieldName);
}
throw new IllegalArgumentException(
"The method '" + method.getName() + "' in '" + method.getDeclaringClass().getName()
+ "' can not be handled by the NBT-API. Please check the Wiki for examples!");
}
private static Type getAction(Method method) {
NBTTarget target = method.getAnnotation(NBTTarget.class);
if (target != null) {
if (target.type() == Type.HAS && method.getParameterCount() == 0
&& method.getReturnType() == boolean.class)
{
return Type.HAS;
}
if (target.type() == Type.GET && method.getParameterCount() == 0) {
return Type.GET;
}
if (target.type() == Type.SET && method.getParameterCount() == 1) {
return Type.SET;
}
}
if (method.getName().startsWith("set") && method.getParameterCount() == 1) {
return Type.SET;
}
if (method.getName().startsWith("get") && method.getParameterCount() == 0) {
return Type.GET;
}
if (method.getName().startsWith("has") && method.getParameterCount() == 0
&& method.getReturnType() == boolean.class)
{
return Type.HAS;
}
return null;
}
private static String getNBTName(Casing casing, Method method) {
NBTTarget target = method.getAnnotation(NBTTarget.class);
if (target != null) {
return target.value();
}
return casing.convertString(method.getName().substring(3));
}
private static Object setNBT(ReadWriteNBT nbt, NBTProxy proxy, String key, Object value) {
// welcome to the "I wish we all could use java 17" method. Thanks, legacy mc
// versions
if (value == null) {
nbt.removeKey(key);
} else if (value instanceof Boolean) {
nbt.setBoolean(key, (Boolean) value);
} else if (value instanceof Byte) {
nbt.setByte(key, (Byte) value);
} else if (value instanceof Short) {
nbt.setShort(key, (Short) value);
} else if (value instanceof Integer) {
nbt.setInteger(key, (Integer) value);
} else if (value instanceof Long) {
nbt.setLong(key, (Long) value);
} else if (value instanceof Float) {
nbt.setFloat(key, (Float) value);
} else if (value instanceof Double) {
nbt.setDouble(key, (Double) value);
} else if (value instanceof byte[]) {
nbt.setByteArray(key, (byte[]) value);
} else if (value instanceof int[]) {
nbt.setIntArray(key, (int[]) value);
} else if (value instanceof long[]) {
nbt.setLongArray(key, (long[]) value);
} else if (value instanceof String) {
nbt.setString(key, (String) value);
} else if (value instanceof UUID) {
nbt.setUUID(key, (UUID) value);
} else if (value.getClass().isEnum()) {
nbt.setEnum(key, (Enum<?>) value);
} else {
@SuppressWarnings("unchecked")
NBTHandler<Object> handler = (NBTHandler<Object>) proxy.getHandler(value.getClass());
if (handler != null) {
handler.set(nbt, key, value);
} else {
for (NBTHandler<Object> nbth : proxy.getHandlers()) {
if (nbth.fuzzyMatch(value)) {
nbth.set(nbt, key, value);
return null;
}
}
throw new IllegalArgumentException("Tried setting an object of type '" + value.getClass().getName()
+ "'. This is not a supported NBT value. Please check the Wiki for examples!");
}
}
return null;
}
}
@@ -0,0 +1,42 @@
package de.tr7zw.changeme.nbtapi.wrapper;
public interface ProxyList<T extends NBTProxy> extends Iterable<T> {
/**
* Adds a new compound tag to the current compound tag
*
* @return A new instance of the class.
*/
T addCompound();
/**
* Returns the number of elements in this collection. If this collection
* contains more than Integer.MAX_VALUE elements, returns Integer.MAX_VALUE.
*
* @return the number of elements in this collection
*/
int size();
/**
* Returns true if this collection contains no elements.
*
* @return true if this collection contains no elements
*/
boolean isEmpty();
/**
* Get the object with the given id.
*
* @param id The id of the object to get.
* @return The object with the given id.
*/
T get(int id);
/**
* Removes the element at the specified position in this list
*
* @param i The index of the element to remove.
*/
void remove(int i);
}
-133
View File
@@ -1,133 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-parent</artifactId>
<version>2.11.1</version>
</parent>
<artifactId>item-nbt-api-plugin</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-api</artifactId>
<version>2.11.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>nbt-injector</artifactId>
<version>2.11.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>nbt-data-api</artifactId>
<version>2.11.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>de.tr7zw.changeme.nbtapi</pattern>
<shadedPattern>de.tr7zw.nbtapi</shadedPattern>
</relocation>
<relocation>
<pattern>javassist</pattern>
<shadedPattern>de.tr7zw.nbtinjector.javassist</shadedPattern>
</relocation>
<relocation>
<pattern>de.tr7zw.annotations</pattern>
<shadedPattern>de.tr7zw.nbtapi.utils.annotations</shadedPattern>
</relocation>
</relocations>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>LICENSE</resource>
</transformer>
</transformers>
</configuration>
<executions>
<execution>
<id>shade</id>
<goals>
<goal>shade</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
<!-- Start and Stop a SpigotMC server automatically before and after the integration-test phase. -->
<plugin>
<groupId>de.tr7zw.spigotmc.maven</groupId>
<artifactId>tr-spigotmc-maven-plugin</artifactId>
<version>0.0.3-SNAPSHOT</version>
<configuration>
<!-- 1.8.8-R0.1-SNAPSHOT-latest, 1.9.2-R0.1-SNAPSHOT-latest, 1.9.4-R0.1-SNAPSHOT-latest, 1.10.2-R0.1-SNAPSHOT-latest,1.11.2,1.12.2,1.13.2,1.14.4,1.15.1,1.16.1,1.16.2 -->
<versions>
https://repo.codemc.io/repository/nms/org/spigotmc/spigot/1.8.8-R0.1-SNAPSHOT/spigot-1.8.8-R0.1-20190527.160303-7.jar,
https://repo.codemc.io/repository/nms/org/spigotmc/spigot/1.9.4-R0.1-SNAPSHOT/spigot-1.9.4-R0.1-20190527.160755-2.jar,
https://repo.codemc.io/repository/nms/org/spigotmc/spigot/1.10.2-R0.1-SNAPSHOT/spigot-1.10.2-R0.1-20190527.154910-2.jar,
https://repo.codemc.io/repository/nms/org/spigotmc/spigot/1.11.2-R0.1-SNAPSHOT/spigot-1.11.2-R0.1-20191216.091129-1.jar,
https://repo.codemc.io/repository/nms/org/spigotmc/spigot/1.12.2-R0.1-SNAPSHOT/spigot-1.12.2-R0.1-20190527.155359-34.jar,
<!--https://repo.codemc.io/repository/nms/org/spigotmc/spigot/1.13.2-R0.1-SNAPSHOT/spigot-1.13.2-R0.1-20191113.201242-53.jar,-->
https://repo.codemc.io/repository/nms/org/spigotmc/spigot/1.14.4-R0.1-SNAPSHOT/spigot-1.14.4-R0.1-20191224.232152-15.jar,
https://repo.codemc.io/repository/nms/org/spigotmc/spigot/1.15.2-R0.1-SNAPSHOT/spigot-1.15.2-R0.1-20200625.172449-18.jar,
https://repo.codemc.io/repository/nms/org/spigotmc/spigot/1.16.5-R0.1-SNAPSHOT/spigot-1.16.5-R0.1-20210611.090701-17.jar
</versions>
<works>Success! This version of NBT-API</works>
<error>WARNING! This version of NBT-API</error>
<filename>item-nbt-api-plugin-${project.version}.jar</filename>
<foldername>item-nbt-plugin</foldername>
</configuration>
<executions>
<execution>
<id>start-server</id>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-server</id>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>nbtapi-javadoc-plugin</artifactId>
<version>3.4.2-SNAPSHOT</version>
<executions>
<execution>
<id>bundle-javadoc</id>
<goals>
<goal>aggregate-jar</goal>
</goals>
<phase>package</phase>
<configuration>
<detectOfflineLinks>false</detectOfflineLinks>
<includeDependencySources>true</includeDependencySources>
<sourcepath>src/main/java;${project.parent.basedir}/item-nbt-api/src/main/java;${project.build.directory}/javadoc-relocate;${defines.dir}</sourcepath>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -7,7 +7,6 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import de.tr7zw.changeme.nbtapi.NbtApiException;
@@ -26,27 +25,31 @@ import de.tr7zw.nbtapi.plugin.tests.compounds.GetterSetterTest;
import de.tr7zw.nbtapi.plugin.tests.compounds.InterfaceTest;
import de.tr7zw.nbtapi.plugin.tests.compounds.IteratorTest;
import de.tr7zw.nbtapi.plugin.tests.compounds.ListTest;
import de.tr7zw.nbtapi.plugin.tests.compounds.LongArrayTest;
import de.tr7zw.nbtapi.plugin.tests.compounds.MergeTest;
import de.tr7zw.nbtapi.plugin.tests.compounds.ModernSubCompoundsTest;
import de.tr7zw.nbtapi.plugin.tests.compounds.RemovingKeys;
import de.tr7zw.nbtapi.plugin.tests.compounds.ResolveTest;
import de.tr7zw.nbtapi.plugin.tests.compounds.StreamTest;
import de.tr7zw.nbtapi.plugin.tests.compounds.SubCompoundsTest;
import de.tr7zw.nbtapi.plugin.tests.compounds.TypeTest;
import de.tr7zw.nbtapi.plugin.tests.data.WorldDataTest;
import de.tr7zw.nbtapi.plugin.tests.entities.EntityCustomNbtPersistentTest;
import de.tr7zw.nbtapi.plugin.tests.entities.EntityTest;
import de.tr7zw.nbtapi.plugin.tests.injector.EntityCustomNbtInjectorTest;
import de.tr7zw.nbtapi.plugin.tests.injector.MergeTileSubCompoundTest;
import de.tr7zw.nbtapi.plugin.tests.injector.SpawnEntityCustomNbtInjectorTest;
import de.tr7zw.nbtapi.plugin.tests.injector.TilesCustomNBTInjectorTest;
import de.tr7zw.nbtapi.plugin.tests.items.ComponentsTest;
import de.tr7zw.nbtapi.plugin.tests.items.DirectApplyMetaTest;
import de.tr7zw.nbtapi.plugin.tests.items.DirectApplyTest;
import de.tr7zw.nbtapi.plugin.tests.items.EmptyItemTest;
import de.tr7zw.nbtapi.plugin.tests.items.ItemConversionTest;
import de.tr7zw.nbtapi.plugin.tests.tiles.TileTest;
import de.tr7zw.nbtapi.plugin.tests.tiles.TilesCustomNBTPersistentTest;
import de.tr7zw.nbtinjector.NBTInjector;
import de.tr7zw.nbtapi.plugin.tests.items.ItemJsonTest;
import de.tr7zw.nbtapi.plugin.tests.items.ItemMergingTest;
import de.tr7zw.nbtapi.plugin.tests.items.ItemStackConversionTest;
import de.tr7zw.nbtapi.plugin.tests.items.LegacyItemTest;
import de.tr7zw.nbtapi.plugin.tests.items.MetaTest;
import de.tr7zw.nbtapi.plugin.tests.items.NBTModifyItemTest;
import de.tr7zw.nbtapi.plugin.tests.items.SmuggleTest;
import de.tr7zw.nbtapi.plugin.tests.proxy.SimpleProxyTest;
import de.tr7zw.nbtapi.plugin.tests.tiles.TileTest;
import de.tr7zw.nbtapi.plugin.tests.tiles.TilesCustomNBTPersistentTest;
public class NBTAPI extends JavaPlugin {
@@ -56,40 +59,21 @@ public class NBTAPI extends JavaPlugin {
private static NBTAPI instance;
public static NBTAPI getInstance() {
return instance;
}
@Override
public void onLoad() {
getConfig().options().copyDefaults(true);
getConfig().addDefault("nbtInjector.enabled", false);
getConfig().addDefault("bStats.enabled", true);
getConfig().addDefault("updateCheck.enabled", true);
getConfig().addDefault("silentquickstart", false);
saveConfig();
saveDefaultConfig();
if (!getConfig().getBoolean("bStats.enabled")) {
getLogger().info("bStats disabled");
MinecraftVersion.disableBStats();
}
if (!getConfig().getBoolean("updateCheck.enabled")) {
getLogger().info("Update check disabled");
MinecraftVersion.disableUpdateCheck();
}
// Disabled by default since 2.1. Enable it yourself by calling
// NBTInjector.inject(); during onLoad/config
if (getConfig().getBoolean("nbtInjector.enabled")) {
getLogger().info("Injecting custom NBT");
try {
NBTInjector.inject();
getLogger().info("Injected!");
} catch (Throwable ex) { // NOSONAR
getLogger().log(Level.SEVERE, "Error while Injecting custom Tile/Entity classes!", ex);
compatible = false;
}
}
// NBTCompounds
@@ -98,9 +82,11 @@ public class NBTAPI extends JavaPlugin {
apiTests.add(new RemovingKeys());
apiTests.add(new EnumTest());
apiTests.add(new InterfaceTest());
apiTests.add(new ResolveTest());
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_8_R3)) // 1.7.10 list support is not complete at all
apiTests.add(new ListTest());
apiTests.add(new SubCompoundsTest());
apiTests.add(new ModernSubCompoundsTest());
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_8_R3)) // 1.7.10 not a thing
apiTests.add(new MergeTest());
apiTests.add(new ForEachTest());
@@ -108,19 +94,40 @@ public class NBTAPI extends JavaPlugin {
apiTests.add(new EqualsTest());
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_8_R3)) // 1.7.10 list support is not complete at all
apiTests.add(new IteratorTest());
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_16_R1))
apiTests.add(new LongArrayTest());
// Items
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_8_R3)) { // 1.7.10 not a thing
apiTests.add(new ItemConversionTest());
apiTests.add(new ItemStackConversionTest());
}
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_20_R4)) {
apiTests.add(new LegacyItemTest());
apiTests.add(new ItemJsonTest());
}
apiTests.add(new ComponentsTest());
apiTests.add(new EmptyItemTest());
apiTests.add(new SmuggleTest());
apiTests.add(new MetaTest());
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_8_R3)) { // 1.7.10 not a thing
apiTests.add(new ItemMergingTest());
apiTests.add(new DirectApplyTest());
apiTests.add(new DirectApplyMetaTest());
apiTests.add(new NBTModifyItemTest());
}
// Proxies
apiTests.add(new SimpleProxyTest());
// Entity
apiTests.add(new EntityTest());
apiTests.add(new EntityCustomNbtPersistentTest());
@@ -138,15 +145,6 @@ public class NBTAPI extends JavaPlugin {
// Files
apiTests.add(new NBTFileTest());
// Data
apiTests.add(new WorldDataTest());
// Injector
apiTests.add(new TilesCustomNBTInjectorTest());
apiTests.add(new MergeTileSubCompoundTest());
apiTests.add(new EntityCustomNbtInjectorTest());
apiTests.add(new SpawnEntityCustomNbtInjectorTest());
if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_8_R3))
apiTests.add(new GameprofileTest());
@@ -154,82 +152,111 @@ public class NBTAPI extends JavaPlugin {
@Override
public void onEnable() {
instance = this; // NOSONAR
// new MetricsLite(this); The metrics moved into the API
if (getConfig().getBoolean("silentquickstart")) {
// we are silent, won't check anything or pre-init
VersionChecker.hideOk = true;
return;
}
getLogger().info("Adding listeners...");
Bukkit.getPluginManager().registerEvents(new ReloadListener(), this);
getLogger().info("Gson:");
MinecraftVersion.hasGsonSupport();
MinecraftVersion.hasGsonSupport(); // init gson(if it hasn't already)
getLogger().info("Checking bindings...");
MinecraftVersion.getVersion();
boolean classUnlinked = false;
for (ClassWrapper c : ClassWrapper.values()) {
if (c.isEnabled() && c.getClazz() == null) {
if (!classUnlinked)
getLogger().info("Classes:");
getLogger().warning(c.name() + " did not find it's class!");
compatible = false;
classUnlinked = true;
}
}
if (!classUnlinked)
getLogger().info("All Classes were able to link!");
boolean methodUnlinked = false;
for (ReflectionMethod method : ReflectionMethod.values()) {
if (method.isCompatible() && !method.isLoaded()) {
if (!methodUnlinked)
getLogger().info("Methods:");
getLogger().warning(method.name() + " did not find the method!");
compatible = false;
methodUnlinked = true;
}
}
if (!methodUnlinked)
getLogger().info("All Methods were able to link!");
getLogger().info("Running NBT reflection test...");
Map<de.tr7zw.nbtapi.plugin.tests.Test, Exception> results = new HashMap<>();
for (de.tr7zw.nbtapi.plugin.tests.Test test : apiTests) {
try {
test.test();
results.put(test, null);
} catch (Exception ex) {
results.put(test, ex);
getLogger().log(Level.WARNING, "Error during '" + test.getClass().getSimpleName() + "' test!", ex);
} catch (NoSuchFieldError th) { // NOSONAR
getLogger().log(Level.SEVERE, "Servere error during '" + test.getClass().getSimpleName() + "' test!");
getLogger().warning(
"WARNING! This version of Item-NBT-API seems to be broken with your Spigot version! Canceled the other tests!");
throw th;
}
}
for (Entry<de.tr7zw.nbtapi.plugin.tests.Test, Exception> entry : results.entrySet()) {
if (entry.getValue() != null) {
compatible = false;
getLogger().info(entry.getKey().getClass().getSimpleName() + ": " + entry.getValue().getMessage());
}
}
String checkMessage = "Plugins that don't check properly may throw Exeptions, crash or have unexpected behaviors!";
if (compatible) {
NbtApiException.confirmedBroken = false;
getLogger().info("Success! This version of NBT-API is compatible with your server.");
} else {
NbtApiException.confirmedBroken = true;
getLogger().warning(
"WARNING! This version of NBT-API seems to be broken with your Spigot version! " + checkMessage);
if (MinecraftVersion.getVersion() == MinecraftVersion.MC1_7_R4) {
getLogger().warning(
"1.7.10 is only partally supported! Some thing will not work/are not yet avaliable in 1.7.10!");
}
}
}
@@ -238,7 +265,9 @@ public class NBTAPI extends JavaPlugin {
* @return True if all selfchecks succeeded
*/
public boolean isCompatible() {
return compatible;
}
}
@@ -1,45 +0,0 @@
package de.tr7zw.nbtapi.plugin;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import de.tr7zw.nbtinjector.NBTInjector;
/**
* This listener class tries to prevent people from reloading while the
* NBTInjector is enabled.
*
* @author tr7zw
*
*/
public class ReloadListener implements Listener {
/**
* Console handler
*
* @param event
*/
@EventHandler
public void onCommand(org.bukkit.event.server.ServerCommandEvent event) {
if (event.getCommand().toLowerCase().startsWith("reload") && NBTInjector.isInjected()) {
event.setCancelled(true);
event.getSender().sendMessage(
"[NBTAPI] The NBTInjector is currently enabled. Reloading will turn the server into an unstable state and data-loss may accure. Please do a clean restart. Canceled reload!");
}
}
/**
* Player handler
*
* @param event
*/
@EventHandler
public void onCommand(org.bukkit.event.player.PlayerCommandPreprocessEvent event) {
if (event.getMessage().toLowerCase().startsWith("/reload") && NBTInjector.isInjected()) {
event.setCancelled(true);
event.getPlayer().sendMessage(
"[NBTAPI] The NBTInjector is currently enabled. Reloading will turn the server into an unstable state and data-loss may accure. Please do a clean restart. Canceled reload!");
}
}
}
@@ -4,22 +4,26 @@ import java.util.UUID;
import com.mojang.authlib.GameProfile;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTGameProfile;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
public class GameprofileTest implements Test {
@Override
public void test() throws Exception {
UUID uuid = UUID.randomUUID();
GameProfile profile = new GameProfile(uuid, "random");
NBTCompound nbt = NBTGameProfile.toNBT(profile);
ReadWriteNBT nbt = NBT.gameProfileToNBT(profile);
profile = null;
profile = NBTGameProfile.fromNBT(nbt);
profile = NBT.gameProfileFromNBT(nbt);
if (profile == null || !profile.getId().equals(uuid)) {
throw new NbtApiException("Error when converting a GameProfile from/to NBT!");
}
}
}
@@ -3,58 +3,76 @@ package de.tr7zw.nbtapi.plugin.tests;
import java.io.File;
import java.nio.file.Files;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTContainer;
import de.tr7zw.changeme.nbtapi.NBTFile;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.NBTFileHandle;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.nbtapi.plugin.NBTAPI;
public class NBTFileTest implements Test {
@Override
public void test() throws Exception {
NBTAPI.getInstance().getDataFolder().mkdirs();
File testFile = new File(NBTAPI.getInstance().getDataFolder(), "test.nbt");
Files.deleteIfExists(testFile.toPath());
NBTFile file = new NBTFile(testFile);
file.addCompound("testcomp").setString("test1", "ok");
NBTCompound comp = file.getCompound("testcomp");
NBTFileHandle file = NBT.getFileHandle(testFile);
file.getOrCreateCompound("testcomp").setString("test1", "ok");
ReadWriteNBT comp = file.getOrCreateCompound("testcomp");
if (comp == null) {
throw new NbtApiException("Error getting compound!");
}
comp.setString("test2", "ok");
file.setLong("time", System.currentTimeMillis());
file.setString("test", "test");
NBTCompound chunks = file.addCompound("chunks");
NBTCompound chunk = chunks.addCompound("somechunk");
NBTCompound block = chunk.addCompound("someblock");
ReadWriteNBT chunks = file.getOrCreateCompound("chunks");
ReadWriteNBT chunk = chunks.getOrCreateCompound("somechunk");
ReadWriteNBT block = chunk.getOrCreateCompound("someblock");
block.setString("type", "wool");
file.save();
if (!"wool".equals(block.getString("type"))) {
throw new NbtApiException("SubCompounds did not work!");
}
NBTFile fileLoaded = new NBTFile(testFile);
NBTFileHandle fileLoaded = NBT.getFileHandle(testFile);
if (!fileLoaded.getString("test").equals("test")) {
throw new NbtApiException("Wasn't able to load NBT File with the correct content!");
}
Files.deleteIfExists(fileLoaded.getFile().toPath());
// String
String str = fileLoaded.toString();
NBTContainer rebuild = new NBTContainer(str);
ReadWriteNBT rebuild = NBT.parseNBT(str);
if (!str.equals(rebuild.toString())) {
throw new NbtApiException("Wasn't able to parse NBT from a String!");
}
NBTCompound dummy = new NBTContainer();
ReadWriteNBT dummy = NBT.createNBTObject();
dummy.setString("test1", "key1");
NBTFile.saveTo(testFile, dummy);
dummy = new NBTContainer();
NBT.writeFile(testFile, dummy);
dummy = NBT.createNBTObject();
dummy.setString("test2", "key2");
NBTFile.saveTo(testFile, dummy);
dummy = NBTFile.readFrom(testFile);
NBT.writeFile(testFile, dummy);
dummy = NBT.readFile(testFile);
if (dummy.hasTag("test1") || !dummy.getString("test2").equals("key2")) {
throw new NbtApiException("Wasn't able to save NBT File with the correct content!");
}
Files.deleteIfExists(fileLoaded.getFile().toPath());
}
}
@@ -14,28 +14,43 @@ public class BlockNBTTest implements Test {
@Override
public void test() throws Exception {
if (MinecraftVersion.getVersion().getVersionId() < MinecraftVersion.MC1_16_R3.getVersionId())
return;
if (!Bukkit.getWorlds().isEmpty()) {
World world = Bukkit.getWorlds().get(0);
try {
if (world.getLoadedChunks().length > 1) {
Chunk chunk = world.getLoadedChunks()[0];
Block block = chunk.getBlock(0, 254, 0);
NBTBlock comp = new NBTBlock(block);
comp.getData().removeKey("Too");
if (comp.getData().hasTag("Too")) {
throw new NbtApiException("Unable to remove key from Block!");
}
comp.getData().setString("Too", "Bar");
if (!new NBTBlock(block).getData().getString("Too").equals("Bar")) {
throw new NbtApiException("Custom Data did not save to a Block!");
}
}
} catch (Exception ex) {
throw new NbtApiException("Wasn't able to use NBTBlocks!", ex);
}
}
}
}
@@ -14,28 +14,43 @@ public class ChunkNBTPersistentTest implements Test {
@Override
public void test() throws Exception {
if (MinecraftVersion.getVersion().getVersionId() < MinecraftVersion.MC1_16_R3.getVersionId())
return;
if (!Bukkit.getWorlds().isEmpty()) {
World world = Bukkit.getWorlds().get(0);
try {
if (world.getLoadedChunks().length > 1) {
Chunk chunk = world.getLoadedChunks()[0];
NBTChunk comp = new NBTChunk(chunk);
NBTCompound persistentData = comp.getPersistentDataContainer();
persistentData.removeKey("Foo");
if (persistentData.hasTag("Foo")) {
throw new NbtApiException("Unable to remove key from Chunk!");
}
persistentData.setString("Foo", "Bar");
if (!new NBTChunk(chunk).getPersistentDataContainer().getString("Foo").equals("Bar")) {
throw new NbtApiException("Custom Data did not save to the Chunk!");
}
}
} catch (Exception ex) {
throw new NbtApiException("Wasn't able to use NBTChunks!", ex);
}
}
}
}
@@ -1,16 +1,17 @@
package de.tr7zw.nbtapi.plugin.tests.compounds;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTContainer;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NBTType;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.nbtapi.plugin.tests.Test;
public class EnumTest implements Test {
@Override
public void test() throws Exception {
NBTCompound comp = new NBTContainer();
ReadWriteNBT comp = NBT.createNBTObject();
comp.setEnum("test", NBTType.NBTTagEnd);
NBTType type = comp.getEnum("test", NBTType.class);
NBTType typeNonNull = comp.getOrNull("test", NBTType.class);
@@ -19,6 +20,7 @@ public class EnumTest implements Test {
if (type != NBTType.NBTTagEnd || typeNonNull != NBTType.NBTTagEnd || typeDefaultFound != NBTType.NBTTagEnd
|| typeDefault != NBTType.NBTTagByte)
throw new NbtApiException("One enum did not match what it should have been!");
}
}
@@ -5,49 +5,59 @@ import java.util.Arrays;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTContainer;
import de.tr7zw.changeme.nbtapi.NBTItem;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.nbtapi.plugin.tests.Test;
public class EqualsTest implements Test {
@Override
public void test() throws Exception {
NBTContainer cont = new NBTContainer();
ReadWriteNBT cont = NBT.createNBTObject();
cont.setString("hello", "world");
cont.setInteger("theAnswer", 42);
cont.addCompound("sub").setString("me", "too");
cont.getOrCreateCompound("sub").setString("me", "too");
cont.getStringList("somelist").addAll(Arrays.asList("a", "b", "c"));
ItemStack item = new ItemStack(Material.STONE);
NBTItem nbti = new NBTItem(item);
NBTCompound customData = nbti.addCompound("customData");
// reverse order
customData.addCompound("sub").setString("me", "too");
customData.setInteger("theAnswer", 42);
customData.setString("hello", "world");
customData.getStringList("somelist").addAll(Arrays.asList("a", "b", "c"));
if (!customData.equals(cont)) {
throw new NbtApiException("Compounds did not match! " + customData + " " + cont);
}
NBT.modify(item, nbti -> {
ReadWriteNBT customData = nbti.getOrCreateCompound("customData");
// reverse order
customData.getOrCreateCompound("sub").setString("me", "too");
customData.setInteger("theAnswer", 42);
customData.setString("hello", "world");
customData.getStringList("somelist").addAll(Arrays.asList("a", "b", "c"));
if (!customData.equals(cont)) {
throw new NbtApiException("Compounds did not match! " + customData + " " + cont);
}
});
// empty test
if (!new NBTContainer().equals(new NBTContainer())) {
if (!NBT.createNBTObject().equals(NBT.createNBTObject())) {
throw new NbtApiException("Two empty tags did not match!");
}
// not equal test
NBTContainer part1 = new NBTContainer();
ReadWriteNBT part1 = NBT.createNBTObject();
part1.setString("a", "a");
part1.setString("b", "b");
NBTContainer part2 = new NBTContainer();
ReadWriteNBT part2 = NBT.createNBTObject();
part2.setString("a", "a");
part2.setString("b", "a");
if (part1.equals(part2)) {
throw new NbtApiException("Missmatched nbt did match!");
}
}
}
@@ -17,34 +17,47 @@ public class ForEachTest implements Test {
@SuppressWarnings("unused")
@Override
public void test() throws Exception {
NBTContainer comp = new NBTContainer();
NBTCompoundList compList = comp.getCompoundList("testkey");
if (compList != null) {
compList.addCompound().setInteger("id", 1);
compList.addCompound().setInteger("id", 2);
compList.addCompound().setInteger("id", 3);
int count = 0;
for (ReadWriteNBT listComp : compList) {
count++;
}
if (count != compList.size())
throw new NbtApiException("For loop did not get all Entries!");
count = 0;
ListIterator<ReadWriteNBT> lit = compList.listIterator();
while (lit.hasNext()) {
lit.next();
count++;
}
if (count != compList.size())
throw new NbtApiException("ListIterator did not get all Entries!");
count = 0;
while (lit.hasPrevious()) {
lit.previous();
count++;
}
if (count != compList.size())
throw new NbtApiException("ListIterator previous did not get all Entries!");
}
}
}
@@ -1,7 +1,8 @@
package de.tr7zw.nbtapi.plugin.tests.compounds;
import de.tr7zw.changeme.nbtapi.NBTContainer;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.nbtapi.plugin.tests.Test;
public class GetterSetterTest implements Test {
@@ -30,7 +31,8 @@ public class GetterSetterTest implements Test {
@Override
public void test() throws Exception {
NBTContainer comp = new NBTContainer();
ReadWriteNBT comp = NBT.createNBTObject();
comp.setString(STRING_TEST_KEY, STRING_TEST_VALUE);
comp.setInteger(INT_TEST_KEY, INT_TEST_VALUE);
@@ -44,18 +46,27 @@ public class GetterSetterTest implements Test {
comp.setByteArray(BYTEARRAY_TEST_KEY, BYTEARRAY_TEST_VALUE);
if (!comp.hasTag(STRING_TEST_KEY)) {
throw new NbtApiException("Wasn't able to check a key! The Item-NBT-API may not work!");
}
int[] intArray = comp.getIntArray(INTARRAY_TEST_KEY);
byte[] byteArray = comp.getByteArray(BYTEARRAY_TEST_KEY);
if (!(STRING_TEST_VALUE).equals(comp.getString(STRING_TEST_KEY))
|| comp.getInteger(INT_TEST_KEY) != INT_TEST_VALUE
|| comp.getDouble(DOUBLE_TEST_KEY) != DOUBLE_TEST_VALUE
|| comp.getByte(BYTE_TEST_KEY) != BYTE_TEST_VALUE || comp.getShort(SHORT_TEST_KEY) != SHORT_TEST_VALUE
|| comp.getFloat(FLOAT_TEST_KEY) != FLOAT_TEST_VALUE || comp.getLong(LONG_TEST_KEY) != LONG_TEST_VALUE
|| comp.getIntArray(INTARRAY_TEST_KEY).length != (INTARRAY_TEST_VALUE).length
|| comp.getByteArray(BYTEARRAY_TEST_KEY).length != (BYTEARRAY_TEST_VALUE).length
|| !comp.getBoolean(BOOLEAN_TEST_KEY).equals(BOOLEAN_TEST_VALUE)) {
|| (intArray != null && intArray.length != (INTARRAY_TEST_VALUE).length)
|| (byteArray != null && byteArray.length != (BYTEARRAY_TEST_VALUE).length)
|| !comp.getBoolean(BOOLEAN_TEST_KEY).equals(BOOLEAN_TEST_VALUE))
{
throw new NbtApiException("One key does not equal the original value! The Item-NBT-API may not work!");
}
}
}
@@ -13,34 +13,52 @@ public class GsonTest implements Test {
@SuppressWarnings("deprecation")
@Override
public void test() throws Exception {
if (!MinecraftVersion.hasGsonSupport()) {
return;
}
try {
ItemStack item = new ItemStack(Material.STONE, 1);
NBTItem nbtItem = new NBTItem(item);
nbtItem.setObject(JSON_TEST_KEY, new SimpleJsonTestObject());
if (!nbtItem.hasTag(JSON_TEST_KEY)) {
throw new NbtApiException(
"Wasn't able to find JSON key! The Item-NBT-API may not work with Json serialization/deserialization!");
} else {
SimpleJsonTestObject simpleObject = nbtItem.getObject(JSON_TEST_KEY, SimpleJsonTestObject.class);
if (simpleObject == null) {
throw new NbtApiException(
"Wasn't able to check JSON key! The Item-NBT-API may not work with Json serialization/deserialization!");
} else if (!(STRING_TEST_VALUE).equals(simpleObject.getTestString())
|| simpleObject.getTestInteger() != INT_TEST_VALUE
|| simpleObject.getTestDouble() != DOUBLE_TEST_VALUE
|| !simpleObject.isTestBoolean() == BOOLEAN_TEST_VALUE) {
|| !simpleObject.isTestBoolean() == BOOLEAN_TEST_VALUE)
{
throw new NbtApiException(
"One key does not equal the original value in JSON! The Item-NBT-API may not work with Json serialization/deserialization!");
}
}
} catch (Exception ex) {
throw new NbtApiException("Exception during Gson check!", ex);
}
}
// region STATIC FINAL VARIABLES
@@ -54,42 +72,60 @@ public class GsonTest implements Test {
// end region STATIC FINAL VARIABLES
public static class SimpleJsonTestObject {
private String testString = STRING_TEST_VALUE;
private int testInteger = INT_TEST_VALUE;
private double testDouble = DOUBLE_TEST_VALUE;
private boolean testBoolean = BOOLEAN_TEST_VALUE;
public String getTestString() {
return testString;
}
public void setTestString(String testString) {
this.testString = testString;
}
public int getTestInteger() {
return testInteger;
}
public void setTestInteger(int testInteger) {
this.testInteger = testInteger;
}
public double getTestDouble() {
return testDouble;
}
public void setTestDouble(double testDouble) {
this.testDouble = testDouble;
}
public boolean isTestBoolean() {
return testBoolean;
}
public void setTestBoolean(boolean testBoolean) {
this.testBoolean = testBoolean;
}
}
}
@@ -9,13 +9,17 @@ public class InterfaceTest implements Test {
@Override
public void test() throws Exception {
ReadWriteNBT src = NBT.createNBTObject();
src.setString("foo", "bar");
ReadWriteNBT target = NBT.createNBTObject();
target.mergeCompound(src);
if (!"bar".equals(target.getString("foo"))) {
throw new NbtApiException("Wasn't able to check the key! The Item-NBT-API may not work!");
}
}
}
@@ -12,6 +12,7 @@ public class IteratorTest implements Test {
@Override
public void test() throws Exception {
NBTList<Integer> testList;
testList = initIntegerList();
@@ -19,9 +20,11 @@ public class IteratorTest implements Test {
testList = initIntegerList();
testIterator(testList.listIterator());
}
private NBTList<Integer> initIntegerList() {
NBTContainer comp = new NBTContainer();
NBTList<Integer> list = comp.getIntegerList("test");
list.add(1);
@@ -29,9 +32,11 @@ public class IteratorTest implements Test {
list.add(3);
list.add(4);
return list;
}
private static void testIterator(Iterator<Integer> iterator) {
assertTrue(iterator.hasNext());
assertTrue(iterator.next() == 1);
assertTrue(iterator.hasNext());
@@ -42,24 +47,38 @@ public class IteratorTest implements Test {
assertTrue(iterator.hasNext());
assertTrue(iterator.next() == 4);
testNoMoreElements(iterator);
}
private static void testNoMoreElements(Iterator<Integer> iterator) {
assertTrue(!iterator.hasNext());
try {
iterator.next();
} catch (NoSuchElementException expected) {
return;
} catch (Exception e) {
throw new NbtApiException("iterator threw wrong exception: " + e.toString());
}
throw new NbtApiException("iterator did not throw exception");
}
private static void assertTrue(boolean condition) {
if (!condition) {
throw new NbtApiException("iterator test failed");
}
}
}
@@ -3,23 +3,23 @@ package de.tr7zw.nbtapi.plugin.tests.compounds;
import java.util.Arrays;
import java.util.UUID;
import de.tr7zw.changeme.nbtapi.NBTCompound;
import de.tr7zw.changeme.nbtapi.NBTCompoundList;
import de.tr7zw.changeme.nbtapi.NBTContainer;
import de.tr7zw.changeme.nbtapi.NBTList;
import de.tr7zw.changeme.nbtapi.NBTListCompound;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NBTType;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBTCompoundList;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBTList;
import de.tr7zw.nbtapi.plugin.tests.Test;
public class ListTest implements Test {
@Override
public void test() throws Exception {
NBTContainer comp = new NBTContainer();
ReadWriteNBT comp = NBT.createNBTObject();
// Strings
NBTList<String> list = comp.getStringList("testlist");
ReadWriteNBTList<String> list = comp.getStringList("testlist");
list.add("test1");
list.add("test2");
list.add("test3");
@@ -27,18 +27,20 @@ public class ListTest implements Test {
list.set(2, "test42");
list.remove(1);
if (!list.get(1).equals("test42") || list.size() != 3) {
throw new NbtApiException("The String-list did not match what it should have looked like.");
}
// Compound
NBTCompoundList taglist = comp.getCompoundList("complist");
NBTListCompound lcomp = taglist.addCompound();
ReadWriteNBTCompoundList taglist = comp.getCompoundList("complist");
ReadWriteNBT lcomp = taglist.addCompound();
lcomp.setDouble("double1", 0.3333);
lcomp.setInteger("int1", 42);
lcomp.setString("test1", "test1");
lcomp.setString("test2", "test2");
lcomp.removeKey("test1");
NBTCompound subsubcomp = lcomp.addCompound("listsubkey");
ReadWriteNBT subsubcomp = lcomp.getOrCreateCompound("listsubkey");
subsubcomp.setString("deep", "String");
subsubcomp.getCompoundList("deeplist").addCompound().setString("test", "test");
subsubcomp.getCompoundList("clonelist").addCompound(comp);
@@ -49,115 +51,168 @@ public class ListTest implements Test {
taglist = comp.getCompoundList("complist");
if (taglist.size() == 1) {
lcomp = taglist.get(0);
ReadWriteNBT sublist = lcomp.getCompound("listsubkey");
if (lcomp.getKeys().size() != 4) {
throw new NbtApiException("Wrong key amount in Taglist (" + lcomp.getKeys().size() + ")!");
} else if (sublist == null) {
throw new NbtApiException("The sublist is null! The Item-NBT-API may not work!");
} else if (!(lcomp.getDouble("double1") == 0.3333 && lcomp.getInteger("int1") == 42
&& lcomp.getString("test2").equals("test2") && !lcomp.hasTag("test1"))) {
&& lcomp.getString("test2").equals("test2") && !lcomp.hasTag("test1")))
{
throw new NbtApiException("One key in the Taglist changed! The Item-NBT-API may not work!");
} else if (lcomp.getCompound("listsubkey") == null
|| !"String".equals(lcomp.getCompound("listsubkey").getString("deep"))) {
} else if (!"String".equals(sublist.getString("deep"))) {
throw new NbtApiException(
"The Compound nested in the listcompound was not correct! The Item-NBT-API may not work!");
} else if (lcomp.getCompound("listsubkey").getType("deep") != NBTType.NBTTagString) {
} else if (sublist.getType("deep") != NBTType.NBTTagString) {
throw new NbtApiException("The nested key's type wasn't correct! The Item-NBT-API may not work!");
} else if (lcomp.getCompound("listsubkey").getType("deeplist") != NBTType.NBTTagList) {
throw new NbtApiException("The nested list's type wasn't correct '"
+ lcomp.getCompound("listsubkey").getType("deeplist") + "'! The Item-NBT-API may not work!");
} else if (sublist.getType("deeplist") != NBTType.NBTTagList) {
throw new NbtApiException("The nested list's type wasn't correct '" + sublist.getType("deeplist")
+ "'! The Item-NBT-API may not work!");
}
} else {
throw new NbtApiException("Taglist is empty! The Item-NBT-API may not work!");
}
if (comp.getListType("complist") != NBTType.NBTTagCompound) {
throw new NbtApiException("complist had the wrong type! The Item-NBT-API may not work!");
}
// Integer
NBTList<Integer> intlist = comp.getIntegerList("inttest");
ReadWriteNBTList<Integer> intlist = comp.getIntegerList("inttest");
intlist.add(42);
intlist.add(69);
if (intlist.size() == 2 && intlist.get(0) == 42 && intlist.get(1) == 69) {
// ok
} else {
throw new NbtApiException("IntList is not correct! " + Arrays.toString(intlist.toArray(new Integer[0])));
}
if (comp.getListType("inttest") != NBTType.NBTTagInt) {
throw new NbtApiException("inttest had the wrong type! The Item-NBT-API may not work!");
}
// Double
NBTList<Double> doublelist = comp.getDoubleList("doubletest");
ReadWriteNBTList<Double> doublelist = comp.getDoubleList("doubletest");
doublelist.add(42.23d);
doublelist.add(69.69d);
if (doublelist.size() == 2 && doublelist.get(0) == 42.23d && doublelist.get(1) == 69.69d) {
// ok
} else {
throw new NbtApiException(
"DoubleList is not correct! " + Arrays.toString(doublelist.toArray(new Double[0])));
}
if (comp.getListType("doubletest") != NBTType.NBTTagDouble) {
throw new NbtApiException("doubletest had the wrong type! The Item-NBT-API may not work!");
}
// Float
NBTList<Float> floatlist = comp.getFloatList("floattest");
ReadWriteNBTList<Float> floatlist = comp.getFloatList("floattest");
floatlist.add(42.23f);
floatlist.add(69.69f);
if (floatlist.size() == 2 && floatlist.get(0) == 42.23f && floatlist.get(1) == 69.69f) {
// ok
} else {
throw new NbtApiException("FloatList is not correct! " + Arrays.toString(floatlist.toArray(new Float[0])));
}
if (comp.getListType("floattest") != NBTType.NBTTagFloat) {
throw new NbtApiException("floattest had the wrong type! The Item-NBT-API may not work!");
}
// Long
NBTList<Long> longlist = comp.getLongList("longtest");
ReadWriteNBTList<Long> longlist = comp.getLongList("longtest");
longlist.add(1241234124124l);
longlist.add(1231454321312l);
if (longlist.size() == 2 && longlist.get(0) == 1241234124124l && longlist.get(1) == 1231454321312l) {
// ok
} else {
throw new NbtApiException("LongList is not correct! " + Arrays.toString(longlist.toArray(new Long[0])));
}
if (comp.getListType("longtest") != NBTType.NBTTagLong) {
throw new NbtApiException("longtest had the wrong type! The Item-NBT-API may not work!");
}
// int[]
NBTList<int[]> intArrayList = comp.getIntArrayList("intatest");
ReadWriteNBTList<int[]> intArrayList = comp.getIntArrayList("intatest");
intArrayList.add(new int[] { 1, 2, 3 });
intArrayList.add(new int[] { 4, 2, 0 });
if (intArrayList.size() == 2 && Arrays.equals(new int[] { 1, 2, 3 }, intArrayList.get(0))
&& Arrays.equals(new int[] { 4, 2, 0 }, intArrayList.get(1))) {
&& Arrays.equals(new int[]
{ 4, 2, 0 }, intArrayList.get(1))) {
// ok
} else {
throw new NbtApiException("IntArrayList is not correct! " + intArrayList);
}
if (comp.getListType("intatest") != NBTType.NBTTagIntArray) {
throw new NbtApiException("intatest had the wrong type! The Item-NBT-API may not work!");
}
// UUID
NBTList<UUID> uuidList = comp.getUUIDList("uuidtest");
ReadWriteNBTList<UUID> uuidList = comp.getUUIDList("uuidtest");
uuidList.add(UUID.fromString("fce0323d-7f50-4317-9720-5f6b14cf78ea"));
uuidList.add(UUID.fromString("853c80ef-3c37-49fd-aa49-938b674adae6"));
if (uuidList.size() == 2 && UUID.fromString("fce0323d-7f50-4317-9720-5f6b14cf78ea").equals(uuidList.get(0))
&& UUID.fromString("853c80ef-3c37-49fd-aa49-938b674adae6").equals(uuidList.get(1))) {
&& UUID.fromString("853c80ef-3c37-49fd-aa49-938b674adae6").equals(uuidList.get(1)))
{
// ok
} else {
throw new NbtApiException("UUIDList is not correct! " + uuidList);
}
if (comp.getListType("uuidtest") != NBTType.NBTTagIntArray) {
throw new NbtApiException("uuidtest had the wrong type! The Item-NBT-API may not work!");
}
}
@@ -0,0 +1,32 @@
package de.tr7zw.nbtapi.plugin.tests.compounds;
import java.util.Arrays;
import de.tr7zw.changeme.nbtapi.NBTContainer;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.nbtapi.plugin.tests.Test;
public class LongArrayTest implements Test {
@Override
public void test() throws Exception {
NBTContainer comp = new NBTContainer();
comp.setLongArray("test", new long[] { 1, 2, 3, 4, Long.MAX_VALUE });
if (!comp.hasTag("test")) {
throw new NbtApiException("Wasn't able to check a key! The Item-NBT-API may not work!");
}
if (!Arrays.equals(comp.getLongArray("test"), new long[] { 1, 2, 3, 4, Long.MAX_VALUE })) {
throw new NbtApiException("The long key does not equal the original value! The Item-NBT-API may not work!");
}
}
}
@@ -8,6 +8,7 @@ public class MergeTest implements Test {
@Override
public void test() throws Exception {
NBTContainer test1 = new NBTContainer();
test1.setString("test1", "test");
NBTContainer test2 = new NBTContainer();
@@ -15,8 +16,11 @@ public class MergeTest implements Test {
test2.addCompound("test").setLong("time", System.currentTimeMillis());
test1.mergeCompound(test2);
if (!test1.getString("test1").equals(test1.getString("test2"))) {
throw new NbtApiException("Wasn't able to merge Compounds!");
}
}
}
@@ -0,0 +1,71 @@
package de.tr7zw.nbtapi.plugin.tests.compounds;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.nbtapi.plugin.tests.Test;
public class ModernSubCompoundsTest implements Test {
private static final String COMP_TEST_KEY = "componentTest";
private static final String STRING_TEST_KEY = "stringTest";
private static final String INT_TEST_KEY = "intTest";
private static final String DOUBLE_TEST_KEY = "doubleTest";
private static final String BOOLEAN_TEST_KEY = "booleanTest";
private static final String STRING_TEST_VALUE = "TestString";
private static final int INT_TEST_VALUE = 42;
private static final double DOUBLE_TEST_VALUE = 1.5d;
private static final boolean BOOLEAN_TEST_VALUE = true;
@Override
public void test() throws Exception {
ReadWriteNBT cont = NBT.createNBTObject();
ReadWriteNBT comp = cont.getOrCreateCompound(COMP_TEST_KEY);
comp.setString(STRING_TEST_KEY, STRING_TEST_VALUE + "2");
comp.setInteger(INT_TEST_KEY, INT_TEST_VALUE * 2);
comp.setDouble(DOUBLE_TEST_KEY, DOUBLE_TEST_VALUE * 2);
if (cont.getCompound("invalide") != null) {
throw new NbtApiException("An invalide compound did not return null!");
}
comp = null;
comp = cont.getCompound(COMP_TEST_KEY);
if (comp == null) {
throw new NbtApiException("Wasn't able to get the NBTCompound!");
}
if (!comp.hasTag(STRING_TEST_KEY)) {
throw new NbtApiException("Wasn't able to check a compound key!");
}
if (!(STRING_TEST_VALUE + "2").equals(comp.getString(STRING_TEST_KEY))
|| comp.getInteger(INT_TEST_KEY) != INT_TEST_VALUE * 2
|| comp.getDouble(DOUBLE_TEST_KEY) != DOUBLE_TEST_VALUE * 2
|| comp.getBoolean(BOOLEAN_TEST_KEY) == BOOLEAN_TEST_VALUE)
{
throw new NbtApiException("One key does not equal the original compound value!");
}
// Using getOrCreateCompound twice
comp.getOrCreateCompound("someName").setString("test", "abc");
if (!comp.getOrCreateCompound("someName").getString("test").equals("abc")) {
throw new NbtApiException("getOrCreateCompound did not return the same compound!");
}
}
}
@@ -30,6 +30,7 @@ public class RemovingKeys implements Test {
@Override
public void test() throws Exception {
NBTContainer comp = new NBTContainer();
comp.setString(STRING_TEST_KEY, STRING_TEST_VALUE);
@@ -44,7 +45,9 @@ public class RemovingKeys implements Test {
comp.setByteArray(BYTEARRAY_TEST_KEY, BYTEARRAY_TEST_VALUE);
if (comp.getKeys().size() != 10) {
throw new NbtApiException("Key amount did not match after setting keys!");
}
comp.setString(STRING_TEST_KEY, null);
@@ -59,7 +62,9 @@ public class RemovingKeys implements Test {
comp.setByteArray(BYTEARRAY_TEST_KEY, null);
if (comp.getKeys().size() != 0) {
throw new NbtApiException("Keys where not removed using the setter with null!");
}
}
@@ -0,0 +1,84 @@
package de.tr7zw.nbtapi.plugin.tests.compounds;
import java.util.Arrays;
import de.tr7zw.changeme.nbtapi.NBT;
import de.tr7zw.changeme.nbtapi.NbtApiException;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBTCompoundList;
import de.tr7zw.changeme.nbtapi.iface.ReadableNBT;
import de.tr7zw.nbtapi.plugin.tests.Test;
public class ResolveTest implements Test {
@Override
public void test() throws Exception {
ReadWriteNBT src = NBT.createNBTObject();
src.resolveOrCreateCompound("foo.bar.baz").setInteger("test", 42);
if (src.resolveOrDefault("foo.bar.baz.test", 0) != 42) {
throw new NbtApiException("Wasn't able to check the value! The Item-NBT-API may not work!");
}
if (!Integer.valueOf(42).equals(src.resolveOrNull("foo.bar.baz.test", Integer.class))) {
throw new NbtApiException("Wasn't able to check the value! The Item-NBT-API may not work!");
}
src.resolveOrCreateCompound("foo.some\\.key.baz").setInteger("other", 123);
if (src.getOrCreateCompound("foo").getOrCreateCompound("some.key").getOrCreateCompound("baz")
.getInteger("other") != 123)
{
throw new NbtApiException("Wasn't able to check the value! The Item-NBT-API may not work!");
}
ReadWriteNBT comp = src.resolveOrCreateCompound("foo.bar.baz");
comp.setIntArray("intarray", new int[] { 1, 2, 3, 4, 5, 6 });
comp.getStringList("strlist").addAll(Arrays.asList("Hello", "World!"));
ReadWriteNBTCompoundList list = comp.getCompoundList("somelist");
list.addCompound().setInteger("id", 1);
list.addCompound().setInteger("id", 2);
list.addCompound().setInteger("id", 3);
list.addCompound().setInteger("id", 4);
list.addCompound().setInteger("id", 5);
list.addCompound().setInteger("id", 6);
ReadableNBT listEntry = src.resolveCompound("foo.bar.baz.somelist[0]");
if (listEntry == null || listEntry.getInteger("id") != 1) {
throw new NbtApiException("The value is not what was expected! The Item-NBT-API may not work!");
}
ReadableNBT lastEntry = src.resolveOrCreateCompound("foo.bar.baz.somelist[-1]");
if (lastEntry == null || lastEntry.getInteger("id") != 6) {
throw new NbtApiException("The value is not what was expected! The Item-NBT-API may not work!");
}
if (src.resolveOrDefault("foo.bar.baz.intarray[1]", 0) != 2) {
throw new NbtApiException("The value is not what was expected! The Item-NBT-API may not work!");
}
if (src.resolveOrNull("foo.bar.baz.intarray[2]", Integer.class) != (Integer) 3) {
throw new NbtApiException("The value is not what was expected! The Item-NBT-API may not work!");
}
if (!"World!".equals(src.resolveOrNull("foo.bar.baz.strlist[1]", String.class))) {
throw new NbtApiException("The value is not what was expected! The Item-NBT-API may not work!");
}
}
}
Loaded 100 of 153 files, more files were not shown because too many files have changed in this diff. Show more