Compare commits
250
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a914d00e7 | ||
|
|
7141c56319 | ||
|
|
992d9717ec | ||
|
|
c5c2652d42 | ||
|
|
fb8e2272b3 | ||
|
|
120d087edc | ||
|
|
12c98d7d94 | ||
|
|
51d06817bc | ||
|
|
3bb4d7b449 | ||
|
|
f562994d18 | ||
|
|
f86d234c9c | ||
|
|
cb8e24428b | ||
|
|
30bd0bcbaf | ||
|
|
bb4d3bb9b0 | ||
|
|
523ce8cf60 | ||
|
|
d3d7a3138c | ||
|
|
e71bf88d12 | ||
|
|
1ba6fc8706 | ||
|
|
a341034de0 | ||
|
|
b45b25c255 | ||
|
|
c7eaa51bdb | ||
|
|
6b1d4e28ed | ||
|
|
4341cb33ea | ||
|
|
bde0bf7c8d | ||
|
|
55ab9a2918 | ||
|
|
7f4d134bd0 | ||
|
|
6e8b8f3565 | ||
|
|
a009b521c0 | ||
|
|
54d0db8189 | ||
|
|
66ffcf2866 | ||
|
|
d653bc67d8 | ||
|
|
533765ba74 | ||
|
|
0232f720cb | ||
|
|
205ca93977 | ||
|
|
fa62c9825d | ||
|
|
5051bc834d | ||
|
|
10ea4b1767 | ||
|
|
b801b46bce | ||
|
|
fc94dac05b | ||
|
|
1ab5f70c88 | ||
|
|
af6a11d649 | ||
|
|
c90636970a | ||
|
|
f3b1cc27e7 | ||
|
|
33eddbaece | ||
|
|
20f9b2f1ce | ||
|
|
e8c24c6bc5 | ||
|
|
affad0d92c | ||
|
|
ba169438ba | ||
|
|
c2e23af84f | ||
|
|
9ff2e38d07 | ||
|
|
5b12aa70e7 | ||
|
|
5424282fe6 | ||
|
|
8b76359143 | ||
|
|
2c6d54b32c | ||
|
|
a341c6a81e | ||
|
|
23b9f9128f | ||
|
|
81c3b75dc9 | ||
|
|
d3b1d00e15 | ||
|
|
177d1fe5b7 | ||
|
|
f1682205d8 | ||
|
|
ced5b15023 | ||
|
|
f6a150d5be | ||
|
|
1bfdb93622 | ||
|
|
09af2df542 | ||
|
|
cd1bdc0436 | ||
|
|
b2ea170f9e | ||
|
|
769ba78aa1 | ||
|
|
0228b68a7c | ||
|
|
2a80e8ff63 | ||
|
|
9bdd79ef7d | ||
|
|
55893bac8a | ||
|
|
bfe627658e | ||
|
|
a929bd2ddc | ||
|
|
3a966e0478 | ||
|
|
62105ead48 | ||
|
|
cfd04fffa6 | ||
|
|
c8231eb050 | ||
|
|
f7bceec594 | ||
|
|
c377927ee6 | ||
|
|
0653f47bc1 | ||
|
|
84e096d8b4 | ||
|
|
8bc066872c | ||
|
|
4491f6780a | ||
|
|
af19868289 | ||
|
|
5588fc60b4 | ||
|
|
7c27630c10 | ||
|
|
4c538aad7b | ||
|
|
45dd70afad | ||
|
|
280ce7a50d | ||
|
|
175065dac4 | ||
|
|
f4bfca8ba8 | ||
|
|
37378b4ee1 | ||
|
|
662c0bb92d | ||
|
|
c485f8c967 | ||
|
|
5759b68d89 | ||
|
|
c22cbaaaf0 | ||
|
|
4a0e1b5557 | ||
|
|
1c2e61875e | ||
|
|
6f25881eda | ||
|
|
bd69504f54 | ||
|
|
85d7224fdd | ||
|
|
8dc51a3d30 | ||
|
|
8a440889b0 | ||
|
|
4a93fdc869 | ||
|
|
c905de852d | ||
|
|
fd7da1e3fb | ||
|
|
1123e27b10 | ||
|
|
a97ed32097 | ||
|
|
05b4249bb4 | ||
|
|
e399590d1d | ||
|
|
310682ea25 | ||
|
|
6b70966926 | ||
|
|
79275c0c19 | ||
|
|
2b21ef46bb | ||
|
|
79e1e62862 | ||
|
|
852ddf4a22 | ||
|
|
f648aca74b | ||
|
|
9e79a604d3 | ||
|
|
13c3f861c3 | ||
|
|
25aa64a895 | ||
|
|
cc61fc1e6e | ||
|
|
54d9ac614e | ||
|
|
306812264f | ||
|
|
af616831bf | ||
|
|
fb4757c0a3 | ||
|
|
ddd96453f0 | ||
|
|
dd17fb4d83 | ||
|
|
465ae73fe6 | ||
|
|
63dbf69c02 | ||
|
|
fffa9118d1 | ||
|
|
e4a8a39473 | ||
|
|
38c42ed577 | ||
|
|
3c20b5db32 | ||
|
|
de62c840d3 | ||
|
|
f10ba986ba | ||
|
|
b28bac5919 | ||
|
|
c5c96e6d17 | ||
|
|
22ded53d31 | ||
|
|
39160df3ec | ||
|
|
49fd713c63 | ||
|
|
58f2fda332 | ||
|
|
c06f8f8145 | ||
|
|
45504d09f0 | ||
|
|
88fb62677d | ||
|
|
07d0f4dbd2 | ||
|
|
e4c7344095 | ||
|
|
9aad17aa0d | ||
|
|
5a4fdc2752 | ||
|
|
fc2c944bb7 | ||
|
|
a49025cc17 | ||
|
|
c6f8f4163a | ||
|
|
54c1c17d07 | ||
|
|
31ddc33667 | ||
|
|
4588724ca8 | ||
|
|
793540f282 | ||
|
|
9927bfb845 | ||
|
|
d83b777862 | ||
|
|
6f9ea15c9f | ||
|
|
d30f984376 | ||
|
|
3a987af139 | ||
|
|
783d4548ab | ||
|
|
f23a1ca325 | ||
|
|
766d57a085 | ||
|
|
f74f6545a7 | ||
|
|
b74c8f524f | ||
|
|
bf65c7ce68 | ||
|
|
42f4af52bc | ||
|
|
8e8285b36d | ||
|
|
ca76df589b | ||
|
|
9e6ae13711 | ||
|
|
02d3ab0b11 | ||
|
|
abb7fdf622 | ||
|
|
7263b5a12f | ||
|
|
e500a443a1 | ||
|
|
332f9e4b42 | ||
|
|
42e37f0838 | ||
|
|
efd22f2bd1 | ||
|
|
4dace8749d | ||
|
|
82dbb4b7d1 | ||
|
|
bb85fd092d | ||
|
|
c9d4ec6cc1 | ||
|
|
ff72945ade | ||
|
|
fc186cc076 | ||
|
|
e59008d475 | ||
|
|
0a033f1fc9 | ||
|
|
0954eaa294 | ||
|
|
854524062e | ||
|
|
4e498e3247 | ||
|
|
5c213e3c2d | ||
|
|
54d3d4a83f | ||
|
|
7ae34cc78c | ||
|
|
620af1f49e | ||
|
|
7a6e778a2a | ||
|
|
2e74e8def8 | ||
|
|
80facd8d8b | ||
|
|
8e4e674443 | ||
|
|
a0ca526af4 | ||
|
|
9d1448f96e | ||
|
|
06b6cdddd0 | ||
|
|
1fc21e8707 | ||
|
|
9000d576ca | ||
|
|
c7ea044853 | ||
|
|
20f5787696 | ||
|
|
cd764ce984 | ||
|
|
57735d76ee | ||
|
|
5d80816f1b | ||
|
|
51dedc0c33 | ||
|
|
7e2a32dda9 | ||
|
|
425ca3f930 | ||
|
|
36e5a5fd02 | ||
|
|
c9b3a92e16 | ||
|
|
bc09a2e84c | ||
|
|
a260cd6345 | ||
|
|
b3107b0e9d | ||
|
|
f3d36fc92c | ||
|
|
d0b0472894 | ||
|
|
a8ddfa7a5a | ||
|
|
eae2ebb72a | ||
|
|
0ca0d3038e | ||
|
|
dd0c421145 | ||
|
|
d0d3e19c70 | ||
|
|
b0cf14c77e | ||
|
|
ba4308e571 | ||
|
|
325591e503 | ||
|
|
fb6c856444 | ||
|
|
3d0a17fa25 | ||
|
|
5b409771e1 | ||
|
|
bca1efce52 | ||
|
|
e3502a50ee | ||
|
|
a495729725 | ||
|
|
88661da61c | ||
|
|
b4720f73e2 | ||
|
|
a97e2c6234 | ||
|
|
8171762e42 | ||
|
|
0602a2b8c3 | ||
|
|
e0c060a982 | ||
|
|
caa37d4cb0 | ||
|
|
de9f2a786f | ||
|
|
423f0a07e4 | ||
|
|
eda1d60ccc | ||
|
|
acb5a376e9 | ||
|
|
165bb4ce68 | ||
|
|
08bde0923f | ||
|
|
a78b68d16f | ||
|
|
87204ac4a0 | ||
|
|
71701d4a3a | ||
|
|
6b156c47e4 | ||
|
|
f783db7fca | ||
|
|
394c093981 | ||
|
|
1f94a8452e |
No files matched your search
@@ -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/"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
text eol=lf
|
||||
+1
-2
@@ -1,4 +1,3 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
patreon: tr7zw
|
||||
custom: https://tr7zw.dev/donate/
|
||||
ko_fi: tr7zw
|
||||
@@ -0,0 +1,36 @@
|
||||
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
|
||||
@@ -8,10 +8,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: 1.8
|
||||
distribution: zulu
|
||||
java-version: 8
|
||||
- name: Build with Maven
|
||||
run: mvn --file pom.xml
|
||||
run: mvn install --file pom.xml
|
||||
@@ -0,0 +1,34 @@
|
||||
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)
|
||||
+106
-104
@@ -1,104 +1,106 @@
|
||||
### Java files ###
|
||||
*.class
|
||||
|
||||
# Package Files
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
|
||||
### Intellij ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
|
||||
# Ignore project files
|
||||
*.iml
|
||||
|
||||
# Ignore IDEA directory
|
||||
.idea/*
|
||||
|
||||
# File-based project format:
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
### Plugin-specific files: ###
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
|
||||
|
||||
### Eclipse ###
|
||||
*.pydevproject
|
||||
.metadata
|
||||
.gradle
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# Eclipse Core
|
||||
.project
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
.classpath
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
|
||||
|
||||
### Maven ###
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
|
||||
|
||||
### NetBeans ###
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
nbactions.xml
|
||||
nb-configuration.xml
|
||||
.nb-gradle/
|
||||
|
||||
|
||||
### Git ###
|
||||
# Don't exclude the .gitignore itself
|
||||
!.gitignore
|
||||
### Java files ###
|
||||
*.class
|
||||
|
||||
# Package Files
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
|
||||
### Intellij ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
|
||||
# Ignore project files
|
||||
*.iml
|
||||
|
||||
# Ignore IDEA directory
|
||||
.idea/
|
||||
|
||||
# File-based project format:
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
### Plugin-specific files: ###
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
|
||||
|
||||
### Eclipse ###
|
||||
*.pydevproject
|
||||
.metadata
|
||||
.gradle
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
.factorypath
|
||||
|
||||
# Eclipse Core
|
||||
.project
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
.classpath
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
|
||||
|
||||
### Maven ###
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
|
||||
|
||||
### NetBeans ###
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
nbactions.xml
|
||||
nb-configuration.xml
|
||||
.nb-gradle/
|
||||
|
||||
|
||||
### Git ###
|
||||
# Don't exclude the .gitignore itself
|
||||
!.gitignore
|
||||
.vscode/settings.json
|
||||
@@ -1,16 +1,20 @@
|
||||
# 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
|
||||
[](https://ci.codemc.org/job/Tr7zw/job/Item-NBT-API/)[](https://sonarcloud.io/dashboard?id=de.tr7zw%3Aitem-nbt-parent)[](https://sonarcloud.io/dashboard?id=de.tr7zw%3Aitem-nbt-parent)[](https://sonarcloud.io/dashboard?id=de.tr7zw%3Aitem-nbt-parent)[](https://sonarcloud.io/dashboard?id=de.tr7zw%3Aitem-nbt-parent)
|
||||
|
||||
[](https://ci.codemc.org/job/Tr7zw/job/Item-NBT-API/)[](https://sonarcloud.io/summary/overall?id=tr7zw_Item-NBT-API)[](https://sonarcloud.io/summary/overall?id=tr7zw_Item-NBT-API)[](https://sonarcloud.io/summary/overall?id=tr7zw_Item-NBT-API)
|
||||
[](https://discordapp.com/invite/yk4caxM)
|
||||
[](https://www.patreon.com/tr7zw)
|
||||
|
||||
### SpigotMC Status
|
||||
|
||||
[](https://www.spigotmc.org/resources/item-entity-tile-nbt-api.7939/)[](https://www.spigotmc.org/resources/item-entity-tile-nbt-api.7939/)[](https://www.spigotmc.org/resources/item-entity-tile-nbt-api.7939/)[](https://bstats.org/plugin/bukkit/ItemNBTAPI)[](https://bstats.org/plugin/bukkit/ItemNBTAPI)[](#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).
|
||||
|
||||
### bStats
|
||||
@@ -18,37 +22,5 @@ Import the API [using Maven](https://github.com/tr7zw/Item-NBT-API/wiki/Using-Ma
|
||||
[](https://bstats.org/plugin/bukkit/ItemNBTAPI)
|
||||
|
||||
### Github Stargazers
|
||||
|
||||
<img src="https://starchart.cc/tr7zw/Item-NBT-API.svg" alt="stargazers" width="800"/>
|
||||
|
||||
## Contributors ✨
|
||||
|
||||
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!
|
||||
+7
-3
@@ -1,17 +1,21 @@
|
||||
# (Item)-NBT-API
|
||||
# (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
|
||||
|
||||
[](https://ci.codemc.org/job/Tr7zw/job/Item-NBT-API/)[](https://sonarcloud.io/dashboard?id=de.tr7zw%3Aitem-nbt-parent)[](https://sonarcloud.io/dashboard?id=de.tr7zw%3Aitem-nbt-parent)[](https://sonarcloud.io/dashboard?id=de.tr7zw%3Aitem-nbt-parent)[](https://sonarcloud.io/dashboard?id=de.tr7zw%3Aitem-nbt-parent)
|
||||
Discord:[](https://discordapp.com/invite/yk4caxM)
|
||||
[](https://www.patreon.com/tr7zw)
|
||||
|
||||
### SpigotMC Status
|
||||
|
||||
[](https://www.spigotmc.org/resources/item-entity-tile-nbt-api.7939/)[](https://www.spigotmc.org/resources/item-entity-tile-nbt-api.7939/)[](https://www.spigotmc.org/resources/item-entity-tile-nbt-api.7939/)[](https://bstats.org/plugin/bukkit/ItemNBTAPI)[](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
|
||||
[](https://bstats.org/plugin/bukkit/ItemNBTAPI)
|
||||
|
||||
[](https://bstats.org/plugin/bukkit/ItemNBTAPI)
|
||||
+390
@@ -0,0 +1,390 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<profiles version="21">
|
||||
<profile kind="CodeFormatterProfile" name="Java Conventions Spaces" version="21">
|
||||
<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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
|
||||
<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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_never"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
|
||||
<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.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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_never"/>
|
||||
<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.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.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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant" value="49"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
|
||||
<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.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_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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_annotations" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
|
||||
<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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_not_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
|
||||
<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.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.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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
|
||||
<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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
|
||||
<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.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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
||||
<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.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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_never"/>
|
||||
<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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
|
||||
<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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
|
||||
<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.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.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.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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field" value="49"/>
|
||||
<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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_never"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration" value="do not insert"/>
|
||||
<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.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.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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
|
||||
<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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
|
||||
<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_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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
|
||||
<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.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"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
|
||||
</profile>
|
||||
</profiles>
|
||||
+48
-63
@@ -1,63 +1,48 @@
|
||||
<?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.8.0</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.2.4</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>
|
||||
<?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.12.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>item-nbt-api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<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.5.0</version>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<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>
|
||||
@@ -0,0 +1,553 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* General utility class for a clean and simple nbt access.
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBT {
|
||||
|
||||
private NBT() {
|
||||
// No instances of NBT. Utility class
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* NBTItem
|
||||
*
|
||||
* @param item The itemstack you want to get the NBT from
|
||||
* @param getter A function that takes a ReadableNBT and returns a value of type
|
||||
* T.
|
||||
* @return The function is being returned.
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* It takes an entity and a function that takes a ReadableNBT and returns a
|
||||
* generic type T, and returns the result of the function
|
||||
*
|
||||
* @param entity The entity to get the NBT from
|
||||
* @param getter A function that takes a ReadableNBT and returns a value.
|
||||
* @return The NBTEntity class is being returned.
|
||||
*/
|
||||
public static <T> T get(Entity entity, Function<ReadableNBT, T> getter) {
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* It takes a block state and a function that takes a readable NBT and returns a
|
||||
* value of type T. It then returns the value of the function applied to a new
|
||||
* NBTTileEntity created from the block state
|
||||
*
|
||||
* @param blockState The block state of the block you want to get the NBT from.
|
||||
* @param getter A function that takes a ReadableNBT and returns a value of
|
||||
* type T.
|
||||
* @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) {
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* It takes an entity and a function that takes a ReadableNBT and returns a
|
||||
* generic type T, and returns the result of the function, applied to the
|
||||
* entities persistent data container
|
||||
*
|
||||
* @param entity The entity to get the data from
|
||||
* @param getter A function that takes a ReadableNBT and returns a value of type
|
||||
* T.
|
||||
* @return The return type is T, which is a generic type.
|
||||
*/
|
||||
public static <T> T getPersistentData(Entity entity, Function<ReadableNBT, T> getter) {
|
||||
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 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
|
||||
* type T.
|
||||
* @return The value of the NBT tag.
|
||||
*/
|
||||
public static <T> T getPersistentData(BlockState blockState, Function<ReadableNBT, T> getter) {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* It takes an ItemStack, applies a function to its NBT, and returns the result
|
||||
* of the function
|
||||
*
|
||||
* @param item The item you want to modify
|
||||
* @param function The function that will be applied to the item.
|
||||
* @return The return value of the function.
|
||||
*/
|
||||
public static <T> T modify(ItemStack item, Function<ReadWriteItemNBT, T> function) {
|
||||
NBTItem nbti = new NBTItem(item, false, false, true);
|
||||
T val = function.apply(nbti);
|
||||
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 and a Consumer<ReadWriteNBT>, and then applies
|
||||
* the Consumer to the ItemStacks NBT
|
||||
*
|
||||
* @param item The item you want to modify
|
||||
* @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, false, false, true);
|
||||
consumer.accept(nbti);
|
||||
nbti.finalizeChanges();
|
||||
nbti.setClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
* It takes an entity and a function that takes a ReadWriteNBT and returns a
|
||||
* generic type T. It then returns the result of the function
|
||||
*
|
||||
* @param entity The entity to modify
|
||||
* @param function The function that will be called.
|
||||
* @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) {
|
||||
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 entity and a function that takes a ReadWriteNBT and applies the
|
||||
* function to the entity
|
||||
*
|
||||
* @param entity The entity to modify
|
||||
* @param consumer The consumer that will be called with the NBTEntity.
|
||||
*/
|
||||
public static void modify(Entity entity, Consumer<ReadWriteNBT> consumer) {
|
||||
NBTEntity nbtEnt = new NBTEntity(entity);
|
||||
NBTContainer cont = new NBTContainer(nbtEnt.getCompound());
|
||||
consumer.accept(cont);
|
||||
nbtEnt.setCompound(cont.getCompound());
|
||||
nbtEnt.setClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
* It takes an entity and a function that takes a ReadWriteNBT from the entities
|
||||
* persistent data and returns a generic type T. It then returns the result of
|
||||
* the function
|
||||
*
|
||||
* @param entity The entity to modify the data of.
|
||||
* @param function The function that will be called.
|
||||
* @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) {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* It allows you to modify the persistent data of an entity without any return
|
||||
* value
|
||||
*
|
||||
* @param entity The entity to modify
|
||||
* @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());
|
||||
}
|
||||
|
||||
/**
|
||||
* It takes a block state and a function that takes a ReadWriteNBT and returns a
|
||||
* generic type T. It then returns the result of the function
|
||||
*
|
||||
* @param blockState The blockstate you want to modify
|
||||
* @param function The function that will be called.
|
||||
* @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) {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* It takes a block state and a consumer, and then it creates a new
|
||||
* NBTTileEntity object with the block state, and then it passes that
|
||||
* NBTTileEntity object to the consumer
|
||||
*
|
||||
* @param blockState The blockstate you want to modify
|
||||
* @param consumer A Consumer<ReadWriteNBT>. This is a function that
|
||||
* takes a ReadWriteNBT and does something with it.
|
||||
*/
|
||||
public static void modify(BlockState blockState, Consumer<ReadWriteNBT> consumer) {
|
||||
NBTTileEntity blockEnt = new NBTTileEntity(blockState);
|
||||
NBTContainer cont = new NBTContainer(blockEnt.getCompound());
|
||||
consumer.accept(cont);
|
||||
blockEnt.setCompound(cont.getCompound());
|
||||
blockEnt.setClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
* It takes a block state and a function that takes a ReadWriteNBT of the block
|
||||
* entities persistent data and returns a generic type T. It then returns the
|
||||
* result of the function
|
||||
*
|
||||
* @param blockState The block state of the block you want to modify.
|
||||
* @param function The function that will be called to modify the NBT data.
|
||||
* @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) {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* It takes a block state and a consumer, and then it calls the consumer with
|
||||
* the persistent data container of the block entity
|
||||
*
|
||||
* @param blockState The block state of the block you want to modify.
|
||||
* @param consumer A Consumer<ReadWriteNBT>. This is a function that
|
||||
* takes a ReadWriteNBT and does something with it.
|
||||
*/
|
||||
public static void modifyPersistentData(BlockState blockState, Consumer<ReadWriteNBT> consumer) {
|
||||
consumer.accept(new NBTTileEntity(blockState).getPersistentDataContainer());
|
||||
}
|
||||
|
||||
/**
|
||||
* It converts a GameProfile object to a ReadWriteNBT object
|
||||
*
|
||||
* @param profile The GameProfile to convert to NBT
|
||||
* @return A ReadWriteNBT object.
|
||||
*/
|
||||
public static ReadWriteNBT gameProfileToNBT(GameProfile profile) {
|
||||
return NBTGameProfile.toNBT(profile);
|
||||
}
|
||||
|
||||
/**
|
||||
* It takes a NBT compound and returns a GameProfile
|
||||
*
|
||||
* @param compound The NBT tag to read the GameProfile from.
|
||||
* @return A GameProfile object.
|
||||
*/
|
||||
public static GameProfile gameProfileFromNBT(ReadableNBT compound) {
|
||||
return NBTGameProfile.fromNBT((NBTCompound) compound);
|
||||
}
|
||||
|
||||
/**
|
||||
* It converts an ItemStack to a ReadWriteNBT object
|
||||
*
|
||||
* @param itemStack The item stack you want to convert to NBT.
|
||||
* @return A ReadWriteNBT object.
|
||||
*/
|
||||
public static ReadWriteNBT itemStackToNBT(ItemStack itemStack) {
|
||||
return NBTItem.convertItemtoNBT(itemStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* It converts a ReadableNBT object into an ItemStack
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* It converts an array of ItemStacks into a ReadWriteNBT object
|
||||
*
|
||||
* @param itemStacks The ItemStack[] you want to convert to NBT
|
||||
* @return An NBTItem object.
|
||||
*/
|
||||
public static ReadWriteNBT itemStackArrayToNBT(ItemStack[] itemStacks) {
|
||||
return NBTItem.convertItemArraytoNBT(itemStacks);
|
||||
}
|
||||
|
||||
/**
|
||||
* It converts a ReadableNBT object into an array of ItemStacks
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new NBTContainer object and return it.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
public static ReadWriteNBT parseNBT(String nbtString) {
|
||||
return new NBTContainer(nbtString);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,23 +4,35 @@ import org.bukkit.block.Block;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
|
||||
/**
|
||||
* Helper class to store NBT data to Block Locations. Use getData() to get the
|
||||
* NBT instance. Important notes:
|
||||
*
|
||||
* - Non BlockEntities can not have NBT data. This stores the data to the chunk
|
||||
* instead!
|
||||
*
|
||||
* - The data is really just on the location. If the block gets
|
||||
* broken/changed/exploded/moved etc., the data is still on that location!
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTBlock {
|
||||
|
||||
private final Block block;
|
||||
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());
|
||||
}
|
||||
private final Block block;
|
||||
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,29 +2,26 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the NBTCompound used by spigots PersistentDataAPI. This method is only
|
||||
* available for 1.16.4+!
|
||||
*
|
||||
* @return NBTCompound containing the data of the PersistentDataAPI
|
||||
*/
|
||||
@AvailableSince(version = MinecraftVersion.MC1_16_R3)
|
||||
public NBTCompound getPersistentDataContainer() {
|
||||
FAUtil.check(this::getPersistentDataContainer, CheckUtil::isAvaliable);
|
||||
return new NBTPersistentDataContainer(chunk.getPersistentDataContainer());
|
||||
}
|
||||
|
||||
private final Chunk chunk;
|
||||
|
||||
public NBTChunk(Chunk chunk) {
|
||||
this.chunk = chunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the NBTCompound used by spigots PersistentDataAPI. This method is only
|
||||
* available for 1.16.4+!
|
||||
*
|
||||
* @return NBTCompound containing the data of the PersistentDataAPI
|
||||
*/
|
||||
public NBTCompound getPersistentDataContainer() {
|
||||
CheckUtil.assertAvailable(MinecraftVersion.MC1_16_R3);
|
||||
return new NBTPersistentDataContainer(chunk.getPersistentDataContainer());
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,7 +1,7 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import org.apache.commons.lang.NotImplementedException;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
|
||||
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBTCompoundList;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
@@ -12,97 +12,110 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTCompoundList extends NBTList<NBTListCompound> {
|
||||
public class NBTCompoundList extends NBTList<ReadWriteNBT> implements ReadWriteNBTCompoundList {
|
||||
|
||||
protected NBTCompoundList(NBTCompound owner, String name, NBTType type, Object list) {
|
||||
super(owner, name, type, list);
|
||||
}
|
||||
protected NBTCompoundList(NBTCompound owner, String name, NBTType type, Object list) {
|
||||
super(owner, name, type, list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new Compound to the end of the List and returns it.
|
||||
*
|
||||
* @return The added {@link NBTListCompound}
|
||||
*/
|
||||
public NBTListCompound addCompound() {
|
||||
return (NBTListCompound) addCompound(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public NBTCompound addCompound(NBTCompound comp) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Adds a new Compound to the end of the List and returns it.
|
||||
*
|
||||
* @return The added {@link NBTListCompound}
|
||||
*/
|
||||
public NBTListCompound addCompound() {
|
||||
return (NBTListCompound) addCompound(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new Compound to the end of the List.
|
||||
*
|
||||
*
|
||||
* @deprecated Please use addCompound!
|
||||
* @param empty
|
||||
* @return True, if compound was added
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean add(NBTListCompound empty) {
|
||||
return addCompound(empty) != null;
|
||||
}
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, NBTListCompound element) {
|
||||
if (element != null) {
|
||||
throw new NotImplementedException("You need to pass null! ListCompounds from other lists won't work.");
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
public NBTCompound addCompound(ReadWriteNBT comp) {
|
||||
if (comp instanceof NBTCompound) {
|
||||
return addCompound((NBTCompound) comp);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Adds a new Compound to the end of the List.
|
||||
*
|
||||
*
|
||||
* @deprecated Please use addCompound!
|
||||
* @param empty
|
||||
* @return True, if compound was added
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean add(ReadWriteNBT empty) {
|
||||
return addCompound(empty) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTListCompound set(int index, NBTListCompound element) {
|
||||
throw new NotImplementedException("This method doesn't work in the ListCompound context.");
|
||||
}
|
||||
@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
|
||||
protected Object asTag(NBTListCompound object) {
|
||||
return null;
|
||||
}
|
||||
@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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,68 +15,89 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
*/
|
||||
public class NBTContainer extends NBTCompound {
|
||||
|
||||
private Object nbt;
|
||||
private Object nbt;
|
||||
private boolean closed;
|
||||
private boolean readOnly;
|
||||
|
||||
/**
|
||||
* Creates an empty, standalone NBTCompound
|
||||
*/
|
||||
public NBTContainer() {
|
||||
super(null, null);
|
||||
nbt = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
/**
|
||||
* Creates an empty, standalone NBTCompound
|
||||
*/
|
||||
public NBTContainer() {
|
||||
super(null, null);
|
||||
nbt = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes in any NMS Compound to wrap it
|
||||
*
|
||||
* @param nbt
|
||||
*/
|
||||
public NBTContainer(Object nbt) {
|
||||
super(null, null);
|
||||
if (nbt == null) {
|
||||
throw new NullPointerException("The NBT-Object can't be null!");
|
||||
}
|
||||
if (!ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz().isAssignableFrom(nbt.getClass())) {
|
||||
throw new NbtApiException("The object '" + nbt.getClass() + "' is not a valid NBT-Object!");
|
||||
}
|
||||
this.nbt = nbt;
|
||||
}
|
||||
/**
|
||||
* Takes in any NMS Compound to wrap it
|
||||
*
|
||||
* @param nbt
|
||||
*/
|
||||
public NBTContainer(Object nbt) {
|
||||
super(null, null);
|
||||
if (nbt == null) {
|
||||
throw new NullPointerException("The NBT-Object can't be null!");
|
||||
}
|
||||
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
|
||||
*/
|
||||
public NBTContainer(InputStream inputsteam) {
|
||||
super(null, null);
|
||||
this.nbt = NBTReflectionUtil.readNBT(inputsteam);
|
||||
}
|
||||
/**
|
||||
* Reads in a NBT InputStream
|
||||
*
|
||||
* @param inputsteam
|
||||
*/
|
||||
public NBTContainer(InputStream inputsteam) {
|
||||
super(null, null);
|
||||
this.nbt = NBTReflectionUtil.readNBT(inputsteam);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses in a NBT String to a standalone {@link NBTCompound}. Can throw a
|
||||
* {@link NbtApiException} in case something goes wrong.
|
||||
*
|
||||
* @param nbtString
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Parses in a NBT String to a standalone {@link NBTCompound}. Can throw a
|
||||
* {@link NbtApiException} in case something goes wrong.
|
||||
*
|
||||
* @param nbtString
|
||||
*/
|
||||
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 Object getCompound() {
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCompound(Object tag) {
|
||||
nbt = tag;
|
||||
}
|
||||
@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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,32 +14,32 @@ 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);
|
||||
}
|
||||
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) {
|
||||
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
|
||||
}
|
||||
}
|
||||
@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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
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
|
||||
@@ -17,39 +16,87 @@ import de.tr7zw.changeme.nbtapi.utils.annotations.CheckUtil;
|
||||
*/
|
||||
public class NBTEntity extends NBTCompound {
|
||||
|
||||
private final Entity ent;
|
||||
private final Entity ent;
|
||||
private final boolean readonly;
|
||||
private final Object compound;
|
||||
private boolean closed = false;
|
||||
|
||||
/**
|
||||
* @param entity Any valid Bukkit Entity
|
||||
*/
|
||||
public NBTEntity(Entity entity) {
|
||||
super(null, null);
|
||||
if (entity == null) {
|
||||
throw new NullPointerException("Entity can't be null!");
|
||||
}
|
||||
ent = entity;
|
||||
}
|
||||
/**
|
||||
* @param entity Any valid Bukkit Entity
|
||||
* @param readonly Readonly makes a copy at init, only reading from that copy
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
return NBTReflectionUtil.getEntityNBTTagCompound(NBTReflectionUtil.getNMSEntity(ent));
|
||||
}
|
||||
/**
|
||||
* @param entity Any valid Bukkit Entity
|
||||
*/
|
||||
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 setCompound(Object compound) {
|
||||
NBTReflectionUtil.setEntityNBTTag(compound, NBTReflectionUtil.getNMSEntity(ent));
|
||||
}
|
||||
@Override
|
||||
protected void setClosed() {
|
||||
this.closed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the NBTCompound used by spigots PersistentDataAPI. This method is only
|
||||
* available for 1.14+!
|
||||
*
|
||||
* @return NBTCompound containing the data of the PersistentDataAPI
|
||||
*/
|
||||
@AvailableSince(version = MinecraftVersion.MC1_14_R1)
|
||||
public NBTCompound getPersistentDataContainer() {
|
||||
FAUtil.check(this::getPersistentDataContainer, CheckUtil::isAvaliable);
|
||||
return new NBTPersistentDataContainer(ent.getPersistentDataContainer());
|
||||
}
|
||||
@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));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the NBTCompound used by spigots PersistentDataAPI. This method is only
|
||||
* available for 1.14+!
|
||||
*
|
||||
* @return NBTCompound containing the data of the PersistentDataAPI
|
||||
*/
|
||||
public NBTCompound getPersistentDataContainer() {
|
||||
CheckUtil.assertAvailable(MinecraftVersion.MC1_14_R1);
|
||||
return new NBTPersistentDataContainer(ent.getPersistentDataContainer());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ObjectCreator;
|
||||
|
||||
@@ -15,66 +14,92 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ObjectCreator;
|
||||
*/
|
||||
public class NBTFile extends NBTCompound {
|
||||
|
||||
private final File file;
|
||||
private Object nbt;
|
||||
private final File file;
|
||||
private Object nbt;
|
||||
|
||||
/**
|
||||
* Creates a NBTFile that uses @param file to store it's data. If this file
|
||||
* exists, the data will be loaded.
|
||||
*
|
||||
* @param file
|
||||
* @throws IOException
|
||||
*/
|
||||
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()) {
|
||||
FileInputStream inputsteam = new FileInputStream(file);
|
||||
nbt = NBTReflectionUtil.readNBT(inputsteam);
|
||||
} else {
|
||||
nbt = ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance();
|
||||
save();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creates a NBTFile that uses @param file to store its data. If this file
|
||||
* exists, the data will be loaded.
|
||||
*
|
||||
* @param file
|
||||
* @throws IOException
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the data to the file
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void save() throws IOException {
|
||||
try {
|
||||
getWriteLock().lock();
|
||||
if (!file.exists()) {
|
||||
file.getParentFile().mkdirs();
|
||||
if (!file.createNewFile())
|
||||
throw new IOException("Unable to create file at " + file.getAbsolutePath());
|
||||
}
|
||||
FileOutputStream outStream = new FileOutputStream(file);
|
||||
NBTReflectionUtil.writeNBT(nbt, outStream);
|
||||
} finally {
|
||||
getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Saves the data to the file
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void save() throws IOException {
|
||||
try {
|
||||
getWriteLock().lock();
|
||||
saveTo(file, this);
|
||||
} finally {
|
||||
getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The File used to store the data
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
/**
|
||||
* @return The File used to store the data
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
return nbt;
|
||||
}
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setCompound(Object compound) {
|
||||
nbt = compound;
|
||||
}
|
||||
@Override
|
||||
protected void setCompound(Object compound) {
|
||||
nbt = compound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads NBT data from the provided file.
|
||||
* <p>
|
||||
* Returns empty NBTContainer if file does not exist.
|
||||
*
|
||||
* @param file file to read
|
||||
* @return NBTCompound holding file's nbt data
|
||||
* @throws IOException exception
|
||||
*/
|
||||
public static NBTCompound readFrom(File file) throws IOException {
|
||||
if (!file.exists())
|
||||
return new NBTContainer();
|
||||
return new NBTContainer(NBTReflectionUtil.readNBT(Files.newInputStream(file.toPath())));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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());
|
||||
}
|
||||
nbt.writeCompound(Files.newOutputStream(file.toPath()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,32 +14,32 @@ 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);
|
||||
}
|
||||
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) {
|
||||
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
|
||||
}
|
||||
}
|
||||
@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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,24 +7,26 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
public class NBTGameProfile {
|
||||
|
||||
/**
|
||||
* Convert a GameProfile to NBT. The NBT then can be modified or be stored
|
||||
*
|
||||
* @param profile
|
||||
* @return A NBTContainer with all the GameProfile data
|
||||
*/
|
||||
public static NBTCompound toNBT(GameProfile profile) {
|
||||
return new NBTContainer(ReflectionMethod.GAMEPROFILE_SERIALIZE.run(null, ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance(), profile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstructs a GameProfile from a NBTCompound
|
||||
*
|
||||
* @param compound Has to contain GameProfile data
|
||||
* @return The reconstructed GameProfile
|
||||
*/
|
||||
public static GameProfile fromNBT(NBTCompound compound) {
|
||||
return (GameProfile) ReflectionMethod.GAMEPROFILE_DESERIALIZE.run(null, NBTReflectionUtil.gettoCompount(compound.getCompound(), compound));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a GameProfile to NBT. The NBT then can be modified or be stored
|
||||
*
|
||||
* @param profile
|
||||
* @return A NBTContainer with all the GameProfile data
|
||||
*/
|
||||
public static NBTCompound toNBT(GameProfile profile) {
|
||||
return new NBTContainer(ReflectionMethod.GAMEPROFILE_SERIALIZE.run(null,
|
||||
ObjectCreator.NMS_NBTTAGCOMPOUND.getInstance(), profile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstructs a GameProfile from a NBTCompound
|
||||
*
|
||||
* @param compound Has to contain GameProfile data
|
||||
* @return The reconstructed GameProfile
|
||||
*/
|
||||
public static GameProfile fromNBT(NBTCompound compound) {
|
||||
return (GameProfile) ReflectionMethod.GAMEPROFILE_DESERIALIZE.run(null,
|
||||
NBTReflectionUtil.gettoCompount(compound.getCompound(), compound));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Integer implementation for NBTLists
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,32 +14,32 @@ 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);
|
||||
}
|
||||
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) {
|
||||
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
|
||||
}
|
||||
}
|
||||
@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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@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,9 +1,18 @@
|
||||
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;
|
||||
|
||||
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.nmsmappings.ClassWrapper;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
/**
|
||||
@@ -13,153 +22,375 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class NBTItem extends NBTCompound {
|
||||
public class NBTItem extends NBTCompound implements ReadWriteItemNBT {
|
||||
|
||||
private ItemStack bukkitItem;
|
||||
private boolean directApply;
|
||||
private ItemStack originalSrcStack = null;
|
||||
private ItemStack bukkitItem;
|
||||
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!
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
public NBTItem(ItemStack item) {
|
||||
this(item, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for NBTItems. The ItemStack will be cloned! If directApply is true,
|
||||
* all changed will be mapped to the original item. Changes to the NBTItem will overwrite changes done
|
||||
* to the original item in that case.
|
||||
*
|
||||
* @param item
|
||||
* @param directApply
|
||||
*/
|
||||
public NBTItem(ItemStack item, boolean directApply) {
|
||||
super(null, null);
|
||||
if (item == null || item.getType() == Material.AIR) {
|
||||
throw new NullPointerException("ItemStack can't be null/Air!");
|
||||
}
|
||||
this.directApply = directApply;
|
||||
bukkitItem = item.clone();
|
||||
if(directApply) {
|
||||
this.originalSrcStack = item;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Constructor for NBTItems. The ItemStack will be cloned!
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
public NBTItem(ItemStack item) {
|
||||
this(item, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
return NBTReflectionUtil.getItemRootNBTTagCompound(ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, bukkitItem));
|
||||
}
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
/**
|
||||
* Constructor for NBTItems. The ItemStack will be cloned! If directApply is
|
||||
* true, all changed will be mapped to the original item. Changes to the NBTItem
|
||||
* will overwrite changes done to the original item in that case.
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply stored NBT tags to the provided ItemStack.
|
||||
* <p>
|
||||
* Note: This will completely override current item's {@link ItemMeta}.
|
||||
* If you still want to keep the original item's NBT tags, see
|
||||
* {@link #mergeNBT(ItemStack)} and {@link #mergeCustomNBT(ItemStack)}.
|
||||
*
|
||||
* @param item ItemStack that should get the new NBT data
|
||||
*/
|
||||
public void applyNBT(ItemStack item) {
|
||||
if (item == null || item.getType() == Material.AIR) {
|
||||
throw new NullPointerException("ItemStack can't be null/Air!");
|
||||
}
|
||||
NBTItem nbti = new NBTItem(new ItemStack(item.getType()));
|
||||
nbti.mergeCompound(this);
|
||||
item.setItemMeta(nbti.getItem().getItemMeta());
|
||||
}
|
||||
@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));
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge all NBT tags to the provided ItemStack.
|
||||
*
|
||||
* @param item ItemStack that should get the new NBT data
|
||||
*/
|
||||
public void mergeNBT(ItemStack item) {
|
||||
NBTItem nbti = new NBTItem(item);
|
||||
nbti.mergeCompound(this);
|
||||
item.setItemMeta(nbti.getItem().getItemMeta());
|
||||
}
|
||||
private void updateCachedCompound() {
|
||||
if (finalizer) {
|
||||
cachedCompound = NBTReflectionUtil
|
||||
.getItemRootNBTTagCompound(ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, bukkitItem));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge only custom (non-vanilla) NBT tags to the provided ItemStack.
|
||||
*
|
||||
* @param item ItemStack that should get the new NBT data
|
||||
*/
|
||||
public void mergeCustomNBT(ItemStack item) {
|
||||
if (item == null || item.getType() == Material.AIR) {
|
||||
throw new NullPointerException("ItemStack can't be null/Air!");
|
||||
}
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
NBTReflectionUtil.getUnhandledNBTTags(meta).putAll(NBTReflectionUtil.getUnhandledNBTTags(bukkitItem.getItemMeta()));
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
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);
|
||||
ReflectionMethod.ITEMSTACK_SET_TAG.run(nmsStack, cachedCompound);
|
||||
bukkitItem = originalSrcStack;
|
||||
} else {
|
||||
Object stack = ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, bukkitItem);
|
||||
ReflectionMethod.ITEMSTACK_SET_TAG.run(stack, cachedCompound);
|
||||
bukkitItem = (ItemStack) ReflectionMethod.ITEMSTACK_BUKKITMIRROR.run(null, stack);
|
||||
originalSrcStack.setItemMeta(bukkitItem.getItemMeta());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all custom (non-vanilla) NBT tags from the NBTItem.
|
||||
*/
|
||||
public void clearCustomNBT() {
|
||||
ItemMeta meta = bukkitItem.getItemMeta();
|
||||
NBTReflectionUtil.getUnhandledNBTTags(meta).clear();
|
||||
bukkitItem.setItemMeta(meta);
|
||||
}
|
||||
@Override
|
||||
protected void setClosed() {
|
||||
this.closed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The modified ItemStack
|
||||
*/
|
||||
public ItemStack getItem() {
|
||||
return bukkitItem;
|
||||
}
|
||||
@Override
|
||||
protected boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
protected void setItem(ItemStack item) {
|
||||
bukkitItem = item;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void setCompound(Object compound) {
|
||||
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);
|
||||
ReflectionMethod.ITEMSTACK_SET_TAG.run(nmsStack, compound);
|
||||
} else {
|
||||
Object stack = ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, bukkitItem);
|
||||
ReflectionMethod.ITEMSTACK_SET_TAG.run(stack, compound);
|
||||
bukkitItem = (ItemStack) ReflectionMethod.ITEMSTACK_BUKKITMIRROR.run(null, stack);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This may return true even when the NBT is empty.
|
||||
*
|
||||
* @return Does the ItemStack have a NBTCompound.
|
||||
*/
|
||||
public boolean hasNBTData() {
|
||||
return getCompound() != null;
|
||||
}
|
||||
/**
|
||||
* Apply stored NBT tags to the provided ItemStack.
|
||||
* <p>
|
||||
* Note: This will completely override current item's {@link ItemMeta}. If you
|
||||
* still want to keep the original item's NBT tags, see
|
||||
* {@link #mergeNBT(ItemStack)} and {@link #mergeCustomNBT(ItemStack)}.
|
||||
*
|
||||
* @param item ItemStack that should get the new NBT data
|
||||
*/
|
||||
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());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that converts {@link ItemStack} to {@link NBTContainer} with
|
||||
* all it's data like Material, Damage, Amount and Tags.
|
||||
*
|
||||
* @param item
|
||||
* @return Standalone {@link NBTContainer} with the Item's data
|
||||
*/
|
||||
public static NBTContainer convertItemtoNBT(ItemStack item) {
|
||||
return NBTReflectionUtil.convertNMSItemtoNBTCompound(ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, item));
|
||||
}
|
||||
/**
|
||||
* Merge all NBT tags to the provided ItemStack.
|
||||
*
|
||||
* @param item ItemStack that should get the new NBT data
|
||||
*/
|
||||
public void mergeNBT(ItemStack item) {
|
||||
NBTItem nbti = new NBTItem(item);
|
||||
nbti.mergeCompound(this);
|
||||
item.setItemMeta(nbti.getItem().getItemMeta());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to do the inverse to "convertItemtoNBT". Creates an
|
||||
* {@link ItemStack} using the {@link NBTCompound}
|
||||
*
|
||||
* @param comp
|
||||
* @return ItemStack using the {@link NBTCompound}'s data
|
||||
*/
|
||||
public static ItemStack convertNBTtoItem(NBTCompound comp) {
|
||||
return (ItemStack) ReflectionMethod.ITEMSTACK_BUKKITMIRROR.run(null,
|
||||
NBTReflectionUtil.convertNBTCompoundtoNMSItem(comp));
|
||||
}
|
||||
/**
|
||||
* Merge only custom (non-vanilla) NBT tags to the provided ItemStack.
|
||||
*
|
||||
* @param item ItemStack that should get the new NBT data
|
||||
*/
|
||||
public void mergeCustomNBT(ItemStack item) {
|
||||
if (item == null || item.getType() == Material.AIR) {
|
||||
throw new NullPointerException("ItemStack can't be null/Air!");
|
||||
}
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
NBTReflectionUtil.getUnhandledNBTTags(meta)
|
||||
.putAll(NBTReflectionUtil.getUnhandledNBTTags(bukkitItem.getItemMeta()));
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveCompound() {
|
||||
if(directApply) {
|
||||
applyNBT(originalSrcStack);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* True, if the item has any tags now known for this item type.
|
||||
*
|
||||
* @return true when custom tags are present
|
||||
*/
|
||||
public boolean hasCustomNbtData() {
|
||||
finalizeChanges();
|
||||
ItemMeta meta = bukkitItem.getItemMeta();
|
||||
return !NBTReflectionUtil.getUnhandledNBTTags(meta).isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all custom (non-vanilla) NBT tags from the NBTItem.
|
||||
*/
|
||||
public void clearCustomNBT() {
|
||||
finalizeChanges();
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the item has NBT data.
|
||||
*
|
||||
* @return Does the ItemStack have a NBTCompound.
|
||||
*/
|
||||
public boolean hasNBTData() {
|
||||
return getCompound() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives save access to the {@link ItemMeta} of the internal {@link ItemStack}.
|
||||
* Supported operations while inside this scope: - any get/set method of
|
||||
* {@link ItemMeta} - any getter on {@link NBTItem}
|
||||
*
|
||||
* All changes made to the {@link NBTItem} during this scope will be reverted at
|
||||
* the end.
|
||||
*
|
||||
* @param handler
|
||||
*/
|
||||
public void modifyMeta(BiConsumer<ReadableNBT, ItemMeta> handler) {
|
||||
finalizeChanges();
|
||||
ItemMeta meta = bukkitItem.getItemMeta();
|
||||
handler.accept(new NBTContainer(getResolvedObject()).setReadOnly(true), meta);
|
||||
bukkitItem.setItemMeta(meta);
|
||||
updateCachedCompound();
|
||||
if (directApply) {
|
||||
applyNBT(originalSrcStack);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives save access to the {@link ItemMeta} of the internal {@link ItemStack}.
|
||||
* Supported operations while inside this scope: - any get/set method of
|
||||
* {@link ItemMeta} - any getter on {@link NBTItem}
|
||||
*
|
||||
* All changes made to the {@link NBTItem} during this scope will be reverted at
|
||||
* the end.
|
||||
*
|
||||
* @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(new NBTContainer(getResolvedObject()).setReadOnly(true), meta);
|
||||
bukkitItem.setItemMeta(meta);
|
||||
updateCachedCompound();
|
||||
if (directApply) {
|
||||
applyNBT(originalSrcStack);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that converts {@link ItemStack} to {@link NBTContainer} with
|
||||
* all it's data like Material, Damage, Amount and Tags.
|
||||
*
|
||||
* @param item
|
||||
* @return Standalone {@link NBTContainer} with the Item's data
|
||||
*/
|
||||
public static NBTContainer convertItemtoNBT(ItemStack item) {
|
||||
return NBTReflectionUtil.convertNMSItemtoNBTCompound(ReflectionMethod.ITEMSTACK_NMSCOPY.run(null, item));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to do the inverse of "convertItemtoNBT". Creates an
|
||||
* {@link ItemStack} using the {@link NBTCompound}
|
||||
*
|
||||
* @param comp
|
||||
* @return ItemStack using the {@link NBTCompound}'s data
|
||||
*/
|
||||
@Nullable
|
||||
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 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
|
||||
*/
|
||||
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.).
|
||||
*
|
||||
* Will return null for invalid data. Empty slots in the array are filled with
|
||||
* AIR Stacks!
|
||||
*
|
||||
* @param comp
|
||||
* @return ItemStack[] using the {@link NBTCompound}'s data
|
||||
*/
|
||||
@Nullable
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,7 +7,9 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBTList;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
@@ -18,412 +20,455 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class NBTList<T> implements List<T> {
|
||||
public abstract class NBTList<T> implements List<T>, ReadWriteNBTList<T> {
|
||||
|
||||
private String listName;
|
||||
private NBTCompound parent;
|
||||
private NBTType type;
|
||||
protected Object listObject;
|
||||
private String listName;
|
||||
private NBTCompound parent;
|
||||
private NBTType type;
|
||||
protected Object listObject;
|
||||
|
||||
protected NBTList(NBTCompound owner, String name, NBTType type, Object list) {
|
||||
parent = owner;
|
||||
listName = name;
|
||||
this.type = type;
|
||||
this.listObject = list;
|
||||
}
|
||||
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 Name of this list-compound
|
||||
*/
|
||||
public String getName() {
|
||||
return listName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Compound's parent Object
|
||||
*/
|
||||
public NBTCompound getParent() {
|
||||
return parent;
|
||||
}
|
||||
/**
|
||||
* @return The Compound's parent Object
|
||||
*/
|
||||
public NBTCompound getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
protected void save() {
|
||||
parent.set(listName, listObject);
|
||||
}
|
||||
private void validateClosed() {
|
||||
if (parent.isClosed()) {
|
||||
throw new NbtApiException("Tried using closed NBT data!");
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Object asTag(T object);
|
||||
private void validateWritable() {
|
||||
if (getParent().isReadOnly()) {
|
||||
throw new NbtApiException("Tried setting data in read only mode!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(T element) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
protected void save() {
|
||||
validateClosed();
|
||||
parent.set(listName, listObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, T element) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
protected abstract Object asTag(T object);
|
||||
|
||||
@Override
|
||||
public T set(int index, T element) {
|
||||
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 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();
|
||||
}
|
||||
}
|
||||
|
||||
public T remove(int i) {
|
||||
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 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();
|
||||
}
|
||||
}
|
||||
|
||||
public int size() {
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
return (int) ReflectionMethod.LIST_SIZE.run(listObject);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException(ex);
|
||||
} finally {
|
||||
parent.getReadLock().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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The type that this list contains
|
||||
*/
|
||||
public NBTType getType() {
|
||||
return type;
|
||||
}
|
||||
@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 boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
while (!isEmpty()) {
|
||||
remove(0);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @return The type that this list contains
|
||||
*/
|
||||
@Override
|
||||
public NBTType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
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 boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object o) {
|
||||
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 void clear() {
|
||||
while (!isEmpty()) {
|
||||
remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends T> c) {
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
int size = size();
|
||||
for (T ele : c) {
|
||||
add(ele);
|
||||
}
|
||||
return size != size();
|
||||
} finally {
|
||||
parent.getWriteLock().unlock();
|
||||
}
|
||||
}
|
||||
@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 boolean addAll(int index, Collection<? extends T> c) {
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
int size = size();
|
||||
for (T ele : c) {
|
||||
add(index++, ele);
|
||||
}
|
||||
return size != size();
|
||||
} finally {
|
||||
parent.getWriteLock().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 containsAll(Collection<?> c) {
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
for (Object ele : c) {
|
||||
if (!contains(ele))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} 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 int lastIndexOf(Object o) {
|
||||
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 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 removeAll(Collection<?> c) {
|
||||
try {
|
||||
parent.getWriteLock().lock();
|
||||
int size = size();
|
||||
for (Object obj : c) {
|
||||
remove(obj);
|
||||
}
|
||||
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 boolean retainAll(Collection<?> c) {
|
||||
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 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 remove(Object o) {
|
||||
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 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 Iterator<T> iterator() {
|
||||
return new Iterator<T>() {
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
||||
private int index = -1;
|
||||
@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 boolean hasNext() {
|
||||
return size() > index + 1;
|
||||
}
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new Iterator<T>() {
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
return get(++index);
|
||||
}
|
||||
private int index = -1;
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
NBTList.this.remove(index);
|
||||
index--;
|
||||
}
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return size() > index + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<T> listIterator() {
|
||||
return listIterator(0);
|
||||
}
|
||||
@Override
|
||||
public T next() {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
return get(++index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<T> listIterator(int startIndex) {
|
||||
final NBTList<T> list = this;
|
||||
return new ListIterator<T>() {
|
||||
@Override
|
||||
public void remove() {
|
||||
NBTList.this.remove(index);
|
||||
index--;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int index = startIndex - 1;
|
||||
@Override
|
||||
public ListIterator<T> listIterator() {
|
||||
return listIterator(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(T e) {
|
||||
list.add(index, e);
|
||||
}
|
||||
@Override
|
||||
public ListIterator<T> listIterator(int startIndex) {
|
||||
final NBTList<T> list = this;
|
||||
return new ListIterator<T>() {
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return size() > index + 1;
|
||||
}
|
||||
int index = startIndex - 1;
|
||||
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return index >= 0 && index <= size();
|
||||
}
|
||||
@Override
|
||||
public void add(T e) {
|
||||
list.add(index, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
return get(++index);
|
||||
}
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return size() > index + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextIndex() {
|
||||
return index + 1;
|
||||
}
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return index >= 0 && index <= size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T previous() {
|
||||
if (!hasPrevious())
|
||||
throw new NoSuchElementException("Id: " + (index - 1));
|
||||
return get(index--);
|
||||
}
|
||||
@Override
|
||||
public T next() {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
return get(++index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousIndex() {
|
||||
return index - 1;
|
||||
}
|
||||
@Override
|
||||
public int nextIndex() {
|
||||
return index + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
list.remove(index);
|
||||
index--;
|
||||
}
|
||||
@Override
|
||||
public T previous() {
|
||||
if (!hasPrevious())
|
||||
throw new NoSuchElementException("Id: " + (index - 1));
|
||||
return get(index--);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(T e) {
|
||||
list.set(index, e);
|
||||
}
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public int previousIndex() {
|
||||
return index - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
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();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void remove() {
|
||||
list.remove(index);
|
||||
index--;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <E> E[] toArray(E[] a) {
|
||||
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 void set(T e) {
|
||||
list.set(index, e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> subList(int fromIndex, int toIndex) {
|
||||
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 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();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
parent.getReadLock().lock();
|
||||
return listObject.toString();
|
||||
} 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,32 +11,51 @@ package de.tr7zw.changeme.nbtapi;
|
||||
*/
|
||||
public class NBTListCompound extends NBTCompound {
|
||||
|
||||
private NBTList<?> owner;
|
||||
private Object compound;
|
||||
private NBTList<?> owner;
|
||||
private Object compound;
|
||||
|
||||
protected NBTListCompound(NBTList<?> parent, Object obj) {
|
||||
super(null, null);
|
||||
owner = parent;
|
||||
compound = obj;
|
||||
}
|
||||
|
||||
public NBTList<?> getListParent() {
|
||||
return owner;
|
||||
}
|
||||
protected NBTListCompound(NBTList<?> parent, Object obj) {
|
||||
super(null, null);
|
||||
owner = parent;
|
||||
compound = obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
return compound;
|
||||
}
|
||||
public NBTList<?> getListParent() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setCompound(Object compound) {
|
||||
this.compound = compound;
|
||||
}
|
||||
@Override
|
||||
protected boolean isClosed() {
|
||||
return owner.getParent().isClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveCompound() {
|
||||
owner.save();
|
||||
}
|
||||
@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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,32 +14,32 @@ 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);
|
||||
}
|
||||
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) {
|
||||
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
|
||||
}
|
||||
}
|
||||
@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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+19
-18
@@ -8,24 +8,25 @@ import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
public class NBTPersistentDataContainer extends NBTCompound {
|
||||
|
||||
private final PersistentDataContainer container;
|
||||
|
||||
protected NBTPersistentDataContainer(PersistentDataContainer container) {
|
||||
super(null, null);
|
||||
this.container = container;
|
||||
}
|
||||
private final PersistentDataContainer container;
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
return ReflectionMethod.CRAFT_PERSISTENT_DATA_CONTAINER_TO_TAG.run(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);
|
||||
}
|
||||
|
||||
@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
@@ -14,29 +14,29 @@ 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);
|
||||
}
|
||||
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
|
||||
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) {
|
||||
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
|
||||
}
|
||||
}
|
||||
@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) {
|
||||
throw new NbtApiException("Error while wrapping the Object " + object + " to it's NMS object!", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
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
|
||||
@@ -18,47 +17,95 @@ import de.tr7zw.changeme.nbtapi.utils.annotations.CheckUtil;
|
||||
*/
|
||||
public class NBTTileEntity extends NBTCompound {
|
||||
|
||||
private final BlockState tile;
|
||||
private final BlockState tile;
|
||||
private final boolean readonly;
|
||||
private final Object compound;
|
||||
private boolean closed = false;
|
||||
|
||||
/**
|
||||
* @param tile BlockState from any TileEntity
|
||||
*/
|
||||
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.tile = tile;
|
||||
}
|
||||
/**
|
||||
* @param tile BlockState from any TileEntity
|
||||
* @param readonly Readonly makes a copy at init, only reading from that copy
|
||||
*/
|
||||
public 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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCompound() {
|
||||
return NBTReflectionUtil.getTileEntityNBTTagCompound(tile);
|
||||
}
|
||||
/**
|
||||
* @param tile BlockState from any TileEntity
|
||||
*/
|
||||
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 setCompound(Object compound) {
|
||||
NBTReflectionUtil.setTileEntityNBTTagCompound(tile, compound);
|
||||
}
|
||||
@Override
|
||||
protected void setClosed() {
|
||||
this.closed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the NBTCompound used by spigots PersistentDataAPI. This method is only
|
||||
* available for 1.14+!
|
||||
*
|
||||
* @return NBTCompound containing the data of the PersistentDataAPI
|
||||
*/
|
||||
@AvailableSince(version = MinecraftVersion.MC1_14_R1)
|
||||
public NBTCompound getPersistentDataContainer() {
|
||||
FAUtil.check(this::getPersistentDataContainer, CheckUtil::isAvaliable);
|
||||
if (hasKey("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");
|
||||
}
|
||||
}
|
||||
@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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the NBTCompound used by spigots PersistentDataAPI. This method is only
|
||||
* available for 1.14+!
|
||||
*
|
||||
* @return NBTCompound containing the data of the PersistentDataAPI
|
||||
*/
|
||||
public NBTCompound getPersistentDataContainer() {
|
||||
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,41 +8,31 @@ 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);
|
||||
NBTTagEnd(0), NBTTagByte(1), NBTTagShort(2), NBTTagInt(3), NBTTagLong(4), NBTTagFloat(5), NBTTagDouble(6),
|
||||
NBTTagByteArray(7), NBTTagString(8), NBTTagList(9), NBTTagCompound(10), NBTTagIntArray(11), NBTTagLongArray(12);
|
||||
|
||||
NBTType(int i) {
|
||||
id = i;
|
||||
}
|
||||
NBTType(int i) {
|
||||
id = i;
|
||||
}
|
||||
|
||||
private final int id;
|
||||
private final int id;
|
||||
|
||||
/**
|
||||
* @return Id used by Minecraft internally
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* @return Id used by Minecraft internally
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id Internal Minecraft id
|
||||
* @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;
|
||||
}
|
||||
/**
|
||||
* @param id Internal Minecraft id
|
||||
* @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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.UUID;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.UUIDUtil;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Integer implementation for NBTLists
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package de.tr7zw.changeme.nbtapi;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
|
||||
/**
|
||||
* A generic {@link RuntimeException} that can be thrown by most methods in the
|
||||
* NBTAPI.
|
||||
@@ -9,48 +11,68 @@ package de.tr7zw.changeme.nbtapi;
|
||||
*/
|
||||
public class NbtApiException extends RuntimeException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -993309714559452334L;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -993309714559452334L;
|
||||
/**
|
||||
* Keep track of the plugin selfcheck. Null = not
|
||||
* checked(silentquickstart/shaded) true = selfcheck failed false = everything
|
||||
* should be fine, but apparently wasn't?
|
||||
*/
|
||||
public static Boolean confirmedBroken = null;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public NbtApiException() {
|
||||
super();
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public NbtApiException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message
|
||||
* @param cause
|
||||
* @param enableSuppression
|
||||
* @param writableStackTrace
|
||||
*/
|
||||
public NbtApiException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
/**
|
||||
* @param message
|
||||
* @param cause
|
||||
* @param enableSuppression
|
||||
* @param writableStackTrace
|
||||
*/
|
||||
public NbtApiException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(generateMessage(message), cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message
|
||||
* @param cause
|
||||
*/
|
||||
public NbtApiException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
/**
|
||||
* @param message
|
||||
* @param cause
|
||||
*/
|
||||
public NbtApiException(String message, Throwable cause) {
|
||||
super(generateMessage(message), cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message
|
||||
*/
|
||||
public NbtApiException(String message) {
|
||||
super(message);
|
||||
}
|
||||
/**
|
||||
* @param message
|
||||
*/
|
||||
public NbtApiException(String message) {
|
||||
super(generateMessage(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cause
|
||||
*/
|
||||
public NbtApiException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
/**
|
||||
* @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 "[?][" + MinecraftVersion.getNBTAPIVersion() + "]" + message;
|
||||
} else if (confirmedBroken == false) {
|
||||
return "[Selfchecked][" + MinecraftVersion.getNBTAPIVersion() + "]" + message;
|
||||
}
|
||||
|
||||
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,89 @@
|
||||
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,15 @@
|
||||
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);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package de.tr7zw.changeme.nbtapi.iface;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTItem;
|
||||
|
||||
public interface ReadWriteItemNBT extends ReadWriteNBT, ReadableItemNBT {
|
||||
|
||||
/**
|
||||
* True, if the item has any tags now known for this item type.
|
||||
*
|
||||
* @return true when custom tags are present
|
||||
*/
|
||||
public boolean hasCustomNbtData();
|
||||
|
||||
/**
|
||||
* Remove all custom (non-vanilla) NBT tags from the NBTItem.
|
||||
*/
|
||||
public void clearCustomNBT();
|
||||
|
||||
/**
|
||||
* Gives save access to the {@link ItemMeta} of the internal {@link ItemStack}.
|
||||
* Supported operations while inside this scope: - any get/set method of
|
||||
* {@link ItemMeta} - any getter on {@link NBTItem}
|
||||
*
|
||||
* All changes made to the {@link NBTItem} during this scope will be reverted at
|
||||
* the end.
|
||||
*
|
||||
* @param handler
|
||||
*/
|
||||
public void modifyMeta(BiConsumer<ReadableNBT, ItemMeta> handler);
|
||||
|
||||
/**
|
||||
* Gives save access to the {@link ItemMeta} of the internal {@link ItemStack}.
|
||||
* Supported operations while inside this scope: - any get/set method of
|
||||
* {@link ItemMeta} - any getter on {@link NBTItem}
|
||||
*
|
||||
* All changes made to the {@link NBTItem} during this scope will be reverted at
|
||||
* the end.
|
||||
*
|
||||
* @param handler
|
||||
*/
|
||||
public <T extends ItemMeta> void modifyMeta(Class<T> type, BiConsumer<ReadableNBT, T> handler);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
package de.tr7zw.changeme.nbtapi.iface;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public interface ReadWriteNBT extends ReadableNBT {
|
||||
|
||||
/**
|
||||
* Merges all data from comp into this compound. This is done in one action, so
|
||||
* it also works with Tiles/Entities
|
||||
*
|
||||
* @param comp
|
||||
*/
|
||||
void mergeCompound(ReadableNBT comp);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
void setString(String key, String value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
void setInteger(String key, Integer value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
void setDouble(String key, Double value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
void setByte(String key, Byte value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
void setShort(String key, Short value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
void setLong(String key, Long value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
void setFloat(String key, Float value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
void setByteArray(String key, byte[] value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
void setIntArray(String key, int[] value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* Requires 1.16+
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
void setLongArray(String key, long[] value);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
void setBoolean(String key, Boolean value);
|
||||
|
||||
/**
|
||||
* Save an ItemStack as a compound under a given key
|
||||
*
|
||||
* @param key
|
||||
* @param item
|
||||
*/
|
||||
void setItemStack(String key, ItemStack item);
|
||||
|
||||
/**
|
||||
* Save an ItemStack Array as a compound under a given key
|
||||
*
|
||||
* @param key
|
||||
* @param items
|
||||
*/
|
||||
void setItemStackArray(String key, ItemStack[] items);
|
||||
|
||||
/**
|
||||
* Setter
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
void setUUID(String key, UUID value);
|
||||
|
||||
/**
|
||||
* @param key Deletes the given Key
|
||||
*/
|
||||
void removeKey(String key);
|
||||
|
||||
/**
|
||||
* The same as addCompound, just with a name that better reflects what it does
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
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
|
||||
* as value will call removeKey(key) instead.
|
||||
*
|
||||
* @param <E>
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
<E extends Enum<?>> void setEnum(String key, E value);
|
||||
|
||||
@Override
|
||||
ReadWriteNBTList<String> getStringList(String name);
|
||||
|
||||
@Override
|
||||
ReadWriteNBTList<Integer> getIntegerList(String name);
|
||||
|
||||
@Override
|
||||
ReadWriteNBTList<int[]> getIntArrayList(String name);
|
||||
|
||||
@Override
|
||||
ReadWriteNBTList<UUID> getUUIDList(String name);
|
||||
|
||||
@Override
|
||||
ReadWriteNBTList<Float> getFloatList(String name);
|
||||
|
||||
@Override
|
||||
ReadWriteNBTList<Double> getDoubleList(String name);
|
||||
|
||||
@Override
|
||||
ReadWriteNBTList<Long> getLongList(String name);
|
||||
|
||||
@Override
|
||||
ReadWriteNBTCompoundList getCompoundList(String name);
|
||||
|
||||
/**
|
||||
* Remove all keys from this compound
|
||||
*/
|
||||
void clearNBT();
|
||||
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package de.tr7zw.changeme.nbtapi.iface;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public interface ReadWriteNBTCompoundList extends ReadableNBTList<ReadWriteNBT> {
|
||||
|
||||
/**
|
||||
* Adds a new compound tag to the current compound tag
|
||||
*
|
||||
* @return A new instance of the class.
|
||||
*/
|
||||
ReadWriteNBT addCompound();
|
||||
|
||||
/**
|
||||
* Removes the element at the specified position in this list
|
||||
*
|
||||
* @param i The index of the element to remove.
|
||||
* @return A new instance of the class.
|
||||
*/
|
||||
ReadWriteNBT remove(int i);
|
||||
|
||||
/**
|
||||
* Clears the contents of the list
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Removes all elements of this list that satisfy the given predicate
|
||||
*
|
||||
* @param pred The predicate to use to test elements.
|
||||
* @return A boolean value.
|
||||
*/
|
||||
boolean removeIf(Predicate<? super ReadWriteNBT> pred);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package de.tr7zw.changeme.nbtapi.iface;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.ListIterator;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public interface ReadWriteNBTList<T> extends ReadableNBTList<T> {
|
||||
|
||||
/**
|
||||
* Adds the specified element to this set if it is not already present.
|
||||
*
|
||||
* @param element The element to be added to the list.
|
||||
* @return A boolean value.
|
||||
*/
|
||||
boolean add(T element);
|
||||
|
||||
/**
|
||||
* Adds the specified element at the specified position in this list.
|
||||
*
|
||||
* @param index The index at which the specified element is to be inserted
|
||||
* @param element The element to be added to the list.
|
||||
*/
|
||||
void add(int index, T element);
|
||||
|
||||
/**
|
||||
* Replaces the element at the specified position in this list with the
|
||||
* specified element.
|
||||
*
|
||||
* @param index The index of the element to replace
|
||||
* @param element The element to be stored at the specified position
|
||||
* @return The element that was previously at the specified position.
|
||||
*/
|
||||
T set(int index, T element);
|
||||
|
||||
/**
|
||||
* Remove the element at index i and return it.
|
||||
*
|
||||
* @param i the index of the element to be removed
|
||||
* @return The element that was removed.
|
||||
*/
|
||||
T remove(int i);
|
||||
|
||||
/**
|
||||
* Clears the contents of the list
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Adds all of the elements in the specified collection to this collection.
|
||||
*
|
||||
* @param c The collection to be added to the list.
|
||||
* @return A boolean value.
|
||||
*/
|
||||
boolean addAll(Collection<? extends T> c);
|
||||
|
||||
/**
|
||||
* Inserts all of the elements in the specified collection into this list,
|
||||
* starting at the specified position.
|
||||
*
|
||||
* @param index The index at which the elements of the specified collection are
|
||||
* to be inserted.
|
||||
* @param c The collection to be added to the list.
|
||||
* @return A boolean value.
|
||||
*/
|
||||
boolean addAll(int index, Collection<? extends T> c);
|
||||
|
||||
/**
|
||||
* Removes from this collection all of its elements that are contained in the
|
||||
* specified collection
|
||||
*
|
||||
* @param c The collection to be removed from this list.
|
||||
* @return A boolean value.
|
||||
*/
|
||||
boolean removeAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Removes all of this collection's elements that are not contained in the
|
||||
* specified collection.
|
||||
*
|
||||
* @param c The collection to be retained in this list
|
||||
* @return A boolean value.
|
||||
*/
|
||||
boolean retainAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* "Remove all elements from the list that match the given predicate."
|
||||
*
|
||||
* The Predicate interface is a functional interface that takes a single
|
||||
* argument and returns a boolean
|
||||
*
|
||||
* @param pred The predicate to apply to each element to determine if it should
|
||||
* be removed.
|
||||
* @return A boolean value.
|
||||
*/
|
||||
boolean removeIf(Predicate<? super T> pred);
|
||||
|
||||
/**
|
||||
* Removes the first occurrence of the specified element from this list, if it
|
||||
* is present.
|
||||
*
|
||||
* @param o The object to be removed from the list.
|
||||
* @return A boolean value.
|
||||
*/
|
||||
boolean remove(Object o);
|
||||
|
||||
/**
|
||||
* Returns a list iterator over the elements in this list (in proper sequence),
|
||||
* starting at the specified position in the list
|
||||
*
|
||||
* @param startIndex The index of the first element to be returned from the list
|
||||
* iterator (by a call to the next method).
|
||||
* @return A list iterator of the list starting at the specified index.
|
||||
*/
|
||||
ListIterator<T> listIterator(int startIndex);
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,352 @@
|
||||
package de.tr7zw.changeme.nbtapi.iface;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* This interface only exposes methods that get data without any changes to the
|
||||
* underlying object.
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public interface ReadableNBT {
|
||||
|
||||
/**
|
||||
* Given a key, return the value associated with that key.
|
||||
*
|
||||
* @param key The key to get the value for.
|
||||
* @return The value of the key.
|
||||
*/
|
||||
String getString(String key);
|
||||
|
||||
/**
|
||||
* Given a key, return the value associated with that key as an Integer, or 0 if
|
||||
* the key is not found.
|
||||
*
|
||||
* @param key The key to look up in the properties file.
|
||||
* @return The value of the key.
|
||||
*/
|
||||
Integer getInteger(String key);
|
||||
|
||||
/**
|
||||
* Returns the value associated with the given key as a double, or false of not
|
||||
* found.
|
||||
*
|
||||
* @param key The key of the preference to retrieve.
|
||||
* @return A double value
|
||||
*/
|
||||
Double getDouble(String key);
|
||||
|
||||
/**
|
||||
* Get the value of the given key as a byte, or 0 if the key is not found.
|
||||
*
|
||||
* @param key The key to get the value for.
|
||||
* @return A byte
|
||||
*/
|
||||
Byte getByte(String key);
|
||||
|
||||
/**
|
||||
* Returns the value of the key as a Short, or 0 if the key is not found.
|
||||
*
|
||||
* @param key The key of the value you want to get.
|
||||
* @return A short value
|
||||
*/
|
||||
Short getShort(String key);
|
||||
|
||||
/**
|
||||
* Returns the value associated with the given key as a Long, or 0 if the key is
|
||||
* not found.
|
||||
*
|
||||
* @param key The key of the value you want to get.
|
||||
* @return A Long object
|
||||
*/
|
||||
Long getLong(String key);
|
||||
|
||||
/**
|
||||
* Returns the value of the given key as a Float, or 0 if the key does not
|
||||
* exist.
|
||||
*
|
||||
* @param key The key of the preference to retrieve.
|
||||
* @return A float value
|
||||
*/
|
||||
Float getFloat(String key);
|
||||
|
||||
/**
|
||||
* Returns the value associated with the given key as a byte array, or null if
|
||||
* the key is not found.
|
||||
*
|
||||
* @param key The key to use to retrieve the value.
|
||||
* @return A byte array.
|
||||
*/
|
||||
@Nullable
|
||||
byte[] getByteArray(String key);
|
||||
|
||||
/**
|
||||
* Returns the value associated with the given key as an array of integers, or
|
||||
* null if the key does not exist.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @param key The key of the preference to retrieve.
|
||||
* @return A boolean value.
|
||||
*/
|
||||
Boolean getBoolean(String key);
|
||||
|
||||
/**
|
||||
* It returns an ItemStack associated with the given key, or null if the key
|
||||
* does not exist.
|
||||
*
|
||||
* @param key The key of the itemstack you want to get.
|
||||
* @return An ItemStack
|
||||
*/
|
||||
@Nullable
|
||||
ItemStack getItemStack(String key);
|
||||
|
||||
/**
|
||||
* Get an {@link ItemStack} array that was saved at the given key, or null if no
|
||||
* stored data was found
|
||||
*
|
||||
* @param key key
|
||||
* @return The stored {@link ItemStack} array, or null if stored data wasn't
|
||||
* found
|
||||
*/
|
||||
@Nullable
|
||||
ItemStack[] getItemStackArray(String key);
|
||||
|
||||
/**
|
||||
* Given a key, return the UUID of the key.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
Set<String> getKeys();
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The Compound instance or null
|
||||
*/
|
||||
@Nullable
|
||||
ReadableNBT getCompound(String name);
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved String List
|
||||
*/
|
||||
ReadableNBTList<String> getStringList(String name);
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved Integer List
|
||||
*/
|
||||
ReadableNBTList<Integer> getIntegerList(String name);
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved Integer List
|
||||
*/
|
||||
ReadableNBTList<int[]> getIntArrayList(String name);
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved Integer List
|
||||
*/
|
||||
ReadableNBTList<UUID> getUUIDList(String name);
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved Float List
|
||||
*/
|
||||
ReadableNBTList<Float> getFloatList(String name);
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved Double List
|
||||
*/
|
||||
ReadableNBTList<Double> getDoubleList(String name);
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved Long List
|
||||
*/
|
||||
ReadableNBTList<Long> getLongList(String name);
|
||||
|
||||
/**
|
||||
* Returns the type of the list, null if not a list
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
@Nullable
|
||||
NBTType getListType(String name);
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The retrieved Compound List
|
||||
*/
|
||||
ReadableNBTList<ReadWriteNBT> getCompoundList(String name);
|
||||
|
||||
/**
|
||||
* Returns the stored 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 key
|
||||
* @param defaultValue default non-null value
|
||||
* @param <T> value type
|
||||
* @return Stored or provided value
|
||||
*/
|
||||
<T> T getOrDefault(String key, T defaultValue);
|
||||
|
||||
/**
|
||||
* Returns the stored 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 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.
|
||||
*
|
||||
* @param <E>
|
||||
* @param key
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
@Nullable
|
||||
<E extends Enum<E>> E getEnum(String key, Class<E> type);
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return The type of the given stored key or null
|
||||
*/
|
||||
NBTType getType(String name);
|
||||
|
||||
/**
|
||||
* Write the content of this Compound into the provided stream.
|
||||
*
|
||||
* @param stream
|
||||
*/
|
||||
void writeCompound(OutputStream stream);
|
||||
|
||||
/**
|
||||
* @return The NBT as printable NBT-Json.
|
||||
*/
|
||||
String toString();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package de.tr7zw.changeme.nbtapi.iface;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTType;
|
||||
|
||||
public interface ReadableNBTList<T> extends Iterable<T> {
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Returns the number of elements in this list.
|
||||
*
|
||||
* @return The size of the list.
|
||||
*/
|
||||
int size();
|
||||
|
||||
/**
|
||||
* Returns the type of this tag
|
||||
*
|
||||
* @return The type of the tag.
|
||||
*/
|
||||
NBTType getType();
|
||||
|
||||
/**
|
||||
* Returns true if the list is empty, false otherwise.
|
||||
*
|
||||
* @return A boolean value.
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Returns true if this list contains the specified element.
|
||||
*
|
||||
* @param o The object to be searched for in the list.
|
||||
* @return A boolean value.
|
||||
*/
|
||||
boolean contains(Object o);
|
||||
|
||||
/**
|
||||
* Returns the index of the first occurrence of the specified element in this
|
||||
* list, or -1 if this list does not contain the element.
|
||||
*
|
||||
* @param o The object to search for.
|
||||
* @return The index of the first occurrence of the specified element in this
|
||||
* list, or -1 if this list does not contain the element.
|
||||
*/
|
||||
int indexOf(Object o);
|
||||
|
||||
/**
|
||||
* Returns true if this collection contains all of the elements in the specified
|
||||
* collection
|
||||
*
|
||||
* @param c The collection to be checked for containment in this list
|
||||
* @return A boolean value.
|
||||
*/
|
||||
boolean containsAll(Collection<?> c);
|
||||
|
||||
/**
|
||||
* Returns the index of the last occurrence of the specified element in this
|
||||
* list, or -1 if this list does not contain the element
|
||||
*
|
||||
* @param o The object to search for.
|
||||
* @return The index of the last occurrence of the specified element in this
|
||||
* list, or -1 if this list does not contain the element.
|
||||
*/
|
||||
int lastIndexOf(Object o);
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the elements in this list in proper
|
||||
* sequence (from first to last element).
|
||||
*
|
||||
* @return An array of objects.
|
||||
*/
|
||||
Object[] toArray();
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the elements in this list in proper
|
||||
* sequence (from first to last element).
|
||||
*
|
||||
* @param a The array into which the elements of the list are to be stored, if
|
||||
* it is big enough; otherwise, a new array of the same runtime type is
|
||||
* allocated for this purpose.
|
||||
* @return An array of the elements in the list.
|
||||
*/
|
||||
<E> E[] toArray(E[] a);
|
||||
|
||||
/**
|
||||
* Returns a view of the portion of this list between the specified fromIndex,
|
||||
* inclusive, and toIndex, exclusive
|
||||
*
|
||||
* @param fromIndex The starting index of the sublist (inclusive).
|
||||
* @param toIndex The index of the last element in the sublist.
|
||||
* @return A view of the specified range within this list.
|
||||
*/
|
||||
List<T> subList(int fromIndex, int toIndex);
|
||||
|
||||
/**
|
||||
* Create a new list containing all entries of this list.
|
||||
*
|
||||
* @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,388 +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) {
|
||||
System.out.println("[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,17 @@
|
||||
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!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,48 +7,56 @@ import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
/**
|
||||
* Helper class for 1.7 servers without Gson
|
||||
*
|
||||
* Please consider your own Gson/Jackson instance instead of the built in
|
||||
* methods.
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@Deprecated
|
||||
public class GsonWrapper {
|
||||
|
||||
/**
|
||||
* Private constructor
|
||||
*/
|
||||
private GsonWrapper() {
|
||||
/**
|
||||
* Private constructor
|
||||
*/
|
||||
private GsonWrapper() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static final Gson gson = new Gson();
|
||||
private static Gson gson = new Gson();
|
||||
|
||||
/**
|
||||
* Turns Objects into Json Strings
|
||||
*
|
||||
* @param obj
|
||||
* @return Json, representing the Object
|
||||
*/
|
||||
public static String getString(Object obj) {
|
||||
return gson.toJson(obj);
|
||||
}
|
||||
/**
|
||||
* Turns Objects into Json Strings
|
||||
*
|
||||
* @param obj
|
||||
* @return Json, representing the Object
|
||||
*/
|
||||
public static String getString(Object obj) {
|
||||
return gson.toJson(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an Object of the given type using the Json String
|
||||
*
|
||||
* @param json
|
||||
* @param type
|
||||
* @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;
|
||||
}
|
||||
public static void overwriteGsonInstance(Gson replacement) {
|
||||
gson = replacement;
|
||||
}
|
||||
|
||||
T obj = gson.fromJson(json, type);
|
||||
return type.cast(obj);
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Error while converting json to " + type.getName(), ex);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creates an Object of the given type using the Json String
|
||||
*
|
||||
* @param json
|
||||
* @param type
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,881 @@
|
||||
/*
|
||||
* This Metrics class was auto-generated and can be copied into your project if you are
|
||||
* not using a build tool like Gradle or Maven for dependency management.
|
||||
*
|
||||
* IMPORTANT: You are not allowed to modify this class, except changing the package.
|
||||
*
|
||||
* Disallowed modifications include but are not limited to:
|
||||
* - Remove the option for users to opt-out
|
||||
* - Change the frequency for data submission
|
||||
* - Obfuscate the code (every obfuscator should allow you to make an exception for specific files)
|
||||
* - Reformat the code (if you use a linter, add an exception)
|
||||
*
|
||||
* Violations will result in a ban of your plugin and account from bStats.
|
||||
*/
|
||||
package de.tr7zw.changeme.nbtapi.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class Metrics {
|
||||
|
||||
private final Plugin plugin;
|
||||
|
||||
private final MetricsBase metricsBase;
|
||||
|
||||
/**
|
||||
* Creates a new Metrics instance.
|
||||
*
|
||||
* @param plugin Your plugin instance.
|
||||
* @param serviceId The id of the service. It can be found at <a
|
||||
* href="https://bstats.org/what-is-my-plugin-id">What is my plugin id?</a>
|
||||
*/
|
||||
public Metrics(JavaPlugin plugin, int serviceId) {
|
||||
this.plugin = plugin;
|
||||
// Get the config file
|
||||
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
||||
File configFile = new File(bStatsFolder, "config.yml");
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
|
||||
if (!config.isSet("serverUuid")) {
|
||||
config.addDefault("enabled", true);
|
||||
config.addDefault("serverUuid", UUID.randomUUID().toString());
|
||||
config.addDefault("logFailedRequests", false);
|
||||
config.addDefault("logSentData", false);
|
||||
config.addDefault("logResponseStatusText", false);
|
||||
// Inform the server owners about bStats
|
||||
config
|
||||
.options()
|
||||
.header(
|
||||
"bStats (https://bStats.org) collects some basic information for plugin authors, like how\n"
|
||||
+ "many people use their plugin and their total player count. It's recommended to keep bStats\n"
|
||||
+ "enabled, but if you're not comfortable with this, you can turn this setting off. There is no\n"
|
||||
+ "performance penalty associated with having metrics enabled, and data sent to bStats is fully\n"
|
||||
+ "anonymous.")
|
||||
.copyDefaults(true);
|
||||
try {
|
||||
config.save(configFile);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
// Load the data
|
||||
boolean enabled = config.getBoolean("enabled", true);
|
||||
String serverUUID = config.getString("serverUuid");
|
||||
boolean logErrors = config.getBoolean("logFailedRequests", false);
|
||||
boolean logSentData = config.getBoolean("logSentData", false);
|
||||
boolean logResponseStatusText = config.getBoolean("logResponseStatusText", false);
|
||||
metricsBase =
|
||||
new MetricsBase(
|
||||
"bukkit",
|
||||
serverUUID,
|
||||
serviceId,
|
||||
enabled,
|
||||
this::appendPlatformData,
|
||||
this::appendServiceData,
|
||||
submitDataTask -> Bukkit.getScheduler().runTask(plugin, submitDataTask),
|
||||
plugin::isEnabled,
|
||||
(message, error) -> this.plugin.getLogger().log(Level.WARNING, message, error),
|
||||
(message) -> this.plugin.getLogger().log(Level.INFO, message),
|
||||
logErrors,
|
||||
logSentData,
|
||||
logResponseStatusText);
|
||||
}
|
||||
|
||||
/** Shuts down the underlying scheduler service. */
|
||||
public void shutdown() {
|
||||
metricsBase.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom chart.
|
||||
*
|
||||
* @param chart The chart to add.
|
||||
*/
|
||||
public void addCustomChart(CustomChart chart) {
|
||||
metricsBase.addCustomChart(chart);
|
||||
}
|
||||
|
||||
private void appendPlatformData(JsonObjectBuilder builder) {
|
||||
builder.appendField("playerAmount", getPlayerAmount());
|
||||
builder.appendField("onlineMode", Bukkit.getOnlineMode() ? 1 : 0);
|
||||
builder.appendField("bukkitVersion", Bukkit.getVersion());
|
||||
builder.appendField("bukkitName", Bukkit.getName());
|
||||
builder.appendField("javaVersion", System.getProperty("java.version"));
|
||||
builder.appendField("osName", System.getProperty("os.name"));
|
||||
builder.appendField("osArch", System.getProperty("os.arch"));
|
||||
builder.appendField("osVersion", System.getProperty("os.version"));
|
||||
builder.appendField("coreCount", Runtime.getRuntime().availableProcessors());
|
||||
}
|
||||
|
||||
private void appendServiceData(JsonObjectBuilder builder) {
|
||||
builder.appendField("pluginVersion", plugin.getDescription().getVersion());
|
||||
}
|
||||
|
||||
private int getPlayerAmount() {
|
||||
try {
|
||||
// Around MC 1.8 the return type was changed from an array to a collection,
|
||||
// This fixes java.lang.NoSuchMethodError:
|
||||
// org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
|
||||
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
|
||||
return onlinePlayersMethod.getReturnType().equals(Collection.class)
|
||||
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
|
||||
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
|
||||
} catch (Exception e) {
|
||||
// Just use the new method if the reflection failed
|
||||
return Bukkit.getOnlinePlayers().size();
|
||||
}
|
||||
}
|
||||
|
||||
public static class MetricsBase {
|
||||
|
||||
/** The version of the Metrics class. */
|
||||
public static final String METRICS_VERSION = "3.0.2";
|
||||
|
||||
private static final String REPORT_URL = "https://bStats.org/api/v2/data/%s";
|
||||
|
||||
private final ScheduledExecutorService scheduler;
|
||||
|
||||
private final String platform;
|
||||
|
||||
private final String serverUuid;
|
||||
|
||||
private final int serviceId;
|
||||
|
||||
private final Consumer<JsonObjectBuilder> appendPlatformDataConsumer;
|
||||
|
||||
private final Consumer<JsonObjectBuilder> appendServiceDataConsumer;
|
||||
|
||||
private final Consumer<Runnable> submitTaskConsumer;
|
||||
|
||||
private final Supplier<Boolean> checkServiceEnabledSupplier;
|
||||
|
||||
private final BiConsumer<String, Throwable> errorLogger;
|
||||
|
||||
private final Consumer<String> infoLogger;
|
||||
|
||||
private final boolean logErrors;
|
||||
|
||||
private final boolean logSentData;
|
||||
|
||||
private final boolean logResponseStatusText;
|
||||
|
||||
private final Set<CustomChart> customCharts = new HashSet<>();
|
||||
|
||||
private final boolean enabled;
|
||||
|
||||
/**
|
||||
* Creates a new MetricsBase class instance.
|
||||
*
|
||||
* @param platform The platform of the service.
|
||||
* @param serviceId The id of the service.
|
||||
* @param serverUuid The server uuid.
|
||||
* @param enabled Whether or not data sending is enabled.
|
||||
* @param appendPlatformDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
|
||||
* appends all platform-specific data.
|
||||
* @param appendServiceDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
|
||||
* appends all service-specific data.
|
||||
* @param submitTaskConsumer A consumer that takes a runnable with the submit task. This can be
|
||||
* used to delegate the data collection to a another thread to prevent errors caused by
|
||||
* concurrency. Can be {@code null}.
|
||||
* @param checkServiceEnabledSupplier A supplier to check if the service is still enabled.
|
||||
* @param errorLogger A consumer that accepts log message and an error.
|
||||
* @param infoLogger A consumer that accepts info log messages.
|
||||
* @param logErrors Whether or not errors should be logged.
|
||||
* @param logSentData Whether or not the sent data should be logged.
|
||||
* @param logResponseStatusText Whether or not the response status text should be logged.
|
||||
*/
|
||||
public MetricsBase(
|
||||
String platform,
|
||||
String serverUuid,
|
||||
int serviceId,
|
||||
boolean enabled,
|
||||
Consumer<JsonObjectBuilder> appendPlatformDataConsumer,
|
||||
Consumer<JsonObjectBuilder> appendServiceDataConsumer,
|
||||
Consumer<Runnable> submitTaskConsumer,
|
||||
Supplier<Boolean> checkServiceEnabledSupplier,
|
||||
BiConsumer<String, Throwable> errorLogger,
|
||||
Consumer<String> infoLogger,
|
||||
boolean logErrors,
|
||||
boolean logSentData,
|
||||
boolean logResponseStatusText) {
|
||||
ScheduledThreadPoolExecutor scheduler =
|
||||
new ScheduledThreadPoolExecutor(1, task -> new Thread(task, "bStats-Metrics"));
|
||||
// We want delayed tasks (non-periodic) that will execute in the future to be
|
||||
// cancelled when the scheduler is shutdown.
|
||||
// Otherwise, we risk preventing the server from shutting down even when
|
||||
// MetricsBase#shutdown() is called
|
||||
scheduler.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
|
||||
this.scheduler = scheduler;
|
||||
this.platform = platform;
|
||||
this.serverUuid = serverUuid;
|
||||
this.serviceId = serviceId;
|
||||
this.enabled = enabled;
|
||||
this.appendPlatformDataConsumer = appendPlatformDataConsumer;
|
||||
this.appendServiceDataConsumer = appendServiceDataConsumer;
|
||||
this.submitTaskConsumer = submitTaskConsumer;
|
||||
this.checkServiceEnabledSupplier = checkServiceEnabledSupplier;
|
||||
this.errorLogger = errorLogger;
|
||||
this.infoLogger = infoLogger;
|
||||
this.logErrors = logErrors;
|
||||
this.logSentData = logSentData;
|
||||
this.logResponseStatusText = logResponseStatusText;
|
||||
checkRelocation();
|
||||
if (enabled) {
|
||||
// WARNING: Removing the option to opt-out will get your plugin banned from
|
||||
// bStats
|
||||
startSubmitting();
|
||||
}
|
||||
}
|
||||
|
||||
public void addCustomChart(CustomChart chart) {
|
||||
this.customCharts.add(chart);
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
scheduler.shutdown();
|
||||
}
|
||||
|
||||
private void startSubmitting() {
|
||||
final Runnable submitTask =
|
||||
() -> {
|
||||
if (!enabled || !checkServiceEnabledSupplier.get()) {
|
||||
// Submitting data or service is disabled
|
||||
scheduler.shutdown();
|
||||
return;
|
||||
}
|
||||
if (submitTaskConsumer != null) {
|
||||
submitTaskConsumer.accept(this::submitData);
|
||||
} else {
|
||||
this.submitData();
|
||||
}
|
||||
};
|
||||
// Many servers tend to restart at a fixed time at xx:00 which causes an uneven
|
||||
// distribution of requests on the
|
||||
// bStats backend. To circumvent this problem, we introduce some randomness into
|
||||
// the initial and second delay.
|
||||
// WARNING: You must not modify and part of this Metrics class, including the
|
||||
// submit delay or frequency!
|
||||
// WARNING: Modifying this code will get your plugin banned on bStats. Just
|
||||
// don't do it!
|
||||
long initialDelay = (long) (1000 * 60 * (3 + Math.random() * 3));
|
||||
long secondDelay = (long) (1000 * 60 * (Math.random() * 30));
|
||||
scheduler.schedule(submitTask, initialDelay, TimeUnit.MILLISECONDS);
|
||||
scheduler.scheduleAtFixedRate(
|
||||
submitTask, initialDelay + secondDelay, 1000 * 60 * 30, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void submitData() {
|
||||
final JsonObjectBuilder baseJsonBuilder = new JsonObjectBuilder();
|
||||
appendPlatformDataConsumer.accept(baseJsonBuilder);
|
||||
final JsonObjectBuilder serviceJsonBuilder = new JsonObjectBuilder();
|
||||
appendServiceDataConsumer.accept(serviceJsonBuilder);
|
||||
JsonObjectBuilder.JsonObject[] chartData =
|
||||
customCharts.stream()
|
||||
.map(customChart -> customChart.getRequestJsonObject(errorLogger, logErrors))
|
||||
.filter(Objects::nonNull)
|
||||
.toArray(JsonObjectBuilder.JsonObject[]::new);
|
||||
serviceJsonBuilder.appendField("id", serviceId);
|
||||
serviceJsonBuilder.appendField("customCharts", chartData);
|
||||
baseJsonBuilder.appendField("service", serviceJsonBuilder.build());
|
||||
baseJsonBuilder.appendField("serverUUID", serverUuid);
|
||||
baseJsonBuilder.appendField("metricsVersion", METRICS_VERSION);
|
||||
JsonObjectBuilder.JsonObject data = baseJsonBuilder.build();
|
||||
scheduler.execute(
|
||||
() -> {
|
||||
try {
|
||||
// Send the data
|
||||
sendData(data);
|
||||
} catch (Exception e) {
|
||||
// Something went wrong! :(
|
||||
if (logErrors) {
|
||||
errorLogger.accept("Could not submit bStats metrics data", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void sendData(JsonObjectBuilder.JsonObject data) throws Exception {
|
||||
if (logSentData) {
|
||||
infoLogger.accept("Sent bStats metrics data: " + data.toString());
|
||||
}
|
||||
String url = String.format(REPORT_URL, platform);
|
||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
|
||||
// Compress the data to save bandwidth
|
||||
byte[] compressedData = compress(data.toString());
|
||||
connection.setRequestMethod("POST");
|
||||
connection.addRequestProperty("Accept", "application/json");
|
||||
connection.addRequestProperty("Connection", "close");
|
||||
connection.addRequestProperty("Content-Encoding", "gzip");
|
||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
connection.setRequestProperty("User-Agent", "Metrics-Service/1");
|
||||
connection.setDoOutput(true);
|
||||
try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
|
||||
outputStream.write(compressedData);
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
try (BufferedReader bufferedReader =
|
||||
new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
builder.append(line);
|
||||
}
|
||||
}
|
||||
if (logResponseStatusText) {
|
||||
infoLogger.accept("Sent data to bStats and received response: " + builder);
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks that the class was properly relocated. */
|
||||
private void checkRelocation() {
|
||||
// You can use the property to disable the check in your test environment
|
||||
if (System.getProperty("bstats.relocatecheck") == null
|
||||
|| !System.getProperty("bstats.relocatecheck").equals("false")) {
|
||||
// Maven's Relocate is clever and changes strings, too. So we have to use this
|
||||
// little "trick" ... :D
|
||||
final String defaultPackage =
|
||||
new String(new byte[] {'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's'});
|
||||
final String examplePackage =
|
||||
new String(new byte[] {'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
||||
// We want to make sure no one just copy & pastes the example and uses the wrong
|
||||
// package names
|
||||
if (MetricsBase.class.getPackage().getName().startsWith(defaultPackage)
|
||||
|| MetricsBase.class.getPackage().getName().startsWith(examplePackage)) {
|
||||
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gzips the given string.
|
||||
*
|
||||
* @param str The string to gzip.
|
||||
* @return The gzipped string.
|
||||
*/
|
||||
private static byte[] compress(final String str) throws IOException {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream)) {
|
||||
gzip.write(str.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
public static class SimplePie extends CustomChart {
|
||||
|
||||
private final Callable<String> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimplePie(String chartId, Callable<String> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
String value = callable.call();
|
||||
if (value == null || value.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("value", value).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class MultiLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
// Skip this invalid
|
||||
continue;
|
||||
}
|
||||
allSkipped = false;
|
||||
valuesBuilder.appendField(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class AdvancedPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
// Skip this invalid
|
||||
continue;
|
||||
}
|
||||
allSkipped = false;
|
||||
valuesBuilder.appendField(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class SimpleBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
valuesBuilder.appendField(entry.getKey(), new int[] {entry.getValue()});
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class AdvancedBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, int[]>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
Map<String, int[]> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, int[]> entry : map.entrySet()) {
|
||||
if (entry.getValue().length == 0) {
|
||||
// Skip this invalid
|
||||
continue;
|
||||
}
|
||||
allSkipped = false;
|
||||
valuesBuilder.appendField(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class DrilldownPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Map<String, Integer>>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
Map<String, Map<String, Integer>> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean reallyAllSkipped = true;
|
||||
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
|
||||
JsonObjectBuilder valueBuilder = new JsonObjectBuilder();
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
|
||||
valueBuilder.appendField(valueEntry.getKey(), valueEntry.getValue());
|
||||
allSkipped = false;
|
||||
}
|
||||
if (!allSkipped) {
|
||||
reallyAllSkipped = false;
|
||||
valuesBuilder.appendField(entryValues.getKey(), valueBuilder.build());
|
||||
}
|
||||
}
|
||||
if (reallyAllSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class CustomChart {
|
||||
|
||||
private final String chartId;
|
||||
|
||||
protected CustomChart(String chartId) {
|
||||
if (chartId == null) {
|
||||
throw new IllegalArgumentException("chartId must not be null");
|
||||
}
|
||||
this.chartId = chartId;
|
||||
}
|
||||
|
||||
public JsonObjectBuilder.JsonObject getRequestJsonObject(
|
||||
BiConsumer<String, Throwable> errorLogger, boolean logErrors) {
|
||||
JsonObjectBuilder builder = new JsonObjectBuilder();
|
||||
builder.appendField("chartId", chartId);
|
||||
try {
|
||||
JsonObjectBuilder.JsonObject data = getChartData();
|
||||
if (data == null) {
|
||||
// If the data is null we don't send the chart.
|
||||
return null;
|
||||
}
|
||||
builder.appendField("data", data);
|
||||
} catch (Throwable t) {
|
||||
if (logErrors) {
|
||||
errorLogger.accept("Failed to get data for custom chart with id " + chartId, t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
protected abstract JsonObjectBuilder.JsonObject getChartData() throws Exception;
|
||||
}
|
||||
|
||||
public static class SingleLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Integer> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SingleLineChart(String chartId, Callable<Integer> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
int value = callable.call();
|
||||
if (value == 0) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("value", value).build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An extremely simple JSON builder.
|
||||
*
|
||||
* <p>While this class is neither feature-rich nor the most performant one, it's sufficient enough
|
||||
* for its use-case.
|
||||
*/
|
||||
public static class JsonObjectBuilder {
|
||||
|
||||
private StringBuilder builder = new StringBuilder();
|
||||
|
||||
private boolean hasAtLeastOneField = false;
|
||||
|
||||
public JsonObjectBuilder() {
|
||||
builder.append("{");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a null field to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendNull(String key) {
|
||||
appendFieldUnescaped(key, "null");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a string field to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param value The value of the field.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, String value) {
|
||||
if (value == null) {
|
||||
throw new IllegalArgumentException("JSON value must not be null");
|
||||
}
|
||||
appendFieldUnescaped(key, "\"" + escape(value) + "\"");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an integer field to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param value The value of the field.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, int value) {
|
||||
appendFieldUnescaped(key, String.valueOf(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an object to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param object The object.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, JsonObject object) {
|
||||
if (object == null) {
|
||||
throw new IllegalArgumentException("JSON object must not be null");
|
||||
}
|
||||
appendFieldUnescaped(key, object.toString());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a string array to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param values The string array.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, String[] values) {
|
||||
if (values == null) {
|
||||
throw new IllegalArgumentException("JSON values must not be null");
|
||||
}
|
||||
String escapedValues =
|
||||
Arrays.stream(values)
|
||||
.map(value -> "\"" + escape(value) + "\"")
|
||||
.collect(Collectors.joining(","));
|
||||
appendFieldUnescaped(key, "[" + escapedValues + "]");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an integer array to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param values The integer array.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, int[] values) {
|
||||
if (values == null) {
|
||||
throw new IllegalArgumentException("JSON values must not be null");
|
||||
}
|
||||
String escapedValues =
|
||||
Arrays.stream(values).mapToObj(String::valueOf).collect(Collectors.joining(","));
|
||||
appendFieldUnescaped(key, "[" + escapedValues + "]");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an object array to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param values The integer array.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, JsonObject[] values) {
|
||||
if (values == null) {
|
||||
throw new IllegalArgumentException("JSON values must not be null");
|
||||
}
|
||||
String escapedValues =
|
||||
Arrays.stream(values).map(JsonObject::toString).collect(Collectors.joining(","));
|
||||
appendFieldUnescaped(key, "[" + escapedValues + "]");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a field to the object.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param escapedValue The escaped value of the field.
|
||||
*/
|
||||
private void appendFieldUnescaped(String key, String escapedValue) {
|
||||
if (builder == null) {
|
||||
throw new IllegalStateException("JSON has already been built");
|
||||
}
|
||||
if (key == null) {
|
||||
throw new IllegalArgumentException("JSON key must not be null");
|
||||
}
|
||||
if (hasAtLeastOneField) {
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("\"").append(escape(key)).append("\":").append(escapedValue);
|
||||
hasAtLeastOneField = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the JSON string and invalidates this builder.
|
||||
*
|
||||
* @return The built JSON string.
|
||||
*/
|
||||
public JsonObject build() {
|
||||
if (builder == null) {
|
||||
throw new IllegalStateException("JSON has already been built");
|
||||
}
|
||||
JsonObject object = new JsonObject(builder.append("}").toString());
|
||||
builder = null;
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes the given string like stated in https://www.ietf.org/rfc/rfc4627.txt.
|
||||
*
|
||||
* <p>This method escapes only the necessary characters '"', '\'. and '\u0000' - '\u001F'.
|
||||
* Compact escapes are not used (e.g., '\n' is escaped as "\u000a" and not as "\n").
|
||||
*
|
||||
* @param value The value to escape.
|
||||
* @return The escaped value.
|
||||
*/
|
||||
private static String escape(String value) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < value.length(); i++) {
|
||||
char c = value.charAt(i);
|
||||
if (c == '"') {
|
||||
builder.append("\\\"");
|
||||
} else if (c == '\\') {
|
||||
builder.append("\\\\");
|
||||
} else if (c <= '\u000F') {
|
||||
builder.append("\\u000").append(Integer.toHexString(c));
|
||||
} else if (c <= '\u001F') {
|
||||
builder.append("\\u00").append(Integer.toHexString(c));
|
||||
} else {
|
||||
builder.append(c);
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* A super simple representation of a JSON object.
|
||||
*
|
||||
* <p>This class only exists to make methods of the {@link JsonObjectBuilder} type-safe and not
|
||||
* allow a raw string inputs for methods like {@link JsonObjectBuilder#appendField(String,
|
||||
* JsonObject)}.
|
||||
*/
|
||||
public static class JsonObject {
|
||||
|
||||
private final String value;
|
||||
|
||||
private JsonObject(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ 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,176 +17,294 @@ 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);
|
||||
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_R3(1193, true), MC1_20_R1(1201, true);
|
||||
|
||||
private static MinecraftVersion version;
|
||||
private static Boolean hasGsonSupport;
|
||||
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");
|
||||
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 = true;
|
||||
/**
|
||||
* Logger used by the api
|
||||
*/
|
||||
private static Logger logger = Logger.getLogger("NBTAPI");
|
||||
|
||||
// NBT-API Version
|
||||
protected static final String VERSION = "2.8.0";
|
||||
// NBT-API Version
|
||||
protected static final String VERSION = "2.12.0-SNAPSHOT";
|
||||
|
||||
private final int versionId;
|
||||
private final int versionId;
|
||||
private final boolean mojangMapping;
|
||||
|
||||
MinecraftVersion(int versionId) {
|
||||
this.versionId = versionId;
|
||||
}
|
||||
MinecraftVersion(int versionId) {
|
||||
this(versionId, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A simple comparable Integer, representing the version.
|
||||
*/
|
||||
public int getVersionId() {
|
||||
return versionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current versions is at least the given Version
|
||||
*
|
||||
* @param version The minimum version
|
||||
* @return
|
||||
*/
|
||||
public static boolean isAtLeastVersion(MinecraftVersion version) {
|
||||
return getVersion().getVersionId() >= version.getVersionId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current versions newer (not equal) than the given version
|
||||
*
|
||||
* @param version The minimum version
|
||||
* @return
|
||||
*/
|
||||
public static boolean isNewerThan(MinecraftVersion version) {
|
||||
return getVersion().getVersionId() > version.getVersionId();
|
||||
}
|
||||
MinecraftVersion(int versionId, boolean mojangMapping) {
|
||||
this.versionId = versionId;
|
||||
this.mojangMapping = mojangMapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for this servers MinecraftVersion. Also init's bStats and checks the
|
||||
* shading.
|
||||
*
|
||||
* @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 {
|
||||
version = MinecraftVersion.valueOf(ver.replace("v", "MC"));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
version = MinecraftVersion.UNKNOWN;
|
||||
}
|
||||
if (version != UNKNOWN) {
|
||||
logger.info("[NBTAPI] NMS support '" + version.name() + "' loaded!");
|
||||
} else {
|
||||
logger.warning("[NBTAPI] Wasn't able to find NMS Support! Some functions may not work!");
|
||||
}
|
||||
init();
|
||||
return version;
|
||||
}
|
||||
/**
|
||||
* @return A simple comparable Integer, representing the version.
|
||||
*/
|
||||
public int getVersionId() {
|
||||
return versionId;
|
||||
}
|
||||
|
||||
private static void init() {
|
||||
try {
|
||||
if (hasGsonSupport() && !bStatsDisabled)
|
||||
new ApiMetricsLite();
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.WARNING, "[NBTAPI] Error enabling Metrics!", ex);
|
||||
}
|
||||
/**
|
||||
* @return True if method names are in Mojang format and need to be remapped
|
||||
* internally
|
||||
*/
|
||||
public boolean isMojangMapping() {
|
||||
return mojangMapping;
|
||||
}
|
||||
|
||||
if (hasGsonSupport() && !updateCheckDisabled)
|
||||
new Thread(() -> {
|
||||
try {
|
||||
VersionChecker.checkForUpdates();
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.WARNING, "[NBTAPI] Error while checking for updates!", ex);
|
||||
}
|
||||
}).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' });
|
||||
if (!disablePackageWarning && MinecraftVersion.class.getPackage().getName().equals(defaultPackage)) {
|
||||
logger.warning(
|
||||
"#########################################- NBTAPI -#########################################");
|
||||
logger.warning(
|
||||
"The NBT-API package has not been moved! This *will* cause problems with other plugins containing");
|
||||
logger.warning(
|
||||
"a different version of the api! Please read the guide on the plugin page on how to get the");
|
||||
logger.warning(
|
||||
"Maven Shade plugin to relocate the api to your personal location! If you are not the developer,");
|
||||
logger.warning("please check your plugins and contact their developer, so he can fix this issue.");
|
||||
logger.warning(
|
||||
"#########################################- NBTAPI -#########################################");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This method is required to hot-wire the plugin during mappings generation for
|
||||
* newer mc versions thanks to md_5 not used mojmap.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getPackageName() {
|
||||
if (this == UNKNOWN) {
|
||||
return Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
|
||||
}
|
||||
return this.name().replace("MC", "v");
|
||||
}
|
||||
|
||||
/**
|
||||
* @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"));
|
||||
hasGsonSupport = true;
|
||||
} catch (Exception ex) {
|
||||
logger.info("[NBTAPI] Gson not found! This will not allow the usage of some methods!");
|
||||
hasGsonSupport = false;
|
||||
}
|
||||
return hasGsonSupport;
|
||||
}
|
||||
/**
|
||||
* Returns true if the current versions is at least the given Version
|
||||
*
|
||||
* @param version The minimum version
|
||||
* @return
|
||||
*/
|
||||
public static boolean isAtLeastVersion(MinecraftVersion version) {
|
||||
return getVersion().getVersionId() >= version.getVersionId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calling this function before the NBT-Api is used will disable bStats stats
|
||||
* collection. Please consider not to do that, since it won't affect your plugin
|
||||
* and helps the NBT-Api developer to see api's demand.
|
||||
*/
|
||||
public static void disableBStats() {
|
||||
bStatsDisabled = true;
|
||||
}
|
||||
/**
|
||||
* Returns true if the current versions newer (not equal) than the given version
|
||||
*
|
||||
* @param version The minimum version
|
||||
* @return
|
||||
*/
|
||||
public static boolean isNewerThan(MinecraftVersion version) {
|
||||
return getVersion().getVersionId() > version.getVersionId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the update check. Uses Spiget to get the current version and prints
|
||||
* a warning when outdated.
|
||||
*/
|
||||
public static void disableUpdateCheck() {
|
||||
updateCheckDisabled = true;
|
||||
}
|
||||
/**
|
||||
* Getter for this servers MinecraftVersion. Also init's bStats and checks the
|
||||
* shading.
|
||||
*
|
||||
* @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 {
|
||||
version = MinecraftVersion.valueOf(ver.replace("v", "MC"));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
version = 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 in " + VersionChecker.getPlugin()
|
||||
+ ". The NBT-API will try to work as good as it can! Some functions may not work!");
|
||||
}
|
||||
init();
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forcefully disables the log message for plugins not shading the API to
|
||||
* another location. This may be helpful for networks or development
|
||||
* environments, but please don't use it for plugins that are uploaded to
|
||||
* Spigotmc.
|
||||
*/
|
||||
public static void disablePackageWarning() {
|
||||
disablePackageWarning = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Logger used by the NBT-API
|
||||
*/
|
||||
public static Logger getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the NBT-API logger with a custom implementation.
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
public static String getNBTAPIVersion() {
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
private static void init() {
|
||||
try {
|
||||
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 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(
|
||||
"The NBT-API package has not been moved! This *will* cause problems with other plugins containing");
|
||||
logger.warning(
|
||||
"a different version of the api! Please read the guide on the plugin page on how to get the");
|
||||
logger.warning(
|
||||
"Maven Shade plugin to relocate the api to your personal location! If you are not the developer,");
|
||||
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())) { // 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 {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calling this function before the NBT-Api is used will disable bStats stats
|
||||
* collection. Please consider not to do that, since it won't affect your plugin
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the update check. Uses Spiget to get the current version and prints a
|
||||
* warning when outdated.
|
||||
*/
|
||||
public static void enableUpdateCheck() {
|
||||
updateCheckDisabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forcefully disables the log message for plugins not shading the API to
|
||||
* another location. This may be helpful for networks or development
|
||||
* environments, but please don't use it for plugins that are uploaded to
|
||||
* Spigotmc.
|
||||
*/
|
||||
public static void disablePackageWarning() {
|
||||
disablePackageWarning = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Logger used by the NBT-API
|
||||
*/
|
||||
public static Logger getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the NBT-API logger with a custom implementation.
|
||||
*
|
||||
* @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,24 @@
|
||||
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("[^\\\\](\\.)");
|
||||
|
||||
public static List<String> splitPath(String path) {
|
||||
List<String> list = new ArrayList<>();
|
||||
Matcher matcher = pattern.matcher(path);
|
||||
int startIndex = 0;
|
||||
while (matcher.find(startIndex)) {
|
||||
list.add(path.substring(startIndex, matcher.end() - 1).replace("\\.", "."));
|
||||
startIndex = matcher.end();
|
||||
}
|
||||
list.add(path.substring(startIndex).replace("\\.", "."));
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,46 +8,46 @@ import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
|
||||
public final class ReflectionUtil {
|
||||
|
||||
private static Field field_modifiers;
|
||||
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.");
|
||||
}
|
||||
}
|
||||
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 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 {
|
||||
field.setAccessible(true);
|
||||
field = makeNonFinal(field);
|
||||
field.set(obj, newValue);
|
||||
}
|
||||
public static void setFinal(Object obj, Field field, Object newValue)
|
||||
throws IllegalArgumentException, IllegalAccessException {
|
||||
field.setAccessible(true);
|
||||
field = makeNonFinal(field);
|
||||
field.set(obj, newValue);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package de.tr7zw.changeme.nbtapi.utils;
|
||||
|
||||
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,11 +1,13 @@
|
||||
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 org.bukkit.configuration.file.YamlConfiguration;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
@@ -19,88 +21,105 @@ import de.tr7zw.changeme.nbtapi.NBTItem;
|
||||
*/
|
||||
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";
|
||||
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 void checkForUpdates() throws Exception {
|
||||
URL url = new URL(REQUEST_URL);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.addRequestProperty("User-Agent", USER_AGENT);// Set
|
||||
// User-Agent
|
||||
|
||||
// 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);
|
||||
// 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);
|
||||
|
||||
// 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 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 nbt-api or the plugin that contains the api!");
|
||||
// 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 in '" + getPlugin() + "' 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)!");
|
||||
|
||||
} else if (versionDifference == 0) {
|
||||
MinecraftVersion.getLogger().log(Level.INFO, "[NBTAPI] The NBT-API seems to be up-to-date!");
|
||||
} else if (versionDifference == 1) {
|
||||
MinecraftVersion.getLogger().log(Level.WARNING, "[NBTAPI] The NBT-API at '" + NBTItem.class.getPackage()
|
||||
+ "' seems to be a future Version, not yet released on Spigot/CurseForge!");
|
||||
MinecraftVersion.getLogger().log(Level.WARNING, "[NBTAPI] Current Version: '" + MinecraftVersion.VERSION
|
||||
+ "' Newest Version: " + latest.get("name").getAsString() + "'");
|
||||
}
|
||||
} else {
|
||||
// wut?!
|
||||
MinecraftVersion.getLogger().log(Level.WARNING,
|
||||
"[NBTAPI] Error when looking for Updates! Got non Json Array: '" + element.toString() + "'");
|
||||
}
|
||||
}
|
||||
} 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 in '" + getPlugin()
|
||||
+ "' 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() + "'");
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
// -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;
|
||||
}
|
||||
|
||||
protected static String getPlugin() {
|
||||
ClassLoader classLoader = VersionChecker.class.getClassLoader();
|
||||
InputStream inputStream = classLoader.getResourceAsStream("plugin.yml");
|
||||
|
||||
if (inputStream != null) {
|
||||
try (InputStreamReader reader = new InputStreamReader(inputStream)) {
|
||||
YamlConfiguration pluginYml = YamlConfiguration.loadConfiguration(reader);
|
||||
return pluginYml.getString("name");
|
||||
} catch (IOException e) {
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
return NBTItem.class.getPackage().getName();
|
||||
}
|
||||
|
||||
}
|
||||
-17
@@ -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,16 +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;
|
||||
}
|
||||
|
||||
}
|
||||
+67
-29
@@ -1,10 +1,10 @@
|
||||
package de.tr7zw.changeme.nbtapi.utils.nmsmappings;
|
||||
|
||||
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;
|
||||
import static de.tr7zw.changeme.nbtapi.utils.MinecraftVersion.getLogger;
|
||||
|
||||
/**
|
||||
* Wraps NMS and CRAFT classes
|
||||
@@ -20,42 +20,61 @@ public enum ClassWrapper {
|
||||
CRAFT_WORLD(PackageWrapper.CRAFTBUKKIT, "CraftWorld", null, null),
|
||||
CRAFT_PERSISTENTDATACONTAINER(PackageWrapper.CRAFTBUKKIT, "persistence.CraftPersistentDataContainer",
|
||||
MinecraftVersion.MC1_14_R1, null),
|
||||
NMS_NBTBASE(PackageWrapper.NMS, "NBTBase", null, null, "net.minecraft.nbt"),
|
||||
NMS_NBTTAGSTRING(PackageWrapper.NMS, "NBTTagString", null, null, "net.minecraft.nbt"),
|
||||
NMS_NBTTAGINT(PackageWrapper.NMS, "NBTTagInt", null, null, "net.minecraft.nbt"),
|
||||
NMS_NBTTAGFLOAT(PackageWrapper.NMS, "NBTTagFloat", null, null, "net.minecraft.nbt"),
|
||||
NMS_NBTTAGDOUBLE(PackageWrapper.NMS, "NBTTagDouble", null, null, "net.minecraft.nbt"),
|
||||
NMS_NBTTAGLONG(PackageWrapper.NMS, "NBTTagLong", null, null, "net.minecraft.nbt"),
|
||||
NMS_ITEMSTACK(PackageWrapper.NMS, "ItemStack", null, null, "net.minecraft.world.item"),
|
||||
NMS_NBTTAGCOMPOUND(PackageWrapper.NMS, "NBTTagCompound", null, null, "net.minecraft.nbt"),
|
||||
NMS_NBTTAGLIST(PackageWrapper.NMS, "NBTTagList", null, null, "net.minecraft.nbt"),
|
||||
NMS_NBTCOMPRESSEDSTREAMTOOLS(PackageWrapper.NMS, "NBTCompressedStreamTools", null, null, "net.minecraft.nbt"),
|
||||
NMS_MOJANGSONPARSER(PackageWrapper.NMS, "MojangsonParser", null, null, "net.minecraft.nbt"),
|
||||
NMS_TILEENTITY(PackageWrapper.NMS, "TileEntity", null, null, "net.minecraft.world.level.block.entity"),
|
||||
NMS_BLOCKPOSITION(PackageWrapper.NMS, "BlockPosition", MinecraftVersion.MC1_8_R3, null, "net.minecraft.core"),
|
||||
NMS_WORLDSERVER(PackageWrapper.NMS, "WorldServer", null, null, "net.minecraft.server.level"),
|
||||
NMS_MINECRAFTSERVER(PackageWrapper.NMS, "MinecraftServer", null, null, "net.minecraft.server"),
|
||||
NMS_WORLD(PackageWrapper.NMS, "World", null, null, "net.minecraft.world.level"),
|
||||
NMS_ENTITY(PackageWrapper.NMS, "Entity", null, null, "net.minecraft.world.entity"),
|
||||
NMS_ENTITYTYPES(PackageWrapper.NMS, "EntityTypes", null, null, "net.minecraft.world.entity"),
|
||||
NMS_NBTBASE(PackageWrapper.NMS, "NBTBase", null, null, "net.minecraft.nbt", "net.minecraft.nbt.Tag"),
|
||||
NMS_NBTTAGSTRING(PackageWrapper.NMS, "NBTTagString", null, null, "net.minecraft.nbt",
|
||||
"net.minecraft.nbt.StringTag"),
|
||||
NMS_NBTTAGINT(PackageWrapper.NMS, "NBTTagInt", null, null, "net.minecraft.nbt", "net.minecraft.nbt.IntTag"),
|
||||
NMS_NBTTAGINTARRAY(PackageWrapper.NMS, "NBTTagIntArray", null, null, "net.minecraft.nbt",
|
||||
"net.minecraft.nbt.IntArrayTag"),
|
||||
NMS_NBTTAGFLOAT(PackageWrapper.NMS, "NBTTagFloat", null, null, "net.minecraft.nbt", "net.minecraft.nbt.FloatTag"),
|
||||
NMS_NBTTAGDOUBLE(PackageWrapper.NMS, "NBTTagDouble", null, null, "net.minecraft.nbt",
|
||||
"net.minecraft.nbt.DoubleTag"),
|
||||
NMS_NBTTAGLONG(PackageWrapper.NMS, "NBTTagLong", null, null, "net.minecraft.nbt", "net.minecraft.nbt.LongTag"),
|
||||
NMS_ITEMSTACK(PackageWrapper.NMS, "ItemStack", null, null, "net.minecraft.world.item",
|
||||
"net.minecraft.world.item.ItemStack"),
|
||||
NMS_NBTTAGCOMPOUND(PackageWrapper.NMS, "NBTTagCompound", null, null, "net.minecraft.nbt",
|
||||
"net.minecraft.nbt.CompoundTag"),
|
||||
NMS_NBTTAGLIST(PackageWrapper.NMS, "NBTTagList", null, null, "net.minecraft.nbt", "net.minecraft.nbt.ListTag"),
|
||||
NMS_NBTCOMPRESSEDSTREAMTOOLS(PackageWrapper.NMS, "NBTCompressedStreamTools", null, null, "net.minecraft.nbt",
|
||||
"net.minecraft.nbt.NbtIo"),
|
||||
NMS_MOJANGSONPARSER(PackageWrapper.NMS, "MojangsonParser", null, null, "net.minecraft.nbt",
|
||||
"net.minecraft.nbt.TagParser"),
|
||||
NMS_TILEENTITY(PackageWrapper.NMS, "TileEntity", null, null, "net.minecraft.world.level.block.entity",
|
||||
"net.minecraft.world.level.block.entity.BlockEntity"),
|
||||
NMS_BLOCKPOSITION(PackageWrapper.NMS, "BlockPosition", MinecraftVersion.MC1_8_R3, null, "net.minecraft.core",
|
||||
"net.minecraft.core.BlockPos"),
|
||||
NMS_WORLDSERVER(PackageWrapper.NMS, "WorldServer", null, null, "net.minecraft.server.level",
|
||||
"net.minecraft.server.level.ServerLevel"),
|
||||
NMS_MINECRAFTSERVER(PackageWrapper.NMS, "MinecraftServer", null, null, "net.minecraft.server",
|
||||
"net.minecraft.server.MinecraftServer"),
|
||||
NMS_WORLD(PackageWrapper.NMS, "World", null, null, "net.minecraft.world.level", "net.minecraft.world.level.Level"),
|
||||
NMS_ENTITY(PackageWrapper.NMS, "Entity", null, null, "net.minecraft.world.entity",
|
||||
"net.minecraft.world.entity.Entity"),
|
||||
NMS_ENTITYTYPES(PackageWrapper.NMS, "EntityTypes", null, null, "net.minecraft.world.entity",
|
||||
"net.minecraft.world.entity.EntityType"),
|
||||
NMS_REGISTRYSIMPLE(PackageWrapper.NMS, "RegistrySimple", MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_12_R1),
|
||||
NMS_REGISTRYMATERIALS(PackageWrapper.NMS, "RegistryMaterials", null, null, "net.minecraft.core"),
|
||||
NMS_IREGISTRY(PackageWrapper.NMS, "IRegistry", null, null, "net.minecraft.core"),
|
||||
NMS_MINECRAFTKEY(PackageWrapper.NMS, "MinecraftKey", MinecraftVersion.MC1_8_R3, null, "net.minecraft.resources"),
|
||||
NMS_GAMEPROFILESERIALIZER(PackageWrapper.NMS, "GameProfileSerializer", null, null, "net.minecraft.nbt"),
|
||||
NMS_REGISTRYMATERIALS(PackageWrapper.NMS, "RegistryMaterials", null, null, "net.minecraft.core",
|
||||
"net.minecraft.core.MappedRegistry"),
|
||||
NMS_IREGISTRY(PackageWrapper.NMS, "IRegistry", null, null, "net.minecraft.core", "net.minecraft.core.Registry"),
|
||||
NMS_MINECRAFTKEY(PackageWrapper.NMS, "MinecraftKey", MinecraftVersion.MC1_8_R3, null, "net.minecraft.resources",
|
||||
"net.minecraft.resources.ResourceKey"),
|
||||
NMS_GAMEPROFILESERIALIZER(PackageWrapper.NMS, "GameProfileSerializer", null, null, "net.minecraft.nbt",
|
||||
"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", "net.minecraft.world.level.block.state.BlockState"),
|
||||
GAMEPROFILE(PackageWrapper.NONE, "com.mojang.authlib.GameProfile", MinecraftVersion.MC1_8_R3, null);
|
||||
|
||||
private Class<?> clazz;
|
||||
private boolean enabled = false;
|
||||
private final String mojangName;
|
||||
|
||||
ClassWrapper(PackageWrapper packageId, String clazzName, MinecraftVersion from, MinecraftVersion to) {
|
||||
this(packageId, clazzName, from, to, null);
|
||||
this(packageId, clazzName, from, to, null, null);
|
||||
}
|
||||
|
||||
ClassWrapper(PackageWrapper packageId, String clazzName, MinecraftVersion from, MinecraftVersion to,
|
||||
String mojangMap) {
|
||||
String mojangMap, String mojangName) {
|
||||
this.mojangName = mojangName;
|
||||
if (from != null && MinecraftVersion.getVersion().getVersionId() < from.getVersionId()) {
|
||||
return;
|
||||
}
|
||||
@@ -64,15 +83,27 @@ public enum ClassWrapper {
|
||||
}
|
||||
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) {
|
||||
clazz = Class.forName(clazzName = Forge1710Mappings.getClassMappings().get(this.name()));
|
||||
} else {
|
||||
String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
|
||||
String version = MinecraftVersion.getVersion().getPackageName();
|
||||
clazz = Class.forName(packageId.getUri() + "." + version + "." + clazzName);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (Throwable ex) {
|
||||
getLogger().log(Level.WARNING, "[NBTAPI] Error while trying to resolve the class '" + clazzName + "'!", ex);
|
||||
}
|
||||
}
|
||||
@@ -91,4 +122,11 @@ public enum ClassWrapper {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Package+Class name used by Mojang
|
||||
*/
|
||||
public String getMojangName() {
|
||||
return mojangName;
|
||||
}
|
||||
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
package de.tr7zw.changeme.nbtapi.utils.nmsmappings;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Temporary solution to hold Forge1710 mappings.
|
||||
*
|
||||
* @author EverNife
|
||||
*
|
||||
*/
|
||||
public class Forge1710Mappings {
|
||||
|
||||
private static Map<String, String> classMap = new HashMap<>();
|
||||
private static Map<String, String> methodMap = new HashMap<>();
|
||||
private static Method crucible_toString;
|
||||
|
||||
static {
|
||||
// Fields
|
||||
classMap.put("NMS_NBTBASE", "net.minecraft.nbt.NBTBase");
|
||||
classMap.put("NMS_NBTTAGSTRING", "net.minecraft.nbt.NBTTagString");
|
||||
classMap.put("NMS_NBTTAGINT", "net.minecraft.nbt.NBTTagInt");
|
||||
classMap.put("NMS_NBTTAGINTARRAY", "net.minecraft.nbt.NBTTagIntArray");
|
||||
classMap.put("NMS_NBTTAGFLOAT", "net.minecraft.nbt.NBTTagFloat");
|
||||
classMap.put("NMS_NBTTAGDOUBLE", "net.minecraft.nbt.NBTTagDouble");
|
||||
classMap.put("NMS_NBTTAGLONG", "net.minecraft.nbt.NBTTagLong");
|
||||
classMap.put("NMS_ITEMSTACK", "net.minecraft.item.ItemStack");
|
||||
classMap.put("NMS_NBTTAGCOMPOUND", "net.minecraft.nbt.NBTTagCompound");
|
||||
classMap.put("NMS_NBTTAGLIST", "net.minecraft.nbt.NBTTagList");
|
||||
classMap.put("NMS_NBTCOMPRESSEDSTREAMTOOLS", "net.minecraft.nbt.CompressedStreamTools");
|
||||
classMap.put("NMS_MOJANGSONPARSER", "io.github.crucible.nbt.Crucible_JsonToNBT");
|
||||
classMap.put("NMS_TILEENTITY", "net.minecraft.tileentity.TileEntity");
|
||||
classMap.put("NMS_WORLDSERVER", "net.minecraft.world.WorldServer");
|
||||
classMap.put("NMS_MINECRAFTSERVER", "net.minecraft.server.MinecraftServer");
|
||||
classMap.put("NMS_WORLD", "net.minecraft.world.World");
|
||||
classMap.put("NMS_ENTITY", "net.minecraft.entity.Entity");
|
||||
classMap.put("NMS_ENTITYTYPES", "net.minecraft.entity.EntityList");
|
||||
classMap.put("NMS_REGISTRYMATERIALS", "net.minecraft.util.RegistryNamespaced");
|
||||
classMap.put("NMS_GAMEPROFILESERIALIZER", "net.minecraft.nbt.NBTUtil");
|
||||
classMap.put("NMS_IREGISTRY", "net.minecraft.util.IRegistry");
|
||||
|
||||
// Methods
|
||||
methodMap.put("COMPOUND_SET_FLOAT", "func_74776_a");
|
||||
methodMap.put("COMPOUND_SET_STRING", "func_74778_a");
|
||||
methodMap.put("COMPOUND_SET_INT", "func_74768_a");
|
||||
methodMap.put("COMPOUND_SET_BYTEARRAY", "func_74773_a");
|
||||
methodMap.put("COMPOUND_SET_INTARRAY", "func_74783_a");
|
||||
methodMap.put("COMPOUND_SET_LONG", "func_74772_a");
|
||||
methodMap.put("COMPOUND_SET_SHORT", "func_74777_a");
|
||||
methodMap.put("COMPOUND_SET_BYTE", "func_74774_a");
|
||||
methodMap.put("COMPOUND_SET_DOUBLE", "func_74780_a");
|
||||
methodMap.put("COMPOUND_SET_BOOLEAN", "func_74757_a");
|
||||
methodMap.put("COMPOUND_MERGE", "merge");// Only present on Crucible
|
||||
methodMap.put("COMPOUND_SET", "func_74782_a");
|
||||
methodMap.put("COMPOUND_GET", "func_74781_a");
|
||||
methodMap.put("COMPOUND_GET_LIST", "func_150295_c");
|
||||
methodMap.put("COMPOUND_OWN_TYPE", "func_74732_a");
|
||||
methodMap.put("COMPOUND_GET_FLOAT", "func_74760_g");
|
||||
methodMap.put("COMPOUND_GET_STRING", "func_74779_i");
|
||||
methodMap.put("COMPOUND_GET_INT", "func_74762_e");
|
||||
methodMap.put("COMPOUND_GET_BYTEARRAY", "func_74770_j");
|
||||
methodMap.put("COMPOUND_GET_INTARRAY", "func_74759_k");
|
||||
methodMap.put("COMPOUND_GET_LONG", "func_74763_f");
|
||||
methodMap.put("COMPOUND_GET_SHORT", "func_74765_d");
|
||||
methodMap.put("COMPOUND_GET_BYTE", "func_74771_c");
|
||||
methodMap.put("COMPOUND_GET_DOUBLE", "func_74769_h");
|
||||
methodMap.put("COMPOUND_GET_BOOLEAN", "func_74767_n");
|
||||
methodMap.put("COMPOUND_GET_COMPOUND", "func_74775_l");
|
||||
methodMap.put("COMPOUND_REMOVE_KEY", "func_82580_o");
|
||||
methodMap.put("COMPOUND_HAS_KEY", "func_74764_b");
|
||||
methodMap.put("COMPOUND_GET_KEYS", "func_150296_c");
|
||||
methodMap.put("LISTCOMPOUND_GET_KEYS", "func_150296_c");
|
||||
methodMap.put("NMSITEM_GETTAG", "func_77978_p");
|
||||
methodMap.put("NMSITEM_SAVE", "func_77955_b");
|
||||
methodMap.put("NMSITEM_CREATESTACK", "func_77949_a");
|
||||
methodMap.put("ITEMSTACK_SET_TAG", "func_77982_d");
|
||||
methodMap.put("LIST_SIZE", "func_74745_c");
|
||||
methodMap.put("LEGACY_LIST_ADD", "func_74742_a");
|
||||
methodMap.put("LIST_GET_STRING", "func_150307_f");
|
||||
methodMap.put("LIST_GET_COMPOUND", "func_150305_b");
|
||||
methodMap.put("LIST_GET", "func_150305_b");
|
||||
methodMap.put("NMS_WORLD_GET_TILEENTITY_1_7_10", "func_147438_o");
|
||||
methodMap.put("TILEENTITY_GET_NBT", "func_145841_b");
|
||||
methodMap.put("TILEENTITY_SET_NBT", "func_145839_a");
|
||||
methodMap.put("TILEENTITY_SET_NBT_LEGACY1151", "func_145839_a");
|
||||
methodMap.put("NMS_ENTITY_GET_NBT", "func_70109_d");
|
||||
methodMap.put("NMS_ENTITY_SET_NBT", "func_70020_e");
|
||||
methodMap.put("NBTFILE_READ", "func_74796_a");
|
||||
methodMap.put("NBTFILE_WRITE", "func_74799_a");
|
||||
methodMap.put("PARSE_NBT", "getTagFromJson");
|
||||
methodMap.put("GAMEPROFILE_DESERIALIZE", "func_152459_a");
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
package de.tr7zw.changeme.nbtapi.utils.nmsmappings;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
|
||||
/**
|
||||
* Temporary solution to hold Mojang to unmapped Spigot mappings.
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
public class MojangToMapping {
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
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");
|
||||
put("net.minecraft.nbt.CompoundTag#putByteArray(java.lang.String,byte[])", "a");
|
||||
put("net.minecraft.nbt.CompoundTag#getDouble(java.lang.String)", "k");
|
||||
put("net.minecraft.nbt.CompoundTag#putDouble(java.lang.String,double)", "a");
|
||||
put("net.minecraft.nbt.CompoundTag#getByteArray(java.lang.String)", "m");
|
||||
put("net.minecraft.nbt.CompoundTag#putInt(java.lang.String,int)", "a");
|
||||
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#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");
|
||||
put("net.minecraft.nbt.CompoundTag#put(java.lang.String,net.minecraft.nbt.Tag)", "a");
|
||||
put("net.minecraft.nbt.CompoundTag#getByte(java.lang.String)", "f");
|
||||
put("net.minecraft.nbt.CompoundTag#putIntArray(java.lang.String,int[])", "a");
|
||||
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#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");
|
||||
put("net.minecraft.nbt.CompoundTag#putFloat(java.lang.String,float)", "a");
|
||||
put("net.minecraft.nbt.CompoundTag#getBoolean(java.lang.String)", "q");
|
||||
put("net.minecraft.nbt.CompoundTag#getUUID(java.lang.String)", "a");
|
||||
put("net.minecraft.nbt.CompoundTag#getFloat(java.lang.String)", "j");
|
||||
put("net.minecraft.nbt.ListTag#addTag(int,net.minecraft.nbt.Tag)", "b");
|
||||
put("net.minecraft.nbt.ListTag#setTag(int,net.minecraft.nbt.Tag)", "a");
|
||||
put("net.minecraft.nbt.ListTag#getString(int)", "j");
|
||||
put("net.minecraft.nbt.ListTag#remove(int)", "remove");
|
||||
put("net.minecraft.nbt.ListTag#getCompound(int)", "a");
|
||||
put("net.minecraft.nbt.ListTag#size()", "size");
|
||||
put("net.minecraft.nbt.ListTag#get(int)", "get");
|
||||
put("net.minecraft.nbt.NbtIo#readCompressed(java.io.InputStream)", "a");
|
||||
put("net.minecraft.nbt.NbtIo#writeCompressed(net.minecraft.nbt.CompoundTag,java.io.OutputStream)", "a");
|
||||
put("net.minecraft.nbt.NbtUtils#readGameProfile(net.minecraft.nbt.CompoundTag)", "a");
|
||||
put("net.minecraft.nbt.NbtUtils#writeGameProfile(net.minecraft.nbt.CompoundTag,com.mojang.authlib.GameProfile)",
|
||||
"a");
|
||||
put("net.minecraft.nbt.TagParser#parseTag(java.lang.String)", "a");
|
||||
put("net.minecraft.world.entity.Entity#getEncodeId()", "bk");
|
||||
put("net.minecraft.world.entity.Entity#load(net.minecraft.nbt.CompoundTag)", "g");
|
||||
put("net.minecraft.world.entity.Entity#saveWithoutId(net.minecraft.nbt.CompoundTag)", "f");
|
||||
put("net.minecraft.world.item.ItemStack#setTag(net.minecraft.nbt.CompoundTag)", "c");
|
||||
put("net.minecraft.world.item.ItemStack#getTag()", "s");
|
||||
put("net.minecraft.world.item.ItemStack#save(net.minecraft.nbt.CompoundTag)", "b");
|
||||
put("net.minecraft.world.level.block.entity.BlockEntity#saveWithId()", "n");
|
||||
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#getBlockState(net.minecraft.core.BlockPos)", "c_");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
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");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
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");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public static Map<String, String> getMapping() {
|
||||
switch (MinecraftVersion.getVersion()) {
|
||||
case MC1_20_R1:
|
||||
return MC1_20R1;
|
||||
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!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+34
-33
@@ -16,41 +16,42 @@ import static de.tr7zw.changeme.nbtapi.utils.MinecraftVersion.getLogger;
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
public enum ObjectCreator {
|
||||
NMS_NBTTAGCOMPOUND(null, null, 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(), ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()),;
|
||||
NMS_NBTTAGCOMPOUND(null, null, 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(),
|
||||
ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()),;
|
||||
|
||||
private Constructor<?> construct;
|
||||
private Class<?> targetClass;
|
||||
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())
|
||||
return;
|
||||
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);
|
||||
}
|
||||
}
|
||||
ObjectCreator(MinecraftVersion from, MinecraftVersion to, Class<?> clazz, Class<?>... args) {
|
||||
if (clazz == null)
|
||||
return;
|
||||
if (from != null && MinecraftVersion.getVersion().getVersionId() < from.getVersionId())
|
||||
return;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an Object instance with given args
|
||||
*
|
||||
* @param args
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creates an Object instance with given args
|
||||
*
|
||||
* @param args
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+16
-15
@@ -8,22 +8,23 @@ 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'})),
|
||||
NONE("")
|
||||
;
|
||||
|
||||
private final String uri;
|
||||
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 PackageWrapper(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
private final String uri;
|
||||
|
||||
/**
|
||||
* @return The Uri for that package
|
||||
*/
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
private PackageWrapper(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Uri for that package
|
||||
*/
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
}
|
||||
+421
-198
@@ -1,198 +1,421 @@
|
||||
package de.tr7zw.changeme.nbtapi.utils.nmsmappings;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
|
||||
/**
|
||||
* This class caches method reflections, keeps track of method name changes between versions and allows early checking for problems
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
public enum ReflectionMethod {
|
||||
|
||||
COMPOUND_SET_FLOAT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, float.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setFloat")),
|
||||
COMPOUND_SET_STRING(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setString")),
|
||||
COMPOUND_SET_INT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setInt")),
|
||||
COMPOUND_SET_BYTEARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, byte[].class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setByteArray")),
|
||||
COMPOUND_SET_INTARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, int[].class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setIntArray")),
|
||||
COMPOUND_SET_LONG(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, long.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setLong")),
|
||||
COMPOUND_SET_SHORT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, short.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setShort")),
|
||||
COMPOUND_SET_BYTE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, byte.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setByte")),
|
||||
COMPOUND_SET_DOUBLE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, double.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setDouble")),
|
||||
COMPOUND_SET_BOOLEAN(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, boolean.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setBoolean")),
|
||||
COMPOUND_SET_UUID(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, UUID.class}, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "a")),
|
||||
COMPOUND_MERGE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a")), //FIXME: No Spigot mapping!
|
||||
COMPOUND_SET(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, ClassWrapper.NMS_NBTBASE.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "set")),
|
||||
COMPOUND_GET(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "get")),
|
||||
COMPOUND_GET_LIST(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class, int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getList")),
|
||||
COMPOUND_OWN_TYPE(ClassWrapper.NMS_NBTBASE.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getTypeId")), // Only needed for 1.7.10 getType
|
||||
|
||||
COMPOUND_GET_FLOAT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getFloat")),
|
||||
COMPOUND_GET_STRING(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getString")),
|
||||
COMPOUND_GET_INT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getInt")),
|
||||
COMPOUND_GET_BYTEARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getByteArray")),
|
||||
COMPOUND_GET_INTARRAY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getIntArray")),
|
||||
COMPOUND_GET_LONG(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getLong")),
|
||||
COMPOUND_GET_SHORT(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getShort")),
|
||||
COMPOUND_GET_BYTE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getByte")),
|
||||
COMPOUND_GET_DOUBLE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getDouble")),
|
||||
COMPOUND_GET_BOOLEAN(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getBoolean")),
|
||||
COMPOUND_GET_UUID(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "a")),
|
||||
COMPOUND_GET_COMPOUND(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getCompound")),
|
||||
|
||||
NMSITEM_GETTAG(ClassWrapper.NMS_ITEMSTACK.getClazz(), new Class[] {}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getTag")),
|
||||
NMSITEM_SAVE(ClassWrapper.NMS_ITEMSTACK.getClazz(), new Class[] {ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "save")),
|
||||
NMSITEM_CREATESTACK(ClassWrapper.NMS_ITEMSTACK.getClazz(), 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.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "remove")),
|
||||
COMPOUND_HAS_KEY(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "hasKey")),
|
||||
COMPOUND_GET_TYPE(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), 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")), //FIXME: No Spigot mapping!
|
||||
COMPOUND_GET_KEYS(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "c"), new Since(MinecraftVersion.MC1_13_R1, "getKeys")),
|
||||
|
||||
LISTCOMPOUND_GET_KEYS(ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "c"), new Since(MinecraftVersion.MC1_13_R1, "getKeys")),
|
||||
LIST_REMOVE_KEY(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "a"), new Since(MinecraftVersion.MC1_9_R1, "remove")),
|
||||
LIST_SIZE(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "size")),
|
||||
LIST_SET(ClassWrapper.NMS_NBTTAGLIST.getClazz(), 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")),
|
||||
LEGACY_LIST_ADD(ClassWrapper.NMS_NBTTAGLIST.getClazz(), 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.getClazz(), new Class[]{int.class, ClassWrapper.NMS_NBTBASE.getClazz()}, MinecraftVersion.MC1_14_R1, new Since(MinecraftVersion.MC1_14_R1, "add")),
|
||||
LIST_GET_STRING(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getString")),
|
||||
LIST_GET_COMPOUND(ClassWrapper.NMS_NBTTAGLIST.getClazz(), new Class[]{int.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "get")),
|
||||
LIST_GET(ClassWrapper.NMS_NBTTAGLIST.getClazz(), 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")),
|
||||
|
||||
ITEMSTACK_SET_TAG(ClassWrapper.NMS_ITEMSTACK.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "setTag")),
|
||||
ITEMSTACK_NMSCOPY(ClassWrapper.CRAFT_ITEMSTACK.getClazz(), new Class[]{ItemStack.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "asNMSCopy")),
|
||||
ITEMSTACK_BUKKITMIRROR(ClassWrapper.CRAFT_ITEMSTACK.getClazz(), new Class[]{ClassWrapper.NMS_ITEMSTACK.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "asCraftMirror")),
|
||||
|
||||
CRAFT_WORLD_GET_HANDLE(ClassWrapper.CRAFT_WORLD.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getHandle")),
|
||||
NMS_WORLD_GET_TILEENTITY(ClassWrapper.NMS_WORLDSERVER.getClazz(), new Class[]{ClassWrapper.NMS_BLOCKPOSITION.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "getTileEntity")),
|
||||
NMS_WORLD_SET_TILEENTITY(ClassWrapper.NMS_WORLDSERVER.getClazz(), 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.getClazz(), new Class[]{ClassWrapper.NMS_BLOCKPOSITION.getClazz()}, MinecraftVersion.MC1_8_R3, 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.getClazz(), new Class[]{int.class, int.class, int.class}, MinecraftVersion.MC1_7_R4, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getTileEntity")),
|
||||
|
||||
TILEENTITY_LOAD_LEGACY191(ClassWrapper.NMS_TILEENTITY.getClazz(), 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.getClazz(), 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")), //FIXME: No Spigot mapping!
|
||||
TILEENTITY_LOAD_LEGACY1121(ClassWrapper.NMS_TILEENTITY.getClazz(), 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.getClazz(), 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.getClazz(), 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.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "b"), new Since(MinecraftVersion.MC1_9_R1, "save")),
|
||||
TILEENTITY_SET_NBT_LEGACY1151(ClassWrapper.NMS_TILEENTITY.getClazz(), 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.getClazz(), 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.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_17_R1, new Since(MinecraftVersion.MC1_16_R1, "load")),
|
||||
TILEENTITY_GET_BLOCKDATA(ClassWrapper.NMS_TILEENTITY.getClazz(), new Class[]{}, MinecraftVersion.MC1_16_R1, new Since(MinecraftVersion.MC1_16_R1, "getBlock")),
|
||||
|
||||
CRAFT_ENTITY_GET_HANDLE(ClassWrapper.CRAFT_ENTITY.getClazz(), new Class[]{}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "getHandle")),
|
||||
NMS_ENTITY_SET_NBT(ClassWrapper.NMS_ENTITY.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "f"), new Since(MinecraftVersion.MC1_16_R1, "load")), //FIXME: No Spigot mapping!
|
||||
NMS_ENTITY_GET_NBT(ClassWrapper.NMS_ENTITY.getClazz(), 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_GETSAVEID(ClassWrapper.NMS_ENTITY.getClazz(), new Class[]{}, MinecraftVersion.MC1_14_R1,new Since(MinecraftVersion.MC1_14_R1, "getSaveID")),
|
||||
|
||||
NBTFILE_READ(ClassWrapper.NMS_NBTCOMPRESSEDSTREAMTOOLS.getClazz(), new Class[]{InputStream.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "a")), //FIXME: No Spigot mapping!
|
||||
NBTFILE_WRITE(ClassWrapper.NMS_NBTCOMPRESSEDSTREAMTOOLS.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), OutputStream.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "a")), //FIXME: No Spigot mapping!
|
||||
|
||||
PARSE_NBT(ClassWrapper.NMS_MOJANGSONPARSER.getClazz(), new Class[]{String.class}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "parse")),
|
||||
REGISTRY_KEYSET (ClassWrapper.NMS_REGISTRYSIMPLE.getClazz(), new Class[]{}, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "keySet")),
|
||||
REGISTRY_GET (ClassWrapper.NMS_REGISTRYSIMPLE.getClazz(), new Class[]{Object.class}, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "get")),
|
||||
REGISTRY_SET (ClassWrapper.NMS_REGISTRYSIMPLE.getClazz(), 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.getClazz(), new Class[]{Object.class}, MinecraftVersion.MC1_11_R1, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_11_R1, "b")), //FIXME: No Spigot mapping!
|
||||
REGISTRYMATERIALS_KEYSET (ClassWrapper.NMS_REGISTRYMATERIALS.getClazz(), new Class[]{}, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_13_R1, "keySet")),
|
||||
REGISTRYMATERIALS_GET (ClassWrapper.NMS_REGISTRYMATERIALS.getClazz(), new Class[]{ClassWrapper.NMS_MINECRAFTKEY.getClazz()}, MinecraftVersion.MC1_13_R1, new Since(MinecraftVersion.MC1_13_R1, "get")),
|
||||
REGISTRYMATERIALS_GETKEY (ClassWrapper.NMS_REGISTRYMATERIALS.getClazz(), new Class[]{Object.class}, MinecraftVersion.MC1_13_R2, new Since(MinecraftVersion.MC1_13_R2, "getKey")),
|
||||
|
||||
GAMEPROFILE_DESERIALIZE (ClassWrapper.NMS_GAMEPROFILESERIALIZER.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_7_R4, new Since(MinecraftVersion.MC1_7_R4, "deserialize")),
|
||||
GAMEPROFILE_SERIALIZE (ClassWrapper.NMS_GAMEPROFILESERIALIZER.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz(), ClassWrapper.GAMEPROFILE.getClazz()}, MinecraftVersion.MC1_8_R3, new Since(MinecraftVersion.MC1_8_R3, "serialize")),
|
||||
|
||||
CRAFT_PERSISTENT_DATA_CONTAINER_TO_TAG (ClassWrapper.CRAFT_PERSISTENTDATACONTAINER.getClazz(), new Class[]{}, MinecraftVersion.MC1_14_R1, new Since(MinecraftVersion.MC1_14_R1, "toTagCompound")),
|
||||
CRAFT_PERSISTENT_DATA_CONTAINER_GET_MAP (ClassWrapper.CRAFT_PERSISTENTDATACONTAINER.getClazz(), new Class[]{}, MinecraftVersion.MC1_14_R1, new Since(MinecraftVersion.MC1_14_R1, "getRaw")),
|
||||
CRAFT_PERSISTENT_DATA_CONTAINER_PUT_ALL (ClassWrapper.CRAFT_PERSISTENTDATACONTAINER.getClazz(), new Class[]{ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz()}, MinecraftVersion.MC1_14_R1, new Since(MinecraftVersion.MC1_14_R1, "putAll")),
|
||||
;
|
||||
|
||||
private MinecraftVersion removedAfter;
|
||||
private Since targetVersion;
|
||||
private Method method;
|
||||
private boolean loaded = false;
|
||||
private boolean compatible = false;
|
||||
private String methodName = null;
|
||||
|
||||
ReflectionMethod(Class<?> targetClass, Class<?>[] args, MinecraftVersion addedSince, MinecraftVersion removedAfter, Since... methodnames){
|
||||
this.removedAfter = removedAfter;
|
||||
if(!MinecraftVersion.isAtLeastVersion(addedSince) || (this.removedAfter != null && MinecraftVersion.isNewerThan(removedAfter)))return;
|
||||
compatible = true;
|
||||
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;
|
||||
try{
|
||||
method = targetClass.getMethod(targetVersion.name, args);
|
||||
method.setAccessible(true);
|
||||
loaded = true;
|
||||
methodName = targetVersion.name;
|
||||
}catch(NullPointerException | NoSuchMethodException | SecurityException ex){
|
||||
System.out.println("[NBTAPI] Unable to find the method '" + targetVersion.name + "' in '" + (targetClass == null ? "null" : targetClass.getSimpleName()) + "' Enum: " + this); //NOSONAR This gets loaded before the logger is loaded
|
||||
}
|
||||
}
|
||||
|
||||
ReflectionMethod(Class<?> targetClass, Class<?>[] args, MinecraftVersion addedSince, Since... methodnames){
|
||||
this(targetClass, args, addedSince, null, methodnames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the method on a given target object using the given args.
|
||||
*
|
||||
* @param target
|
||||
* @param args
|
||||
* @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, 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;
|
||||
}
|
||||
|
||||
protected static class Since{
|
||||
public final MinecraftVersion version;
|
||||
public final String name;
|
||||
public Since(MinecraftVersion version, String name) {
|
||||
this.version = version;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
package de.tr7zw.changeme.nbtapi.utils.nmsmappings;
|
||||
|
||||
import java.io.InputStream;
|
||||
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;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
|
||||
/**
|
||||
* This class caches method reflections, keeps track of method name changes
|
||||
* between versions and allows early checking for problems
|
||||
*
|
||||
* @author tr7zw
|
||||
*
|
||||
*/
|
||||
@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"),
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
new Since(MinecraftVersion.MC1_18_R1, "putIntArray(java.lang.String,int[])")),
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
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_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"),
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
new Since(MinecraftVersion.MC1_18_R1, "getIntArray(java.lang.String)")),
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
new Since(MinecraftVersion.MC1_18_R1, "getCompound(java.lang.String)")),
|
||||
|
||||
NMSITEM_GETTAG(ClassWrapper.NMS_ITEMSTACK, new Class[] {}, MinecraftVersion.MC1_7_R4,
|
||||
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"),
|
||||
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")),
|
||||
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
new Since(MinecraftVersion.MC1_18_R1, "getAllKeys()")),
|
||||
// FIXME ?!?
|
||||
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_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"),
|
||||
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"),
|
||||
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)")),
|
||||
|
||||
ITEMSTACK_SET_TAG(ClassWrapper.NMS_ITEMSTACK, new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() },
|
||||
MinecraftVersion.MC1_7_R4, 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")),
|
||||
|
||||
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"),
|
||||
new Since(MinecraftVersion.MC1_18_R1, "getBlockState(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_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() },
|
||||
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"),
|
||||
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_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"),
|
||||
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"),
|
||||
new Since(MinecraftVersion.MC1_18_R1, "getBlockState()")),
|
||||
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
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,
|
||||
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"),
|
||||
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")),
|
||||
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")),
|
||||
|
||||
GAMEPROFILE_DESERIALIZE(ClassWrapper.NMS_GAMEPROFILESERIALIZER,
|
||||
new Class[] { ClassWrapper.NMS_NBTTAGCOMPOUND.getClazz() }, MinecraftVersion.MC1_7_R4,
|
||||
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"),
|
||||
new Since(MinecraftVersion.MC1_18_R1,
|
||||
"writeGameProfile(net.minecraft.nbt.CompoundTag,com.mojang.authlib.GameProfile)")),
|
||||
|
||||
CRAFT_PERSISTENT_DATA_CONTAINER_TO_TAG(ClassWrapper.CRAFT_PERSISTENTDATACONTAINER, new Class[] {},
|
||||
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")),;
|
||||
|
||||
private MinecraftVersion removedAfter;
|
||||
private Since targetVersion;
|
||||
private Method method;
|
||||
private boolean loaded = false;
|
||||
private boolean compatible = false;
|
||||
private String methodName = null;
|
||||
private ClassWrapper parentClassWrapper;
|
||||
|
||||
ReflectionMethod(ClassWrapper targetClass, Class<?>[] args, MinecraftVersion addedSince,
|
||||
MinecraftVersion removedAfter, Since... methodnames) {
|
||||
this.removedAfter = removedAfter;
|
||||
this.parentClassWrapper = targetClass;
|
||||
// Special Case for Modded 1.7.10
|
||||
boolean specialCase = (MinecraftVersion.isForgePresent() && this.name().equals("COMPOUND_MERGE")
|
||||
&& MinecraftVersion.getVersion() == MinecraftVersion.MC1_7_R4); // COMPOUND_MERGE is only present on
|
||||
// Crucible, not on vanilla 1.7.10
|
||||
if (!specialCase && (!MinecraftVersion.isAtLeastVersion(addedSince)
|
||||
|| (this.removedAfter != null && MinecraftVersion.isNewerThan(removedAfter))))
|
||||
return;
|
||||
compatible = true;
|
||||
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);
|
||||
method = targetClass.getClazz().getMethod(targetMethodName, args);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the method on a given target object using the given args.
|
||||
*
|
||||
* @param target
|
||||
* @param args
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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,42 @@
|
||||
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,55 @@
|
||||
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,35 @@
|
||||
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,19 @@
|
||||
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,199 @@
|
||||
package de.tr7zw.changeme.nbtapi.wrapper;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
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")
|
||||
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();
|
||||
};
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
+24
-6
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-parent</artifactId>
|
||||
<version>2.8.0</version>
|
||||
<version>2.12.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>item-nbt-api-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
@@ -12,19 +12,19 @@
|
||||
<dependency>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>item-nbt-api</artifactId>
|
||||
<version>2.8.0</version>
|
||||
<version>2.12.0-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>nbt-injector</artifactId>
|
||||
<version>2.8.0</version>
|
||||
<version>2.12.0-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.tr7zw</groupId>
|
||||
<artifactId>nbt-data-api</artifactId>
|
||||
<version>2.8.0</version>
|
||||
<version>2.12.0-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@@ -39,7 +39,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.4</version>
|
||||
<version>3.5.0</version>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>true</createDependencyReducedPom>
|
||||
<relocations>
|
||||
@@ -88,7 +88,7 @@
|
||||
<!--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-20210514.231722-14.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>
|
||||
@@ -110,6 +110,24 @@
|
||||
</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>
|
||||
@@ -1,223 +1,263 @@
|
||||
package de.tr7zw.nbtapi.plugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
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.utils.MinecraftVersion;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
import de.tr7zw.nbtapi.plugin.tests.GameprofileTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.NBTFileTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.blocks.BlockNBTTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.chunks.ChunkNBTPersistentTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.EqualsTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.ForEachTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.GetterSetterTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.IteratorTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.ListTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.MergeTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.RemovingKeys;
|
||||
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.DirectApplyTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.items.EmptyItemTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.items.ItemConvertionTest;
|
||||
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.ItemMergingTest;
|
||||
|
||||
public class NBTAPI extends JavaPlugin {
|
||||
|
||||
private boolean compatible = true;
|
||||
private ArrayList<de.tr7zw.nbtapi.plugin.tests.Test> apiTests = new ArrayList<>();
|
||||
|
||||
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);
|
||||
saveConfig();
|
||||
|
||||
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
|
||||
apiTests.add(new GetterSetterTest());
|
||||
apiTests.add(new TypeTest());
|
||||
apiTests.add(new RemovingKeys());
|
||||
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());
|
||||
if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_8_R3)) // 1.7.10 not a thing
|
||||
apiTests.add(new MergeTest());
|
||||
apiTests.add(new ForEachTest());
|
||||
apiTests.add(new StreamTest());
|
||||
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());
|
||||
|
||||
// Items
|
||||
if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_8_R3)) // 1.7.10 not a thing
|
||||
apiTests.add(new ItemConvertionTest());
|
||||
apiTests.add(new EmptyItemTest());
|
||||
if(MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_8_R3)) { // 1.7.10 not a thing
|
||||
apiTests.add(new ItemMergingTest());
|
||||
apiTests.add(new DirectApplyTest());
|
||||
}
|
||||
|
||||
// Entity
|
||||
apiTests.add(new EntityTest());
|
||||
apiTests.add(new EntityCustomNbtPersistentTest());
|
||||
|
||||
// Tiles
|
||||
apiTests.add(new TileTest());
|
||||
apiTests.add(new TilesCustomNBTPersistentTest());
|
||||
|
||||
// Chunks
|
||||
apiTests.add(new ChunkNBTPersistentTest());
|
||||
|
||||
// Blocks
|
||||
apiTests.add(new BlockNBTTest());
|
||||
|
||||
// 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());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this; // NOSONAR
|
||||
// new MetricsLite(this); The metrics moved into the API
|
||||
|
||||
getLogger().info("Adding listeners...");
|
||||
Bukkit.getPluginManager().registerEvents(new ReloadListener(), this);
|
||||
getLogger().info("Gson:");
|
||||
MinecraftVersion.hasGsonSupport();
|
||||
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() == null ? "Ok" : entry.getValue().getMessage()));
|
||||
}
|
||||
|
||||
String checkMessage = "Plugins that don't check properly may throw Exeptions, crash or have unexpected behaviors!";
|
||||
if (compatible) {
|
||||
getLogger().info("Success! This version of NBT-API is compatible with your server.");
|
||||
} else {
|
||||
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!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if all selfchecks succeeded
|
||||
*/
|
||||
public boolean isCompatible() {
|
||||
return compatible;
|
||||
}
|
||||
|
||||
}
|
||||
package de.tr7zw.nbtapi.plugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
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;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import de.tr7zw.changeme.nbtapi.utils.VersionChecker;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ClassWrapper;
|
||||
import de.tr7zw.changeme.nbtapi.utils.nmsmappings.ReflectionMethod;
|
||||
import de.tr7zw.nbtapi.plugin.tests.GameprofileTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.NBTFileTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.blocks.BlockNBTTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.chunks.ChunkNBTPersistentTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.EnumTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.EqualsTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.compounds.ForEachTest;
|
||||
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.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.ItemMergingTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.items.ItemStackConversionTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.proxy.DataItemProxyTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.proxy.SimpleProxyTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.items.MetaTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.items.NBTModifyItemTest;
|
||||
import de.tr7zw.nbtapi.plugin.tests.items.SmuggleTest;
|
||||
|
||||
public class NBTAPI extends JavaPlugin {
|
||||
|
||||
private boolean compatible = true;
|
||||
private List<de.tr7zw.nbtapi.plugin.tests.Test> apiTests = new ArrayList<>();
|
||||
|
||||
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();
|
||||
|
||||
if (!getConfig().getBoolean("bStats.enabled")) {
|
||||
getLogger().info("bStats disabled");
|
||||
MinecraftVersion.disableBStats();
|
||||
}
|
||||
|
||||
if (!getConfig().getBoolean("updateCheck.enabled")) {
|
||||
getLogger().info("Update check disabled");
|
||||
MinecraftVersion.disableUpdateCheck();
|
||||
} else {
|
||||
MinecraftVersion.enableUpdateCheck();
|
||||
}
|
||||
|
||||
// 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
|
||||
apiTests.add(new GetterSetterTest());
|
||||
apiTests.add(new TypeTest());
|
||||
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());
|
||||
apiTests.add(new StreamTest());
|
||||
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());
|
||||
}
|
||||
apiTests.add(new EmptyItemTest());
|
||||
apiTests.add(new SmuggleTest());
|
||||
apiTests.add(new DataItemProxyTest());
|
||||
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());
|
||||
|
||||
// Tiles
|
||||
apiTests.add(new TileTest());
|
||||
apiTests.add(new TilesCustomNBTPersistentTest());
|
||||
|
||||
// Chunks
|
||||
apiTests.add(new ChunkNBTPersistentTest());
|
||||
|
||||
// Blocks
|
||||
apiTests.add(new BlockNBTTest());
|
||||
|
||||
// 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());
|
||||
|
||||
}
|
||||
|
||||
@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);
|
||||
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!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if all selfchecks succeeded
|
||||
*/
|
||||
public boolean isCompatible() {
|
||||
return compatible;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,42 +1,45 @@
|
||||
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!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
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!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,16 +10,16 @@ import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
|
||||
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);
|
||||
profile = null;
|
||||
profile = NBTGameProfile.fromNBT(nbt);
|
||||
if (profile == null || !profile.getId().equals(uuid)) {
|
||||
throw new NbtApiException("Error when converting a GameProfile from/to NBT!");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
GameProfile profile = new GameProfile(uuid, "random");
|
||||
NBTCompound nbt = NBTGameProfile.toNBT(profile);
|
||||
profile = null;
|
||||
profile = NBTGameProfile.fromNBT(nbt);
|
||||
if (profile == null || !profile.getId().equals(uuid)) {
|
||||
throw new NbtApiException("Error when converting a GameProfile from/to NBT!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,38 +11,53 @@ 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");
|
||||
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");
|
||||
block.setString("type", "wool");
|
||||
file.save();
|
||||
|
||||
if(!"wool".equals(block.getString("type"))) {
|
||||
throw new NbtApiException("SubCompounds did not work!");
|
||||
}
|
||||
@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");
|
||||
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");
|
||||
block.setString("type", "wool");
|
||||
file.save();
|
||||
|
||||
NBTFile fileLoaded = new NBTFile(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.asNBTString();
|
||||
NBTContainer rebuild = new NBTContainer(str);
|
||||
if (!str.equals(rebuild.asNBTString())) {
|
||||
throw new NbtApiException("Wasn't able to parse NBT from a String!");
|
||||
}
|
||||
}
|
||||
if (!"wool".equals(block.getString("type"))) {
|
||||
throw new NbtApiException("SubCompounds did not work!");
|
||||
}
|
||||
|
||||
NBTFile fileLoaded = new NBTFile(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);
|
||||
if (!str.equals(rebuild.toString())) {
|
||||
throw new NbtApiException("Wasn't able to parse NBT from a String!");
|
||||
}
|
||||
|
||||
NBTCompound dummy = new NBTContainer();
|
||||
dummy.setString("test1", "key1");
|
||||
NBTFile.saveTo(testFile, dummy);
|
||||
dummy = new NBTContainer();
|
||||
dummy.setString("test2", "key2");
|
||||
NBTFile.saveTo(testFile, dummy);
|
||||
dummy = NBTFile.readFrom(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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,6 @@ package de.tr7zw.nbtapi.plugin.tests;
|
||||
|
||||
public interface Test {
|
||||
|
||||
public void test() throws Exception; // NOSONAR
|
||||
|
||||
public void test() throws Exception; // NOSONAR
|
||||
|
||||
}
|
||||
+25
-24
@@ -12,29 +12,30 @@ import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
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().hasKey("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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+25
-24
@@ -12,29 +12,30 @@ import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
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.hasKey("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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package de.tr7zw.nbtapi.plugin.tests.compounds;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NBTContainer;
|
||||
import de.tr7zw.changeme.nbtapi.NBTType;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class EnumTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTCompound comp = new NBTContainer();
|
||||
comp.setEnum("test", NBTType.NBTTagEnd);
|
||||
NBTType type = comp.getEnum("test", NBTType.class);
|
||||
NBTType typeNonNull = comp.getOrNull("test", NBTType.class);
|
||||
NBTType typeDefault = comp.getOrDefault("invalid", NBTType.NBTTagByte);
|
||||
NBTType typeDefaultFound = comp.getOrDefault("test", NBTType.NBTTagByte);
|
||||
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!");
|
||||
}
|
||||
|
||||
}
|
||||
+37
-20
@@ -11,26 +11,43 @@ import de.tr7zw.changeme.nbtapi.NBTItem;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class EqualsTest implements Test{
|
||||
public class EqualsTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTContainer cont = new NBTContainer();
|
||||
cont.setString("hello", "world");
|
||||
cont.setInteger("theAnswer", 42);
|
||||
cont.addCompound("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);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTContainer cont = new NBTContainer();
|
||||
cont.setString("hello", "world");
|
||||
cont.setInteger("theAnswer", 42);
|
||||
cont.addCompound("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);
|
||||
}
|
||||
|
||||
// empty test
|
||||
|
||||
if (!new NBTContainer().equals(new NBTContainer())) {
|
||||
throw new NbtApiException("Two empty tags did not match!");
|
||||
}
|
||||
|
||||
// not equal test
|
||||
NBTContainer part1 = new NBTContainer();
|
||||
part1.setString("a", "a");
|
||||
part1.setString("b", "b");
|
||||
NBTContainer part2 = new NBTContainer();
|
||||
part2.setString("a", "a");
|
||||
part2.setString("b", "a");
|
||||
if (part1.equals(part2)) {
|
||||
throw new NbtApiException("Missmatched nbt did match!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+24
-24
@@ -4,8 +4,8 @@ import java.util.ListIterator;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTCompoundList;
|
||||
import de.tr7zw.changeme.nbtapi.NBTContainer;
|
||||
import de.tr7zw.changeme.nbtapi.NBTListCompound;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
/**
|
||||
@@ -14,37 +14,37 @@ import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
*/
|
||||
public class ForEachTest implements Test {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTContainer comp = new NBTContainer();
|
||||
@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);
|
||||
compList.addCompound().setInteger("id", 1);
|
||||
compList.addCompound().setInteger("id", 2);
|
||||
compList.addCompound().setInteger("id", 3);
|
||||
int count = 0;
|
||||
for (NBTListCompound listComp : compList) {
|
||||
count++;
|
||||
for (ReadWriteNBT listComp : compList) {
|
||||
count++;
|
||||
}
|
||||
if(count != compList.size())
|
||||
throw new NbtApiException("For loop did not get all Entries!");
|
||||
if (count != compList.size())
|
||||
throw new NbtApiException("For loop did not get all Entries!");
|
||||
count = 0;
|
||||
ListIterator<NBTListCompound> lit = compList.listIterator();
|
||||
while(lit.hasNext()){
|
||||
lit.next();
|
||||
count++;
|
||||
ListIterator<ReadWriteNBT> lit = compList.listIterator();
|
||||
while (lit.hasNext()) {
|
||||
lit.next();
|
||||
count++;
|
||||
}
|
||||
if(count != compList.size())
|
||||
throw new NbtApiException("ListIterator did not get all Entries!");
|
||||
if (count != compList.size())
|
||||
throw new NbtApiException("ListIterator did not get all Entries!");
|
||||
count = 0;
|
||||
while(lit.hasPrevious()){
|
||||
lit.previous();
|
||||
count++;
|
||||
while (lit.hasPrevious()) {
|
||||
lit.previous();
|
||||
count++;
|
||||
}
|
||||
if(count != compList.size())
|
||||
throw new NbtApiException("ListIterator previous did not get all Entries!");
|
||||
if (count != compList.size())
|
||||
throw new NbtApiException("ListIterator previous did not get all Entries!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+51
-48
@@ -1,61 +1,64 @@
|
||||
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 {
|
||||
|
||||
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 SHORT_TEST_KEY = "shortTest";
|
||||
private static final String BYTE_TEST_KEY = "byteTest";
|
||||
private static final String FLOAT_TEST_KEY = "floatTest";
|
||||
private static final String LONG_TEST_KEY = "longTest";
|
||||
private static final String INTARRAY_TEST_KEY = "intarrayTest";
|
||||
private static final String BYTEARRAY_TEST_KEY = "bytearrayTest";
|
||||
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 SHORT_TEST_KEY = "shortTest";
|
||||
private static final String BYTE_TEST_KEY = "byteTest";
|
||||
private static final String FLOAT_TEST_KEY = "floatTest";
|
||||
private static final String LONG_TEST_KEY = "longTest";
|
||||
private static final String INTARRAY_TEST_KEY = "intarrayTest";
|
||||
private static final String BYTEARRAY_TEST_KEY = "bytearrayTest";
|
||||
|
||||
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;
|
||||
private static final short SHORT_TEST_VALUE = 64;
|
||||
private static final byte BYTE_TEST_VALUE = 7;
|
||||
private static final float FLOAT_TEST_VALUE = 13.37f;
|
||||
private static final long LONG_TEST_VALUE = (long) Integer.MAX_VALUE + 42L;
|
||||
private static final int[] INTARRAY_TEST_VALUE = new int[] { 1337, 42, 69 };
|
||||
private static final byte[] BYTEARRAY_TEST_VALUE = new byte[] { 8, 7, 3, 2 };
|
||||
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;
|
||||
private static final short SHORT_TEST_VALUE = 64;
|
||||
private static final byte BYTE_TEST_VALUE = 7;
|
||||
private static final float FLOAT_TEST_VALUE = 13.37f;
|
||||
private static final long LONG_TEST_VALUE = (long) Integer.MAX_VALUE + 42L;
|
||||
private static final int[] INTARRAY_TEST_VALUE = new int[] { 1337, 42, 69 };
|
||||
private static final byte[] BYTEARRAY_TEST_VALUE = new byte[] { 8, 7, 3, 2 };
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTContainer comp = new NBTContainer();
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
ReadWriteNBT comp = NBT.createNBTObject();
|
||||
|
||||
comp.setString(STRING_TEST_KEY, STRING_TEST_VALUE);
|
||||
comp.setInteger(INT_TEST_KEY, INT_TEST_VALUE);
|
||||
comp.setDouble(DOUBLE_TEST_KEY, DOUBLE_TEST_VALUE);
|
||||
comp.setBoolean(BOOLEAN_TEST_KEY, BOOLEAN_TEST_VALUE);
|
||||
comp.setByte(BYTE_TEST_KEY, BYTE_TEST_VALUE);
|
||||
comp.setShort(SHORT_TEST_KEY, SHORT_TEST_VALUE);
|
||||
comp.setLong(LONG_TEST_KEY, LONG_TEST_VALUE);
|
||||
comp.setFloat(FLOAT_TEST_KEY, FLOAT_TEST_VALUE);
|
||||
comp.setIntArray(INTARRAY_TEST_KEY, INTARRAY_TEST_VALUE);
|
||||
comp.setByteArray(BYTEARRAY_TEST_KEY, BYTEARRAY_TEST_VALUE);
|
||||
comp.setString(STRING_TEST_KEY, STRING_TEST_VALUE);
|
||||
comp.setInteger(INT_TEST_KEY, INT_TEST_VALUE);
|
||||
comp.setDouble(DOUBLE_TEST_KEY, DOUBLE_TEST_VALUE);
|
||||
comp.setBoolean(BOOLEAN_TEST_KEY, BOOLEAN_TEST_VALUE);
|
||||
comp.setByte(BYTE_TEST_KEY, BYTE_TEST_VALUE);
|
||||
comp.setShort(SHORT_TEST_KEY, SHORT_TEST_VALUE);
|
||||
comp.setLong(LONG_TEST_KEY, LONG_TEST_VALUE);
|
||||
comp.setFloat(FLOAT_TEST_KEY, FLOAT_TEST_VALUE);
|
||||
comp.setIntArray(INTARRAY_TEST_KEY, INTARRAY_TEST_VALUE);
|
||||
comp.setByteArray(BYTEARRAY_TEST_KEY, BYTEARRAY_TEST_VALUE);
|
||||
|
||||
if (!comp.hasKey(STRING_TEST_KEY)) {
|
||||
throw new NbtApiException("Wasn't able to check a key! The Item-NBT-API may not work!");
|
||||
}
|
||||
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)) {
|
||||
throw new NbtApiException("One key does not equal the original value! The Item-NBT-API may not work!");
|
||||
}
|
||||
}
|
||||
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
|
||||
|| (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!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+67
-66
@@ -10,85 +10,86 @@ import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class GsonTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if (!MinecraftVersion.hasGsonSupport()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ItemStack item = new ItemStack(Material.STONE, 1);
|
||||
NBTItem nbtItem = new NBTItem(item);
|
||||
@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());
|
||||
nbtItem.setObject(JSON_TEST_KEY, new SimpleJsonTestObject());
|
||||
|
||||
if (!nbtItem.hasKey(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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
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
|
||||
private static final String JSON_TEST_KEY = "jsonTest";
|
||||
// region STATIC FINAL VARIABLES
|
||||
private static final String JSON_TEST_KEY = "jsonTest";
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
// end region STATIC FINAL VARIABLES
|
||||
// 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 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 String getTestString() {
|
||||
return testString;
|
||||
}
|
||||
|
||||
public void setTestString(String testString) {
|
||||
this.testString = testString;
|
||||
}
|
||||
public void setTestString(String testString) {
|
||||
this.testString = testString;
|
||||
}
|
||||
|
||||
public int getTestInteger() {
|
||||
return testInteger;
|
||||
}
|
||||
public int getTestInteger() {
|
||||
return testInteger;
|
||||
}
|
||||
|
||||
public void setTestInteger(int testInteger) {
|
||||
this.testInteger = testInteger;
|
||||
}
|
||||
public void setTestInteger(int testInteger) {
|
||||
this.testInteger = testInteger;
|
||||
}
|
||||
|
||||
public double getTestDouble() {
|
||||
return testDouble;
|
||||
}
|
||||
public double getTestDouble() {
|
||||
return testDouble;
|
||||
}
|
||||
|
||||
public void setTestDouble(double testDouble) {
|
||||
this.testDouble = testDouble;
|
||||
}
|
||||
public void setTestDouble(double testDouble) {
|
||||
this.testDouble = testDouble;
|
||||
}
|
||||
|
||||
public boolean isTestBoolean() {
|
||||
return testBoolean;
|
||||
}
|
||||
public boolean isTestBoolean() {
|
||||
return testBoolean;
|
||||
}
|
||||
|
||||
public void setTestBoolean(boolean testBoolean) {
|
||||
this.testBoolean = testBoolean;
|
||||
}
|
||||
}
|
||||
public void setTestBoolean(boolean testBoolean) {
|
||||
this.testBoolean = testBoolean;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
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 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!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+3
-3
@@ -48,16 +48,16 @@ public class IteratorTest implements Test {
|
||||
assertTrue(!iterator.hasNext());
|
||||
try {
|
||||
iterator.next();
|
||||
} catch(NoSuchElementException expected) {
|
||||
} catch (NoSuchElementException expected) {
|
||||
return;
|
||||
} catch(Exception e) {
|
||||
} 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) {
|
||||
if (!condition) {
|
||||
throw new NbtApiException("iterator test failed");
|
||||
}
|
||||
}
|
||||
|
||||
+142
-107
@@ -1,6 +1,7 @@
|
||||
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;
|
||||
@@ -9,125 +10,159 @@ import de.tr7zw.changeme.nbtapi.NBTList;
|
||||
import de.tr7zw.changeme.nbtapi.NBTListCompound;
|
||||
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 ListTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTContainer comp = new NBTContainer();
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTContainer comp = new NBTContainer();
|
||||
|
||||
// Strings
|
||||
NBTList<String> list = comp.getStringList("testlist");
|
||||
list.add("test1");
|
||||
list.add("test2");
|
||||
list.add("test3");
|
||||
list.add("test4");
|
||||
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.");
|
||||
}
|
||||
// Strings
|
||||
NBTList<String> list = comp.getStringList("testlist");
|
||||
list.add("test1");
|
||||
list.add("test2");
|
||||
list.add("test3");
|
||||
list.add("test4");
|
||||
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();
|
||||
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");
|
||||
subsubcomp.setString("deep", "String");
|
||||
subsubcomp.getCompoundList("deeplist").addCompound().setString("test", "test");
|
||||
subsubcomp.getCompoundList("clonelist").addCompound(comp);
|
||||
// Compound
|
||||
NBTCompoundList taglist = comp.getCompoundList("complist");
|
||||
NBTListCompound 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");
|
||||
subsubcomp.setString("deep", "String");
|
||||
subsubcomp.getCompoundList("deeplist").addCompound().setString("test", "test");
|
||||
subsubcomp.getCompoundList("clonelist").addCompound(comp);
|
||||
|
||||
taglist = null;
|
||||
lcomp = null;
|
||||
subsubcomp = null;
|
||||
taglist = null;
|
||||
lcomp = null;
|
||||
subsubcomp = null;
|
||||
|
||||
taglist = comp.getCompoundList("complist");
|
||||
if (taglist.size() == 1) {
|
||||
lcomp = taglist.get(0);
|
||||
if (lcomp.getKeys().size() != 4) {
|
||||
throw new NbtApiException("Wrong key amount in Taglist (" + lcomp.getKeys().size() + ")!");
|
||||
} else if (!(lcomp.getDouble("double1") == 0.3333 && lcomp.getInteger("int1") == 42
|
||||
&& lcomp.getString("test2").equals("test2") && !lcomp.hasKey("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"))) {
|
||||
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) {
|
||||
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 {
|
||||
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!");
|
||||
}
|
||||
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"))) {
|
||||
throw new NbtApiException("One key in the Taglist changed! The Item-NBT-API may not work!");
|
||||
} 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 (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 (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!");
|
||||
}
|
||||
|
||||
// Integer
|
||||
NBTList<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!");
|
||||
}
|
||||
if (comp.getListType("complist") != NBTType.NBTTagCompound) {
|
||||
throw new NbtApiException("complist had the wrong type! The Item-NBT-API may not work!");
|
||||
}
|
||||
|
||||
// Double
|
||||
NBTList<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!");
|
||||
}
|
||||
// Integer
|
||||
NBTList<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])));
|
||||
}
|
||||
|
||||
// Float
|
||||
NBTList<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!");
|
||||
}
|
||||
if (comp.getListType("inttest") != NBTType.NBTTagInt) {
|
||||
throw new NbtApiException("inttest had the wrong type! The Item-NBT-API may not work!");
|
||||
}
|
||||
|
||||
// Long
|
||||
NBTList<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])));
|
||||
}
|
||||
// Double
|
||||
NBTList<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("longtest") != NBTType.NBTTagLong) {
|
||||
throw new NbtApiException("longtest had the wrong type! The Item-NBT-API may not work!");
|
||||
}
|
||||
|
||||
}
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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))) {
|
||||
// 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");
|
||||
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))) {
|
||||
// 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!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
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!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+12
-12
@@ -6,17 +6,17 @@ import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class MergeTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTContainer test1 = new NBTContainer();
|
||||
test1.setString("test1", "test");
|
||||
NBTContainer test2 = new NBTContainer();
|
||||
test2.setString("test2", "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!");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTContainer test1 = new NBTContainer();
|
||||
test1.setString("test1", "test");
|
||||
NBTContainer test2 = new NBTContainer();
|
||||
test2.setString("test2", "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!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
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!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+50
-50
@@ -6,62 +6,62 @@ import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class RemovingKeys implements Test {
|
||||
|
||||
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 SHORT_TEST_KEY = "shortTest";
|
||||
private static final String BYTE_TEST_KEY = "byteTest";
|
||||
private static final String FLOAT_TEST_KEY = "floatTest";
|
||||
private static final String LONG_TEST_KEY = "longTest";
|
||||
private static final String INTARRAY_TEST_KEY = "intarrayTest";
|
||||
private static final String BYTEARRAY_TEST_KEY = "bytearrayTest";
|
||||
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 SHORT_TEST_KEY = "shortTest";
|
||||
private static final String BYTE_TEST_KEY = "byteTest";
|
||||
private static final String FLOAT_TEST_KEY = "floatTest";
|
||||
private static final String LONG_TEST_KEY = "longTest";
|
||||
private static final String INTARRAY_TEST_KEY = "intarrayTest";
|
||||
private static final String BYTEARRAY_TEST_KEY = "bytearrayTest";
|
||||
|
||||
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;
|
||||
private static final short SHORT_TEST_VALUE = 64;
|
||||
private static final byte BYTE_TEST_VALUE = 7;
|
||||
private static final float FLOAT_TEST_VALUE = 13.37f;
|
||||
private static final long LONG_TEST_VALUE = (long) Integer.MAX_VALUE + 42L;
|
||||
private static final int[] INTARRAY_TEST_VALUE = new int[] { 1337, 42, 69 };
|
||||
private static final byte[] BYTEARRAY_TEST_VALUE = new byte[] { 8, 7, 3, 2 };
|
||||
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;
|
||||
private static final short SHORT_TEST_VALUE = 64;
|
||||
private static final byte BYTE_TEST_VALUE = 7;
|
||||
private static final float FLOAT_TEST_VALUE = 13.37f;
|
||||
private static final long LONG_TEST_VALUE = (long) Integer.MAX_VALUE + 42L;
|
||||
private static final int[] INTARRAY_TEST_VALUE = new int[] { 1337, 42, 69 };
|
||||
private static final byte[] BYTEARRAY_TEST_VALUE = new byte[] { 8, 7, 3, 2 };
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTContainer comp = new NBTContainer();
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTContainer comp = new NBTContainer();
|
||||
|
||||
comp.setString(STRING_TEST_KEY, STRING_TEST_VALUE);
|
||||
comp.setInteger(INT_TEST_KEY, INT_TEST_VALUE);
|
||||
comp.setDouble(DOUBLE_TEST_KEY, DOUBLE_TEST_VALUE);
|
||||
comp.setBoolean(BOOLEAN_TEST_KEY, BOOLEAN_TEST_VALUE);
|
||||
comp.setByte(BYTE_TEST_KEY, BYTE_TEST_VALUE);
|
||||
comp.setShort(SHORT_TEST_KEY, SHORT_TEST_VALUE);
|
||||
comp.setLong(LONG_TEST_KEY, LONG_TEST_VALUE);
|
||||
comp.setFloat(FLOAT_TEST_KEY, FLOAT_TEST_VALUE);
|
||||
comp.setIntArray(INTARRAY_TEST_KEY, INTARRAY_TEST_VALUE);
|
||||
comp.setByteArray(BYTEARRAY_TEST_KEY, BYTEARRAY_TEST_VALUE);
|
||||
comp.setString(STRING_TEST_KEY, STRING_TEST_VALUE);
|
||||
comp.setInteger(INT_TEST_KEY, INT_TEST_VALUE);
|
||||
comp.setDouble(DOUBLE_TEST_KEY, DOUBLE_TEST_VALUE);
|
||||
comp.setBoolean(BOOLEAN_TEST_KEY, BOOLEAN_TEST_VALUE);
|
||||
comp.setByte(BYTE_TEST_KEY, BYTE_TEST_VALUE);
|
||||
comp.setShort(SHORT_TEST_KEY, SHORT_TEST_VALUE);
|
||||
comp.setLong(LONG_TEST_KEY, LONG_TEST_VALUE);
|
||||
comp.setFloat(FLOAT_TEST_KEY, FLOAT_TEST_VALUE);
|
||||
comp.setIntArray(INTARRAY_TEST_KEY, INTARRAY_TEST_VALUE);
|
||||
comp.setByteArray(BYTEARRAY_TEST_KEY, BYTEARRAY_TEST_VALUE);
|
||||
|
||||
if (comp.getKeys().size() != 10) {
|
||||
throw new NbtApiException("Key amount did not match after setting keys!");
|
||||
}
|
||||
if (comp.getKeys().size() != 10) {
|
||||
throw new NbtApiException("Key amount did not match after setting keys!");
|
||||
}
|
||||
|
||||
comp.setString(STRING_TEST_KEY, null);
|
||||
comp.setInteger(INT_TEST_KEY, null);
|
||||
comp.setDouble(DOUBLE_TEST_KEY, null);
|
||||
comp.setBoolean(BOOLEAN_TEST_KEY, null);
|
||||
comp.setByte(BYTE_TEST_KEY, null);
|
||||
comp.setShort(SHORT_TEST_KEY, null);
|
||||
comp.setLong(LONG_TEST_KEY, null);
|
||||
comp.setFloat(FLOAT_TEST_KEY, null);
|
||||
comp.setIntArray(INTARRAY_TEST_KEY, null);
|
||||
comp.setByteArray(BYTEARRAY_TEST_KEY, null);
|
||||
comp.setString(STRING_TEST_KEY, null);
|
||||
comp.setInteger(INT_TEST_KEY, null);
|
||||
comp.setDouble(DOUBLE_TEST_KEY, null);
|
||||
comp.setBoolean(BOOLEAN_TEST_KEY, null);
|
||||
comp.setByte(BYTE_TEST_KEY, null);
|
||||
comp.setShort(SHORT_TEST_KEY, null);
|
||||
comp.setLong(LONG_TEST_KEY, null);
|
||||
comp.setFloat(FLOAT_TEST_KEY, null);
|
||||
comp.setIntArray(INTARRAY_TEST_KEY, null);
|
||||
comp.setByteArray(BYTEARRAY_TEST_KEY, null);
|
||||
|
||||
if (comp.getKeys().size() != 0) {
|
||||
throw new NbtApiException("Keys where not removed using the setter with null!");
|
||||
}
|
||||
if (comp.getKeys().size() != 0) {
|
||||
throw new NbtApiException("Keys where not removed using the setter with null!");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
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 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!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+14
-14
@@ -7,20 +7,20 @@ import de.tr7zw.changeme.nbtapi.NBTContainer;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class StreamTest implements Test{
|
||||
public class StreamTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTContainer base = new NBTContainer();
|
||||
base.addCompound("sub").setString("hello", "world");
|
||||
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
||||
base.getCompound("sub").writeCompound(outStream);
|
||||
byte[] data = outStream.toByteArray();
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
|
||||
NBTContainer container = new NBTContainer(inputStream);
|
||||
if(!container.toString().equals(base.getCompound("sub").toString())) {
|
||||
throw new NbtApiException("Component content did not match! " + base.getCompound("sub") + " " + container);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTContainer base = new NBTContainer();
|
||||
base.getOrCreateCompound("sub").setString("hello", "world");
|
||||
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
||||
base.getOrCreateCompound("sub").writeCompound(outStream);
|
||||
byte[] data = outStream.toByteArray();
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
|
||||
NBTContainer container = new NBTContainer(inputStream);
|
||||
if (!container.toString().equals(base.getOrCreateCompound("sub").toString())) {
|
||||
throw new NbtApiException("Component content did not match! " + base.getCompound("sub") + " " + container);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+40
-40
@@ -7,50 +7,50 @@ import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class SubCompoundsTest 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;
|
||||
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 {
|
||||
NBTContainer cont = new NBTContainer();
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTContainer cont = new NBTContainer();
|
||||
|
||||
NBTCompound comp = cont.addCompound(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);
|
||||
NBTCompound comp = cont.addCompound(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!");
|
||||
}
|
||||
if (cont.getCompound("invalide") != null) {
|
||||
throw new NbtApiException("An invalide compound did not return null!");
|
||||
}
|
||||
|
||||
comp = null;
|
||||
comp = null;
|
||||
|
||||
comp = cont.getCompound(COMP_TEST_KEY);
|
||||
if (comp == null) {
|
||||
throw new NbtApiException("Wasn't able to get the NBTCompound!");
|
||||
}
|
||||
if (!comp.hasKey(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!");
|
||||
}
|
||||
}
|
||||
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!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+10
-10
@@ -8,15 +8,15 @@ import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class TypeTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTCompound comp = new NBTContainer();
|
||||
comp.setString("s", "test");
|
||||
comp.setInteger("i", 42);
|
||||
comp.addCompound("c");
|
||||
if (comp.getType("s") != NBTType.NBTTagString || comp.getType("i") != NBTType.NBTTagInt
|
||||
|| comp.getType("c") != NBTType.NBTTagCompound)
|
||||
throw new NbtApiException("One parsed type did not match what it should have been!");
|
||||
}
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
NBTCompound comp = new NBTContainer();
|
||||
comp.setString("s", "test");
|
||||
comp.setInteger("i", 42);
|
||||
comp.addCompound("c");
|
||||
if (comp.getType("s") != NBTType.NBTTagString || comp.getType("i") != NBTType.NBTTagInt
|
||||
|| comp.getType("c") != NBTType.NBTTagCompound)
|
||||
throw new NbtApiException("One parsed type did not match what it should have been!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,15 +10,17 @@ import de.tr7zw.changeme.nbtapi.data.NBTData;
|
||||
import de.tr7zw.changeme.nbtapi.data.WorldData;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class WorldDataTest implements Test{
|
||||
public class WorldDataTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
for(World world : Bukkit.getWorlds()){
|
||||
if(!new File(world.getWorldFolder(), "level.dat").exists())continue;
|
||||
WorldData data = NBTData.getWorldData(world);
|
||||
if(data.getWorldName() == null || data.getSpawnPosition() == null)throw new NbtApiException("Got Null");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
if (!new File(world.getWorldFolder(), "level.dat").exists())
|
||||
continue;
|
||||
WorldData data = NBTData.getWorldData(world);
|
||||
if (data.getWorldName() == null || data.getSpawnPosition() == null)
|
||||
throw new NbtApiException("Got Null");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+23
-22
@@ -14,28 +14,29 @@ import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class EntityCustomNbtPersistentTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if(MinecraftVersion.getVersion().getVersionId() < MinecraftVersion.MC1_14_R1.getVersionId())return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
if (!world.getEntitiesByClasses(Animals.class, Monster.class).isEmpty()) {
|
||||
Entity ent = world.getEntitiesByClasses(Animals.class, Monster.class).iterator().next();
|
||||
NBTEntity nbtEnt = new NBTEntity(ent);
|
||||
NBTCompound comp = nbtEnt.getPersistentDataContainer();
|
||||
comp.setString("Hello", "World");
|
||||
NBTEntity nbtent = new NBTEntity(ent);
|
||||
if (!nbtent.toString().contains("Hello:\"World\"")) {
|
||||
throw new NbtApiException("Custom Data did not save to the Entity!");
|
||||
}
|
||||
comp.removeKey("Hello");
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if (MinecraftVersion.getVersion().getVersionId() < MinecraftVersion.MC1_14_R1.getVersionId())
|
||||
return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
if (!world.getEntitiesByClasses(Animals.class, Monster.class).isEmpty()) {
|
||||
Entity ent = world.getEntitiesByClasses(Animals.class, Monster.class).iterator().next();
|
||||
NBTEntity nbtEnt = new NBTEntity(ent);
|
||||
NBTCompound comp = nbtEnt.getPersistentDataContainer();
|
||||
comp.setString("Hello", "World");
|
||||
NBTEntity nbtent = new NBTEntity(ent);
|
||||
if (!nbtent.toString().contains("Hello:\"World\"")) {
|
||||
throw new NbtApiException("Custom Data did not save to the Entity!");
|
||||
}
|
||||
comp.removeKey("Hello");
|
||||
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTEntities!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTEntities!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+15
-15
@@ -11,20 +11,20 @@ import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class EntityTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
if (!world.getEntitiesByClasses(Animals.class, Monster.class).isEmpty()) {
|
||||
NBTEntity nbte = new NBTEntity(
|
||||
world.getEntitiesByClasses(Animals.class, Monster.class).iterator().next());
|
||||
nbte.setString("INVALIDEKEY", "test");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTEntities!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
if (!world.getEntitiesByClasses(Animals.class, Monster.class).isEmpty()) {
|
||||
NBTEntity nbte = new NBTEntity(
|
||||
world.getEntitiesByClasses(Animals.class, Monster.class).iterator().next());
|
||||
nbte.setString("INVALIDEKEY", "test");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTEntities!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+23
-22
@@ -14,28 +14,29 @@ import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
public class EntityCustomNbtInjectorTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if(!NBTInjector.isInjected())return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
if (!world.getEntitiesByClasses(Animals.class, Monster.class).isEmpty()) {
|
||||
Entity ent = world.getEntitiesByClasses(Animals.class, Monster.class).iterator().next();
|
||||
ent = NBTInjector.patchEntity(ent);
|
||||
NBTCompound comp = NBTInjector.getNbtData(ent);
|
||||
comp.setString("Hello", "World");
|
||||
NBTEntity nbtent = new NBTEntity(ent);
|
||||
if (!nbtent.toString().contains("__extraData:{Hello:\"World\"}")) {
|
||||
throw new NbtApiException("Custom Data did not save to the Entity!");
|
||||
}
|
||||
comp.removeKey("Hello");
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if (!NBTInjector.isInjected())
|
||||
return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
if (!world.getEntitiesByClasses(Animals.class, Monster.class).isEmpty()) {
|
||||
Entity ent = world.getEntitiesByClasses(Animals.class, Monster.class).iterator().next();
|
||||
ent = NBTInjector.patchEntity(ent);
|
||||
NBTCompound comp = NBTInjector.getNbtData(ent);
|
||||
comp.setString("Hello", "World");
|
||||
NBTEntity nbtent = new NBTEntity(ent);
|
||||
if (!nbtent.toString().contains("__extraData:{Hello:\"World\"}")) {
|
||||
throw new NbtApiException("Custom Data did not save to the Entity!");
|
||||
}
|
||||
comp.removeKey("Hello");
|
||||
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTEntities!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTEntities!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+29
-29
@@ -13,34 +13,34 @@ import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
public class MergeTileSubCompoundTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if (!NBTInjector.isInjected())
|
||||
return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
boolean failed = false;
|
||||
Block block = world.getBlockAt(world.getSpawnLocation().getBlockX(), 255,
|
||||
world.getSpawnLocation().getBlockZ());
|
||||
if (block.getType() == Material.AIR) {
|
||||
block.setType(Material.CHEST);
|
||||
NBTCompound comp = NBTInjector.getNbtData(block.getState());
|
||||
comp.addCompound("subcomp").setString("hello", "world");
|
||||
NBTContainer cont = new NBTContainer();
|
||||
cont.mergeCompound(comp.getCompound("subcomp"));
|
||||
if (!(cont.hasKey("hello") && "world".equals(cont.getString("hello")))) {
|
||||
failed = true;
|
||||
}
|
||||
block.setType(Material.AIR);
|
||||
if(failed) {
|
||||
throw new NbtApiException("Data was not correct! " + cont);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTTiles!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if (!NBTInjector.isInjected())
|
||||
return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
boolean failed = false;
|
||||
Block block = world.getBlockAt(world.getSpawnLocation().getBlockX(), 255,
|
||||
world.getSpawnLocation().getBlockZ());
|
||||
if (block.getType() == Material.AIR) {
|
||||
block.setType(Material.CHEST);
|
||||
NBTCompound comp = NBTInjector.getNbtData(block.getState());
|
||||
comp.addCompound("subcomp").setString("hello", "world");
|
||||
NBTContainer cont = new NBTContainer();
|
||||
cont.mergeCompound(comp.getCompound("subcomp"));
|
||||
if (!(cont.hasTag("hello") && "world".equals(cont.getString("hello")))) {
|
||||
failed = true;
|
||||
}
|
||||
block.setType(Material.AIR);
|
||||
if (failed) {
|
||||
throw new NbtApiException("Data was not correct! " + cont);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTTiles!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+22
-22
@@ -14,28 +14,28 @@ import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
public class SpawnEntityCustomNbtInjectorTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if (!NBTInjector.isInjected())
|
||||
return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
Entity entity = world.spawnEntity(new Location(world, 0, 0, 0), EntityType.ARMOR_STAND);
|
||||
entity = NBTInjector.patchEntity(entity);
|
||||
NBTCompound comp = NBTInjector.getNbtData(entity);
|
||||
comp.setString("Hello", "World");
|
||||
NBTEntity nbtent = new NBTEntity(entity);
|
||||
if (!nbtent.toString().contains("__extraData:{Hello:\"World\"}")) {
|
||||
throw new NbtApiException("Custom Data did not save to the Entity!");
|
||||
}
|
||||
comp.removeKey("Hello");
|
||||
entity.remove();
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if (!NBTInjector.isInjected())
|
||||
return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
Entity entity = world.spawnEntity(new Location(world, 0, 0, 0), EntityType.ARMOR_STAND);
|
||||
entity = NBTInjector.patchEntity(entity);
|
||||
NBTCompound comp = NBTInjector.getNbtData(entity);
|
||||
comp.setString("Hello", "World");
|
||||
NBTEntity nbtent = new NBTEntity(entity);
|
||||
if (!nbtent.toString().contains("__extraData:{Hello:\"World\"}")) {
|
||||
throw new NbtApiException("Custom Data did not save to the Entity!");
|
||||
}
|
||||
comp.removeKey("Hello");
|
||||
entity.remove();
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTEntities!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTEntities!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+24
-23
@@ -13,28 +13,29 @@ import de.tr7zw.nbtinjector.NBTInjector;
|
||||
|
||||
public class TilesCustomNBTInjectorTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if(!NBTInjector.isInjected())return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
Block block = world.getBlockAt(world.getSpawnLocation().getBlockX(), 255,
|
||||
world.getSpawnLocation().getBlockZ());
|
||||
if (block.getType() == Material.AIR) {
|
||||
block.setType(Material.CHEST);
|
||||
NBTCompound comp = NBTInjector.getNbtData(block.getState());
|
||||
comp.setString("Foo", "Bar");
|
||||
if (!new NBTTileEntity(block.getState()).toString().contains("__extraData:{Foo:\"Bar\"}")) {
|
||||
block.setType(Material.AIR);
|
||||
throw new NbtApiException("Custom Data did not save to the Tile!");
|
||||
}
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTTiles!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
if (!NBTInjector.isInjected())
|
||||
return;
|
||||
if (!Bukkit.getWorlds().isEmpty()) {
|
||||
World world = Bukkit.getWorlds().get(0);
|
||||
try {
|
||||
Block block = world.getBlockAt(world.getSpawnLocation().getBlockX(), 255,
|
||||
world.getSpawnLocation().getBlockZ());
|
||||
if (block.getType() == Material.AIR) {
|
||||
block.setType(Material.CHEST);
|
||||
NBTCompound comp = NBTInjector.getNbtData(block.getState());
|
||||
comp.setString("Foo", "Bar");
|
||||
if (!new NBTTileEntity(block.getState()).toString().contains("__extraData:{Foo:\"Bar\"}")) {
|
||||
block.setType(Material.AIR);
|
||||
throw new NbtApiException("Custom Data did not save to the Tile!");
|
||||
}
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new NbtApiException("Wasn't able to use NBTTiles!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package de.tr7zw.nbtapi.plugin.tests.items;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBTItem;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.changeme.nbtapi.iface.ReadableNBT;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class DirectApplyMetaTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
ItemStack baseItem = new ItemStack(Material.STONE);
|
||||
NBTItem nbti = new NBTItem(baseItem, true);
|
||||
nbti.setString("SomeKey", "SomeValue");
|
||||
nbti.modifyMeta(this::modifyMeta);
|
||||
|
||||
if (!new NBTItem(baseItem).hasTag("SomeKey") || !"SomeValue".equals(baseItem.getItemMeta().getDisplayName())) {
|
||||
throw new NbtApiException("The item was not modified correctly!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void modifyMeta(ReadableNBT nbt, ItemMeta meta) {
|
||||
meta.setDisplayName(nbt.getString("SomeKey"));
|
||||
}
|
||||
|
||||
}
|
||||
+30
-10
@@ -3,20 +3,40 @@ package de.tr7zw.nbtapi.plugin.tests.items;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBT;
|
||||
import de.tr7zw.changeme.nbtapi.NBTItem;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class DirectApplyTest implements Test{
|
||||
public class DirectApplyTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
ItemStack baseItem = new ItemStack(Material.STONE);
|
||||
NBTItem nbti = new NBTItem(baseItem, true);
|
||||
nbti.setString("SomeKey", "SomeValue");
|
||||
if(!baseItem.equals(nbti.getItem()) || !new NBTItem(baseItem).hasKey("SomeKey")) {
|
||||
throw new NbtApiException("The item's where not equal!");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
ItemStack baseItem = new ItemStack(Material.STONE);
|
||||
NBTItem nbti = new NBTItem(baseItem, true);
|
||||
nbti.setString("SomeKey", "SomeValue");
|
||||
if (!baseItem.equals(nbti.getItem()) || !new NBTItem(baseItem).hasTag("SomeKey")) {
|
||||
throw new NbtApiException("The item's where not equal!");
|
||||
}
|
||||
baseItem = new ItemStack(Material.STONE);
|
||||
String inside = NBT.modify(baseItem, nbt -> {
|
||||
nbt.setString("SomeKey", "SomeValue");
|
||||
return nbt.getString("SomeKey");
|
||||
});
|
||||
baseItem = NBT.itemStackFromNBT(NBT.itemStackToNBT(baseItem)); // trick to force the item to be "real", not a
|
||||
// Spigot only item
|
||||
String outside = NBT.get(baseItem, nbt -> {
|
||||
return nbt.getString("SomeKey");
|
||||
});
|
||||
if (!new NBTItem(baseItem).hasTag("SomeKey")) {
|
||||
throw new NbtApiException("The data was not applied!");
|
||||
}
|
||||
if (!"SomeValue".equals(inside)) {
|
||||
throw new NbtApiException("Inside returned the wrong value!");
|
||||
}
|
||||
if (!"SomeValue".equals(outside)) {
|
||||
throw new NbtApiException("Outside returned the wrong value!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+52
-14
@@ -3,26 +3,64 @@ package de.tr7zw.nbtapi.plugin.tests.items;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import de.tr7zw.changeme.nbtapi.NBT;
|
||||
import de.tr7zw.changeme.nbtapi.NBTItem;
|
||||
import de.tr7zw.changeme.nbtapi.NbtApiException;
|
||||
import de.tr7zw.nbtapi.plugin.tests.Test;
|
||||
|
||||
public class EmptyItemTest implements Test {
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
ItemStack item = new ItemStack(Material.STONE);
|
||||
NBTItem nbti = new NBTItem(item);
|
||||
if (nbti.getBoolean("test") == null || nbti.getString("test") == null)
|
||||
throw new NbtApiException("Getters return null instead of the default value");
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
ItemStack item = new ItemStack(Material.STONE);
|
||||
NBTItem nbti = new NBTItem(item);
|
||||
if (nbti.hasNBTData()) {
|
||||
throw new NbtApiException("Item reported to have data");
|
||||
}
|
||||
if (nbti.getBoolean("test") == null || nbti.getString("test") == null || nbti.getFloatList("test") == null) {
|
||||
throw new NbtApiException("Getters return null instead of the default value");
|
||||
}
|
||||
nbti.setString("test", "test");
|
||||
if (!nbti.hasNBTData()) {
|
||||
throw new NbtApiException("Item reported to have no data");
|
||||
}
|
||||
nbti.removeKey("test");
|
||||
if (nbti.hasNBTData()) {
|
||||
throw new NbtApiException("Item reported to have data after deletion");
|
||||
}
|
||||
|
||||
try {
|
||||
Material barrel = Material.valueOf("BARREL");
|
||||
item = new ItemStack(barrel);
|
||||
nbti = new NBTItem(item);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// old version
|
||||
}
|
||||
}
|
||||
try {
|
||||
Material barrel = Material.valueOf("BARREL");
|
||||
item = new ItemStack(barrel);
|
||||
nbti = new NBTItem(item);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// old version
|
||||
}
|
||||
|
||||
item = new ItemStack(Material.STONE);
|
||||
NBT.modify(item, nbt -> {
|
||||
nbt.setString("test", "test");
|
||||
});
|
||||
NBT.get(item, nbt -> {
|
||||
if (!nbt.hasNBTData()) {
|
||||
throw new NbtApiException("Item reported to have no data");
|
||||
}
|
||||
return nbt.hasNBTData();
|
||||
});
|
||||
NBT.modify(item, nbt -> {
|
||||
nbt.removeKey("test");
|
||||
});
|
||||
NBT.get(item, nbt -> {
|
||||
if (nbt.hasNBTData()) {
|
||||
throw new NbtApiException("Item reported to have data after deletion");
|
||||
}
|
||||
return nbt.hasNBTData();
|
||||
});
|
||||
|
||||
ItemStack testItem = new ItemStack(Material.STONE);
|
||||
NBTItem nbt = new NBTItem(testItem, true);
|
||||
nbt.removeKey("not there");
|
||||
nbt.setBoolean("test", true);
|
||||
}
|
||||
|
||||
}
|
||||
Loaded 100 of 138 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user